如何使用Python和Gstreamer创建MPEG2传输流管道

时间:2017-04-12 01:06:27

标签: streaming gstreamer mpeg2-ts python-gstreamer gstreamer-1.0

在开发流式音频应用程序时,我使用gst-launch-1.0命令行工具生成用于测试的MPEG传输流。这按预期工作(我能够从一个简单的http服务器提供流,并使用VLC媒体播放器听到它)。然后我尝试在Python gstreamer代码中复制该流的编码部分。连接到服务器的Python版本确定,但没有听到任何音频。我试图理解为什么命令行实现有效,但Python没有。我正在使用Mac OS 10.11和Python 2.7。

有效的命令行如下:

gst-launch-1.0 audiotestsrc freq=1000 ! avenc_aac ! aacparse ! mpegtsmux ! tcpclientsink host=127.0.0.1 port=9999

创建gstreamer管道的Python代码如下所示。它实例化时没有产生任何错误,并且它成功连接到http服务器,但是没有声音可以通过VLC听到。我通过使用单独的gstreamer管道直接播放音频,验证了Python代码中的AppSrc是否正常工作。这很好。

def create_mpeg2_pipeline():
     play = Gst.Pipeline()
     src = GstApp.AppSrc(format=Gst.Format.TIME, emit_signals=True)
     src.connect('need-data', need_data, samples())  # need_data and samples defined elsewhere
     play.add(src)

     capsFilterOne = Gst.ElementFactory.make('capsfilter', 'capsFilterOne')
     capsFilterOne.props.caps = Gst.Caps('audio/x-raw, format=(string)S16LE, rate=(int)44100, channels=(int)2')
     play.add(capsFilterOne)
     src.link(capsFilterOne)

     audioConvert = Gst.ElementFactory.make('audioconvert', 'audioConvert')
     play.add(audioConvert)
     capsFilterOne.link(audioConvert)

     capsFilterTwo = Gst.ElementFactory.make('capsfilter', 'capsFilterTwo')
     capsFilterTwo.props.caps = Gst.Caps('audio/x-raw, format=(string)F32LE, rate=(int)44100, channels=(int)2')
     play.add(capsFilterTwo)
     audioConvert.link(capsFilterTwo)

     aacEncoder = Gst.ElementFactory.make('avenc_aac', 'aacEncoder')
     play.add(aacEncoder)
     capsFilterTwo.link(aacEncoder)

     aacParser = Gst.ElementFactory.make('aacparse', 'aacParser')
     play.add(aacParser)
     aacEncoder.link(aacParser)

     mpegTransportStreamMuxer = Gst.ElementFactory.make('mpegtsmux', 'mpegTransportStreamMuxer')
     play.add(mpegTransportStreamMuxer)
     aacParser.link(mpegTransportStreamMuxer)

     tcpClientSink = Gst.ElementFactory.make('tcpclientsink', 'tcpClientSink')
     tcpClientSink.set_property('host', '127.0.0.1')
     tcpClientSink.set_property('port', 9999)
     play.add(tcpClientSink)
     mpegTransportStreamMuxer.link(tcpClientSink)

我的问题是,我在Python中实现的gstreamer管道与命令行管道有何不同?更一般地说,你如何调试这种事情? gstreamer是否有任何'详细的'模式?

感谢。

1 个答案:

答案 0 :(得分:0)

一次一个问题:

1)与gst-launch-1.0有什么不同? 如果没有看到完整的代码,很难说,但我会尝试猜测: gst-launch-1.0做正确的pad连接。如果您拥有muxer,则可以在没有任何接收垫的情况下直接链接它。您需要在链接之前请求创建一个。看一下动态垫:https://gstreamer.freedesktop.org/documentation/application-development/basics/pads.html

此外,gst-launch-1.0有错误处理,因此它检查每个操作是否成功,否则报告错误。我建议您添加GstBus消息处理程序,以便至少收到错误消息的通知。此外,您应该检查您在GStreamer中调用的函数的返回值,这样您就可以在程序中捕获此链接错误。

2)Gstreamer调试? 主要通过设置GST_DEBUG变量来完成:https://gstreamer.freedesktop.org/documentation/tutorials/basic/debugging-tools.html#the-debug-log

使用GST_DEBUG=6 ./yourapplication运行您的应用程序,您应该会看到大量的日志记录。