Skip to content

Commit 91fcab7

Browse files
committed
Migrate gstreamer-send to go-gst
Drop our custom code
1 parent e358219 commit 91fcab7

File tree

7 files changed

+202
-267
lines changed

7 files changed

+202
-267
lines changed

gstreamer-send-offer/main.go

Lines changed: 68 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,21 @@ import (
1111
"flag"
1212
"fmt"
1313

14-
gst "github.com/pion/example-webrtc-applications/v3/internal/gstreamer-src"
14+
"github.com/go-gst/go-gst/gst"
15+
"github.com/go-gst/go-gst/gst/app"
1516
"github.com/pion/example-webrtc-applications/v3/internal/signal"
1617
"github.com/pion/webrtc/v3"
18+
"github.com/pion/webrtc/v3/pkg/media"
1719
)
1820

1921
func main() {
2022
audioSrc := flag.String("audio-src", "audiotestsrc", "GStreamer audio src")
2123
videoSrc := flag.String("video-src", "videotestsrc", "GStreamer video src")
2224
sdpChan := signal.HTTPSDPServer()
2325

26+
// Initialize GStreamer
27+
gst.Init(nil)
28+
2429
// Everything below is the Pion WebRTC API! Thanks for using it ❤️.
2530

2631
// Prepare the configuration
@@ -93,9 +98,69 @@ func main() {
9398
}
9499

95100
// Start pushing buffers on these tracks
96-
gst.CreatePipeline("opus", []*webrtc.TrackLocalStaticSample{opusTrack}, *audioSrc).Start()
97-
gst.CreatePipeline("vp8", []*webrtc.TrackLocalStaticSample{vp8Track}, *videoSrc).Start()
101+
pipelineForCodec("opus", []*webrtc.TrackLocalStaticSample{opusTrack}, *audioSrc)
102+
pipelineForCodec("vp8", []*webrtc.TrackLocalStaticSample{vp8Track}, *videoSrc)
98103

99104
// Block forever
100105
select {}
101106
}
107+
108+
// Create the appropriate GStreamer pipeline depending on what codec we are working with
109+
func pipelineForCodec(codecName string, tracks []*webrtc.TrackLocalStaticSample, pipelineSrc string) {
110+
pipelineStr := "appsink name=appsink"
111+
switch codecName {
112+
case "vp8":
113+
pipelineStr = pipelineSrc + " ! vp8enc error-resilient=partitions keyframe-max-dist=10 auto-alt-ref=true cpu-used=5 deadline=1 ! " + pipelineStr
114+
case "vp9":
115+
pipelineStr = pipelineSrc + " ! vp9enc ! " + pipelineStr
116+
case "h264":
117+
pipelineStr = pipelineSrc + " ! video/x-raw,format=I420 ! x264enc speed-preset=ultrafast tune=zerolatency key-int-max=20 ! video/x-h264,stream-format=byte-stream ! " + pipelineStr
118+
case "opus":
119+
pipelineStr = pipelineSrc + " ! opusenc ! " + pipelineStr
120+
case "pcmu":
121+
pipelineStr = pipelineSrc + " ! audio/x-raw, rate=8000 ! mulawenc ! " + pipelineStr
122+
case "pcma":
123+
pipelineStr = pipelineSrc + " ! audio/x-raw, rate=8000 ! alawenc ! " + pipelineStr
124+
default:
125+
panic("Unhandled codec " + codecName) //nolint
126+
}
127+
128+
pipeline, err := gst.NewPipelineFromString(pipelineStr)
129+
if err != nil {
130+
panic(err)
131+
}
132+
133+
if err = pipeline.SetState(gst.StatePlaying); err != nil {
134+
panic(err)
135+
}
136+
137+
appSink, err := pipeline.GetElementByName("appsink")
138+
if err != nil {
139+
panic(err)
140+
}
141+
142+
app.SinkFromElement(appSink).SetCallbacks(&app.SinkCallbacks{
143+
NewSampleFunc: func(sink *app.Sink) gst.FlowReturn {
144+
sample := sink.PullSample()
145+
if sample == nil {
146+
return gst.FlowEOS
147+
}
148+
149+
buffer := sample.GetBuffer()
150+
if buffer == nil {
151+
return gst.FlowError
152+
}
153+
154+
samples := buffer.Map(gst.MapRead).Bytes()
155+
defer buffer.Unmap()
156+
157+
for _, t := range tracks {
158+
if err := t.WriteSample(media.Sample{Data: samples, Duration: *buffer.Duration().AsDuration()}); err != nil {
159+
panic(err) //nolint
160+
}
161+
}
162+
163+
return gst.FlowOK
164+
},
165+
})
166+
}

gstreamer-send/main.go

