1- // +build darwin
2-
31package gstadapter
42
53import (
@@ -25,14 +23,18 @@ type GstAdapter struct {
2523const audioAppSrcTargetElementName = "audio_target"
2624const videoAppSrcTargetElementName = "video_target"
2725
26+ const MP3 = "mp3"
27+ const OGG = "ogg"
28+
2829//New creates a new MAC OSX compatible gstreamer pipeline that will play device video and audio
2930//in a nice little window :-D
3031func New () * GstAdapter {
3132 log .Info ("Starting Gstreamer.." )
3233 pl := gst .NewPipeline ("QT_Hack_Pipeline" )
3334
3435 videoAppSrc := setUpVideoPipeline (pl )
35- audioAppSrc := setUpAudioPipeline (pl )
36+ audioAppSrc := setUpAudioPipelineBase (pl )
37+ setupLivePlayAudio (pl )
3638
3739 pl .SetState (gst .STATE_PLAYING )
3840 runGlibMainLoop ()
@@ -43,6 +45,29 @@ func New() *GstAdapter {
4345 return & gsta
4446}
4547
48+ func NewWithAudioPipeline (outfile string , audiotype string ) (* GstAdapter , error ) {
49+ log .Info ("Starting Gstreamer.." )
50+ pl := gst .NewPipeline ("QT_Hack_Pipeline" )
51+
52+ audioAppSrc := setUpAudioPipelineBase (pl )
53+ switch audiotype {
54+ case MP3 :
55+ setupMp3 (pl , outfile )
56+ case OGG :
57+ setupVorbis (pl , outfile )
58+ default :
59+ log .Fatalf ("Unrecognized Audio type:%s" , audiotype )
60+ }
61+
62+ pl .SetState (gst .STATE_PLAYING )
63+ runGlibMainLoop ()
64+
65+ log .Info ("Gstreamer is running!" )
66+ gsta := GstAdapter {audioAppSrc : audioAppSrc , firstAudioSample : true }
67+
68+ return & gsta , nil
69+ }
70+
4671//NewWithCustomPipeline will parse the given pipelineString, connect the videoAppSrc to whatever element has the name "video_target" and the audioAppSrc to "audio_target"
4772//see also: https://gstreamer.freedesktop.org/documentation/application-development/appendix/programs.html?gi-language=c
4873func NewWithCustomPipeline (pipelineString string ) (* GstAdapter , error ) {
@@ -89,13 +114,17 @@ func NewWithCustomPipeline(pipelineString string) (*GstAdapter, error) {
89114//sending EOS will result in a broken mp4 file
90115func (gsta GstAdapter ) Stop () {
91116 log .Info ("Stopping Gstreamer.." )
92- success := gsta .audioAppSrc .SendEvent (gst .Eos ())
93- if ! success {
94- log .Warn ("Failed sending EOS signal for audio app source" )
117+ if gsta .audioAppSrc != nil {
118+ success := gsta .audioAppSrc .SendEvent (gst .Eos ())
119+ if ! success {
120+ log .Warn ("Failed sending EOS signal for audio app source" )
121+ }
95122 }
96- success = gsta .videoAppSrc .SendEvent (gst .Eos ())
97- if ! success {
98- log .Warn ("Failed sending EOS signal for video app source" )
123+ if gsta .videoAppSrc != nil {
124+ success := gsta .videoAppSrc .SendEvent (gst .Eos ())
125+ if ! success {
126+ log .Warn ("Failed sending EOS signal for video app source" )
127+ }
99128 }
100129
101130 if gsta .pipeline == nil {
@@ -126,8 +155,7 @@ func runGlibMainLoop() {
126155 glib .NewMainLoop (nil ).Run ()
127156 }()
128157}
129-
130- func setUpAudioPipeline (pl * gst.Pipeline ) * gst.AppSrc {
158+ func setUpAudioPipelineBase (pl * gst.Pipeline ) * gst.AppSrc {
131159 asrc := gst .NewAppSrc ("my-audio-src" )
132160 asrc .SetProperty ("is-live" , true )
133161
@@ -144,59 +172,43 @@ func setUpAudioPipeline(pl *gst.Pipeline) *gst.AppSrc {
144172 audioconvert := gst .ElementFactoryMake ("audioconvert" , "audioconvert_01" )
145173 checkElem (audioconvert , "audioconvert_01" )
146174
147- autoaudiosink := gst .ElementFactoryMake ("autoaudiosink" , "autoaudiosink_01" )
148- checkElem (autoaudiosink , "autoaudiosink_01" )
149- autoaudiosink .SetProperty ("sync" , false )
150-
151- pl .Add (asrc .AsElement (), queue1 , wavparse , audioconvert , queue2 , autoaudiosink )
175+ pl .Add (asrc .AsElement (), queue1 , wavparse , audioconvert , queue2 )
152176 asrc .Link (queue1 )
153177 queue1 .Link (wavparse )
154178 wavparse .Link (audioconvert )
155179
156180 audioconvert .Link (queue2 )
157- queue2 .Link (autoaudiosink )
158181
159182 return asrc
160183}
161-
162- func setUpVideoPipeline (pl * gst.Pipeline ) * gst.AppSrc {
163- asrc := gst .NewAppSrc ("my-video-src" )
164- asrc .SetProperty ("is-live" , true )
165-
166- queue1 := gst .ElementFactoryMake ("queue" , "queue_11" )
167- checkElem (queue1 , "queue_11" )
168-
169- h264parse := gst .ElementFactoryMake ("h264parse" , "h264parse_01" )
170- checkElem (h264parse , "h264parse" )
171-
172- avdecH264 := gst .ElementFactoryMake ("vtdec" , "vtdec_01" )
173- checkElem (avdecH264 , "vtdec_01" )
174-
175- queue2 := gst .ElementFactoryMake ("queue" , "queue_12" )
176- checkElem (queue2 , "queue_12" )
177-
178- videoconvert := gst .ElementFactoryMake ("videoconvert" , "videoconvert_01" )
179- checkElem (videoconvert , "videoconvert_01" )
180-
181- queue3 := gst .ElementFactoryMake ("queue" , "queue_13" )
182- checkElem (queue3 , "queue_13" )
183-
184- sink := gst .ElementFactoryMake ("autovideosink" , "autovideosink_01" )
185- // setting this to true, creates extremely choppy video
186- // I probably messed up something regarding the time stamps
187- sink .SetProperty ("sync" , false )
188- checkElem (sink , "autovideosink_01" )
189-
190- pl .Add (asrc .AsElement (), queue1 , h264parse , avdecH264 , queue2 , videoconvert , queue3 , sink )
191-
192- asrc .Link (queue1 )
193- queue1 .Link (h264parse )
194- h264parse .Link (avdecH264 )
195- avdecH264 .Link (queue2 )
196- queue2 .Link (videoconvert )
197- videoconvert .Link (queue3 )
198- queue3 .Link (sink )
199- return asrc
184+ func setupVorbis (pl * gst.Pipeline , filepath string ) {
185+ //vorbisenc ! oggmux ! filesink location=alsasrc.ogg
186+ vorbisEnc := gst .ElementFactoryMake ("vorbisenc" , "vorbisenc_01" )
187+ checkElem (vorbisEnc , "vorbisenc_01" )
188+ oggMux := gst .ElementFactoryMake ("oggmux" , "oggmux_01" )
189+ checkElem (oggMux , "oggmux_01" )
190+
191+ filesink := gst .ElementFactoryMake ("filesink" , "filesink_01" )
192+ filesink .SetProperty ("location" , filepath )
193+ checkElem (filesink , "filesink_01" )
194+
195+ pl .Add (vorbisEnc , oggMux , filesink )
196+
197+ pl .GetByName ("queue2" ).Link (vorbisEnc )
198+ vorbisEnc .Link (oggMux )
199+ oggMux .Link (filesink )
200+ }
201+ func setupMp3 (pl * gst.Pipeline , filepath string ) {
202+ // lamemp3enc ! filesink location=sine.mp3
203+ lameEnc := gst .ElementFactoryMake ("lamemp3enc" , "lamemp3enc_01" )
204+ checkElem (lameEnc , "lamemp3enc_01" )
205+
206+ filesink := gst .ElementFactoryMake ("filesink" , "filesink_01" )
207+ filesink .SetProperty ("location" , filepath )
208+ checkElem (filesink , "filesink_01" )
209+ pl .Add (lameEnc , filesink )
210+ pl .GetByName ("queue2" ).Link (lameEnc )
211+ lameEnc .Link (filesink )
200212}
201213
202214func checkElem (e * gst.Element , name string ) {
0 commit comments