使用Gstreamer的元件播放MKV,MP4等格式视频(python)
--完成成果及步骤总结
1.Gstreamer播放视频的框架及使用时涉及的相关元件
1)播放元件框架示意图(图为引用)
2)衬垫的连接函数
def cb_demuxer_newpad(src, pad, dst, dst2): #分出视频流和音频流并连接音、视频队列 #注意各个分流器的音、视频属性是不同的 #可以使用gst-inspect-1.0 [分流器]查看分流器属性 if pad.get_property("template").name_template == "video_%u": vdec_pad = dst.get_static_pad("sink") pad.link(vdec_pad) elif pad.get_property("template").name_template == "audio_%u": adec_pad = dst2.get_static_pad("sink") pad.link(adec_pad) |
3)相关元件
#数据流管道 pipe = Gst.Pipeline.new("test")
#播放视频源元件,下面会设置视频源的地址 src = Gst.ElementFactory.make("filesrc", "src")
#MKV分流器为matorskademux demuxer = Gst.ElementFactory.make("matroskademux", "demux") #视频队列元件 queuev = Gst.ElementFactory.make("queue", "queue")#视频队列 decodebin = Gst.ElementFactory.make("avdec_h264", "decode")#视频解码器 conv = Gst.ElementFactory.make("videoconvert", "conv")#视频转换器 sink = Gst.ElementFactory.make("xvimagesink", "sink")#显卡播放视频
#音频队列 queuea = Gst.ElementFactory.make("queue", "queuea")#音频队列 decodebina = Gst.ElementFactory.make("faad", "decodea")#音频解码 conva = Gst.ElementFactory.make("audioconvert", "conva")#音频转换器 sinka = Gst.ElementFactory.make("autoaudiosink", "sinka")#声卡播放
#设置src路径,此时源文件和代码在同一路径下 src.set_property("location", "a.mkv")
#连接队列的pad demuxer.connect("pad-added", cb_demuxer_newpad, queuev, queuea) |
4)元件添加至队列
pipe.add(src) pipe.add(demuxer)
pipe.add(queuev) pipe.add(decodebin) pipe.add(conv) pipe.add(sink)
pipe.add(queuea) pipe.add(decodebina) pipe.add(conva) pipe.add(sinka) |
5)元件连接
src.link(demuxer)
queuev.link(decodebin) decodebin.link(conv) conv.link(sink)
queuea.link(decodebina) decodebina.link(conva) conva.link(sinka) |
6)设置管道状态
pipe.set_state(Gst.State.PLAYING) |
2.步骤总结:
(1)查看将要播放视屏的属性,找到容器、视频和音频相应的编码格式
我们找到了
容器:matroska
视频编解码格式为:H.264;
音频编解码格式为:AAC.
(2)接下来使用gst-inspect-1.0 | grep [编码格式]找到要使用的元件
同样使用gst-inspect-1.0 | grep [容器]找到matroskademux.
(3)在代码中修改视、音频解码元件
#视频解码元件 decodebin = Gst.ElementFactory.make("avdec_h264", "decode") |
#音频解码元件 decodebina = Gst.ElementFactory.make("faad", "decodea") |
3.播放MKV视频完整代码(python)
import gi gi.require_version('Gst', '1.0') from gi.repository import Gst, GObject, GLib
Gst.init(None) def cb_demuxer_newpad(src, pad, dst, dst2): if pad.get_property("template").name_template == "video_%u": vdec_pad = dst.get_static_pad("sink") pad.link(vdec_pad) elif pad.get_property("template").name_template == "audio_%u": adec_pad = dst2.get_static_pad("sink") pad.link(adec_pad)
pipe = Gst.Pipeline.new("test") src = Gst.ElementFactory.make("filesrc", "src") demuxer = Gst.ElementFactory.make("matroskademux", "demux")
decodebin = Gst.ElementFactory.make("avdec_h264", "decode") queuev = Gst.ElementFactory.make("queue", "queue") conv = Gst.ElementFactory.make("videoconvert", "conv") sink = Gst.ElementFactory.make("xvimagesink", "sink")
decodebina = Gst.ElementFactory.make("faad", "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") demuxer.connect("pad-added", cb_demuxer_newpad, queuev,queuea)
pipe.add(src) pipe.add(demuxer) pipe.add(queuev) pipe.add(decodebin) pipe.add(conv) pipe.add(sink)
pipe.add(queuea) pipe.add(decodebina) pipe.add(conva) pipe.add(sinka)
src.link(demuxer) queuev.link(decodebin) decodebin.link(conv) conv.link(sink)
queuea.link(decodebina) decodebina.link(conva) conva.link(sinka)
pipe.set_state(Gst.State.PLAYING)
mainloop = GLib.MainLoop() mainloop.run() |