GStreamer Python decodebin,jpegenc元素没有链接

时间:2018-04-03 21:26:14

标签: python gstreamer avi mjpeg python-gstreamer

我开始使用Gstreamer使用gst-python绑定。我正在研究的一个例子是读取.mp4文件,在MJPEG流中对其进行编码并将其保存在.avi容器中。我为此建立的管道是:

gst-launch-1.0 filesrc location=./my_movie.mp4 ! decodebin ! jpegenc ! avimux ! filesink location=./encoded_movie.avi

哪个工作正常。我可以使用VLC媒体播放器播放encoded_movie.avi

我编写了一个Python脚本,尝试使用以下代码构建该管道:

import sys
# Gstreamer
import gi 
gi.require_version('Gst', '1.0')
from gi.repository import Gst, GObject, GLib

# initialize GStreamer
Gst.init(None)
# This does some things:
# 1. It initializes all internal structures
# 2. It checks what plugins are available.
# 3. It executes any command-line option intended for GStreamer

# Build pipeline
source = Gst.ElementFactory.make('filesrc', 'source')
decoder = Gst.ElementFactory.make('decodebin', 'decoder')
encoder = Gst.ElementFactory.make('jpegenc', 'encoder')
avi = Gst.ElementFactory.make('avimux', 'avimux')
sink = Gst.ElementFactory.make('filesink', 'sink')


# Create empty pipeline
pipeline = Gst.Pipeline.new('test-pipeline')

if (not pipeline or not source or not decoder or not sink or not encoder or 
  not avi):
  print('ERROR: could not init pipeline')
  sys.exit(1)

# build the pipeline
pipeline.add(source)
pipeline.add(decoder)
pipeline.add(encoder)
pipeline.add(avi)
pipeline.add(sink)

print('Added all sources')

if not source.link(decoder):
  print('ERROR: Could not link source to decoder')
  sys.exit(1)

if not decoder.link(encoder):
  print('ERROR: Could not link decoder to ' + encoder.get_property('name'))
  sys.exit(1)

if not encoder.link(avi):
  print('ERROR: Could not link ' + encoder.get_property('name') + ' with ' + 
    avi.get_property('name'))
  sys.exit(1)

if not avi.link(sink):
  print('ERROR: Could not link ' + avi.get_property('name') + ' with ' + 
    sink.get_property('name'))

print('linked all sources')
# modify source and sink properties
source.set_property('location', './my_movie.mp4')
print(source.get_property('location'))
sink.set_property('location', './encoded_movie.avi')
print(sink.get_property('location'))

# Start playing
try:
  # start playing
  ret = pipeline.set_state(Gst.State.PLAYING)
  if ret == Gst.StateChangeReturn.FAILURE:
    print("ERROR: Unable to set the pipeline to the playing state")
  else:
    print('Pipeline started')

  # wait for EOS or error
  bus = pipeline.get_bus()
  msg = bus.timed_pop_filtered(
    Gst.CLOCK_TIME_NONE,
    Gst.MessageType.ERROR | Gst.MessageType.EOS
  )
  # Error handling
  if msg:
    t = msg.type 
    if t == Gst.MessageType.ERROR:
      err, dbg = msg.parse_error()
      print('ERROR:', msg.src.get_name(), '\n', err.message)
      if dbg:
          print('Debugging info:', dbg)
    elif t == Gst.MessageType.EOS:
      print('End-Of-Stream reached')
    print('Clean up pipeline')
    pipeline.set_state(Gst.State.NULL)
except KeyboardInterrupt:
  # Free resources and exit
  pipeline.set_state(Gst.State.NULL)
  sys.exit()       
finally:
  pipeline.set_state(Gst.State.NULL)

我得到了一个我自己的错误,因为输出是:

Added all sources
ERROR: Could not link decoder to encoder

我想知道为什么元素不能使用绑定链接?由于管道确实可以在我自己的主机上运行。

gst-launch-1.0的管道使用GStreamer 1.0在macOS High Sierra版本10.13.4上运行。

Python脚本在运行Ubuntu v.17.10,GStreamer 1.0,Python3.6的Docker容器中运行

1 个答案:

答案 0 :(得分:0)

decodebin元素使用动态填充。您必须使用“添加了打击垫”的信号来选择打击垫。

示例

def decodebin_pad_added(self, element, pad):
    string = pad.query_caps(None).to_string()
    print('Found stream: %s' % string)
    if string.startswith('video/x-raw'):
        pad.link(encoder.get_static_pad('sink'))


decoder.connect("pad-added", decodebin_pad_added)