main.go 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. // SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
  2. // SPDX-License-Identifier: MIT
  3. //go:build !js
  4. // +build !js
  5. // custom-logger is an example of how the Pion API provides an customizable logging API
  6. package main
  7. import (
  8. "fmt"
  9. "os"
  10. "github.com/pion/logging"
  11. "github.com/pion/webrtc/v3"
  12. )
  13. // Everything below is the Pion WebRTC API! Thanks for using it ❤️.
  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...)
  17. type customLogger struct{}
  18. // Print all messages except trace
  19. func (c customLogger) Trace(string) {}
  20. func (c customLogger) Tracef(string, ...interface{}) {}
  21. func (c customLogger) Debug(msg string) { fmt.Printf("customLogger Debug: %s\n", msg) }
  22. func (c customLogger) Debugf(format string, args ...interface{}) {
  23. c.Debug(fmt.Sprintf(format, args...))
  24. }
  25. func (c customLogger) Info(msg string) { fmt.Printf("customLogger Info: %s\n", msg) }
  26. func (c customLogger) Infof(format string, args ...interface{}) {
  27. c.Trace(fmt.Sprintf(format, args...))
  28. }
  29. func (c customLogger) Warn(msg string) { fmt.Printf("customLogger Warn: %s\n", msg) }
  30. func (c customLogger) Warnf(format string, args ...interface{}) {
  31. c.Warn(fmt.Sprintf(format, args...))
  32. }
  33. func (c customLogger) Error(msg string) { fmt.Printf("customLogger Error: %s\n", msg) }
  34. func (c customLogger) Errorf(format string, args ...interface{}) {
  35. c.Error(fmt.Sprintf(format, args...))
  36. }
  37. // customLoggerFactory satisfies the interface logging.LoggerFactory
  38. // This allows us to create different loggers per subsystem. So we can
  39. // add custom behavior
  40. type customLoggerFactory struct{}
  41. func (c customLoggerFactory) NewLogger(subsystem string) logging.LeveledLogger {
  42. fmt.Printf("Creating logger for %s \n", subsystem)
  43. return customLogger{}
  44. }
  45. func main() {
  46. // Create a new API with a custom logger
  47. // This SettingEngine allows non-standard WebRTC behavior
  48. s := webrtc.SettingEngine{
  49. LoggerFactory: customLoggerFactory{},
  50. }
  51. api := webrtc.NewAPI(webrtc.WithSettingEngine(s))
  52. // Create a new RTCPeerConnection
  53. offerPeerConnection, err := api.NewPeerConnection(webrtc.Configuration{})
  54. if err != nil {
  55. panic(err)
  56. }
  57. defer func() {
  58. if cErr := offerPeerConnection.Close(); cErr != nil {
  59. fmt.Printf("cannot close offerPeerConnection: %v\n", cErr)
  60. }
  61. }()
  62. // We need a DataChannel so we can have ICE Candidates
  63. if _, err = offerPeerConnection.CreateDataChannel("custom-logger", nil); err != nil {
  64. panic(err)
  65. }
  66. // Create a new RTCPeerConnection
  67. answerPeerConnection, err := api.NewPeerConnection(webrtc.Configuration{})
  68. if err != nil {
  69. panic(err)
  70. }
  71. defer func() {
  72. if cErr := answerPeerConnection.Close(); cErr != nil {
  73. fmt.Printf("cannot close answerPeerConnection: %v\n", cErr)
  74. }
  75. }()
  76. // Set the handler for Peer connection state
  77. // This will notify you when the peer has connected/disconnected
  78. offerPeerConnection.OnConnectionStateChange(func(s webrtc.PeerConnectionState) {
  79. fmt.Printf("Peer Connection State has changed: %s (offerer)\n", s.String())
  80. if s == webrtc.PeerConnectionStateFailed {
  81. // Wait until PeerConnection has had no network activity for 30 seconds or another failure. It may be reconnected using an ICE Restart.
  82. // Use webrtc.PeerConnectionStateDisconnected if you are interested in detecting faster timeout.
  83. // Note that the PeerConnection may come back from PeerConnectionStateDisconnected.
  84. fmt.Println("Peer Connection has gone to failed exiting")
  85. os.Exit(0)
  86. }
  87. })
  88. // Set the handler for Peer connection state
  89. // This will notify you when the peer has connected/disconnected
  90. answerPeerConnection.OnConnectionStateChange(func(s webrtc.PeerConnectionState) {
  91. fmt.Printf("Peer Connection State has changed: %s (answerer)\n", s.String())
  92. if s == webrtc.PeerConnectionStateFailed {
  93. // Wait until PeerConnection has had no network activity for 30 seconds or another failure. It may be reconnected using an ICE Restart.
  94. // Use webrtc.PeerConnectionStateDisconnected if you are interested in detecting faster timeout.
  95. // Note that the PeerConnection may come back from PeerConnectionStateDisconnected.
  96. fmt.Println("Peer Connection has gone to failed exiting")
  97. os.Exit(0)
  98. }
  99. })
  100. // Set ICE Candidate handler. As soon as a PeerConnection has gathered a candidate
  101. // send it to the other peer
  102. answerPeerConnection.OnICECandidate(func(i *webrtc.ICECandidate) {
  103. if i != nil {
  104. if iceErr := offerPeerConnection.AddICECandidate(i.ToJSON()); iceErr != nil {
  105. panic(iceErr)
  106. }
  107. }
  108. })
  109. // Set ICE Candidate handler. As soon as a PeerConnection has gathered a candidate
  110. // send it to the other peer
  111. offerPeerConnection.OnICECandidate(func(i *webrtc.ICECandidate) {
  112. if i != nil {
  113. if iceErr := answerPeerConnection.AddICECandidate(i.ToJSON()); iceErr != nil {
  114. panic(iceErr)
  115. }
  116. }
  117. })
  118. // Create an offer for the other PeerConnection
  119. offer, err := offerPeerConnection.CreateOffer(nil)
  120. if err != nil {
  121. panic(err)
  122. }
  123. // SetLocalDescription, needed before remote gets offer
  124. if err = offerPeerConnection.SetLocalDescription(offer); err != nil {
  125. panic(err)
  126. }
  127. // Take offer from remote, answerPeerConnection is now able to contact
  128. // the other PeerConnection
  129. if err = answerPeerConnection.SetRemoteDescription(offer); err != nil {
  130. panic(err)
  131. }
  132. // Create an Answer to send back to our originating PeerConnection
  133. answer, err := answerPeerConnection.CreateAnswer(nil)
  134. if err != nil {
  135. panic(err)
  136. }
  137. // Set the answerer's LocalDescription
  138. if err = answerPeerConnection.SetLocalDescription(answer); err != nil {
  139. panic(err)
  140. }
  141. // SetRemoteDescription on original PeerConnection, this finishes our signaling
  142. // bother PeerConnections should be able to communicate with each other now
  143. if err = offerPeerConnection.SetRemoteDescription(answer); err != nil {
  144. panic(err)
  145. }
  146. // Block forever
  147. select {}
  148. }