From 121fa2dae07a642d08e72939f55e1ea57933a257 Mon Sep 17 00:00:00 2001 From: Sean DuBois Date: Tue, 10 Sep 2024 16:22:23 -0400 Subject: [PATCH] Remove examples/internal Users find it frustrating that example code doesn't work out of tree. This makes copying the examples out of the repo easier. Relates to pion/webrtc#1981 --- c-data-channels/webrtc.go | 54 ++++++++++++++++- ffmpeg-send/main.go | 53 +++++++++++++++- gocv-receive/main.go | 52 +++++++++++++++- gstreamer-receive/main.go | 53 +++++++++++++++- gstreamer-send-offer/main.go | 51 ++++++++++++++-- gstreamer-send/main.go | 54 ++++++++++++++++- internal/signal/http.go | 34 ----------- internal/signal/signal.go | 113 ----------------------------------- play-from-disk-h264/main.go | 51 +++++++++++++++- play-from-disk-mkv/main.go | 53 +++++++++++++++- rtmp-to-webrtc/main.go | 54 ++++++++++++++++- save-to-webm/main.go | 51 +++++++++++++++- sip-to-webrtc/main.go | 54 ++++++++++++++++- twitch/main.go | 50 +++++++++++++++- 14 files changed, 593 insertions(+), 184 deletions(-) delete mode 100644 internal/signal/http.go delete mode 100644 internal/signal/signal.go diff --git a/c-data-channels/webrtc.go b/c-data-channels/webrtc.go index c3d1625e..f9086580 100644 --- a/c-data-channels/webrtc.go +++ b/c-data-channels/webrtc.go @@ -4,9 +4,15 @@ package main import ( + "bufio" + "encoding/base64" + "encoding/json" + "errors" "fmt" + "io" + "os" + "strings" - "github.com/pion/example-webrtc-applications/v3/internal/signal" "github.com/pion/webrtc/v3" ) @@ -43,7 +49,7 @@ func Run(f func(*webrtc.DataChannel)) { // 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) @@ -72,10 +78,52 @@ func Run(f func(*webrtc.DataChannel)) { <-gatherComplete // Output the answer in base64 so we can paste it in browser - fmt.Println(signal.Encode(*peerConnection.LocalDescription())) //nolint + fmt.Println(encode(peerConnection.LocalDescription())) //nolint // Block forever select {} } 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/ffmpeg-send/main.go b/ffmpeg-send/main.go index 16478922..c13189f1 100644 --- a/ffmpeg-send/main.go +++ b/ffmpeg-send/main.go @@ -8,12 +8,17 @@ package main import ( + "bufio" + "encoding/base64" + "encoding/json" "errors" "fmt" + "io" + "os" + "strings" "time" "github.com/asticode/go-astiav" - "github.com/pion/example-webrtc-applications/v3/internal/signal" "github.com/pion/webrtc/v3" "github.com/pion/webrtc/v3/pkg/media" ) @@ -48,7 +53,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) @@ -74,7 +79,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())) // Start pushing buffers on these tracks writeH264ToTrack(videoTrack) @@ -264,3 +269,45 @@ func freeVideoCoding() { encodeCodecContext.Free() encodePacket.Free() } + +// 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/gocv-receive/main.go b/gocv-receive/main.go index bc4eb7f8..7b4ba04a 100644 --- a/gocv-receive/main.go +++ b/gocv-receive/main.go @@ -8,16 +8,20 @@ package main import ( "bufio" + "encoding/base64" + "encoding/json" + "errors" "fmt" "image" "image/color" "io" + "os" "os/exec" "runtime" "strconv" + "strings" "time" - "github.com/pion/example-webrtc-applications/v3/internal/signal" "github.com/pion/rtcp" "github.com/pion/webrtc/v3" "github.com/pion/webrtc/v3/pkg/media/ivfwriter" @@ -187,7 +191,7 @@ func createWebRTCConn(ffmpegIn io.Writer) { // 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) @@ -216,5 +220,47 @@ func createWebRTCConn(ffmpegIn io.Writer) { <-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 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/gstreamer-receive/main.go b/gstreamer-receive/main.go index ae4030b9..25645769 100644 --- a/gstreamer-receive/main.go +++ b/gstreamer-receive/main.go @@ -8,13 +8,18 @@ package main import ( + "bufio" + "encoding/base64" + "encoding/json" + "errors" "fmt" + "io" + "os" "strings" "time" "github.com/go-gst/go-gst/gst" "github.com/go-gst/go-gst/gst/app" - "github.com/pion/example-webrtc-applications/v3/internal/signal" "github.com/pion/rtcp" "github.com/pion/webrtc/v3" ) @@ -79,7 +84,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) @@ -108,7 +113,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 {} @@ -148,3 +153,45 @@ func pipelineForCodec(track *webrtc.TrackRemote, codecName string) *app.Source { return app.SrcFromElement(appSrc) } + +// 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/gstreamer-send-offer/main.go b/gstreamer-send-offer/main.go index 3fdc30f8..81c9fb14 100644 --- a/gstreamer-send-offer/main.go +++ b/gstreamer-send-offer/main.go @@ -8,12 +8,16 @@ package main import ( + "encoding/base64" + "encoding/json" "flag" "fmt" + "io" + "net/http" + "strconv" "github.com/go-gst/go-gst/gst" "github.com/go-gst/go-gst/gst/app" - "github.com/pion/example-webrtc-applications/v3/internal/signal" "github.com/pion/webrtc/v3" "github.com/pion/webrtc/v3/pkg/media" ) @@ -21,7 +25,7 @@ import ( func main() { audioSrc := flag.String("audio-src", "audiotestsrc", "GStreamer audio src") videoSrc := flag.String("video-src", "videotestsrc", "GStreamer video src") - sdpChan := signal.HTTPSDPServer() + sdpChan := httpSDPServer() // Initialize GStreamer gst.Init(nil) @@ -85,11 +89,11 @@ func main() { <-gatherComplete // Output the offer in base64 so we can paste it in browser - fmt.Println(signal.Encode(*peerConnection.LocalDescription())) + fmt.Println(encode(peerConnection.LocalDescription())) // Wait for the answer to be submitted via HTTP answer := webrtc.SessionDescription{} - signal.Decode(<-sdpChan, &answer) + decode(<-sdpChan, &answer) // Set the remote SessionDescription err = peerConnection.SetRemoteDescription(answer) @@ -164,3 +168,42 @@ func pipelineForCodec(codecName string, tracks []*webrtc.TrackLocalStaticSample, }, }) } + +// 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/gstreamer-send/main.go b/gstreamer-send/main.go index c1bede24..dd8bf105 100644 --- a/gstreamer-send/main.go +++ b/gstreamer-send/main.go @@ -8,12 +8,18 @@ package main import ( + "bufio" + "encoding/base64" + "encoding/json" + "errors" "flag" "fmt" + "io" + "os" + "strings" "github.com/go-gst/go-gst/gst" "github.com/go-gst/go-gst/gst/app" - "github.com/pion/example-webrtc-applications/v3/internal/signal" "github.com/pion/webrtc/v3" "github.com/pion/webrtc/v3/pkg/media" ) @@ -75,7 +81,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) @@ -101,7 +107,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())) // Start pushing buffers on these tracks pipelineForCodec("opus", []*webrtc.TrackLocalStaticSample{audioTrack}, *audioSrc) @@ -170,3 +176,45 @@ func pipelineForCodec(codecName string, tracks []*webrtc.TrackLocalStaticSample, }, }) } + +// 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/internal/signal/http.go b/internal/signal/http.go deleted file mode 100644 index 015364c9..00000000 --- a/internal/signal/http.go +++ /dev/null @@ -1,34 +0,0 @@ -// SPDX-FileCopyrightText: 2023 The Pion community -// SPDX-License-Identifier: MIT - -package signal - -import ( - "flag" - "fmt" - "io" - "net/http" - "strconv" -) - -// HTTPSDPServer starts a HTTP Server that consumes SDPs -func HTTPSDPServer() chan string { - port := flag.Int("port", 8080, "http server port") - flag.Parse() - - sdpChan := make(chan string) - http.HandleFunc("/sdp", func(w http.ResponseWriter, r *http.Request) { - body, _ := io.ReadAll(r.Body) - fmt.Fprintf(w, "done") // nolint - sdpChan <- string(body) - }) - - go func() { - err := http.ListenAndServe(":"+strconv.Itoa(*port), nil) // nolint:gosec - if err != nil { - panic(err) //nolint - } - }() - - return sdpChan -} diff --git a/internal/signal/signal.go b/internal/signal/signal.go deleted file mode 100644 index a067bacd..00000000 --- a/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) //nolint - } - } - in = strings.TrimSpace(in) - if len(in) > 0 { - break - } - } - - fmt.Println("") //nolint - - 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) //nolint - } - - 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) //nolint - } - - if compress { - b = unzip(b) - } - - err = json.Unmarshal(b, obj) - if err != nil { - panic(err) //nolint - } -} - -func zip(in []byte) []byte { - var b bytes.Buffer - gz := gzip.NewWriter(&b) - _, err := gz.Write(in) - if err != nil { - panic(err) //nolint - } - err = gz.Flush() - if err != nil { - panic(err) //nolint - } - err = gz.Close() - if err != nil { - panic(err) //nolint - } - return b.Bytes() -} - -func unzip(in []byte) []byte { - var b bytes.Buffer - _, err := b.Write(in) - if err != nil { - panic(err) //nolint - } - r, err := gzip.NewReader(&b) - if err != nil { - panic(err) //nolint - } - res, err := io.ReadAll(r) - if err != nil { - panic(err) //nolint - } - return res -} diff --git a/play-from-disk-h264/main.go b/play-from-disk-h264/main.go index cd05bcce..3da64815 100644 --- a/play-from-disk-h264/main.go +++ b/play-from-disk-h264/main.go @@ -8,14 +8,17 @@ package main import ( + "bufio" "context" + "encoding/base64" + "encoding/json" "errors" "fmt" "io" "os" + "strings" "time" - "github.com/pion/example-webrtc-applications/v3/internal/signal" "github.com/pion/webrtc/v3" "github.com/pion/webrtc/v3/pkg/media" "github.com/pion/webrtc/v3/pkg/media/h264reader" @@ -218,7 +221,7 @@ func main() { //nolint // 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 { @@ -245,8 +248,50 @@ func main() { //nolint <-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/play-from-disk-mkv/main.go b/play-from-disk-mkv/main.go index 2d201f6e..606e1a5b 100644 --- a/play-from-disk-mkv/main.go +++ b/play-from-disk-mkv/main.go @@ -8,14 +8,19 @@ package main import ( + "bufio" + "encoding/base64" "encoding/binary" + "encoding/json" + "errors" "fmt" + "io" "os" + "strings" "time" "github.com/at-wat/ebml-go" "github.com/at-wat/ebml-go/webm" - "github.com/pion/example-webrtc-applications/v3/internal/signal" "github.com/pion/webrtc/v3" "github.com/pion/webrtc/v3/pkg/media" ) @@ -109,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 if err = peerConnection.SetRemoteDescription(offer); err != nil { @@ -136,7 +141,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 from the MKV and write the Audio and Video tracks sendMkv(mkvFile, audioTrack, videoTrack) @@ -286,3 +291,45 @@ func rtcpReader(rtpSender *webrtc.RTPSender) { } }() } + +// 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/rtmp-to-webrtc/main.go b/rtmp-to-webrtc/main.go index cb2c59e5..d33cd735 100644 --- a/rtmp-to-webrtc/main.go +++ b/rtmp-to-webrtc/main.go @@ -8,10 +8,16 @@ package main import ( + "bufio" + "encoding/base64" + "encoding/json" + "errors" "fmt" + "io" "net" + "os" + "strings" - "github.com/pion/example-webrtc-applications/v3/internal/signal" "github.com/pion/rtp" "github.com/pion/rtp/codecs" "github.com/pion/webrtc/v3" @@ -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 if err = peerConnection.SetRemoteDescription(offer); err != nil { @@ -87,7 +93,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())) go rtpToTrack(videoTrack, &codecs.VP8Packet{}, 90000, 5004) rtpToTrack(audioTrack, &codecs.OpusPacket{}, 48000, 5006) @@ -150,3 +156,45 @@ func processRTCP(rtpSender *webrtc.RTPSender) { } }() } + +// 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/save-to-webm/main.go b/save-to-webm/main.go index 9668a055..d628a5ac 100644 --- a/save-to-webm/main.go +++ b/save-to-webm/main.go @@ -8,15 +8,18 @@ package main import ( + "bufio" + "encoding/base64" + "encoding/json" "errors" "fmt" "io" "os" "os/signal" + "strings" "time" "github.com/at-wat/ebml-go/webm" - webrtcsignal "github.com/pion/example-webrtc-applications/v3/internal/signal" "github.com/pion/rtcp" "github.com/pion/rtp" "github.com/pion/rtp/codecs" @@ -233,7 +236,7 @@ func createWebRTCConn(saver *webmSaver) *webrtc.PeerConnection { // Wait for the offer to be pasted offer := webrtc.SessionDescription{} - webrtcsignal.Decode(webrtcsignal.MustReadStdin(), &offer) + decode(readUntilNewline(), &offer) // Set the remote SessionDescription err = peerConnection.SetRemoteDescription(offer) @@ -262,7 +265,49 @@ func createWebRTCConn(saver *webmSaver) *webrtc.PeerConnection { <-gatherComplete // Output the answer in base64 so we can paste it in browser - fmt.Println(webrtcsignal.Encode(*peerConnection.LocalDescription())) + fmt.Println(encode(peerConnection.LocalDescription())) return peerConnection } + +// 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/sip-to-webrtc/main.go b/sip-to-webrtc/main.go index 57b20cb6..141dd9ec 100644 --- a/sip-to-webrtc/main.go +++ b/sip-to-webrtc/main.go @@ -8,14 +8,20 @@ package main import ( + "bufio" "context" + "encoding/base64" + "encoding/json" + "errors" "flag" "fmt" + "io" "net" + "os" + "strings" "github.com/emiago/sipgo" "github.com/emiago/sipgo/sip" - "github.com/pion/example-webrtc-applications/v3/internal/signal" "github.com/pion/sdp/v3" "github.com/pion/webrtc/v3" ) @@ -83,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 { @@ -107,7 +113,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())) // Create the SIP UA sipUserAgent, err := sipgo.NewUA() @@ -238,3 +244,45 @@ func generateAnswer(offer []byte, unicastAddress string, rtpListenerPort int) [] } return answerByte } + +// 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/twitch/main.go b/twitch/main.go index b6c3d485..f12ca140 100644 --- a/twitch/main.go +++ b/twitch/main.go @@ -9,15 +9,17 @@ package main import ( "bufio" + "encoding/base64" + "encoding/json" "errors" "fmt" "io" "os" "os/exec" + "strings" "time" "github.com/at-wat/ebml-go/webm" - "github.com/pion/example-webrtc-applications/v3/internal/signal" "github.com/pion/rtcp" "github.com/pion/rtp" "github.com/pion/rtp/codecs" @@ -120,7 +122,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) @@ -141,7 +143,7 @@ func main() { } // 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 {} @@ -246,3 +248,45 @@ func pushVP8(rtpPacket *rtp.Packet) { } } } + +// 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) + } +}