简体   繁体   English

是否有将 gstreamer 管道转换为 python 代码的指南?

[英]Is there a guide for converting a gstreamer pipeline to python code?

I am trying to implement a simple gstreamer pipeline that works okay through terminal command ( gst-launch-1.0 filesrc location=sample.264 ! h264parse ! decodebin ! videoconvert ! autovideosink ) using python.我正在尝试使用 python 通过终端命令( gst-launch-1.0 filesrc location=sample.264 ! h264parse ! decodebin ! videoconvert ! autovideosink )实现一个简单的gstreamer管道。 Here is my complete code:这是我的完整代码:

import sys
import platform
import configparser

import gi

gi.require_version('Gst', '1.0')

from gi.repository import GObject, Gst, GLib

def bus_call(bus, message, loop):
    t = message.type
    if t == Gst.MessageType.EOS:
        sys.stdout.write("End-of-stream\n")
        loop.quit()
    elif t==Gst.MessageType.WARNING:
        err, debug = message.parse_warning()
        sys.stderr.write("Warning: %s: %s\n" % (err, debug))
    elif t == Gst.MessageType.ERROR:
        err, debug = message.parse_error()
        sys.stderr.write("Error: %s: %s\n" % (err, debug))
        loop.quit()
    return True

def main(args):
    if len(args) != 2:
        sys.stderr.write("usage: %s <media file or uri>\n" % args[0])
        sys.exit(1)
        
    GObject.threads_init()
    Gst.init(None)
    
    print("Creating Pipeline \n ")
    pipeline = Gst.Pipeline()
    
    if not pipeline:
        sys.stderr.write(" Unable to create Pipeline \n")
        
    print("Creating Source \n ")
    source = Gst.ElementFactory.make("filesrc", "file-source")
    if not source:
        sys.stderr.write(" Unable to create Source \n")
    
    print("Creating H264Parser \n")
    h264parser = Gst.ElementFactory.make("h264parse", "h264-parser")
    if not h264parser:
        sys.stderr.write(" Unable to create h264 parser \n")
        
    print("Creating Decoder \n ")
    decoder = Gst.ElementFactory.make("decodebin", "decode")
    if not decoder:
        sys.stderr.write(" Unable to create Decode \n")
        
    print("Creating Video Converter \n ")
    converter = Gst.ElementFactory.make("videoconvert", "converter")
    if not source:
        sys.stderr.write(" Unable to create Video Converter \n")
        
    print("Creating Sink \n ")
    sink = Gst.ElementFactory.make("autovideosink", "video-sink")
    if not source:
        sys.stderr.write(" Unable to create Sink \n")
        
    print("Playing file %s " %args[1])
    source.set_property('location', args[1])
    
    print("Adding elements to Pipeline \n")
    pipeline.add(source)
    pipeline.add(h264parser)
    pipeline.add(decoder)
    pipeline.add(converter)
    pipeline.add(sink)
    
    print("Linking elements in the Pipeline \n")
    source.link(h264parser)
    h264parser.link(decoder)
    decoder.link(converter)
    converter.link(sink)
    
    loop = GLib.MainLoop()
    
    bus = pipeline.get_bus()
    bus.add_signal_watch()
    bus.connect ("message", bus_call, loop)
    
    print("Starting pipeline \n")
    
    pipeline.set_state(Gst.State.PLAYING)
    try:
        loop.run()
    except:
        pass
        
    pipeline.set_state(Gst.State.NULL)
    
if __name__ == '__main__':
    sys.exit(main(sys.argv))

When I run this script, the terminal shows an error after starting the pipeline:当我运行此脚本时,终端在启动管道后显示错误:

Error: gst-stream-error-quark: Internal data stream error. (1): gstbaseparse.c(3634): gst_base_parse_loop (): /GstPipeline:pipeline0/GstH264Parse:h264-parser:
streaming stopped, reason not-linked (-1)

Here is the complete terminal output:这是完整的终端输出:

sudo python3 pipe.py sample.264

Creating Pipeline 
 
Creating Source 
 
Creating H264Parser 

Creating Decoder 
 
Creating Video Converter 
 
Creating Sink 
 
Playing file sample.264 
Adding elements to Pipeline 

Linking elements in the Pipeline 

Starting pipeline 

Error: gst-stream-error-quark: Internal data stream error. (1): gstbaseparse.c(3634): gst_base_parse_loop (): /GstPipeline:pipeline0/GstH264Parse:h264-parser:
streaming stopped, reason not-linked (-1)

Is there a way to solve this?有没有办法解决这个问题?

You can make your life a lot easier when using convenience function like gst_parse_launch() .使用gst_parse_launch()等便利功能时,您可以让您的生活更轻松。 This will construct pipelines from the same syntax you give to gst-launch-1.0 .这将根据您提供给gst-launch-1.0的相同语法构建管道。

In python and your example something along this:在 python 和你的例子中,有一些东西:

pipeline = Gst.parse_launch("filesrc location=sample.264 ! h264parse ! decodebin ! videoconvert ! autovideosink")

You can set bus callbacks on that pipeline and set it to PLAYING etc like you did in your example.您可以在该管道上设置总线回调,并将其设置为 PLAYING 等,就像您在示例中所做的那样。

Some explanation on your original code: You use the decodebin element.对原始代码的一些解释:您使用了decodebin元素。 That one will only expose pads once the pipeline is running.一旦管道运行,那个只会暴露焊盘。 So you cannot link it to anything before that.所以你不能在此之前将它链接到任何东西。 That is something that has to be done manually by hooking into it's callbacks.这是必须通过挂钩到它的回调来手动完成的事情。

For further reading head on to the dynamic pipeline example:要进一步阅读动态管道示例:

https://gstreamer.freedesktop.org/documentation/tutorials/basic/dynamic-pipelines.html?gi-language=c https://gstreamer.freedesktop.org/documentation/tutorials/basic/dynamic-pipelines.html?gi-language=c

gst-launch-1.0 as well as gst_parse_launch() create this logic automatically for you internally. gst-launch-1.0以及gst_parse_launch()在内部自动为您创建此逻辑。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM