在gstreamer中连接视频文件(在python中)

2024-09-29 20:32:42 发布

您现在位置: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)

这将显示最后一个线段的持续时间,并尝试将下一个线段的偏移量设置为上一个线段的终点。这确实可以进行代码转换,但它总是返回到输出文件的开头并覆盖以前的内容。很明显,这不是我想要的输出!在

我错过了什么吗?我曾尝试将此作为pad探测,但它不允许我从它自己的线程停止和重新启动管道,并悲惨地崩溃(告诉我在消息处理程序中这样做,这就是我现在拥有的)。在


Tags: 文件selfsrc消息视频pipelinetimelogger
1条回答
网友
1楼 · 发布于 2024-09-29 20:32:42

filesink总是覆盖现有文件。这里您真正想要的是将新的段附加到现有的MP4文件中(而且您也不希望只在现有MP4文件的末尾附加另一个MP4文件)。在

你要做的是你必须通过一个pad探针捕捉srcpad上的EOS事件(不是消息)。然后从pad probe回调中取消srcpad和muxer的sinkpad的链接。然后,您将动态链接新的输入并将其链接到muxer,同时像您已经做的那样设置pad offset。永远不要改变管道的状态,在最后一段,你会让EOS事件通过并等待EOS消息(不是事件!)张贴在公共汽车上。然后关闭管道。在

现在这一切的棘手之处在于,你可能还想清理旧的部分。不能从pad probe回调中执行此操作,因为EOS是从流式线程发送的。您需要做的是(在与pad probe回调断开链接之后!)您将从另一个线程的管道中删除与旧段相关的元素,将它们的状态设置为GST_state_NULL,然后取消引用它们。在

相关问题 更多 >

    热门问题