使用Gstreamer播放未知格式视频(python)
1.播放含Audio的未知格式视频
使用Gstreamer中的decodebin来实现。实现图解:
实现代码如下:
import gi
gi.require_version('Gst', '1.0')
from gi.repository import Gst, GObject, GLib
Gst.init(None)
#decodebin产生新pad的回调函数
def cb_decodebin_newpad(src, pad, dst,dst2):
caps = Gst.Pad.get_current_caps(pad)
structure_name = caps.to_string()
if structure_name.startswith("video"):
videorate_pad = dst.get_static_pad("sink")
pad.link(videorate_pad)
elif structure_name.startswith("audio"):
volume_pad = dst2.get_static_pad("sink")
pad.link(volume_pad)
pipe = Gst.Pipeline.new("test")
src = Gst.ElementFactory.make("filesrc", "src")
queuev = Gst.ElementFactory.make("queue", "queue")
conv = Gst.ElementFactory.make("videoconvert", "conv")
sink = Gst.ElementFactory.make("xvimagesink", "sink")
decodebina = Gst.ElementFactory.make("decodebin", "decodea")
queuea = Gst.ElementFactory.make("queue", "queuea")
conva = Gst.ElementFactory.make("audioconvert", "conva")
sinka = Gst.ElementFactory.make("autoaudiosink", "sinka")
src.set_property("location", "a.mkv")
decodebina.connect("pad-added", cb_decodebin_newpad, queuev,queuea)
pipe.add(src)
pipe.add(queuev)
pipe.add(conv)
pipe.add(sink)
pipe.add(queuea)
pipe.add(decodebina)
pipe.add(conva)
pipe.add(sinka)
src.link(decodebina)
queuev.link(conv)
conv.link(sink)
queuea.link(conva)
conva.link(sinka)
pipe.set_state(Gst.State.PLAYING)
mainloop = GLib.MainLoop()
mainloop.run()
2.播放未知是否含有Audio的视频
使用Gstreamer中的衬垫探测机制和阻塞来完成。
目前程序还存在一个问题:视频开始播放后的短暂的时间内可能会出现没有声音的现象。正在尝试解决。
图解:
实现代码如下:
import gi
gi.require_version('Gst', '1.0')
from gi.repository import Gst, GObject, GLib
Gst.init(None)
a = 0
def cb_add_elements(src,pad):
global a
if a == 0:
a = 1
pipe.add(queuea)
pipe.add(conva)
pipe.add(sinka)
queuea.link(conva)
conva.link(sinka)
return Gst.PadProbeReturn.PASS
else:
return Gst.PadProbeReturn.DROP
def cb_decodebin_newpad(src, pad):
caps = Gst.Pad.get_current_caps(pad)
structure_name = caps.to_string()
if structure_name.startswith("video"):
videorate_pad = queuev.get_static_pad("sink")
pad.link(videorate_pad)
elif structure_name.startswith("audio"):
Gst.Pad.add_probe(pad, Gst.PadProbeType.IDLE, cb_add_elements)
volume_pad = queuea.get_static_pad("sink")
pad.link(volume_pad)
pipe = Gst.Pipeline.new("test")
src = Gst.ElementFactory.make("filesrc", "src")
queuev = Gst.ElementFactory.make("queue", "queue")
conv = Gst.ElementFactory.make("videoconvert", "conv")
sink = Gst.ElementFactory.make("xvimagesink", "sink")
decodebin = Gst.ElementFactory.make("decodebin", "decodea")
queuea = Gst.ElementFactory.make("queue", "queuea")
conva = Gst.ElementFactory.make("audioconvert", "conva")
sinka = Gst.ElementFactory.make("autoaudiosink", "sinka")
src.set_property("location", "a.mkv")
decodebin.connect("pad-added", cb_decodebin_newpad)
pipe.add(src)
pipe.add(queuev)
pipe.add(conv)
pipe.add(sink)
pipe.add(decodebin)
src.link(decodebin)
queuev.link(conv)
conv.link(sink)
pipe.set_state(Gst.State.PLAYING)
mainloop = GLib.MainLoop()
mainloop.run()
3.相关学习资料
Gsreamer动态连接资料:gstreamer动态连接
Gstreamer语句C语言与Python对照:语句对照