Skip to content

Commit 6aeb342

Browse files
committed
Move to new Track API
See v2.0.0 Release Notes[0] for all changes Resolves #405 [0] https://github.com/pions/webrtc/wiki/v2.0.0-Release-Notes#media-api
1 parent f5d11df commit 6aeb342

File tree

18 files changed

+711
-533
lines changed

18 files changed

+711
-533
lines changed

datachannel_test.go

+3-1
Original file line numberDiff line numberDiff line change
@@ -156,8 +156,10 @@ func TestDataChannel_MessagesAreOrdered(t *testing.T) {
156156
out := make(chan int)
157157
inner := func(msg DataChannelMessage) {
158158
// randomly sleep
159-
// NB: The big.Int/crypto.Rand is overkill but makes the linter happy
159+
// math/rand a weak RNG, but this does not need to be secure. Ignore with #nosec
160+
/* #nosec */
160161
randInt, err := rand.Int(rand.Reader, big.NewInt(int64(max)))
162+
/* #nosec */
161163
if err != nil {
162164
t.Fatalf("Failed to get random sleep duration: %s", err)
163165
}

examples/gstreamer-receive/main.go

+11-6
Original file line numberDiff line numberDiff line change
@@ -34,26 +34,31 @@ func gstreamerReceiveMain() {
3434

3535
// Set a handler for when a new remote track starts, this handler creates a gstreamer pipeline
3636
// for the given codec
37-
peerConnection.OnTrack(func(track *webrtc.Track) {
37+
peerConnection.OnTrack(func(track *webrtc.Track, receiver *webrtc.RTPReceiver) {
3838
// Send a PLI on an interval so that the publisher is pushing a keyframe every rtcpPLIInterval
3939
// This is a temporary fix until we implement incoming RTCP events, then we would push a PLI only when a viewer requests it
4040
go func() {
4141
ticker := time.NewTicker(time.Second * 3)
4242
for range ticker.C {
43-
err := peerConnection.SendRTCP(&rtcp.PictureLossIndication{MediaSSRC: track.SSRC})
43+
err := peerConnection.SendRTCP(&rtcp.PictureLossIndication{MediaSSRC: track.SSRC()})
4444
if err != nil {
4545
fmt.Println(err)
4646
}
4747
}
4848
}()
4949

50-
codec := track.Codec
51-
fmt.Printf("Track has started, of type %d: %s \n", track.PayloadType, codec.Name)
50+
codec := track.Codec()
51+
fmt.Printf("Track has started, of type %d: %s \n", track.PayloadType(), codec.Name)
5252
pipeline := gst.CreatePipeline(codec.Name)
5353
pipeline.Start()
54+
buf := make([]byte, 1400)
5455
for {
55-
p := <-track.Packets
56-
pipeline.Push(p.Raw)
56+
i, err := track.Read(buf)
57+
if err != nil {
58+
panic(err)
59+
}
60+
61+
pipeline.Push(buf[:i])
5762
}
5863
})
5964

examples/gstreamer-send-offer/main.go

+5-4
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package main
22

33
import (
44
"fmt"
5+
"math/rand"
56

67
"github.com/pions/webrtc"
78

@@ -34,7 +35,7 @@ func main() {
3435
})
3536

3637
// Create a audio track
37-
opusTrack, err := peerConnection.NewSampleTrack(webrtc.DefaultPayloadTypeOpus, "audio", "pion1")
38+
opusTrack, err := peerConnection.NewTrack(webrtc.DefaultPayloadTypeOpus, rand.Uint32(), "audio", "pion1")
3839
if err != nil {
3940
panic(err)
4041
}
@@ -44,7 +45,7 @@ func main() {
4445
}
4546

4647
// Create a video track
47-
vp8Track, err := peerConnection.NewSampleTrack(webrtc.DefaultPayloadTypeVP8, "video", "pion2")
48+
vp8Track, err := peerConnection.NewTrack(webrtc.DefaultPayloadTypeVP8, rand.Uint32(), "video", "pion2")
4849
if err != nil {
4950
panic(err)
5051
}
@@ -79,8 +80,8 @@ func main() {
7980
}
8081

8182
// Start pushing buffers on these tracks
82-
gst.CreatePipeline(webrtc.Opus, opusTrack.Samples, "audiotestsrc").Start()
83-
gst.CreatePipeline(webrtc.VP8, vp8Track.Samples, "videotestsrc").Start()
83+
gst.CreatePipeline(webrtc.Opus, opusTrack, "audiotestsrc").Start()
84+
gst.CreatePipeline(webrtc.VP8, vp8Track, "videotestsrc").Start()
8485

8586
// Block forever
8687
select {}

examples/gstreamer-send/main.go

+5-4
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package main
33
import (
44
"flag"
55
"fmt"
6+
"math/rand"
67

78
"github.com/pions/webrtc"
89

@@ -39,7 +40,7 @@ func main() {
3940
})
4041

4142
// Create a audio track
42-
opusTrack, err := peerConnection.NewSampleTrack(webrtc.DefaultPayloadTypeOpus, "audio", "pion1")
43+
opusTrack, err := peerConnection.NewTrack(webrtc.DefaultPayloadTypeOpus, rand.Uint32(), "audio", "pion1")
4344
if err != nil {
4445
panic(err)
4546
}
@@ -49,7 +50,7 @@ func main() {
4950
}
5051

5152
// Create a video track
52-
vp8Track, err := peerConnection.NewSampleTrack(webrtc.DefaultPayloadTypeVP8, "video", "pion2")
53+
vp8Track, err := peerConnection.NewTrack(webrtc.DefaultPayloadTypeVP8, rand.Uint32(), "video", "pion2")
5354
if err != nil {
5455
panic(err)
5556
}
@@ -84,8 +85,8 @@ func main() {
8485
fmt.Println(signal.Encode(answer))
8586

8687
// Start pushing buffers on these tracks
87-
gst.CreatePipeline(webrtc.Opus, opusTrack.Samples, *audioSrc).Start()
88-
gst.CreatePipeline(webrtc.VP8, vp8Track.Samples, *videoSrc).Start()
88+
gst.CreatePipeline(webrtc.Opus, opusTrack, *audioSrc).Start()
89+
gst.CreatePipeline(webrtc.VP8, vp8Track, *videoSrc).Start()
8990

9091
// Block forever
9192
select {}

examples/internal/gstreamer-src/gst.go

+5-6
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ func init() {
2323
// Pipeline is a wrapper for a GStreamer Pipeline
2424
type Pipeline struct {
2525
Pipeline *C.GstElement
26-
in chan<- media.Sample
26+
track *webrtc.Track
2727
// stop acts as a signal that this pipeline is stopped
2828
// any pending sends to Pipeline.in should be cancelled
2929
stop chan interface{}
@@ -35,7 +35,7 @@ var pipelines = make(map[int]*Pipeline)
3535
var pipelinesLock sync.Mutex
3636

3737
// CreatePipeline creates a GStreamer Pipeline
38-
func CreatePipeline(codecName string, in chan<- media.Sample, pipelineSrc string) *Pipeline {
38+
func CreatePipeline(codecName string, track *webrtc.Track, pipelineSrc string) *Pipeline {
3939
pipelineStr := "appsink name=appsink"
4040
switch codecName {
4141
case webrtc.VP8:
@@ -60,7 +60,7 @@ func CreatePipeline(codecName string, in chan<- media.Sample, pipelineSrc string
6060

6161
pipeline := &Pipeline{
6262
Pipeline: C.gstreamer_send_create_pipeline(pipelineStrUnsafe),
63-
in: in,
63+
track: track,
6464
id: len(pipelines),
6565
codecName: codecName,
6666
}
@@ -105,9 +105,8 @@ func goHandlePipelineBuffer(buffer unsafe.Pointer, bufferLen C.int, duration C.i
105105
}
106106
// We need to be able to cancel this function even f pipeline.in isn't being serviced
107107
// When pipeline.stop is closed the sending of data will be cancelled.
108-
select {
109-
case pipeline.in <- media.Sample{Data: C.GoBytes(buffer, bufferLen), Samples: samples}:
110-
case <-pipeline.stop:
108+
if err := pipeline.track.WriteSample(media.Sample{Data: C.GoBytes(buffer, bufferLen), Samples: samples}); err != nil {
109+
panic(err)
111110
}
112111
} else {
113112
fmt.Printf("discarding buffer, no pipeline with id %d", int(pipelineID))

examples/janus-gateway/streaming/main.go

+9-3
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,8 @@ func main() {
5252
fmt.Printf("Connection State has changed %s \n", connectionState.String())
5353
})
5454

55-
peerConnection.OnTrack(func(track *webrtc.Track) {
56-
if track.Codec.Name == webrtc.Opus {
55+
peerConnection.OnTrack(func(track *webrtc.Track, receiver *webrtc.RTPReceiver) {
56+
if track.Codec().Name == webrtc.Opus {
5757
return
5858
}
5959

@@ -62,8 +62,14 @@ func main() {
6262
if err != nil {
6363
panic(err)
6464
}
65+
6566
for {
66-
err = i.AddPacket(<-track.Packets)
67+
packet, err := track.ReadRTP()
68+
if err != nil {
69+
panic(err)
70+
}
71+
72+
err = i.AddPacket(packet)
6773
if err != nil {
6874
panic(err)
6975
}

examples/janus-gateway/video-room/main.go

+5-4
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package main
33
import (
44
"fmt"
55
"log"
6+
"math/rand"
67

78
janus "github.com/notedit/janus-go"
89
"github.com/pions/webrtc"
@@ -54,7 +55,7 @@ func main() {
5455
})
5556

5657
// Create a audio track
57-
opusTrack, err := peerConnection.NewSampleTrack(webrtc.DefaultPayloadTypeOpus, "audio", "pion1")
58+
opusTrack, err := peerConnection.NewTrack(webrtc.DefaultPayloadTypeOpus, rand.Uint32(), "audio", "pion1")
5859
if err != nil {
5960
panic(err)
6061
}
@@ -64,7 +65,7 @@ func main() {
6465
}
6566

6667
// Create a video track
67-
vp8Track, err := peerConnection.NewSampleTrack(webrtc.DefaultPayloadTypeVP8, "video", "pion2")
68+
vp8Track, err := peerConnection.NewTrack(webrtc.DefaultPayloadTypeVP8, rand.Uint32(), "video", "pion2")
6869
if err != nil {
6970
panic(err)
7071
}
@@ -134,8 +135,8 @@ func main() {
134135
}
135136

136137
// Start pushing buffers on these tracks
137-
gst.CreatePipeline(webrtc.Opus, opusTrack.Samples, "audiotestsrc").Start()
138-
gst.CreatePipeline(webrtc.VP8, vp8Track.Samples, "videotestsrc").Start()
138+
gst.CreatePipeline(webrtc.Opus, opusTrack, "audiotestsrc").Start()
139+
gst.CreatePipeline(webrtc.VP8, vp8Track, "videotestsrc").Start()
139140
}
140141

141142
select {}

examples/save-to-disk/main.go

+10-5
Original file line numberDiff line numberDiff line change
@@ -44,27 +44,32 @@ func main() {
4444
// Set a handler for when a new remote track starts, this handler saves buffers to disk as
4545
// an ivf file, since we could have multiple video tracks we provide a counter.
4646
// In your application this is where you would handle/process video
47-
peerConnection.OnTrack(func(track *webrtc.Track) {
47+
peerConnection.OnTrack(func(track *webrtc.Track, receiver *webrtc.RTPReceiver) {
4848
// Send a PLI on an interval so that the publisher is pushing a keyframe every rtcpPLIInterval
49-
// This is a temporary fix until we implement incoming RTCP events, then we would push a PLI only when a viewer requests it
5049
go func() {
5150
ticker := time.NewTicker(time.Second * 3)
5251
for range ticker.C {
53-
err := peerConnection.SendRTCP(&rtcp.PictureLossIndication{MediaSSRC: track.SSRC})
52+
err := peerConnection.SendRTCP(&rtcp.PictureLossIndication{MediaSSRC: track.SSRC()})
5453
if err != nil {
5554
fmt.Println(err)
5655
}
5756
}
5857
}()
5958

60-
if track.Codec.Name == webrtc.VP8 {
59+
if track.Codec().Name == webrtc.VP8 {
6160
fmt.Println("Got VP8 track, saving to disk as output.ivf")
6261
i, err := ivfwriter.New("output.ivf")
6362
if err != nil {
6463
panic(err)
6564
}
65+
6666
for {
67-
err = i.AddPacket(<-track.Packets)
67+
packet, err := track.ReadRTP()
68+
if err != nil {
69+
panic(err)
70+
}
71+
72+
err = i.AddPacket(packet)
6873
if err != nil {
6974
panic(err)
7075
}

examples/sfu/main.go

+19-35
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,9 @@ import (
77
"io/ioutil"
88
"net/http"
99
"strconv"
10-
"sync"
1110
"time"
1211

1312
"github.com/pions/rtcp"
14-
"github.com/pions/rtp"
1513
"github.com/pions/webrtc"
1614

1715
"github.com/pions/webrtc/examples/internal/signal"
@@ -84,41 +82,38 @@ func main() {
8482
panic(err)
8583
}
8684

87-
inboundSSRC := make(chan uint32)
88-
inboundPayloadType := make(chan uint8)
89-
90-
outboundRTP := []chan<- *rtp.Packet{}
91-
var outboundRTPLock sync.RWMutex
85+
localTrackChan := make(chan *webrtc.Track)
9286
// Set a handler for when a new remote track starts, this just distributes all our packets
9387
// to connected peers
94-
peerConnection.OnTrack(func(track *webrtc.Track) {
88+
peerConnection.OnTrack(func(remoteTrack *webrtc.Track, receiver *webrtc.RTPReceiver) {
9589
// Send a PLI on an interval so that the publisher is pushing a keyframe every rtcpPLIInterval
9690
// This can be less wasteful by processing incoming RTCP events, then we would emit a NACK/PLI when a viewer requests it
9791
go func() {
9892
ticker := time.NewTicker(rtcpPLIInterval)
9993
for range ticker.C {
100-
if err := peerConnection.SendRTCP(&rtcp.PictureLossIndication{MediaSSRC: track.SSRC}); err != nil {
94+
if err := peerConnection.SendRTCP(&rtcp.PictureLossIndication{MediaSSRC: remoteTrack.SSRC()}); err != nil {
10195
fmt.Println(err)
10296
}
10397
}
10498
}()
10599

106-
inboundSSRC <- track.SSRC
107-
inboundPayloadType <- track.PayloadType
100+
// Create a local track, all our SFU clients will be fed via this track
101+
localTrack, err := peerConnection.NewTrack(remoteTrack.PayloadType(), remoteTrack.SSRC(), "video", "pion")
102+
if err != nil {
103+
panic(err)
104+
}
105+
localTrackChan <- localTrack
108106

107+
rtpBuf := make([]byte, 1400)
109108
for {
110-
rtpPacket := <-track.Packets
111-
112-
outboundRTPLock.RLock()
113-
for _, outChan := range outboundRTP {
114-
outPacket := rtpPacket
115-
outPacket.Payload = append([]byte{}, outPacket.Payload...)
116-
select {
117-
case outChan <- outPacket:
118-
default:
119-
}
109+
i, err := remoteTrack.Read(rtpBuf)
110+
if err != nil {
111+
panic(err)
112+
}
113+
114+
if _, err = localTrack.Write(rtpBuf[:i]); err != nil {
115+
panic(err)
120116
}
121-
outboundRTPLock.RUnlock()
122117
}
123118
})
124119

@@ -143,8 +138,7 @@ func main() {
143138
// Get the LocalDescription and take it to base64 so we can paste in browser
144139
fmt.Println(signal.Encode(answer))
145140

146-
outboundSSRC := <-inboundSSRC
147-
outboundPayloadType := <-inboundPayloadType
141+
localTrack := <-localTrackChan
148142
for {
149143
fmt.Println("")
150144
fmt.Println("Curl an base64 SDP to start sendonly peer connection")
@@ -158,21 +152,11 @@ func main() {
158152
panic(err)
159153
}
160154

161-
// Create a single VP8 Track to send videa
162-
vp8Track, err := peerConnection.NewRawRTPTrack(outboundPayloadType, outboundSSRC, "video", "pion")
163-
if err != nil {
164-
panic(err)
165-
}
166-
167-
_, err = peerConnection.AddTrack(vp8Track)
155+
_, err = peerConnection.AddTrack(localTrack)
168156
if err != nil {
169157
panic(err)
170158
}
171159

172-
outboundRTPLock.Lock()
173-
outboundRTP = append(outboundRTP, vp8Track.RawRTP)
174-
outboundRTPLock.Unlock()
175-
176160
// Set the remote SessionDescription
177161
err = peerConnection.SetRemoteDescription(recvOnlyOffer)
178162
if err != nil {

0 commit comments

Comments
 (0)