Lines changed: 69 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,26 +11,25 @@ import (
1111
"flag"
1212
"fmt"
1313

14-
gst "github.com/pion/example-webrtc-applications/v3/internal/gstreamer-src"
14+
"github.com/go-gst/go-gst/gst"
15+
"github.com/go-gst/go-gst/gst/app"
1516
"github.com/pion/example-webrtc-applications/v3/internal/signal"
1617
"github.com/pion/webrtc/v3"
18+
"github.com/pion/webrtc/v3/pkg/media"
1719
)
1820

1921
func main() {
2022
audioSrc := flag.String("audio-src", "audiotestsrc", "GStreamer audio src")
2123
videoSrc := flag.String("video-src", "videotestsrc", "GStreamer video src")
2224
flag.Parse()
2325

26+
// Initialize GStreamer
27+
gst.Init(nil)
28+
2429
// Everything below is the Pion WebRTC API! Thanks for using it ❤️.
2530

2631
// Prepare the configuration
27-
config := webrtc.Configuration{
28-
ICEServers: []webrtc.ICEServer{
29-
{
30-
URLs: []string{"stun:stun.l.google.com:19302"},
31-
},
32-
},
33-
}
32+
config := webrtc.Configuration{}
3433

3534
// Create a new RTCPeerConnection
3635
peerConnection, err := webrtc.NewPeerConnection(config)
@@ -105,9 +104,69 @@ func main() {
105104
fmt.Println(signal.Encode(*peerConnection.LocalDescription()))
106105

107106
// Start pushing buffers on these tracks
108-
gst.CreatePipeline("opus", []*webrtc.TrackLocalStaticSample{audioTrack}, *audioSrc).Start()
109-
gst.CreatePipeline("vp8", []*webrtc.TrackLocalStaticSample{firstVideoTrack, secondVideoTrack}, *videoSrc).Start()
107+
pipelineForCodec("opus", []*webrtc.TrackLocalStaticSample{audioTrack}, *audioSrc)
108+
pipelineForCodec("vp8", []*webrtc.TrackLocalStaticSample{firstVideoTrack, secondVideoTrack}, *videoSrc)
110109

111110
// Block forever
112111
select {}
113112
}
113+
114+
// Create the appropriate GStreamer pipeline depending on what codec we are working with
115+
func pipelineForCodec(codecName string, tracks []*webrtc.TrackLocalStaticSample, pipelineSrc string) {
116+
pipelineStr := "appsink name=appsink"
117+
switch codecName {
118+
case "vp8":
119+
pipelineStr = pipelineSrc + " ! vp8enc error-resilient=partitions keyframe-max-dist=10 auto-alt-ref=true cpu-used=5 deadline=1 ! " + pipelineStr
120+
case "vp9":
121+
pipelineStr = pipelineSrc + " ! vp9enc ! " + pipelineStr
122+
case "h264":
123+
pipelineStr = pipelineSrc + " ! video/x-raw,format=I420 ! x264enc speed-preset=ultrafast tune=zerolatency key-int-max=20 ! video/x-h264,stream-format=byte-stream ! " + pipelineStr
124+
case "opus":
125+
pipelineStr = pipelineSrc + " ! opusenc ! " + pipelineStr
126+
case "pcmu":
127+
pipelineStr = pipelineSrc + " ! audio/x-raw, rate=8000 ! mulawenc ! " + pipelineStr
128+
case "pcma":
129+
pipelineStr = pipelineSrc + " ! audio/x-raw, rate=8000 ! alawenc ! " + pipelineStr
130+
default:
131+
panic("Unhandled codec " + codecName) //nolint
132+
}
133+
134+
pipeline, err := gst.NewPipelineFromString(pipelineStr)
135+
if err != nil {
136+
panic(err)
137+
}
138+
139+
if err = pipeline.SetState(gst.StatePlaying); err != nil {
140+
panic(err)
141+
}
142+
143+
appSink, err := pipeline.GetElementByName("appsink")
144+
if err != nil {
145+
panic(err)
146+
}
147+
148+
app.SinkFromElement(appSink).SetCallbacks(&app.SinkCallbacks{
149+
NewSampleFunc: func(sink *app.Sink) gst.FlowReturn {
150+
sample := sink.PullSample()
151+
if sample == nil {
152+
return gst.FlowEOS
153+
}
154+
155+
buffer := sample.GetBuffer()
156+
if buffer == nil {
157+
return gst.FlowError
158+
}
159+
160+
samples := buffer.Map(gst.MapRead).Bytes()
161+
defer buffer.Unmap()
162+
163+
for _, t := range tracks {
164+
if err := t.WriteSample(media.Sample{Data: samples, Duration: *buffer.Duration().AsDuration()}); err != nil {
165+
panic(err) //nolint
166+
}
167+
}
168+
169+
return gst.FlowOK
170+
},
171+
})
172+
}

internal/gstreamer-src/gst.c

Lines changed: 0 additions & 91 deletions
This file was deleted.

0 commit comments

Comments
 (0)