[英]Concatenating video files in gstreamer (in python)
我正在尝试获取一系列视频片段文件(.flv格式,所有音频/视频编码都相同),并将它们连接到一个新文件(.mp4格式)。 我的编码管道适用于普通的单段文件,但是一旦添加了第二段,我就可以毫不费力地使它正常工作。
在当前的实现中,我有一个用于EOS消息的消息处理程序,如下所示:
def on_eos(self, bus, msg):
remain = len(self.metadata['localSegments'])
logger.warning("Hit EOS Probe: %d segments left" % remain)
if remain == 0:
self.abort = True
self.mainloop.quit()
return
duration = self.pipeline.query_duration(Gst.Format(Gst.Format.TIME))[1]
self.offset += duration
logger.info("Duration: %s, new offset: %s" % (Gst.TIME_ARGS(duration),
Gst.TIME_ARGS(self.offset)))
self.pipeline.set_state(Gst.State.READY)
self.localInFile = self.metadata['localSegments'].pop(0)
logger.info("Starting new file: %s" % self.localInFile)
self.elem_src.set_property('location', self.localInFile)
self.elem_src_src.set_offset(self.offset)
self.pipeline.set_state(Gst.State.PLAYING)
这显示了最后一个片段的持续时间,并尝试将下一个片段的偏移量设置为上一个片段的结尾。 确实可以对代码进行转码,但是它始终会返回到输出文件的开头并覆盖先前的内容。 显然,这没有给出我想要的输出!
我在这里错过了什么吗? 我已经尝试将其用作填充探针,但是它不会让我停止并从其自己的线程重新启动管道,并且崩溃极了(告诉我在消息处理程序中进行此操作,这就是我现在所拥有的) 。
filesink始终会覆盖现有文件。 您真正想要的是将新段附加到现有的MP4文件中(而且您也不想仅将另一个MP4文件附加到现有文件的末尾)。
为此,您将必须通过填充探针在多路复用器前面的srcpad上捕获EOS 事件 (不是消息)。 然后,从pad探针回调中,取消该srcpad和复用器的接收板的链接。 然后,您将动态链接一个新的输入并将其链接到多路复用器,同时像已经设置的那样设置打击垫的偏移量。 永远不要更改管道的状态,在最后一段中,您将让EOS事件通过并等待EOS消息(不是事件!)在总线上发布。 只有这样才能关闭管道。
现在,所有这些棘手的部分是,您可能还希望清理旧的段。 由于EOS是从流线程发送的,因此您无法从pad探针回调中执行此操作。 您需要做的是(从pad probe回调取消链接之后!)您将从另一个线程的管道中删除与旧段相关的元素,将它们的状态设置为GST_STATE_NULL,然后取消引用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.