1
- // +build darwin
2
-
3
1
package gstadapter
4
2
5
3
import (
@@ -25,14 +23,18 @@ type GstAdapter struct {
25
23
const audioAppSrcTargetElementName = "audio_target"
26
24
const videoAppSrcTargetElementName = "video_target"
27
25
26
+ const MP3 = "mp3"
27
+ const OGG = "ogg"
28
+
28
29
//New creates a new MAC OSX compatible gstreamer pipeline that will play device video and audio
29
30
//in a nice little window :-D
30
31
func New () * GstAdapter {
31
32
log .Info ("Starting Gstreamer.." )
32
33
pl := gst .NewPipeline ("QT_Hack_Pipeline" )
33
34
34
35
videoAppSrc := setUpVideoPipeline (pl )
35
- audioAppSrc := setUpAudioPipeline (pl )
36
+ audioAppSrc := setUpAudioPipelineBase (pl )
37
+ setupLivePlayAudio (pl )
36
38
37
39
pl .SetState (gst .STATE_PLAYING )
38
40
runGlibMainLoop ()
@@ -43,6 +45,29 @@ func New() *GstAdapter {
43
45
return & gsta
44
46
}
45
47
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
+
46
71
//NewWithCustomPipeline will parse the given pipelineString, connect the videoAppSrc to whatever element has the name "video_target" and the audioAppSrc to "audio_target"
47
72
//see also: https://gstreamer.freedesktop.org/documentation/application-development/appendix/programs.html?gi-language=c
48
73
func NewWithCustomPipeline (pipelineString string ) (* GstAdapter , error ) {
@@ -89,13 +114,17 @@ func NewWithCustomPipeline(pipelineString string) (*GstAdapter, error) {
89
114
//sending EOS will result in a broken mp4 file
90
115
func (gsta GstAdapter ) Stop () {
91
116
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
+ }
95
122
}
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
+ }
99
128
}
100
129
101
130
if gsta .pipeline == nil {
@@ -126,8 +155,7 @@ func runGlibMainLoop() {
126
155
glib .NewMainLoop (nil ).Run ()
127
156
}()
128
157
}
129
-
130
- func setUpAudioPipeline (pl * gst.Pipeline ) * gst.AppSrc {
158
+ func setUpAudioPipelineBase (pl * gst.Pipeline ) * gst.AppSrc {
131
159
asrc := gst .NewAppSrc ("my-audio-src" )
132
160
asrc .SetProperty ("is-live" , true )
133
161
@@ -144,59 +172,43 @@ func setUpAudioPipeline(pl *gst.Pipeline) *gst.AppSrc {
144
172
audioconvert := gst .ElementFactoryMake ("audioconvert" , "audioconvert_01" )
145
173
checkElem (audioconvert , "audioconvert_01" )
146
174
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 )
152
176
asrc .Link (queue1 )
153
177
queue1 .Link (wavparse )
154
178
wavparse .Link (audioconvert )
155
179
156
180
audioconvert .Link (queue2 )
157
- queue2 .Link (autoaudiosink )
158
181
159
182
return asrc
160
183
}
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 )
200
212
}
201
213
202
214
func checkElem (e * gst.Element , name string ) {
0 commit comments