繁体   English   中英

在gstreamer中串联视频文件(在python中)

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM