Gstreamer 在 EOS 之前动态更改源

Gstreamer dynamically change source before EOS

我正在尝试使用 GStreamer 1.8.2 和 Python 3.5 创建动态管道。目标是能够播放一些视频并在 EOS 更改它,以类似于使用 about-to-finish of playbin 的方式实现无缝播放。

我的想法是filesrc -> decodebin -> queue -> videosink,然后在decodebin video src上放一个探针,等待EOS事件,unlink filesrc和decodebin,新建一个filesrc和一个新的decodebin ad link 在将它们设置为 PLAYING 状态后将它们发送到视频接收器。我不知道这是否是 best/correct 方法,但据我所知它应该有效。

我的第一次尝试是 this。第一个循环的播放效果很好,然后视频开始播放得太快。我认为时间戳 and/or 管道时钟存在一些问题,但我无法找到解决方案或更好地诊断问题。

编辑:在 vaapisink 中将 max-lateness 设置为 -1,播放速度仍然更快,但速度要慢得多。所以这是一个时间问题。

那么我能告诉你什么 - 使用 concat 或 videomixer/audiomixer(我更喜欢 concat 方式)..你不需要任何自定义解决方案:)

Concat 完全按照您的意愿进行操作,它根据当前源的 EOS 切换到另一个源。Here 是一个很好的例子。

使用多个流(音频、视频、字幕..)有点棘手,然后您需要合并流同步器或类似 here ..

还要检查这个 已经有一个关于 concat 的例子..但也请阅读评论。

更新关于手动方式:

使用 videomixer 和 audiomixer 有点棘手。

让我们考虑一下视频部分..

您将为要播放的流创建 bin(第一个)- 假设您在那里有 uridecodebin,它将预卷整个内容并创建 pads.. 当您发现新 pad 是 video/x-raw 你将在那里添加 pad 探针并插入 videomixer。

然后一段时间后(如果可能的话)您将使用另一个 uridecodebin 创建另一个 bin(所以这是您假设的播放列表中的第二个 "track")并再次进行预卷。当你拿到打击垫时,你不会将它们连接到 videomixer 而是阻止整个事情(我认为 PAUSED 就足够了)

当第一个进入 EOS 时,您将启用第二个,在第一个中,您将刷新视频的其余部分。

当然你也会对音频做同样的事情..

现在是棘手的部分 - 您必须将视频与音频对齐(音频的大小更精确,您比较时间戳直到音频与视频匹配,然后丢弃其余的音频左右)- 这是需要的为了不失去同步。

这种方法很难做..我做过一次,音视频同步遇到了无数个问题