GStreamer Python decodebin,jpegenc 元素未链接
GStreamer Python decodebin, jpegenc elements not linking
我开始使用 gst-python 绑定的 GStreamer。我正在处理的一个示例是读取 .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 脚本在 Docker 容器中 运行 运行 Ubuntu v. 17.10,GStreamer 1.0,Python3.6
decodebin 元素使用动态垫。您必须使用 'pad-added' 信号 select 打击垫。
示例
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)
我开始使用 gst-python 绑定的 GStreamer。我正在处理的一个示例是读取 .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 脚本在 Docker 容器中 运行 运行 Ubuntu v. 17.10,GStreamer 1.0,Python3.6
decodebin 元素使用动态垫。您必须使用 'pad-added' 信号 select 打击垫。
示例
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)