Examples: Make examples/util internal

Resolves #424
This commit is contained in:
backkem
2019-02-20 20:42:19 +01:00
committed by Michiel De Backker
parent bf422e0c0a
commit ddcef2d84f
24 changed files with 542 additions and 247 deletions

View File

@@ -6,8 +6,9 @@ import (
"time"
"github.com/pions/webrtc"
"github.com/pions/webrtc/examples/util"
"github.com/pions/webrtc/pkg/datachannel"
"github.com/pions/webrtc/examples/internal/signal"
)
func main() {
@@ -27,7 +28,9 @@ func main() {
// Create a new RTCPeerConnection
peerConnection, err := webrtc.NewPeerConnection(config)
util.Check(err)
if err != nil {
panic(err)
}
// Set the handler for ICE connection state
// This will notify you when the peer has connected/disconnected
@@ -52,18 +55,22 @@ func main() {
cnt := *closeAfter
for range ticker.C {
message := util.RandSeq(15)
message := signal.RandSeq(15)
fmt.Printf("Sending %s \n", message)
err := d.Send(datachannel.PayloadString{Data: []byte(message)})
util.Check(err)
if err != nil {
panic(err)
}
cnt--
if cnt < 0 {
fmt.Printf("Sent %d times. Closing data channel '%s'-'%d'.\n", *closeAfter, d.Label, d.ID)
ticker.Stop()
err = d.Close()
util.Check(err)
if err != nil {
panic(err)
}
}
}
})
@@ -83,22 +90,28 @@ func main() {
// Wait for the offer to be pasted
offer := webrtc.SessionDescription{}
util.Decode(util.MustReadStdin(), &offer)
signal.Decode(signal.MustReadStdin(), &offer)
// Set the remote SessionDescription
err = peerConnection.SetRemoteDescription(offer)
util.Check(err)
if err != nil {
panic(err)
}
// Create answer
answer, err := peerConnection.CreateAnswer(nil)
util.Check(err)
if err != nil {
panic(err)
}
// Sets the LocalDescription, and starts our UDP listeners
err = peerConnection.SetLocalDescription(answer)
util.Check(err)
if err != nil {
panic(err)
}
// Output the answer in base64 so we can paste it in browser
fmt.Println(util.Encode(answer))
fmt.Println(signal.Encode(answer))
// Block forever
select {}

View File

@@ -5,8 +5,9 @@ import (
"time"
"github.com/pions/webrtc"
"github.com/pions/webrtc/examples/util"
"github.com/pions/webrtc/pkg/datachannel"
sugar "github.com/pions/webrtc/pkg/datachannel"
"github.com/pions/webrtc/examples/internal/signal"
)
func main() {
@@ -23,11 +24,15 @@ func main() {
// Create a new RTCPeerConnection
peerConnection, err := webrtc.NewPeerConnection(config)
util.Check(err)
if err != nil {
panic(err)
}
// Create a datachannel with label 'data'
dataChannel, err := peerConnection.CreateDataChannel("data", nil)
util.Check(err)
if err != nil {
panic(err)
}
// Set the handler for ICE connection state
// This will notify you when the peer has connected/disconnected
@@ -40,20 +45,22 @@ func main() {
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 := util.RandSeq(15)
message := signal.RandSeq(15)
fmt.Printf("Sending %s \n", message)
err := dataChannel.Send(datachannel.PayloadString{Data: []byte(message)})
util.Check(err)
err := dataChannel.Send(sugar.PayloadString{Data: []byte(message)})
if err != nil {
panic(err)
}
}
})
// Register the OnMessage to handle incoming messages
dataChannel.OnMessage(func(payload datachannel.Payload) {
dataChannel.OnMessage(func(payload sugar.Payload) {
switch p := payload.(type) {
case *datachannel.PayloadString:
case *sugar.PayloadString:
fmt.Printf("Message '%s' from DataChannel '%s' payload '%s'\n", p.PayloadType().String(), dataChannel.Label, string(p.Data))
case *datachannel.PayloadBinary:
case *sugar.PayloadBinary:
fmt.Printf("Message '%s' from DataChannel '%s' payload '% 02x'\n", p.PayloadType().String(), dataChannel.Label, p.Data)
default:
fmt.Printf("Message '%s' from DataChannel '%s' no payload \n", p.PayloadType().String(), dataChannel.Label)
@@ -62,22 +69,28 @@ func main() {
// Create an offer to send to the browser
offer, err := peerConnection.CreateOffer(nil)
util.Check(err)
if err != nil {
panic(err)
}
// Sets the LocalDescription, and starts our UDP listeners
err = peerConnection.SetLocalDescription(offer)
util.Check(err)
if err != nil {
panic(err)
}
// Output the offer in base64 so we can paste it in browser
fmt.Println(util.Encode(offer))
fmt.Println(signal.Encode(offer))
// Wait for the answer to be pasted
answer := webrtc.SessionDescription{}
util.Decode(util.MustReadStdin(), &answer)
signal.Decode(signal.MustReadStdin(), &answer)
// Apply the answer as the remote description
err = peerConnection.SetRemoteDescription(answer)
util.Check(err)
if err != nil {
panic(err)
}
// Block forever
select {}

View File

@@ -6,7 +6,8 @@ import (
"github.com/pions/datachannel"
"github.com/pions/webrtc"
"github.com/pions/webrtc/examples/util"
"github.com/pions/webrtc/examples/internal/signal"
)
const messageSize = 15
@@ -30,11 +31,15 @@ func main() {
// Create a new RTCPeerConnection
peerConnection, err := webrtc.NewPeerConnection(config)
util.Check(err)
if err != nil {
panic(err)
}
// Create a datachannel with label 'data'
dataChannel, err := peerConnection.CreateDataChannel("data", nil)
util.Check(err)
if err != nil {
panic(err)
}
// Set the handler for ICE connection state
// This will notify you when the peer has connected/disconnected
@@ -48,7 +53,9 @@ func main() {
// Detach the data channel
raw, dErr := dataChannel.Detach()
util.Check(dErr)
if dErr != nil {
panic(dErr)
}
// Handle reading from the data channel
go ReadLoop(raw)
@@ -59,22 +66,28 @@ func main() {
// Create an offer to send to the browser
offer, err := peerConnection.CreateOffer(nil)
util.Check(err)
if err != nil {
panic(err)
}
// Sets the LocalDescription, and starts our UDP listeners
err = peerConnection.SetLocalDescription(offer)
util.Check(err)
if err != nil {
panic(err)
}
// Output the offer in base64 so we can paste it in browser
fmt.Println(util.Encode(offer))
fmt.Println(signal.Encode(offer))
// Wait for the answer to be pasted
answer := webrtc.SessionDescription{}
util.Decode(util.MustReadStdin(), answer)
signal.Decode(signal.MustReadStdin(), answer)
// Apply the answer as the remote description
err = peerConnection.SetRemoteDescription(answer)
util.Check(err)
if err != nil {
panic(err)
}
// Block forever
select {}
@@ -97,10 +110,12 @@ func ReadLoop(d *datachannel.DataChannel) {
// WriteLoop shows how to write to the datachannel directly
func WriteLoop(d *datachannel.DataChannel) {
for range time.NewTicker(5 * time.Second).C {
message := util.RandSeq(messageSize)
message := signal.RandSeq(messageSize)
fmt.Printf("Sending %s \n", message)
_, err := d.Write([]byte(message))
util.Check(err)
if err != nil {
panic(err)
}
}
}

View File

@@ -6,7 +6,8 @@ import (
"github.com/pions/datachannel"
"github.com/pions/webrtc"
"github.com/pions/webrtc/examples/util"
"github.com/pions/webrtc/examples/internal/signal"
)
const messageSize = 15
@@ -30,7 +31,9 @@ func main() {
// Create a new RTCPeerConnection
peerConnection, err := webrtc.NewPeerConnection(config)
util.Check(err)
if err != nil {
panic(err)
}
// Set the handler for ICE connection state
// This will notify you when the peer has connected/disconnected
@@ -48,7 +51,9 @@ func main() {
// Detach the data channel
raw, dErr := d.Detach()
util.Check(dErr)
if dErr != nil {
panic(dErr)
}
// Handle reading from the data channel
go ReadLoop(raw)
@@ -60,22 +65,28 @@ func main() {
// Wait for the offer to be pasted
offer := webrtc.SessionDescription{}
util.Decode(util.MustReadStdin(), offer)
signal.Decode(signal.MustReadStdin(), offer)
// Set the remote SessionDescription
err = peerConnection.SetRemoteDescription(offer)
util.Check(err)
if err != nil {
panic(err)
}
// Create answer
answer, err := peerConnection.CreateAnswer(nil)
util.Check(err)
if err != nil {
panic(err)
}
// Sets the LocalDescription, and starts our UDP listeners
err = peerConnection.SetLocalDescription(answer)
util.Check(err)
if err != nil {
panic(err)
}
// Output the answer in base64 so we can paste it in browser
fmt.Println(util.Encode(answer))
fmt.Println(signal.Encode(answer))
// Block forever
select {}
@@ -98,10 +109,12 @@ func ReadLoop(d *datachannel.DataChannel) {
// WriteLoop shows how to write to the datachannel directly
func WriteLoop(d *datachannel.DataChannel) {
for range time.NewTicker(5 * time.Second).C {
message := util.RandSeq(messageSize)
message := signal.RandSeq(messageSize)
fmt.Printf("Sending %s \n", message)
_, err := d.Write([]byte(message))
util.Check(err)
if err != nil {
panic(err)
}
}
}

View File

@@ -5,8 +5,9 @@ import (
"time"
"github.com/pions/webrtc"
"github.com/pions/webrtc/examples/util"
"github.com/pions/webrtc/pkg/datachannel"
sugar "github.com/pions/webrtc/pkg/datachannel"
"github.com/pions/webrtc/examples/internal/signal"
)
func main() {
@@ -23,7 +24,9 @@ func main() {
// Create a new RTCPeerConnection
peerConnection, err := webrtc.NewPeerConnection(config)
util.Check(err)
if err != nil {
panic(err)
}
// Set the handler for ICE connection state
// This will notify you when the peer has connected/disconnected
@@ -40,20 +43,22 @@ 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 := util.RandSeq(15)
message := signal.RandSeq(15)
fmt.Printf("Sending %s \n", message)
err := d.Send(datachannel.PayloadString{Data: []byte(message)})
util.Check(err)
err := d.Send(sugar.PayloadString{Data: []byte(message)})
if err != nil {
panic(err)
}
}
})
// Register message handling
d.OnMessage(func(payload datachannel.Payload) {
d.OnMessage(func(payload sugar.Payload) {
switch p := payload.(type) {
case *datachannel.PayloadString:
case *sugar.PayloadString:
fmt.Printf("Message '%s' from DataChannel '%s' payload '%s'\n", p.PayloadType().String(), d.Label, string(p.Data))
case *datachannel.PayloadBinary:
case *sugar.PayloadBinary:
fmt.Printf("Message '%s' from DataChannel '%s' payload '% 02x'\n", p.PayloadType().String(), d.Label, p.Data)
default:
fmt.Printf("Message '%s' from DataChannel '%s' no payload \n", p.PayloadType().String(), d.Label)
@@ -63,22 +68,28 @@ func main() {
// Wait for the offer to be pasted
offer := webrtc.SessionDescription{}
util.Decode(util.MustReadStdin(), &offer)
signal.Decode(signal.MustReadStdin(), &offer)
// Set the remote SessionDescription
err = peerConnection.SetRemoteDescription(offer)
util.Check(err)
if err != nil {
panic(err)
}
// Create an answer
answer, err := peerConnection.CreateAnswer(nil)
util.Check(err)
if err != nil {
panic(err)
}
// Sets the LocalDescription, and starts our UDP listeners
err = peerConnection.SetLocalDescription(answer)
util.Check(err)
if err != nil {
panic(err)
}
// Output the answer in base64 so we can paste it in browser
fmt.Println(util.Encode(answer))
fmt.Println(signal.Encode(answer))
// Block forever
select {}

View File

@@ -7,8 +7,9 @@ import (
"github.com/pions/rtcp"
"github.com/pions/webrtc"
"github.com/pions/webrtc/examples/util"
gst "github.com/pions/webrtc/examples/util/gstreamer-sink"
gst "github.com/pions/webrtc/examples/internal/gstreamer-sink"
"github.com/pions/webrtc/examples/internal/signal"
)
// gstreamerReceiveMain is launched in a goroutine because the main thread is needed
@@ -31,7 +32,9 @@ func gstreamerReceiveMain() {
// Create a new RTCPeerConnection
peerConnection, err := webrtc.NewPeerConnection(config)
util.Check(err)
if err != nil {
panic(err)
}
// Set a handler for when a new remote track starts, this handler creates a gstreamer pipeline
// for the given codec
@@ -66,22 +69,28 @@ func gstreamerReceiveMain() {
// Wait for the offer to be pasted
offer := webrtc.SessionDescription{}
util.Decode(util.MustReadStdin(), &offer)
signal.Decode(signal.MustReadStdin(), &offer)
// Set the remote SessionDescription
err = peerConnection.SetRemoteDescription(offer)
util.Check(err)
if err != nil {
panic(err)
}
// Create an answer
answer, err := peerConnection.CreateAnswer(nil)
util.Check(err)
if err != nil {
panic(err)
}
// Sets the LocalDescription, and starts our UDP listeners
err = peerConnection.SetLocalDescription(answer)
util.Check(err)
if err != nil {
panic(err)
}
// Output the answer in base64 so we can paste it in browser
fmt.Println(util.Encode(answer))
fmt.Println(signal.Encode(answer))
// Block forever
select {}

View File

@@ -4,8 +4,9 @@ import (
"fmt"
"github.com/pions/webrtc"
"github.com/pions/webrtc/examples/util"
gst "github.com/pions/webrtc/examples/util/gstreamer-src"
gst "github.com/pions/webrtc/examples/internal/gstreamer-src"
"github.com/pions/webrtc/examples/internal/signal"
)
func main() {
@@ -26,7 +27,9 @@ func main() {
// Create a new RTCPeerConnection
peerConnection, err := webrtc.NewPeerConnection(config)
util.Check(err)
if err != nil {
panic(err)
}
// Set the handler for ICE connection state
// This will notify you when the peer has connected/disconnected
@@ -36,34 +39,48 @@ func main() {
// Create a audio track
opusTrack, err := peerConnection.NewSampleTrack(webrtc.DefaultPayloadTypeOpus, "audio", "pion1")
util.Check(err)
if err != nil {
panic(err)
}
_, err = peerConnection.AddTrack(opusTrack)
util.Check(err)
if err != nil {
panic(err)
}
// Create a video track
vp8Track, err := peerConnection.NewSampleTrack(webrtc.DefaultPayloadTypeVP8, "video", "pion2")
util.Check(err)
if err != nil {
panic(err)
}
_, err = peerConnection.AddTrack(vp8Track)
util.Check(err)
if err != nil {
panic(err)
}
// Create an offer to send to the browser
offer, err := peerConnection.CreateOffer(nil)
util.Check(err)
if err != nil {
panic(err)
}
// Sets the LocalDescription, and starts our UDP listeners
err = peerConnection.SetLocalDescription(offer)
util.Check(err)
if err != nil {
panic(err)
}
// Output the offer in base64 so we can paste it in browser
fmt.Println(util.Encode(offer))
fmt.Println(signal.Encode(offer))
// Wait for the answer to be pasted
answer := webrtc.SessionDescription{}
util.Decode(util.MustReadStdin(), &answer)
signal.Decode(signal.MustReadStdin(), &answer)
// Set the remote SessionDescription
err = peerConnection.SetRemoteDescription(answer)
util.Check(err)
if err != nil {
panic(err)
}
// Start pushing buffers on these tracks
gst.CreatePipeline(webrtc.Opus, opusTrack.Samples, "audiotestsrc").Start()

View File

@@ -5,8 +5,9 @@ import (
"fmt"
"github.com/pions/webrtc"
"github.com/pions/webrtc/examples/util"
gst "github.com/pions/webrtc/examples/util/gstreamer-src"
gst "github.com/pions/webrtc/examples/internal/gstreamer-src"
"github.com/pions/webrtc/examples/internal/signal"
)
func main() {
@@ -31,7 +32,9 @@ func main() {
// Create a new RTCPeerConnection
peerConnection, err := webrtc.NewPeerConnection(config)
util.Check(err)
if err != nil {
panic(err)
}
// Set the handler for ICE connection state
// This will notify you when the peer has connected/disconnected
@@ -41,34 +44,48 @@ func main() {
// Create a audio track
opusTrack, err := peerConnection.NewSampleTrack(webrtc.DefaultPayloadTypeOpus, "audio", "pion1")
util.Check(err)
if err != nil {
panic(err)
}
_, err = peerConnection.AddTrack(opusTrack)
util.Check(err)
if err != nil {
panic(err)
}
// Create a video track
vp8Track, err := peerConnection.NewSampleTrack(webrtc.DefaultPayloadTypeVP8, "video", "pion2")
util.Check(err)
if err != nil {
panic(err)
}
_, err = peerConnection.AddTrack(vp8Track)
util.Check(err)
if err != nil {
panic(err)
}
// Wait for the offer to be pasted
offer := webrtc.SessionDescription{}
util.Decode(util.MustReadStdin(), &offer)
signal.Decode(signal.MustReadStdin(), &offer)
// Set the remote SessionDescription
err = peerConnection.SetRemoteDescription(offer)
util.Check(err)
if err != nil {
panic(err)
}
// Create an answer
answer, err := peerConnection.CreateAnswer(nil)
util.Check(err)
if err != nil {
panic(err)
}
// Sets the LocalDescription, and starts our UDP listeners
err = peerConnection.SetLocalDescription(answer)
util.Check(err)
if err != nil {
panic(err)
}
// Output the answer in base64 so we can paste it in browser
fmt.Println(util.Encode(answer))
fmt.Println(signal.Encode(answer))
// Start pushing buffers on these tracks
gst.CreatePipeline(webrtc.Opus, opusTrack.Samples, *audioSrc).Start()

View File

@@ -0,0 +1,17 @@
package signal
import (
"math/rand"
"time"
)
// RandSeq generates a random string to serve as dummy data
func RandSeq(n int) string {
r := rand.New(rand.NewSource(time.Now().UnixNano()))
letters := []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
b := make([]rune, n)
for i := range b {
b[i] = letters[r.Intn(len(letters))]
}
return string(b)
}

View File

@@ -1,4 +1,6 @@
package util
// Package signal contains helpers to exchange the SDP session
// description between examples.
package signal
import (
"bufio"
@@ -9,23 +11,13 @@ import (
"fmt"
"io"
"io/ioutil"
"math/rand"
"os"
"strings"
"time"
)
// Allows compressing offer/answer to bypass terminal input limits.
const compress = false
// Check is used to panic in an error occurs.
// Don't do this! We're only using it to make the examples shorter.
func Check(err error) {
if err != nil {
panic(err)
}
}
// MustReadStdin blocks until input is received from stdin
func MustReadStdin() string {
r := bufio.NewReader(os.Stdin)
@@ -35,7 +27,9 @@ func MustReadStdin() string {
var err error
in, err = r.ReadString('\n')
if err != io.EOF {
Check(err)
if err != nil {
panic(err)
}
}
in = strings.TrimSpace(in)
if len(in) > 0 {
@@ -52,7 +46,9 @@ func MustReadStdin() string {
// It can optionally zip the input before encoding
func Encode(obj interface{}) string {
b, err := json.Marshal(obj)
Check(err)
if err != nil {
panic(err)
}
if compress {
b = zip(b)
@@ -65,46 +61,51 @@ func Encode(obj interface{}) string {
// It can optionally unzip the input after decoding
func Decode(in string, obj interface{}) {
b, err := base64.StdEncoding.DecodeString(in)
Check(err)
if err != nil {
panic(err)
}
if compress {
b = unzip(b)
}
err = json.Unmarshal(b, obj)
Check(err)
}
// RandSeq generates a random string to serve as dummy data
func RandSeq(n int) string {
r := rand.New(rand.NewSource(time.Now().UnixNano()))
letters := []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
b := make([]rune, n)
for i := range b {
b[i] = letters[r.Intn(len(letters))]
if err != nil {
panic(err)
}
return string(b)
}
func zip(in []byte) []byte {
var b bytes.Buffer
gz := gzip.NewWriter(&b)
_, err := gz.Write(in)
Check(err)
if err != nil {
panic(err)
}
err = gz.Flush()
Check(err)
if err != nil {
panic(err)
}
err = gz.Close()
Check(err)
if err != nil {
panic(err)
}
return b.Bytes()
}
func unzip(in []byte) []byte {
var b bytes.Buffer
_, err := b.Write(in)
Check(err)
if err != nil {
panic(err)
}
r, err := gzip.NewReader(&b)
Check(err)
if err != nil {
panic(err)
}
res, err := ioutil.ReadAll(r)
Check(err)
if err != nil {
panic(err)
}
return res
}

View File

@@ -6,7 +6,6 @@ import (
janus "github.com/notedit/janus-go"
"github.com/pions/webrtc"
"github.com/pions/webrtc/examples/util"
"github.com/pions/webrtc/pkg/media/ivfwriter"
)
@@ -49,7 +48,9 @@ func main() {
// Create a new RTCPeerConnection
peerConnection, err := webrtc.NewPeerConnection(config)
util.Check(err)
if err != nil {
panic(err)
}
peerConnection.OnICEConnectionStateChange(func(connectionState webrtc.ICEConnectionState) {
fmt.Printf("Connection State has changed %s \n", connectionState.String())
@@ -62,24 +63,34 @@ func main() {
fmt.Println("Got VP8 track, saving to disk as output.ivf")
i, err := ivfwriter.New("output.ivf")
util.Check(err)
if err != nil {
panic(err)
}
for {
err = i.AddPacket(<-track.Packets)
util.Check(err)
if err != nil {
panic(err)
}
}
})
// Janus
gateway, err := janus.Connect("ws://localhost:8188/")
util.Check(err)
if err != nil {
panic(err)
}
// Create session
session, err := gateway.Create()
util.Check(err)
if err != nil {
panic(err)
}
// Create handle
handle, err := session.Attach("janus.plugin.streaming")
util.Check(err)
if err != nil {
panic(err)
}
go watchHandle(handle)
@@ -87,27 +98,37 @@ func main() {
_, err = handle.Request(map[string]interface{}{
"request": "list",
})
util.Check(err)
if err != nil {
panic(err)
}
// Watch the second stream
msg, err := handle.Message(map[string]interface{}{
"request": "watch",
"id": 1,
}, nil)
util.Check(err)
if err != nil {
panic(err)
}
if msg.Jsep != nil {
err = peerConnection.SetRemoteDescription(webrtc.SessionDescription{
Type: webrtc.SDPTypeOffer,
SDP: msg.Jsep["sdp"].(string),
})
util.Check(err)
if err != nil {
panic(err)
}
answer, err := peerConnection.CreateAnswer(nil)
util.Check(err)
if err != nil {
panic(err)
}
err = peerConnection.SetLocalDescription(answer)
util.Check(err)
if err != nil {
panic(err)
}
// now we start
_, err = handle.Message(map[string]interface{}{
@@ -117,11 +138,15 @@ func main() {
"sdp": answer.SDP,
"trickle": false,
})
util.Check(err)
if err != nil {
panic(err)
}
}
for {
_, err = session.KeepAlive()
util.Check(err)
if err != nil {
panic(err)
}
time.Sleep(5 * time.Second)
}

View File

@@ -6,8 +6,8 @@ import (
janus "github.com/notedit/janus-go"
"github.com/pions/webrtc"
"github.com/pions/webrtc/examples/util"
gst "github.com/pions/webrtc/examples/util/gstreamer-src"
gst "github.com/pions/webrtc/examples/internal/gstreamer-src"
)
func watchHandle(handle *janus.Handle) {
@@ -49,7 +49,9 @@ func main() {
// Create a new RTCPeerConnection
peerConnection, err := webrtc.NewPeerConnection(config)
util.Check(err)
if err != nil {
panic(err)
}
peerConnection.OnICEConnectionStateChange(func(connectionState webrtc.ICEConnectionState) {
fmt.Printf("Connection State has changed %s \n", connectionState.String())
@@ -57,30 +59,48 @@ func main() {
// Create a audio track
opusTrack, err := peerConnection.NewSampleTrack(webrtc.DefaultPayloadTypeOpus, "audio", "pion1")
util.Check(err)
if err != nil {
panic(err)
}
_, err = peerConnection.AddTrack(opusTrack)
util.Check(err)
if err != nil {
panic(err)
}
// Create a video track
vp8Track, err := peerConnection.NewSampleTrack(webrtc.DefaultPayloadTypeVP8, "video", "pion2")
util.Check(err)
if err != nil {
panic(err)
}
_, err = peerConnection.AddTrack(vp8Track)
util.Check(err)
if err != nil {
panic(err)
}
offer, err := peerConnection.CreateOffer(nil)
util.Check(err)
if err != nil {
panic(err)
}
err = peerConnection.SetLocalDescription(offer)
util.Check(err)
if err != nil {
panic(err)
}
gateway, err := janus.Connect("ws://localhost:8188/janus")
util.Check(err)
if err != nil {
panic(err)
}
session, err := gateway.Create()
util.Check(err)
if err != nil {
panic(err)
}
handle, err := session.Attach("janus.plugin.videoroom")
util.Check(err)
if err != nil {
panic(err)
}
go watchHandle(handle)
@@ -90,7 +110,9 @@ func main() {
"room": 1234,
"id": 1,
}, nil)
util.Check(err)
if err != nil {
panic(err)
}
msg, err := handle.Message(map[string]interface{}{
"request": "publish",
@@ -102,14 +124,18 @@ func main() {
"sdp": offer.SDP,
"trickle": false,
})
util.Check(err)
if err != nil {
panic(err)
}
if msg.Jsep != nil {
err = peerConnection.SetRemoteDescription(webrtc.SessionDescription{
Type: webrtc.SDPTypeAnswer,
SDP: msg.Jsep["sdp"].(string),
})
util.Check(err)
if err != nil {
panic(err)
}
// Start pushing buffers on these tracks
gst.CreatePipeline(webrtc.Opus, opusTrack.Samples, "audiotestsrc").Start()

View File

@@ -5,10 +5,10 @@ import (
"fmt"
"time"
"github.com/pions/webrtc"
"github.com/pions/webrtc/pkg/quic"
"github.com/pions/webrtc"
"github.com/pions/webrtc/examples/util"
"github.com/pions/webrtc/examples/internal/signal"
)
const messageSize = 15
@@ -33,14 +33,18 @@ func main() {
// Create the ICE gatherer
gatherer, err := api.NewICEGatherer(iceOptions)
util.Check(err)
if err != nil {
panic(err)
}
// Construct the ICE transport
ice := api.NewICETransport(gatherer)
// Construct the Quic transport
qt, err := api.NewQUICTransport(ice, nil)
util.Check(err)
if err != nil {
panic(err)
}
// Handle incoming streams
qt.OnBidirectionalStream(func(stream *quic.BidirectionalStream) {
@@ -55,26 +59,32 @@ func main() {
// Gather candidates
err = gatherer.Gather()
util.Check(err)
if err != nil {
panic(err)
}
iceCandidates, err := gatherer.GetLocalCandidates()
util.Check(err)
if err != nil {
panic(err)
}
iceParams, err := gatherer.GetLocalParameters()
util.Check(err)
if err != nil {
panic(err)
}
quicParams := qt.GetLocalParameters()
signal := Signal{
s := Signal{
ICECandidates: iceCandidates,
ICEParameters: iceParams,
QuicParameters: quicParams,
}
// Exchange the information
fmt.Println(util.Encode(signal))
fmt.Println(signal.Encode(s))
remoteSignal := Signal{}
util.Decode(util.MustReadStdin(), &remoteSignal)
signal.Decode(signal.MustReadStdin(), &remoteSignal)
iceRole := webrtc.ICERoleControlled
if *isOffer {
@@ -82,21 +92,29 @@ func main() {
}
err = ice.SetRemoteCandidates(remoteSignal.ICECandidates)
util.Check(err)
if err != nil {
panic(err)
}
// Start the ICE transport
err = ice.Start(nil, remoteSignal.ICEParameters, &iceRole)
util.Check(err)
if err != nil {
panic(err)
}
// Start the Quic transport
err = qt.Start(remoteSignal.QuicParameters)
util.Check(err)
if err != nil {
panic(err)
}
// Construct the stream as the offerer
if *isOffer {
var stream *quic.BidirectionalStream
stream, err = qt.CreateBidirectionalStream()
util.Check(err)
if err != nil {
panic(err)
}
// Handle reading from the stream
go ReadLoop(stream)
@@ -122,7 +140,9 @@ func ReadLoop(s *quic.BidirectionalStream) {
for {
buffer := make([]byte, messageSize)
params, err := s.ReadInto(buffer)
util.Check(err)
if err != nil {
panic(err)
}
fmt.Printf("Message from stream '%d': %s\n", s.StreamID(), string(buffer[:params.Amount]))
}
@@ -131,13 +151,15 @@ func ReadLoop(s *quic.BidirectionalStream) {
// WriteLoop writes to the stream
func WriteLoop(s *quic.BidirectionalStream) {
for range time.NewTicker(5 * time.Second).C {
message := util.RandSeq(messageSize)
message := signal.RandSeq(messageSize)
fmt.Printf("Sending %s \n", message)
data := quic.StreamWriteParameters{
Data: []byte(message),
}
err := s.Write(data)
util.Check(err)
if err != nil {
panic(err)
}
}
}

View File

@@ -6,8 +6,9 @@ import (
"time"
"github.com/pions/webrtc"
"github.com/pions/webrtc/examples/util"
"github.com/pions/webrtc/pkg/datachannel"
sugar "github.com/pions/webrtc/pkg/datachannel"
"github.com/pions/webrtc/examples/internal/signal"
)
func main() {
@@ -28,14 +29,18 @@ func main() {
// Create the ICE gatherer
gatherer, err := api.NewICEGatherer(iceOptions)
util.Check(err)
if err != nil {
panic(err)
}
// Construct the ICE transport
ice := api.NewICETransport(gatherer)
// Construct the DTLS transport
dtls, err := api.NewDTLSTransport(ice, nil)
util.Check(err)
if err != nil {
panic(err)
}
// Construct the SCTP transport
sctp := api.NewSCTPTransport(dtls)
@@ -51,19 +56,25 @@ func main() {
// Gather candidates
err = gatherer.Gather()
util.Check(err)
if err != nil {
panic(err)
}
iceCandidates, err := gatherer.GetLocalCandidates()
util.Check(err)
if err != nil {
panic(err)
}
iceParams, err := gatherer.GetLocalParameters()
util.Check(err)
if err != nil {
panic(err)
}
dtlsParams := dtls.GetLocalParameters()
sctpCapabilities := sctp.GetCapabilities()
signal := Signal{
s := Signal{
ICECandidates: iceCandidates,
ICEParameters: iceParams,
DTLSParameters: dtlsParams,
@@ -71,9 +82,9 @@ func main() {
}
// Exchange the information
fmt.Println(util.Encode(signal))
fmt.Println(signal.Encode(s))
remoteSignal := Signal{}
util.Decode(util.MustReadStdin(), &remoteSignal)
signal.Decode(signal.MustReadStdin(), &remoteSignal)
iceRole := webrtc.ICERoleControlled
if *isOffer {
@@ -81,19 +92,27 @@ func main() {
}
err = ice.SetRemoteCandidates(remoteSignal.ICECandidates)
util.Check(err)
if err != nil {
panic(err)
}
// Start the ICE transport
err = ice.Start(nil, remoteSignal.ICEParameters, &iceRole)
util.Check(err)
if err != nil {
panic(err)
}
// Start the DTLS transport
err = dtls.Start(remoteSignal.DTLSParameters)
util.Check(err)
if err != nil {
panic(err)
}
// Start the SCTP transport
err = sctp.Start(remoteSignal.SCTPCapabilities)
util.Check(err)
if err != nil {
panic(err)
}
// Construct the data channel as the offerer
if *isOffer {
@@ -103,7 +122,9 @@ func main() {
}
var channel *webrtc.DataChannel
channel, err = api.NewDataChannel(sctp, dcParams)
util.Check(err)
if err != nil {
panic(err)
}
// Register the handlers
// channel.OnOpen(handleOnOpen(channel)) // TODO: OnOpen on handle ChannelAck
@@ -129,21 +150,23 @@ 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 := util.RandSeq(15)
message := signal.RandSeq(15)
fmt.Printf("Sending %s \n", message)
err := channel.Send(datachannel.PayloadString{Data: []byte(message)})
util.Check(err)
err := channel.Send(sugar.PayloadString{Data: []byte(message)})
if err != nil {
panic(err)
}
}
}
}
func handleMessage(channel *webrtc.DataChannel) func(datachannel.Payload) {
return func(payload datachannel.Payload) {
func handleMessage(channel *webrtc.DataChannel) func(sugar.Payload) {
return func(payload sugar.Payload) {
switch p := payload.(type) {
case *datachannel.PayloadString:
case *sugar.PayloadString:
fmt.Printf("Message '%s' from DataChannel '%s' payload '%s'\n", p.PayloadType().String(), channel.Label, string(p.Data))
case *datachannel.PayloadBinary:
case *sugar.PayloadBinary:
fmt.Printf("Message '%s' from DataChannel '%s' payload '% 02x'\n", p.PayloadType().String(), channel.Label, p.Data)
default:
fmt.Printf("Message '%s' from DataChannel '%s' no payload \n", p.PayloadType().String(), channel.Label)

View File

@@ -8,8 +8,9 @@ import (
"time"
"github.com/pions/webrtc"
"github.com/pions/webrtc/examples/util"
"github.com/pions/webrtc/pkg/datachannel"
sugar "github.com/pions/webrtc/pkg/datachannel"
"github.com/pions/webrtc/examples/internal/signal"
)
func main() {
@@ -29,7 +30,9 @@ func main() {
// Create a new RTCPeerConnection
peerConnection, err := webrtc.NewPeerConnection(config)
util.Check(err)
if err != nil {
panic(err)
}
// Set the handler for ICE connection state
// This will notify you when the peer has connected/disconnected
@@ -46,20 +49,22 @@ 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 := util.RandSeq(15)
message := signal.RandSeq(15)
fmt.Printf("Sending %s \n", message)
err := d.Send(datachannel.PayloadString{Data: []byte(message)})
util.Check(err)
err := d.Send(sugar.PayloadString{Data: []byte(message)})
if err != nil {
panic(err)
}
}
})
// Register message handling
d.OnMessage(func(payload datachannel.Payload) {
d.OnMessage(func(payload sugar.Payload) {
switch p := payload.(type) {
case *datachannel.PayloadString:
case *sugar.PayloadString:
fmt.Printf("Message '%s' from DataChannel '%s' payload '%s'\n", p.PayloadType().String(), d.Label, string(p.Data))
case *datachannel.PayloadBinary:
case *sugar.PayloadBinary:
fmt.Printf("Message '%s' from DataChannel '%s' payload '% 02x'\n", p.PayloadType().String(), d.Label, p.Data)
default:
fmt.Printf("Message '%s' from DataChannel '%s' no payload \n", p.PayloadType().String(), d.Label)
@@ -74,15 +79,21 @@ func main() {
offer := <-offerChan
err = peerConnection.SetRemoteDescription(offer)
util.Check(err)
if err != nil {
panic(err)
}
// Create answer
answer, err := peerConnection.CreateAnswer(nil)
util.Check(err)
if err != nil {
panic(err)
}
// Sets the LocalDescription, and starts our UDP listeners
err = peerConnection.SetLocalDescription(answer)
util.Check(err)
if err != nil {
panic(err)
}
// Send the answer
answerChan <- answer
@@ -99,13 +110,17 @@ func mustSignalViaHTTP(address string) (offerOut chan webrtc.SessionDescription,
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
var offer webrtc.SessionDescription
err := json.NewDecoder(r.Body).Decode(&offer)
util.Check(err)
if err != nil {
panic(err)
}
offerOut <- offer
answer := <-answerIn
err = json.NewEncoder(w).Encode(answer)
util.Check(err)
if err != nil {
panic(err)
}
})

View File

@@ -9,8 +9,9 @@ import (
"time"
"github.com/pions/webrtc"
"github.com/pions/webrtc/examples/util"
"github.com/pions/webrtc/pkg/datachannel"
sugar "github.com/pions/webrtc/pkg/datachannel"
"github.com/pions/webrtc/examples/internal/signal"
)
func main() {
@@ -30,11 +31,15 @@ func main() {
// Create a new RTCPeerConnection
peerConnection, err := webrtc.NewPeerConnection(config)
util.Check(err)
if err != nil {
panic(err)
}
// Create a datachannel with label 'data'
dataChannel, err := peerConnection.CreateDataChannel("data", nil)
util.Check(err)
if err != nil {
panic(err)
}
// Set the handler for ICE connection state
// This will notify you when the peer has connected/disconnected
@@ -47,20 +52,22 @@ func main() {
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 := util.RandSeq(15)
message := signal.RandSeq(15)
fmt.Printf("Sending %s \n", message)
err := dataChannel.Send(datachannel.PayloadString{Data: []byte(message)})
util.Check(err)
err := dataChannel.Send(sugar.PayloadString{Data: []byte(message)})
if err != nil {
panic(err)
}
}
})
// Register the OnMessage to handle incoming messages
dataChannel.OnMessage(func(payload datachannel.Payload) {
dataChannel.OnMessage(func(payload sugar.Payload) {
switch p := payload.(type) {
case *datachannel.PayloadString:
case *sugar.PayloadString:
fmt.Printf("Message '%s' from DataChannel '%s' payload '%s'\n", p.PayloadType().String(), dataChannel.Label, string(p.Data))
case *datachannel.PayloadBinary:
case *sugar.PayloadBinary:
fmt.Printf("Message '%s' from DataChannel '%s' payload '% 02x'\n", p.PayloadType().String(), dataChannel.Label, p.Data)
default:
fmt.Printf("Message '%s' from DataChannel '%s' no payload \n", p.PayloadType().String(), dataChannel.Label)
@@ -69,18 +76,24 @@ func main() {
// Create an offer to send to the browser
offer, err := peerConnection.CreateOffer(nil)
util.Check(err)
if err != nil {
panic(err)
}
// Sets the LocalDescription, and starts our UDP listeners
err = peerConnection.SetLocalDescription(offer)
util.Check(err)
if err != nil {
panic(err)
}
// Exchange the offer for the answer
answer := mustSignalViaHTTP(offer, *addr)
// Apply the answer as the remote description
err = peerConnection.SetRemoteDescription(answer)
util.Check(err)
if err != nil {
panic(err)
}
// Block forever
select {}
@@ -90,15 +103,21 @@ func main() {
func mustSignalViaHTTP(offer webrtc.SessionDescription, address string) webrtc.SessionDescription {
b := new(bytes.Buffer)
err := json.NewEncoder(b).Encode(offer)
util.Check(err)
if err != nil {
panic(err)
}
resp, err := http.Post("http://"+address, "application/json; charset=utf-8", b)
util.Check(err)
if err != nil {
panic(err)
}
defer resp.Body.Close()
var answer webrtc.SessionDescription
err = json.NewDecoder(resp.Body).Decode(&answer)
util.Check(err)
if err != nil {
panic(err)
}
return answer
}

View File

@@ -6,8 +6,9 @@ import (
"github.com/pions/rtcp"
"github.com/pions/webrtc"
"github.com/pions/webrtc/examples/util"
"github.com/pions/webrtc/pkg/media/ivfwriter"
"github.com/pions/webrtc/examples/internal/signal"
)
func main() {
@@ -29,7 +30,9 @@ func main() {
// Create a new RTCPeerConnection
peerConnection, err := webrtc.NewPeerConnection(config)
util.Check(err)
if err != nil {
panic(err)
}
// Set a handler for when a new remote track starts, this handler saves buffers to disk as
// an ivf file, since we could have multiple video tracks we provide a counter.
@@ -50,10 +53,14 @@ func main() {
if track.Codec.Name == webrtc.VP8 {
fmt.Println("Got VP8 track, saving to disk as output.ivf")
i, err := ivfwriter.New("output.ivf")
util.Check(err)
if err != nil {
panic(err)
}
for {
err = i.AddPacket(<-track.Packets)
util.Check(err)
if err != nil {
panic(err)
}
}
}
})
@@ -66,22 +73,28 @@ func main() {
// Wait for the offer to be pasted
offer := webrtc.SessionDescription{}
util.Decode(util.MustReadStdin(), &offer)
signal.Decode(signal.MustReadStdin(), &offer)
// Set the remote SessionDescription
err = peerConnection.SetRemoteDescription(offer)
util.Check(err)
if err != nil {
panic(err)
}
// Create answer
answer, err := peerConnection.CreateAnswer(nil)
util.Check(err)
if err != nil {
panic(err)
}
// Sets the LocalDescription, and starts our UDP listeners
err = peerConnection.SetLocalDescription(answer)
util.Check(err)
if err != nil {
panic(err)
}
// Output the answer in base64 so we can paste it in browser
fmt.Println(util.Encode(answer))
fmt.Println(signal.Encode(answer))
// Block forever
select {}

View File

@@ -13,7 +13,8 @@ import (
"github.com/pions/rtcp"
"github.com/pions/rtp"
"github.com/pions/webrtc"
"github.com/pions/webrtc/examples/util"
"github.com/pions/webrtc/examples/internal/signal"
)
var peerConnectionConfig = webrtc.Configuration{
@@ -26,7 +27,9 @@ var peerConnectionConfig = webrtc.Configuration{
func mustReadStdin(reader *bufio.Reader) string {
rawSd, err := reader.ReadString('\n')
util.Check(err)
if err != nil {
panic(err)
}
fmt.Println("")
return rawSd
@@ -54,11 +57,13 @@ func main() {
go func() {
err := http.ListenAndServe(":"+strconv.Itoa(*port), nil)
util.Check(err)
if err != nil {
panic(err)
}
}()
offer := webrtc.SessionDescription{}
util.Decode(mustReadHTTP(sdp), &offer)
signal.Decode(mustReadHTTP(sdp), &offer)
fmt.Println("")
/* Everything below is the pion-WebRTC API, thanks for using it! */
@@ -68,7 +73,9 @@ func main() {
// Create a new RTCPeerConnection
peerConnection, err := webrtc.NewPeerConnection(peerConnectionConfig)
util.Check(err)
if err != nil {
panic(err)
}
inboundSSRC := make(chan uint32)
inboundPayloadType := make(chan uint8)
@@ -109,18 +116,25 @@ func main() {
})
// Set the remote SessionDescription
util.Check(peerConnection.SetRemoteDescription(offer))
err = peerConnection.SetRemoteDescription(offer)
if err != nil {
panic(err)
}
// Create answer
answer, err := peerConnection.CreateAnswer(nil)
util.Check(err)
if err != nil {
panic(err)
}
// Sets the LocalDescription, and starts our UDP listeners
err = peerConnection.SetLocalDescription(answer)
util.Check(err)
if err != nil {
panic(err)
}
// Get the LocalDescription and take it to base64 so we can paste in browser
fmt.Println(util.Encode(answer))
fmt.Println(signal.Encode(answer))
outboundSSRC := <-inboundSSRC
outboundPayloadType := <-inboundPayloadType
@@ -129,18 +143,24 @@ func main() {
fmt.Println("Curl an base64 SDP to start sendonly peer connection")
recvOnlyOffer := webrtc.SessionDescription{}
util.Decode(mustReadHTTP(sdp), &recvOnlyOffer)
signal.Decode(mustReadHTTP(sdp), &recvOnlyOffer)
// Create a new PeerConnection
peerConnection, err := webrtc.NewPeerConnection(peerConnectionConfig)
util.Check(err)
if err != nil {
panic(err)
}
// Create a single VP8 Track to send videa
vp8Track, err := peerConnection.NewRawRTPTrack(outboundPayloadType, outboundSSRC, "video", "pion")
util.Check(err)
if err != nil {
panic(err)
}
_, err = peerConnection.AddTrack(vp8Track)
util.Check(err)
if err != nil {
panic(err)
}
outboundRTPLock.Lock()
outboundRTP = append(outboundRTP, vp8Track.RawRTP)
@@ -148,17 +168,23 @@ func main() {
// Set the remote SessionDescription
err = peerConnection.SetRemoteDescription(recvOnlyOffer)
util.Check(err)
if err != nil {
panic(err)
}
// Create answer
answer, err := peerConnection.CreateAnswer(nil)
util.Check(err)
if err != nil {
panic(err)
}
// Sets the LocalDescription, and starts our UDP listeners
err = peerConnection.SetLocalDescription(answer)
util.Check(err)
if err != nil {
panic(err)
}
// Get the LocalDescription and take it to base64 so we can paste in browser
fmt.Println(util.Encode(answer))
fmt.Println(signal.Encode(answer))
}
}