diff --git a/examples/bandwidth-estimation-from-disk/main.go b/examples/bandwidth-estimation-from-disk/main.go index c1cf585f87..54e73d1a00 100644 --- a/examples/bandwidth-estimation-from-disk/main.go +++ b/examples/bandwidth-estimation-from-disk/main.go @@ -8,17 +8,20 @@ package main import ( + "bufio" + "encoding/base64" + "encoding/json" "errors" "fmt" "io" "os" + "strings" "time" "github.com/pion/interceptor" "github.com/pion/interceptor/pkg/cc" "github.com/pion/interceptor/pkg/gcc" "github.com/pion/webrtc/v4" - "github.com/pion/webrtc/v4/examples/internal/signal" "github.com/pion/webrtc/v4/pkg/media" "github.com/pion/webrtc/v4/pkg/media/ivfreader" ) @@ -144,7 +147,7 @@ func main() { // Wait for the offer to be pasted offer := webrtc.SessionDescription{} - signal.Decode(signal.MustReadStdin(), &offer) + decode(readUntilNewline(), &offer) // Set the remote SessionDescription if err = peerConnection.SetRemoteDescription(offer); err != nil { @@ -171,7 +174,7 @@ func main() { <-gatherComplete // Output the answer in base64 so we can paste it in browser - fmt.Println(signal.Encode(*peerConnection.LocalDescription())) + fmt.Println(encode(peerConnection.LocalDescription())) // Open a IVF file and start reading using our IVFReader file, err := os.Open(qualityLevels[currentQuality].fileName) @@ -254,3 +257,45 @@ func setReaderFile(filename string) func(_ int64) io.Reader { return file } } + +// Read from stdin until we get a newline +func readUntilNewline() (in string) { + var err error + + r := bufio.NewReader(os.Stdin) + for { + in, err = r.ReadString('\n') + if err != nil && !errors.Is(err, io.EOF) { + panic(err) + } + + if in = strings.TrimSpace(in); len(in) > 0 { + break + } + } + + fmt.Println("") + return +} + +// JSON encode + base64 a SessionDescription +func encode(obj *webrtc.SessionDescription) string { + b, err := json.Marshal(obj) + if err != nil { + panic(err) + } + + return base64.StdEncoding.EncodeToString(b) +} + +// Decode a base64 and unmarshal JSON into a SessionDescription +func decode(in string, obj *webrtc.SessionDescription) { + b, err := base64.StdEncoding.DecodeString(in) + if err != nil { + panic(err) + } + + if err = json.Unmarshal(b, obj); err != nil { + panic(err) + } +} diff --git a/examples/broadcast/main.go b/examples/broadcast/main.go index 22a3d914dd..c92971c597 100644 --- a/examples/broadcast/main.go +++ b/examples/broadcast/main.go @@ -8,26 +8,29 @@ package main import ( + "encoding/base64" + "encoding/json" "errors" "flag" "fmt" "io" + "net/http" + "strconv" "github.com/pion/interceptor" "github.com/pion/interceptor/pkg/intervalpli" "github.com/pion/webrtc/v4" - "github.com/pion/webrtc/v4/examples/internal/signal" ) func main() { // nolint:gocognit port := flag.Int("port", 8080, "http server port") flag.Parse() - sdpChan := signal.HTTPSDPServer(*port) + sdpChan := httpSDPServer(*port) // Everything below is the Pion WebRTC API, thanks for using it ❤️. offer := webrtc.SessionDescription{} - signal.Decode(<-sdpChan, &offer) + decode(<-sdpChan, &offer) fmt.Println("") peerConnectionConfig := webrtc.Configuration{ @@ -132,7 +135,7 @@ func main() { // nolint:gocognit <-gatherComplete // Get the LocalDescription and take it to base64 so we can paste in browser - fmt.Println(signal.Encode(*peerConnection.LocalDescription())) + fmt.Println(encode(peerConnection.LocalDescription())) localTrack := <-localTrackChan for { @@ -140,7 +143,7 @@ func main() { // nolint:gocognit fmt.Println("Curl an base64 SDP to start sendonly peer connection") recvOnlyOffer := webrtc.SessionDescription{} - signal.Decode(<-sdpChan, &recvOnlyOffer) + decode(<-sdpChan, &recvOnlyOffer) // Create a new PeerConnection peerConnection, err := webrtc.NewPeerConnection(peerConnectionConfig) @@ -192,6 +195,45 @@ func main() { // nolint:gocognit <-gatherComplete // Get the LocalDescription and take it to base64 so we can paste in browser - fmt.Println(signal.Encode(*peerConnection.LocalDescription())) + fmt.Println(encode(peerConnection.LocalDescription())) } } + +// JSON encode + base64 a SessionDescription +func encode(obj *webrtc.SessionDescription) string { + b, err := json.Marshal(obj) + if err != nil { + panic(err) + } + + return base64.StdEncoding.EncodeToString(b) +} + +// Decode a base64 and unmarshal JSON into a SessionDescription +func decode(in string, obj *webrtc.SessionDescription) { + b, err := base64.StdEncoding.DecodeString(in) + if err != nil { + panic(err) + } + + if err = json.Unmarshal(b, obj); err != nil { + panic(err) + } +} + +// httpSDPServer starts a HTTP Server that consumes SDPs +func httpSDPServer(port int) chan string { + sdpChan := make(chan string) + http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { + body, _ := io.ReadAll(r.Body) + fmt.Fprintf(w, "done") + sdpChan <- string(body) + }) + + go func() { + // nolint: gosec + panic(http.ListenAndServe(":"+strconv.Itoa(port), nil)) + }() + + return sdpChan +} diff --git a/examples/data-channels-detach/jsfiddle/main.go b/examples/data-channels-detach/jsfiddle/main.go index bb093cf925..6ed1626a89 100644 --- a/examples/data-channels-detach/jsfiddle/main.go +++ b/examples/data-channels-detach/jsfiddle/main.go @@ -7,14 +7,19 @@ package main import ( + "bufio" + "encoding/base64" + "encoding/json" + "errors" "fmt" "io" + "os" + "strings" "syscall/js" "time" + "github.com/pion/randutil" "github.com/pion/webrtc/v4" - - "github.com/pion/webrtc/v4/examples/internal/signal" ) const messageSize = 15 @@ -95,7 +100,7 @@ func main() { }) peerConnection.OnICECandidate(func(candidate *webrtc.ICECandidate) { if candidate != nil { - encodedDescr := signal.Encode(peerConnection.LocalDescription()) + encodedDescr := encode(peerConnection.LocalDescription()) el := getElementByID("localSessionDescription") el.Set("value", encodedDescr) } @@ -126,7 +131,7 @@ func main() { } descr := webrtc.SessionDescription{} - signal.Decode(sd, &descr) + decode(sd, &descr) if err := peerConnection.SetRemoteDescription(descr); err != nil { handleError(err) } @@ -155,13 +160,15 @@ func ReadLoop(d io.Reader) { // WriteLoop shows how to write to the datachannel directly func WriteLoop(d io.Writer) { for range time.NewTicker(5 * time.Second).C { - message := signal.RandSeq(messageSize) - log(fmt.Sprintf("Sending %s \n", message)) - - _, err := d.Write([]byte(message)) + message, err := randutil.GenerateCryptoRandomString(messageSize, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ") if err != nil { handleError(err) } + + log(fmt.Sprintf("Sending %s \n", message)) + if _, err := d.Write([]byte(message)); err != nil { + handleError(err) + } } } @@ -178,3 +185,45 @@ func handleError(err error) { func getElementByID(id string) js.Value { return js.Global().Get("document").Call("getElementById", id) } + +// Read from stdin until we get a newline +func readUntilNewline() (in string) { + var err error + + r := bufio.NewReader(os.Stdin) + for { + in, err = r.ReadString('\n') + if err != nil && !errors.Is(err, io.EOF) { + panic(err) + } + + if in = strings.TrimSpace(in); len(in) > 0 { + break + } + } + + fmt.Println("") + return +} + +// JSON encode + base64 a SessionDescription +func encode(obj *webrtc.SessionDescription) string { + b, err := json.Marshal(obj) + if err != nil { + panic(err) + } + + return base64.StdEncoding.EncodeToString(b) +} + +// Decode a base64 and unmarshal JSON into a SessionDescription +func decode(in string, obj *webrtc.SessionDescription) { + b, err := base64.StdEncoding.DecodeString(in) + if err != nil { + panic(err) + } + + if err = json.Unmarshal(b, obj); err != nil { + panic(err) + } +} diff --git a/examples/data-channels-detach/main.go b/examples/data-channels-detach/main.go index 8e16245119..4a4ef2b3b7 100644 --- a/examples/data-channels-detach/main.go +++ b/examples/data-channels-detach/main.go @@ -5,13 +5,18 @@ package main import ( + "bufio" + "encoding/base64" + "encoding/json" + "errors" "fmt" "io" "os" + "strings" "time" + "github.com/pion/randutil" "github.com/pion/webrtc/v4" - "github.com/pion/webrtc/v4/examples/internal/signal" ) const messageSize = 15 @@ -94,7 +99,7 @@ func main() { // Wait for the offer to be pasted offer := webrtc.SessionDescription{} - signal.Decode(signal.MustReadStdin(), &offer) + decode(readUntilNewline(), &offer) // Set the remote SessionDescription err = peerConnection.SetRemoteDescription(offer) @@ -123,7 +128,7 @@ func main() { <-gatherComplete // Output the answer in base64 so we can paste it in browser - fmt.Println(signal.Encode(*peerConnection.LocalDescription())) + fmt.Println(encode(peerConnection.LocalDescription())) // Block forever select {} @@ -146,12 +151,56 @@ func ReadLoop(d io.Reader) { // WriteLoop shows how to write to the datachannel directly func WriteLoop(d io.Writer) { for range time.NewTicker(5 * time.Second).C { - message := signal.RandSeq(messageSize) + message, err := randutil.GenerateCryptoRandomString(messageSize, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ") + if err != nil { + panic(err) + } + fmt.Printf("Sending %s \n", message) + if _, err := d.Write([]byte(message)); err != nil { + panic(err) + } + } +} - _, err := d.Write([]byte(message)) - if err != nil { +// Read from stdin until we get a newline +func readUntilNewline() (in string) { + var err error + + r := bufio.NewReader(os.Stdin) + for { + in, err = r.ReadString('\n') + if err != nil && !errors.Is(err, io.EOF) { panic(err) } + + if in = strings.TrimSpace(in); len(in) > 0 { + break + } + } + + fmt.Println("") + return +} + +// JSON encode + base64 a SessionDescription +func encode(obj *webrtc.SessionDescription) string { + b, err := json.Marshal(obj) + if err != nil { + panic(err) + } + + return base64.StdEncoding.EncodeToString(b) +} + +// Decode a base64 and unmarshal JSON into a SessionDescription +func decode(in string, obj *webrtc.SessionDescription) { + b, err := base64.StdEncoding.DecodeString(in) + if err != nil { + panic(err) + } + + if err = json.Unmarshal(b, obj); err != nil { + panic(err) } } diff --git a/examples/data-channels/jsfiddle/main.go b/examples/data-channels/jsfiddle/main.go index 001b3f2226..44faed1a59 100644 --- a/examples/data-channels/jsfiddle/main.go +++ b/examples/data-channels/jsfiddle/main.go @@ -7,11 +7,17 @@ package main import ( + "bufio" + "encoding/base64" + "encoding/json" + "errors" "fmt" + "io" + "os" + "strings" "syscall/js" "github.com/pion/webrtc/v4" - "github.com/pion/webrtc/v4/examples/internal/signal" ) func main() { @@ -63,7 +69,7 @@ func main() { }) pc.OnICECandidate(func(candidate *webrtc.ICECandidate) { if candidate != nil { - encodedDescr := signal.Encode(pc.LocalDescription()) + encodedDescr := encode(pc.LocalDescription()) el := getElementByID("localSessionDescription") el.Set("value", encodedDescr) } @@ -94,7 +100,7 @@ func main() { } descr := webrtc.SessionDescription{} - signal.Decode(sd, &descr) + decode(sd, &descr) if err := pc.SetRemoteDescription(descr); err != nil { handleError(err) } @@ -146,3 +152,45 @@ func handleError(err error) { func getElementByID(id string) js.Value { return js.Global().Get("document").Call("getElementById", id) } + +// Read from stdin until we get a newline +func readUntilNewline() (in string) { + var err error + + r := bufio.NewReader(os.Stdin) + for { + in, err = r.ReadString('\n') + if err != nil && !errors.Is(err, io.EOF) { + panic(err) + } + + if in = strings.TrimSpace(in); len(in) > 0 { + break + } + } + + fmt.Println("") + return +} + +// JSON encode + base64 a SessionDescription +func encode(obj *webrtc.SessionDescription) string { + b, err := json.Marshal(obj) + if err != nil { + panic(err) + } + + return base64.StdEncoding.EncodeToString(b) +} + +// Decode a base64 and unmarshal JSON into a SessionDescription +func decode(in string, obj *webrtc.SessionDescription) { + b, err := base64.StdEncoding.DecodeString(in) + if err != nil { + panic(err) + } + + if err = json.Unmarshal(b, obj); err != nil { + panic(err) + } +} diff --git a/examples/data-channels/main.go b/examples/data-channels/main.go index 012413f241..217f59f9db 100644 --- a/examples/data-channels/main.go +++ b/examples/data-channels/main.go @@ -5,12 +5,18 @@ package main import ( + "bufio" + "encoding/base64" + "encoding/json" + "errors" "fmt" + "io" "os" + "strings" "time" + "github.com/pion/randutil" "github.com/pion/webrtc/v4" - "github.com/pion/webrtc/v4/examples/internal/signal" ) func main() { @@ -65,12 +71,14 @@ func main() { fmt.Printf("Data channel '%s'-'%d' open. Random messages will now be sent to any connected DataChannels every 5 seconds\n", d.Label(), d.ID()) for range time.NewTicker(5 * time.Second).C { - message := signal.RandSeq(15) - fmt.Printf("Sending '%s'\n", message) + message, sendErr := randutil.GenerateCryptoRandomString(15, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ") + if sendErr != nil { + panic(sendErr) + } // Send the message as text - sendErr := d.SendText(message) - if sendErr != nil { + fmt.Printf("Sending '%s'\n", message) + if sendErr = d.SendText(message); sendErr != nil { panic(sendErr) } } @@ -84,7 +92,7 @@ func main() { // Wait for the offer to be pasted offer := webrtc.SessionDescription{} - signal.Decode(signal.MustReadStdin(), &offer) + decode(readUntilNewline(), &offer) // Set the remote SessionDescription err = peerConnection.SetRemoteDescription(offer) @@ -113,8 +121,50 @@ func main() { <-gatherComplete // Output the answer in base64 so we can paste it in browser - fmt.Println(signal.Encode(*peerConnection.LocalDescription())) + fmt.Println(encode(peerConnection.LocalDescription())) // Block forever select {} } + +// Read from stdin until we get a newline +func readUntilNewline() (in string) { + var err error + + r := bufio.NewReader(os.Stdin) + for { + in, err = r.ReadString('\n') + if err != nil && !errors.Is(err, io.EOF) { + panic(err) + } + + if in = strings.TrimSpace(in); len(in) > 0 { + break + } + } + + fmt.Println("") + return +} + +// JSON encode + base64 a SessionDescription +func encode(obj *webrtc.SessionDescription) string { + b, err := json.Marshal(obj) + if err != nil { + panic(err) + } + + return base64.StdEncoding.EncodeToString(b) +} + +// Decode a base64 and unmarshal JSON into a SessionDescription +func decode(in string, obj *webrtc.SessionDescription) { + b, err := base64.StdEncoding.DecodeString(in) + if err != nil { + panic(err) + } + + if err = json.Unmarshal(b, obj); err != nil { + panic(err) + } +} diff --git a/examples/insertable-streams/main.go b/examples/insertable-streams/main.go index b80229b264..97d3eb2f17 100644 --- a/examples/insertable-streams/main.go +++ b/examples/insertable-streams/main.go @@ -8,15 +8,18 @@ package main import ( + "bufio" "context" + "encoding/base64" + "encoding/json" "errors" "fmt" "io" "os" + "strings" "time" "github.com/pion/webrtc/v4" - "github.com/pion/webrtc/v4/examples/internal/signal" "github.com/pion/webrtc/v4/pkg/media" "github.com/pion/webrtc/v4/pkg/media/ivfreader" ) @@ -136,7 +139,7 @@ func main() { // Wait for the offer to be pasted offer := webrtc.SessionDescription{} - signal.Decode(signal.MustReadStdin(), &offer) + decode(readUntilNewline(), &offer) // Set the remote SessionDescription if err = peerConnection.SetRemoteDescription(offer); err != nil { @@ -163,8 +166,50 @@ func main() { <-gatherComplete // Output the answer in base64 so we can paste it in browser - fmt.Println(signal.Encode(*peerConnection.LocalDescription())) + fmt.Println(encode(peerConnection.LocalDescription())) // Block forever select {} } + +// Read from stdin until we get a newline +func readUntilNewline() (in string) { + var err error + + r := bufio.NewReader(os.Stdin) + for { + in, err = r.ReadString('\n') + if err != nil && !errors.Is(err, io.EOF) { + panic(err) + } + + if in = strings.TrimSpace(in); len(in) > 0 { + break + } + } + + fmt.Println("") + return +} + +// JSON encode + base64 a SessionDescription +func encode(obj *webrtc.SessionDescription) string { + b, err := json.Marshal(obj) + if err != nil { + panic(err) + } + + return base64.StdEncoding.EncodeToString(b) +} + +// Decode a base64 and unmarshal JSON into a SessionDescription +func decode(in string, obj *webrtc.SessionDescription) { + b, err := base64.StdEncoding.DecodeString(in) + if err != nil { + panic(err) + } + + if err = json.Unmarshal(b, obj); err != nil { + panic(err) + } +} diff --git a/examples/internal/signal/http.go b/examples/internal/signal/http.go deleted file mode 100644 index d705e6428f..0000000000 --- a/examples/internal/signal/http.go +++ /dev/null @@ -1,31 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package signal - -import ( - "fmt" - "io" - "net/http" - "strconv" -) - -// HTTPSDPServer starts a HTTP Server that consumes SDPs -func HTTPSDPServer(port int) chan string { - sdpChan := make(chan string) - http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { - body, _ := io.ReadAll(r.Body) - fmt.Fprintf(w, "done") - sdpChan <- string(body) - }) - - go func() { - // nolint: gosec - err := http.ListenAndServe(":"+strconv.Itoa(port), nil) - if err != nil { - panic(err) - } - }() - - return sdpChan -} diff --git a/examples/internal/signal/rand.go b/examples/internal/signal/rand.go deleted file mode 100644 index c55fc6cf54..0000000000 --- a/examples/internal/signal/rand.go +++ /dev/null @@ -1,19 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package signal - -import "github.com/pion/randutil" - -// RandSeq generates a random string to serve as dummy data -// -// It returns a deterministic sequence of values each time a program is run. -// Use rand.Seed() function in your real applications. -func RandSeq(n int) string { - val, err := randutil.GenerateCryptoRandomString(n, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ") - if err != nil { - panic(err) - } - - return val -} diff --git a/examples/internal/signal/signal.go b/examples/internal/signal/signal.go deleted file mode 100644 index 14547a33c0..0000000000 --- a/examples/internal/signal/signal.go +++ /dev/null @@ -1,113 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -// Package signal contains helpers to exchange the SDP session -// description between examples. -package signal - -import ( - "bufio" - "bytes" - "compress/gzip" - "encoding/base64" - "encoding/json" - "fmt" - "io" - "os" - "strings" -) - -// Allows compressing offer/answer to bypass terminal input limits. -const compress = false - -// MustReadStdin blocks until input is received from stdin -func MustReadStdin() string { - r := bufio.NewReader(os.Stdin) - - var in string - for { - var err error - in, err = r.ReadString('\n') - if err != io.EOF { - if err != nil { - panic(err) - } - } - in = strings.TrimSpace(in) - if len(in) > 0 { - break - } - } - - fmt.Println("") - - return in -} - -// Encode encodes the input in base64 -// It can optionally zip the input before encoding -func Encode(obj interface{}) string { - b, err := json.Marshal(obj) - if err != nil { - panic(err) - } - - if compress { - b = zip(b) - } - - return base64.StdEncoding.EncodeToString(b) -} - -// Decode decodes the input from base64 -// It can optionally unzip the input after decoding -func Decode(in string, obj interface{}) { - b, err := base64.StdEncoding.DecodeString(in) - if err != nil { - panic(err) - } - - if compress { - b = unzip(b) - } - - err = json.Unmarshal(b, obj) - if err != nil { - panic(err) - } -} - -func zip(in []byte) []byte { - var b bytes.Buffer - gz := gzip.NewWriter(&b) - _, err := gz.Write(in) - if err != nil { - panic(err) - } - err = gz.Flush() - if err != nil { - panic(err) - } - err = gz.Close() - if err != nil { - panic(err) - } - return b.Bytes() -} - -func unzip(in []byte) []byte { - var b bytes.Buffer - _, err := b.Write(in) - if err != nil { - panic(err) - } - r, err := gzip.NewReader(&b) - if err != nil { - panic(err) - } - res, err := io.ReadAll(r) - if err != nil { - panic(err) - } - return res -} diff --git a/examples/ortc-media/main.go b/examples/ortc-media/main.go index 3915502421..2029554e60 100644 --- a/examples/ortc-media/main.go +++ b/examples/ortc-media/main.go @@ -8,15 +8,20 @@ package main import ( + "bufio" + "encoding/base64" + "encoding/json" "errors" "flag" "fmt" "io" + "net/http" "os" + "strconv" + "strings" "time" "github.com/pion/webrtc/v4" - "github.com/pion/webrtc/v4/examples/internal/signal" "github.com/pion/webrtc/v4/pkg/media" "github.com/pion/webrtc/v4/pkg/media/ivfreader" ) @@ -142,16 +147,16 @@ func main() { iceRole := webrtc.ICERoleControlled // Exchange the information - fmt.Println(signal.Encode(s)) + fmt.Println(encode(&s)) remoteSignal := Signal{} if *isOffer { - signalingChan := signal.HTTPSDPServer(*port) - signal.Decode(<-signalingChan, &remoteSignal) + signalingChan := httpSDPServer(*port) + decode(<-signalingChan, &remoteSignal) iceRole = webrtc.ICERoleControlling } else { - signal.Decode(signal.MustReadStdin(), &remoteSignal) + decode(readUntilNewline(), &remoteSignal) } if err = ice.SetRemoteCandidates(remoteSignal.ICECandidates); err != nil { @@ -244,3 +249,62 @@ type Signal struct { DTLSParameters webrtc.DTLSParameters `json:"dtlsParameters"` RTPSendParameters webrtc.RTPSendParameters `json:"rtpSendParameters"` } + +// Read from stdin until we get a newline +func readUntilNewline() (in string) { + var err error + + r := bufio.NewReader(os.Stdin) + for { + in, err = r.ReadString('\n') + if err != nil && !errors.Is(err, io.EOF) { + panic(err) + } + + if in = strings.TrimSpace(in); len(in) > 0 { + break + } + } + + fmt.Println("") + return +} + +// JSON encode + base64 a SessionDescription +func encode(obj *Signal) string { + b, err := json.Marshal(obj) + if err != nil { + panic(err) + } + + return base64.StdEncoding.EncodeToString(b) +} + +// Decode a base64 and unmarshal JSON into a SessionDescription +func decode(in string, obj *Signal) { + b, err := base64.StdEncoding.DecodeString(in) + if err != nil { + panic(err) + } + + if err = json.Unmarshal(b, obj); err != nil { + panic(err) + } +} + +// httpSDPServer starts a HTTP Server that consumes SDPs +func httpSDPServer(port int) chan string { + sdpChan := make(chan string) + http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { + body, _ := io.ReadAll(r.Body) + fmt.Fprintf(w, "done") + sdpChan <- string(body) + }) + + go func() { + // nolint: gosec + panic(http.ListenAndServe(":"+strconv.Itoa(port), nil)) + }() + + return sdpChan +} diff --git a/examples/ortc/main.go b/examples/ortc/main.go index 60ad6c83f3..d9981896b0 100644 --- a/examples/ortc/main.go +++ b/examples/ortc/main.go @@ -8,12 +8,21 @@ package main import ( + "bufio" + "encoding/base64" + "encoding/json" + "errors" "flag" "fmt" + "io" + "net/http" + "os" + "strconv" + "strings" "time" + "github.com/pion/randutil" "github.com/pion/webrtc/v4" - "github.com/pion/webrtc/v4/examples/internal/signal" ) func main() { @@ -103,16 +112,16 @@ func main() { iceRole := webrtc.ICERoleControlled // Exchange the information - fmt.Println(signal.Encode(s)) + fmt.Println(encode(s)) remoteSignal := Signal{} if *isOffer { - signalingChan := signal.HTTPSDPServer(*port) - signal.Decode(<-signalingChan, &remoteSignal) + signalingChan := httpSDPServer(*port) + decode(<-signalingChan, &remoteSignal) iceRole = webrtc.ICERoleControlling } else { - signal.Decode(signal.MustReadStdin(), &remoteSignal) + decode(readUntilNewline(), &remoteSignal) } if err = ice.SetRemoteCandidates(remoteSignal.ICECandidates); err != nil { @@ -175,12 +184,74 @@ func handleOnOpen(channel *webrtc.DataChannel) func() { fmt.Printf("Data channel '%s'-'%d' open. Random messages will now be sent to any connected DataChannels every 5 seconds\n", channel.Label(), channel.ID()) for range time.NewTicker(5 * time.Second).C { - message := signal.RandSeq(15) - fmt.Printf("Sending '%s' \n", message) + message, err := randutil.GenerateCryptoRandomString(15, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ") + if err != nil { + panic(err) + } + fmt.Printf("Sending %s \n", message) if err := channel.SendText(message); err != nil { panic(err) } } } } + +// Read from stdin until we get a newline +func readUntilNewline() (in string) { + var err error + + r := bufio.NewReader(os.Stdin) + for { + in, err = r.ReadString('\n') + if err != nil && !errors.Is(err, io.EOF) { + panic(err) + } + + if in = strings.TrimSpace(in); len(in) > 0 { + break + } + } + + fmt.Println("") + return +} + +// JSON encode + base64 a SessionDescription +func encode(obj Signal) string { + b, err := json.Marshal(obj) + if err != nil { + panic(err) + } + + return base64.StdEncoding.EncodeToString(b) +} + +// Decode a base64 and unmarshal JSON into a SessionDescription +func decode(in string, obj *Signal) { + b, err := base64.StdEncoding.DecodeString(in) + if err != nil { + panic(err) + } + + if err = json.Unmarshal(b, obj); err != nil { + panic(err) + } +} + +// httpSDPServer starts a HTTP Server that consumes SDPs +func httpSDPServer(port int) chan string { + sdpChan := make(chan string) + http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { + body, _ := io.ReadAll(r.Body) + fmt.Fprintf(w, "done") + sdpChan <- string(body) + }) + + go func() { + // nolint: gosec + panic(http.ListenAndServe(":"+strconv.Itoa(port), nil)) + }() + + return sdpChan +} diff --git a/examples/pion-to-pion/answer/main.go b/examples/pion-to-pion/answer/main.go index 97a53f5826..01dfbaa14e 100644 --- a/examples/pion-to-pion/answer/main.go +++ b/examples/pion-to-pion/answer/main.go @@ -5,18 +5,22 @@ package main import ( + "bufio" "bytes" + "encoding/base64" "encoding/json" + "errors" "flag" "fmt" "io" "net/http" "os" + "strings" "sync" "time" + "github.com/pion/randutil" "github.com/pion/webrtc/v4" - "github.com/pion/webrtc/v4/examples/internal/signal" ) func signalCandidate(addr string, c *webrtc.ICECandidate) error { @@ -164,12 +168,14 @@ func main() { // nolint:gocognit fmt.Printf("Data channel '%s'-'%d' open. Random messages will now be sent to any connected DataChannels every 5 seconds\n", d.Label(), d.ID()) for range time.NewTicker(5 * time.Second).C { - message := signal.RandSeq(15) - fmt.Printf("Sending '%s'\n", message) + message, sendTextErr := randutil.GenerateCryptoRandomString(15, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ") + if sendTextErr != nil { + panic(sendTextErr) + } // Send the message as text - sendTextErr := d.SendText(message) - if sendTextErr != nil { + fmt.Printf("Sending '%s'\n", message) + if sendTextErr = d.SendText(message); sendTextErr != nil { panic(sendTextErr) } } @@ -185,3 +191,45 @@ func main() { // nolint:gocognit // nolint: gosec panic(http.ListenAndServe(*answerAddr, nil)) } + +// Read from stdin until we get a newline +func readUntilNewline() (in string) { + var err error + + r := bufio.NewReader(os.Stdin) + for { + in, err = r.ReadString('\n') + if err != nil && !errors.Is(err, io.EOF) { + panic(err) + } + + if in = strings.TrimSpace(in); len(in) > 0 { + break + } + } + + fmt.Println("") + return +} + +// JSON encode + base64 a SessionDescription +func encode(obj *webrtc.SessionDescription) string { + b, err := json.Marshal(obj) + if err != nil { + panic(err) + } + + return base64.StdEncoding.EncodeToString(b) +} + +// Decode a base64 and unmarshal JSON into a SessionDescription +func decode(in string, obj *webrtc.SessionDescription) { + b, err := base64.StdEncoding.DecodeString(in) + if err != nil { + panic(err) + } + + if err = json.Unmarshal(b, obj); err != nil { + panic(err) + } +} diff --git a/examples/pion-to-pion/offer/main.go b/examples/pion-to-pion/offer/main.go index 236212a74a..16332f0d23 100644 --- a/examples/pion-to-pion/offer/main.go +++ b/examples/pion-to-pion/offer/main.go @@ -15,8 +15,8 @@ import ( "sync" "time" + "github.com/pion/randutil" "github.com/pion/webrtc/v4" - "github.com/pion/webrtc/v4/examples/internal/signal" ) func signalCandidate(addr string, c *webrtc.ICECandidate) error { @@ -145,12 +145,14 @@ func main() { //nolint:gocognit fmt.Printf("Data channel '%s'-'%d' open. Random messages will now be sent to any connected DataChannels every 5 seconds\n", dataChannel.Label(), dataChannel.ID()) for range time.NewTicker(5 * time.Second).C { - message := signal.RandSeq(15) - fmt.Printf("Sending '%s'\n", message) + message, sendTextErr := randutil.GenerateCryptoRandomString(15, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ") + if sendTextErr != nil { + panic(sendTextErr) + } // Send the message as text - sendTextErr := dataChannel.SendText(message) - if sendTextErr != nil { + fmt.Printf("Sending '%s'\n", message) + if sendTextErr = dataChannel.SendText(message); sendTextErr != nil { panic(sendTextErr) } } diff --git a/examples/play-from-disk/main.go b/examples/play-from-disk/main.go index 13b7f707cf..c6bb33632f 100644 --- a/examples/play-from-disk/main.go +++ b/examples/play-from-disk/main.go @@ -8,15 +8,18 @@ package main import ( + "bufio" "context" + "encoding/base64" + "encoding/json" "errors" "fmt" "io" "os" + "strings" "time" "github.com/pion/webrtc/v4" - "github.com/pion/webrtc/v4/examples/internal/signal" "github.com/pion/webrtc/v4/pkg/media" "github.com/pion/webrtc/v4/pkg/media/ivfreader" "github.com/pion/webrtc/v4/pkg/media/oggreader" @@ -248,7 +251,7 @@ func main() { // Wait for the offer to be pasted offer := webrtc.SessionDescription{} - signal.Decode(signal.MustReadStdin(), &offer) + decode(readUntilNewline(), &offer) // Set the remote SessionDescription if err = peerConnection.SetRemoteDescription(offer); err != nil { @@ -275,8 +278,50 @@ func main() { <-gatherComplete // Output the answer in base64 so we can paste it in browser - fmt.Println(signal.Encode(*peerConnection.LocalDescription())) + fmt.Println(encode(peerConnection.LocalDescription())) // Block forever select {} } + +// Read from stdin until we get a newline +func readUntilNewline() (in string) { + var err error + + r := bufio.NewReader(os.Stdin) + for { + in, err = r.ReadString('\n') + if err != nil && !errors.Is(err, io.EOF) { + panic(err) + } + + if in = strings.TrimSpace(in); len(in) > 0 { + break + } + } + + fmt.Println("") + return +} + +// JSON encode + base64 a SessionDescription +func encode(obj *webrtc.SessionDescription) string { + b, err := json.Marshal(obj) + if err != nil { + panic(err) + } + + return base64.StdEncoding.EncodeToString(b) +} + +// Decode a base64 and unmarshal JSON into a SessionDescription +func decode(in string, obj *webrtc.SessionDescription) { + b, err := base64.StdEncoding.DecodeString(in) + if err != nil { + panic(err) + } + + if err = json.Unmarshal(b, obj); err != nil { + panic(err) + } +} diff --git a/examples/reflect/main.go b/examples/reflect/main.go index ff859432f9..f666cf17e3 100644 --- a/examples/reflect/main.go +++ b/examples/reflect/main.go @@ -8,13 +8,18 @@ package main import ( + "bufio" + "encoding/base64" + "encoding/json" + "errors" "fmt" + "io" "os" + "strings" "github.com/pion/interceptor" "github.com/pion/interceptor/pkg/intervalpli" "github.com/pion/webrtc/v4" - "github.com/pion/webrtc/v4/examples/internal/signal" ) // nolint:gocognit @@ -102,7 +107,7 @@ func main() { // Wait for the offer to be pasted offer := webrtc.SessionDescription{} - signal.Decode(signal.MustReadStdin(), &offer) + decode(readUntilNewline(), &offer) // Set the remote SessionDescription err = peerConnection.SetRemoteDescription(offer) @@ -167,8 +172,50 @@ func main() { <-gatherComplete // Output the answer in base64 so we can paste it in browser - fmt.Println(signal.Encode(*peerConnection.LocalDescription())) + fmt.Println(encode(peerConnection.LocalDescription())) // Block forever select {} } + +// Read from stdin until we get a newline +func readUntilNewline() (in string) { + var err error + + r := bufio.NewReader(os.Stdin) + for { + in, err = r.ReadString('\n') + if err != nil && !errors.Is(err, io.EOF) { + panic(err) + } + + if in = strings.TrimSpace(in); len(in) > 0 { + break + } + } + + fmt.Println("") + return +} + +// JSON encode + base64 a SessionDescription +func encode(obj *webrtc.SessionDescription) string { + b, err := json.Marshal(obj) + if err != nil { + panic(err) + } + + return base64.StdEncoding.EncodeToString(b) +} + +// Decode a base64 and unmarshal JSON into a SessionDescription +func decode(in string, obj *webrtc.SessionDescription) { + b, err := base64.StdEncoding.DecodeString(in) + if err != nil { + panic(err) + } + + if err = json.Unmarshal(b, obj); err != nil { + panic(err) + } +} diff --git a/examples/rtcp-processing/main.go b/examples/rtcp-processing/main.go index afd01870d1..5b5e61b2f6 100644 --- a/examples/rtcp-processing/main.go +++ b/examples/rtcp-processing/main.go @@ -8,10 +8,16 @@ package main import ( + "bufio" + "encoding/base64" + "encoding/json" + "errors" "fmt" + "io" + "os" + "strings" "github.com/pion/webrtc/v4" - "github.com/pion/webrtc/v4/examples/internal/signal" ) func main() { @@ -60,7 +66,7 @@ func main() { // Wait for the offer to be pasted offer := webrtc.SessionDescription{} - signal.Decode(signal.MustReadStdin(), &offer) + decode(readUntilNewline(), &offer) // Set the remote SessionDescription err = peerConnection.SetRemoteDescription(offer) @@ -89,8 +95,50 @@ func main() { <-gatherComplete // Output the answer in base64 so we can paste it in browser - fmt.Println(signal.Encode(*peerConnection.LocalDescription())) + fmt.Println(encode(peerConnection.LocalDescription())) // Block forever select {} } + +// Read from stdin until we get a newline +func readUntilNewline() (in string) { + var err error + + r := bufio.NewReader(os.Stdin) + for { + in, err = r.ReadString('\n') + if err != nil && !errors.Is(err, io.EOF) { + panic(err) + } + + if in = strings.TrimSpace(in); len(in) > 0 { + break + } + } + + fmt.Println("") + return +} + +// JSON encode + base64 a SessionDescription +func encode(obj *webrtc.SessionDescription) string { + b, err := json.Marshal(obj) + if err != nil { + panic(err) + } + + return base64.StdEncoding.EncodeToString(b) +} + +// Decode a base64 and unmarshal JSON into a SessionDescription +func decode(in string, obj *webrtc.SessionDescription) { + b, err := base64.StdEncoding.DecodeString(in) + if err != nil { + panic(err) + } + + if err = json.Unmarshal(b, obj); err != nil { + panic(err) + } +} diff --git a/examples/rtp-forwarder/main.go b/examples/rtp-forwarder/main.go index 57d02816f5..12cd65d1f9 100644 --- a/examples/rtp-forwarder/main.go +++ b/examples/rtp-forwarder/main.go @@ -8,16 +8,20 @@ package main import ( + "bufio" + "encoding/base64" + "encoding/json" "errors" "fmt" + "io" "net" "os" + "strings" "github.com/pion/interceptor" "github.com/pion/interceptor/pkg/intervalpli" "github.com/pion/rtp" "github.com/pion/webrtc/v4" - "github.com/pion/webrtc/v4/examples/internal/signal" ) type udpConn struct { @@ -207,7 +211,7 @@ func main() { // Wait for the offer to be pasted offer := webrtc.SessionDescription{} - signal.Decode(signal.MustReadStdin(), &offer) + decode(readUntilNewline(), &offer) // Set the remote SessionDescription if err = peerConnection.SetRemoteDescription(offer); err != nil { @@ -234,8 +238,50 @@ func main() { <-gatherComplete // Output the answer in base64 so we can paste it in browser - fmt.Println(signal.Encode(*peerConnection.LocalDescription())) + fmt.Println(encode(peerConnection.LocalDescription())) // Block forever select {} } + +// Read from stdin until we get a newline +func readUntilNewline() (in string) { + var err error + + r := bufio.NewReader(os.Stdin) + for { + in, err = r.ReadString('\n') + if err != nil && !errors.Is(err, io.EOF) { + panic(err) + } + + if in = strings.TrimSpace(in); len(in) > 0 { + break + } + } + + fmt.Println("") + return +} + +// JSON encode + base64 a SessionDescription +func encode(obj *webrtc.SessionDescription) string { + b, err := json.Marshal(obj) + if err != nil { + panic(err) + } + + return base64.StdEncoding.EncodeToString(b) +} + +// Decode a base64 and unmarshal JSON into a SessionDescription +func decode(in string, obj *webrtc.SessionDescription) { + b, err := base64.StdEncoding.DecodeString(in) + if err != nil { + panic(err) + } + + if err = json.Unmarshal(b, obj); err != nil { + panic(err) + } +} diff --git a/examples/rtp-to-webrtc/main.go b/examples/rtp-to-webrtc/main.go index 81acf82c81..5b86f9acad 100644 --- a/examples/rtp-to-webrtc/main.go +++ b/examples/rtp-to-webrtc/main.go @@ -8,13 +8,17 @@ package main import ( + "bufio" + "encoding/base64" + "encoding/json" "errors" "fmt" "io" "net" + "os" + "strings" "github.com/pion/webrtc/v4" - "github.com/pion/webrtc/v4/examples/internal/signal" ) func main() { @@ -85,7 +89,7 @@ func main() { // Wait for the offer to be pasted offer := webrtc.SessionDescription{} - signal.Decode(signal.MustReadStdin(), &offer) + decode(readUntilNewline(), &offer) // Set the remote SessionDescription if err = peerConnection.SetRemoteDescription(offer); err != nil { @@ -112,7 +116,7 @@ func main() { <-gatherComplete // Output the answer in base64 so we can paste it in browser - fmt.Println(signal.Encode(*peerConnection.LocalDescription())) + fmt.Println(encode(peerConnection.LocalDescription())) // Read RTP packets forever and send them to the WebRTC Client inboundRTPPacket := make([]byte, 1600) // UDP MTU @@ -132,3 +136,45 @@ func main() { } } } + +// Read from stdin until we get a newline +func readUntilNewline() (in string) { + var err error + + r := bufio.NewReader(os.Stdin) + for { + in, err = r.ReadString('\n') + if err != nil && !errors.Is(err, io.EOF) { + panic(err) + } + + if in = strings.TrimSpace(in); len(in) > 0 { + break + } + } + + fmt.Println("") + return +} + +// JSON encode + base64 a SessionDescription +func encode(obj *webrtc.SessionDescription) string { + b, err := json.Marshal(obj) + if err != nil { + panic(err) + } + + return base64.StdEncoding.EncodeToString(b) +} + +// Decode a base64 and unmarshal JSON into a SessionDescription +func decode(in string, obj *webrtc.SessionDescription) { + b, err := base64.StdEncoding.DecodeString(in) + if err != nil { + panic(err) + } + + if err = json.Unmarshal(b, obj); err != nil { + panic(err) + } +} diff --git a/examples/save-to-disk-av1/main.go b/examples/save-to-disk-av1/main.go index 29f03e59d7..a985f63780 100644 --- a/examples/save-to-disk-av1/main.go +++ b/examples/save-to-disk-av1/main.go @@ -8,14 +8,18 @@ package main import ( + "bufio" + "encoding/base64" + "encoding/json" + "errors" "fmt" + "io" "os" "strings" "github.com/pion/interceptor" "github.com/pion/interceptor/pkg/intervalpli" "github.com/pion/webrtc/v4" - "github.com/pion/webrtc/v4/examples/internal/signal" "github.com/pion/webrtc/v4/pkg/media" "github.com/pion/webrtc/v4/pkg/media/ivfwriter" ) @@ -133,7 +137,7 @@ func main() { // Wait for the offer to be pasted offer := webrtc.SessionDescription{} - signal.Decode(signal.MustReadStdin(), &offer) + decode(readUntilNewline(), &offer) // Set the remote SessionDescription err = peerConnection.SetRemoteDescription(offer) @@ -162,8 +166,50 @@ func main() { <-gatherComplete // Output the answer in base64 so we can paste it in browser - fmt.Println(signal.Encode(*peerConnection.LocalDescription())) + fmt.Println(encode(peerConnection.LocalDescription())) // Block forever select {} } + +// Read from stdin until we get a newline +func readUntilNewline() (in string) { + var err error + + r := bufio.NewReader(os.Stdin) + for { + in, err = r.ReadString('\n') + if err != nil && !errors.Is(err, io.EOF) { + panic(err) + } + + if in = strings.TrimSpace(in); len(in) > 0 { + break + } + } + + fmt.Println("") + return +} + +// JSON encode + base64 a SessionDescription +func encode(obj *webrtc.SessionDescription) string { + b, err := json.Marshal(obj) + if err != nil { + panic(err) + } + + return base64.StdEncoding.EncodeToString(b) +} + +// Decode a base64 and unmarshal JSON into a SessionDescription +func decode(in string, obj *webrtc.SessionDescription) { + b, err := base64.StdEncoding.DecodeString(in) + if err != nil { + panic(err) + } + + if err = json.Unmarshal(b, obj); err != nil { + panic(err) + } +} diff --git a/examples/save-to-disk/main.go b/examples/save-to-disk/main.go index 1113f42208..a519aed2a2 100644 --- a/examples/save-to-disk/main.go +++ b/examples/save-to-disk/main.go @@ -8,14 +8,18 @@ package main import ( + "bufio" + "encoding/base64" + "encoding/json" + "errors" "fmt" + "io" "os" "strings" "github.com/pion/interceptor" "github.com/pion/interceptor/pkg/intervalpli" "github.com/pion/webrtc/v4" - "github.com/pion/webrtc/v4/examples/internal/signal" "github.com/pion/webrtc/v4/pkg/media" "github.com/pion/webrtc/v4/pkg/media/ivfwriter" "github.com/pion/webrtc/v4/pkg/media/oggwriter" @@ -161,7 +165,7 @@ func main() { // Wait for the offer to be pasted offer := webrtc.SessionDescription{} - signal.Decode(signal.MustReadStdin(), &offer) + decode(readUntilNewline(), &offer) // Set the remote SessionDescription err = peerConnection.SetRemoteDescription(offer) @@ -190,8 +194,50 @@ func main() { <-gatherComplete // Output the answer in base64 so we can paste it in browser - fmt.Println(signal.Encode(*peerConnection.LocalDescription())) + fmt.Println(encode(peerConnection.LocalDescription())) // Block forever select {} } + +// Read from stdin until we get a newline +func readUntilNewline() (in string) { + var err error + + r := bufio.NewReader(os.Stdin) + for { + in, err = r.ReadString('\n') + if err != nil && !errors.Is(err, io.EOF) { + panic(err) + } + + if in = strings.TrimSpace(in); len(in) > 0 { + break + } + } + + fmt.Println("") + return +} + +// JSON encode + base64 a SessionDescription +func encode(obj *webrtc.SessionDescription) string { + b, err := json.Marshal(obj) + if err != nil { + panic(err) + } + + return base64.StdEncoding.EncodeToString(b) +} + +// Decode a base64 and unmarshal JSON into a SessionDescription +func decode(in string, obj *webrtc.SessionDescription) { + b, err := base64.StdEncoding.DecodeString(in) + if err != nil { + panic(err) + } + + if err = json.Unmarshal(b, obj); err != nil { + panic(err) + } +} diff --git a/examples/simulcast/main.go b/examples/simulcast/main.go index 6054bf6a96..25b0692890 100644 --- a/examples/simulcast/main.go +++ b/examples/simulcast/main.go @@ -8,15 +8,18 @@ package main import ( + "bufio" + "encoding/base64" + "encoding/json" "errors" "fmt" "io" "os" + "strings" "time" "github.com/pion/rtcp" "github.com/pion/webrtc/v4" - "github.com/pion/webrtc/v4/examples/internal/signal" ) // nolint:gocognit @@ -96,7 +99,7 @@ func main() { // Wait for the offer to be pasted offer := webrtc.SessionDescription{} - signal.Decode(signal.MustReadStdin(), &offer) + decode(readUntilNewline(), &offer) if err = peerConnection.SetRemoteDescription(offer); err != nil { panic(err) @@ -171,8 +174,50 @@ func main() { <-gatherComplete // Output the answer in base64 so we can paste it in browser - fmt.Println(signal.Encode(*peerConnection.LocalDescription())) + fmt.Println(encode(peerConnection.LocalDescription())) // Block forever select {} } + +// Read from stdin until we get a newline +func readUntilNewline() (in string) { + var err error + + r := bufio.NewReader(os.Stdin) + for { + in, err = r.ReadString('\n') + if err != nil && !errors.Is(err, io.EOF) { + panic(err) + } + + if in = strings.TrimSpace(in); len(in) > 0 { + break + } + } + + fmt.Println("") + return +} + +// JSON encode + base64 a SessionDescription +func encode(obj *webrtc.SessionDescription) string { + b, err := json.Marshal(obj) + if err != nil { + panic(err) + } + + return base64.StdEncoding.EncodeToString(b) +} + +// Decode a base64 and unmarshal JSON into a SessionDescription +func decode(in string, obj *webrtc.SessionDescription) { + b, err := base64.StdEncoding.DecodeString(in) + if err != nil { + panic(err) + } + + if err = json.Unmarshal(b, obj); err != nil { + panic(err) + } +} diff --git a/examples/stats/main.go b/examples/stats/main.go index 9d3a9574f8..1cf7082eba 100644 --- a/examples/stats/main.go +++ b/examples/stats/main.go @@ -8,13 +8,19 @@ package main import ( + "bufio" + "encoding/base64" + "encoding/json" + "errors" "fmt" + "io" + "os" + "strings" "time" "github.com/pion/interceptor" "github.com/pion/interceptor/pkg/stats" "github.com/pion/webrtc/v4" - "github.com/pion/webrtc/v4/examples/internal/signal" ) // nolint:gocognit @@ -108,7 +114,7 @@ func main() { // Wait for the offer to be pasted offer := webrtc.SessionDescription{} - signal.Decode(signal.MustReadStdin(), &offer) + decode(readUntilNewline(), &offer) // Set the remote SessionDescription err = peerConnection.SetRemoteDescription(offer) @@ -137,8 +143,50 @@ func main() { <-gatherComplete // Output the answer in base64 so we can paste it in browser - fmt.Println(signal.Encode(*peerConnection.LocalDescription())) + fmt.Println(encode(peerConnection.LocalDescription())) // Block forever select {} } + +// Read from stdin until we get a newline +func readUntilNewline() (in string) { + var err error + + r := bufio.NewReader(os.Stdin) + for { + in, err = r.ReadString('\n') + if err != nil && !errors.Is(err, io.EOF) { + panic(err) + } + + if in = strings.TrimSpace(in); len(in) > 0 { + break + } + } + + fmt.Println("") + return +} + +// JSON encode + base64 a SessionDescription +func encode(obj *webrtc.SessionDescription) string { + b, err := json.Marshal(obj) + if err != nil { + panic(err) + } + + return base64.StdEncoding.EncodeToString(b) +} + +// Decode a base64 and unmarshal JSON into a SessionDescription +func decode(in string, obj *webrtc.SessionDescription) { + b, err := base64.StdEncoding.DecodeString(in) + if err != nil { + panic(err) + } + + if err = json.Unmarshal(b, obj); err != nil { + panic(err) + } +} diff --git a/examples/swap-tracks/main.go b/examples/swap-tracks/main.go index 85935baa8f..8b36b6120c 100644 --- a/examples/swap-tracks/main.go +++ b/examples/swap-tracks/main.go @@ -8,16 +8,20 @@ package main import ( + "bufio" "context" + "encoding/base64" + "encoding/json" "errors" "fmt" "io" + "os" + "strings" "time" "github.com/pion/rtcp" "github.com/pion/rtp" "github.com/pion/webrtc/v4" - "github.com/pion/webrtc/v4/examples/internal/signal" ) func main() { // nolint:gocognit @@ -68,7 +72,7 @@ func main() { // nolint:gocognit // Wait for the offer to be pasted offer := webrtc.SessionDescription{} - signal.Decode(signal.MustReadStdin(), &offer) + decode(readUntilNewline(), &offer) // Set the remote SessionDescription err = peerConnection.SetRemoteDescription(offer) @@ -166,7 +170,7 @@ func main() { // nolint:gocognit // in a production application you should exchange ICE Candidates via OnICECandidate <-gatherComplete - fmt.Println(signal.Encode(*peerConnection.LocalDescription())) + fmt.Println(encode(peerConnection.LocalDescription())) // Asynchronously take all packets in the channel and write them out to our // track @@ -215,3 +219,45 @@ func main() { // nolint:gocognit fmt.Printf("Switched to track #%v\n", currTrack+1) } } + +// Read from stdin until we get a newline +func readUntilNewline() (in string) { + var err error + + r := bufio.NewReader(os.Stdin) + for { + in, err = r.ReadString('\n') + if err != nil && !errors.Is(err, io.EOF) { + panic(err) + } + + if in = strings.TrimSpace(in); len(in) > 0 { + break + } + } + + fmt.Println("") + return +} + +// JSON encode + base64 a SessionDescription +func encode(obj *webrtc.SessionDescription) string { + b, err := json.Marshal(obj) + if err != nil { + panic(err) + } + + return base64.StdEncoding.EncodeToString(b) +} + +// Decode a base64 and unmarshal JSON into a SessionDescription +func decode(in string, obj *webrtc.SessionDescription) { + b, err := base64.StdEncoding.DecodeString(in) + if err != nil { + panic(err) + } + + if err = json.Unmarshal(b, obj); err != nil { + panic(err) + } +}