1// +build !js
2
3package main
4
5import (
6	"fmt"
7
8	"github.com/pion/logging"
9	"github.com/pion/webrtc/v3"
10)
11
12// Everything below is the Pion WebRTC API! Thanks for using it ❤️.
13
14// customLogger satisfies the interface logging.LeveledLogger
15// a logger is created per subsystem in Pion, so you can have custom
16// behavior per subsystem (ICE, DTLS, SCTP...)
17type customLogger struct {
18}
19
20// Print all messages except trace
21func (c customLogger) Trace(msg string)                          {}
22func (c customLogger) Tracef(format string, args ...interface{}) {}
23
24func (c customLogger) Debug(msg string) { fmt.Printf("customLogger Debug: %s\n", msg) }
25func (c customLogger) Debugf(format string, args ...interface{}) {
26	c.Debug(fmt.Sprintf(format, args...))
27}
28func (c customLogger) Info(msg string) { fmt.Printf("customLogger Info: %s\n", msg) }
29func (c customLogger) Infof(format string, args ...interface{}) {
30	c.Trace(fmt.Sprintf(format, args...))
31}
32func (c customLogger) Warn(msg string) { fmt.Printf("customLogger Warn: %s\n", msg) }
33func (c customLogger) Warnf(format string, args ...interface{}) {
34	c.Warn(fmt.Sprintf(format, args...))
35}
36func (c customLogger) Error(msg string) { fmt.Printf("customLogger Error: %s\n", msg) }
37func (c customLogger) Errorf(format string, args ...interface{}) {
38	c.Error(fmt.Sprintf(format, args...))
39}
40
41// customLoggerFactory satisfies the interface logging.LoggerFactory
42// This allows us to create different loggers per subsystem. So we can
43// add custom behavior
44type customLoggerFactory struct {
45}
46
47func (c customLoggerFactory) NewLogger(subsystem string) logging.LeveledLogger {
48	fmt.Printf("Creating logger for %s \n", subsystem)
49	return customLogger{}
50}
51
52func main() {
53	// Create a new API with a custom logger
54	// This SettingEngine allows non-standard WebRTC behavior
55	s := webrtc.SettingEngine{
56		LoggerFactory: customLoggerFactory{},
57	}
58	api := webrtc.NewAPI(webrtc.WithSettingEngine(s))
59
60	// Create a new RTCPeerConnection
61	offerPeerConnection, err := api.NewPeerConnection(webrtc.Configuration{})
62	if err != nil {
63		panic(err)
64	}
65
66	// We need a DataChannel so we can have ICE Candidates
67	if _, err = offerPeerConnection.CreateDataChannel("custom-logger", nil); err != nil {
68		panic(err)
69	}
70
71	// Create a new RTCPeerConnection
72	answerPeerConnection, err := api.NewPeerConnection(webrtc.Configuration{})
73	if err != nil {
74		panic(err)
75	}
76
77	// Set ICE Candidate handler. As soon as a PeerConnection has gathered a candidate
78	// send it to the other peer
79	answerPeerConnection.OnICECandidate(func(i *webrtc.ICECandidate) {
80		if i != nil {
81			if iceErr := offerPeerConnection.AddICECandidate(i.ToJSON()); iceErr != nil {
82				panic(iceErr)
83			}
84		}
85	})
86
87	// Set ICE Candidate handler. As soon as a PeerConnection has gathered a candidate
88	// send it to the other peer
89	offerPeerConnection.OnICECandidate(func(i *webrtc.ICECandidate) {
90		if i != nil {
91			if iceErr := answerPeerConnection.AddICECandidate(i.ToJSON()); iceErr != nil {
92				panic(iceErr)
93			}
94		}
95	})
96
97	// Create an offer for the other PeerConnection
98	offer, err := offerPeerConnection.CreateOffer(nil)
99	if err != nil {
100		panic(err)
101	}
102
103	// SetLocalDescription, needed before remote gets offer
104	if err = offerPeerConnection.SetLocalDescription(offer); err != nil {
105		panic(err)
106	}
107
108	// Take offer from remote, answerPeerConnection is now able to contact
109	// the other PeerConnection
110	if err = answerPeerConnection.SetRemoteDescription(offer); err != nil {
111		panic(err)
112	}
113
114	// Create an Answer to send back to our originating PeerConnection
115	answer, err := answerPeerConnection.CreateAnswer(nil)
116	if err != nil {
117		panic(err)
118	}
119
120	// Set the answerer's LocalDescription
121	if err = answerPeerConnection.SetLocalDescription(answer); err != nil {
122		panic(err)
123	}
124
125	// SetRemoteDescription on original PeerConnection, this finishes our signaling
126	// bother PeerConnections should be able to communicate with each other now
127	if err = offerPeerConnection.SetRemoteDescription(answer); err != nil {
128		panic(err)
129	}
130
131	select {}
132}
133