python - 如何使用 gstreamer 预缓冲传入的网络流?

标签 python gstreamer

我正在使用 gstreamer 通过网络传输音频。我的目标看似简单:将传入流预缓冲到某个时间/字节阈值,然后开始播放。 我可能忽略了 gstreamer 的一个非常简单的功能,但到目前为止,我还没有找到一种方法来做到这一点。

我的(简化的)管道看起来像这样:udpsrc -> alsasink。到目前为止,我实现目标的所有尝试都是在两者之间使用队列元素:

  1. 在两者之间添加一个队列元素。
  2. 使用 min-threshold-time 属性。这确实有效,但问题是,它使所有传入数据在队列中花费指定的最短时间,而不仅仅是开始,这不是我想要的。
  3. 为了解决前面的问题,我尝试让队列在数据第一次进入音频接收器时通知我的代码,认为这是取消我之前设置的 min-time 属性的时间,因此,实现“预缓冲”行为。

这是我尝试过的代码的粗略等价物:

def remove_thresh(pad, info, queue):
    pad.remove_data_probe(probe_id)
    queue.set_property("min-threshold-time", 0)

queue.set_property("min-threshold-time", delay)
queue.set_property("max-size-time", delay * 2)
probe_id = audiosink.get_pad("sink").add_data_probe(remove_thresh, queue)

这行不通有两个原因:

  1. 我的回调比我提供的 delay 变量更早被调用。
  2. 调用后,存储在队列中的所有数据都将丢失。播放开始时就好像队列根本不存在一样。

我认为我对这个东西的工作原理存在根本性的误解。有谁知道我做错了什么,或者可以提供一种(可能)更好的方法来做到这一点? 我在这里使用 python,但欢迎使用任何语言的任何解决方案。

谢谢。

最佳答案

缓冲已经在 GStreamer 中实现。某些元素(如队列)能够构建此缓冲区并发布有关缓冲区级别(队列状态)的总线消息。

然后,如果缓冲区级别不够高(通常,只要缓冲区级别低于 100%),想要获得更多网络弹性的应用程序应该监听这些消息并暂停播放。

因此,您所要做的就是在队列缓冲时将管道设置为PAUSED 状态。在您的情况下,您只想缓冲一次,因此为此使用任何逻辑(可能设置标志变量以仅在第一次暂停管道)。

  1. 将队列的“max-size-bytes”属性设置为您想要的值。
  2. 要么听取“溢出”信号以在缓冲区变满时通知您,要么使用 gst_message_parse_buffering () 查找缓冲级别。
  3. 一旦您的缓冲区已满,将管道设置为PLAYING 状态,然后忽略所有进一步的缓冲消息。

最后,完整的流式例子,可以引用这个教程:https://gstreamer.freedesktop.org/documentation/tutorials/basic/streaming.html 代码在 C 中,但演练应该可以帮助您。

关于python - 如何使用 gstreamer 预缓冲传入的网络流?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16135324/

相关文章:

c++ - 如何释放appsrc?

python - 如何使用python svn模块从SVN远程存储库中删除文件

python - 是否有一种最佳方法可以迭代数据帧的每个单元格而无需迭代?

python - Django "App with label XYZ could not be found"

python - 是否可以将 GCM 与 python GAE 后端一起使用?

gstreamer - 使用 Gstreamer 编码/解码 VP8 或 VP9?

video - 即使录制意外中断(例如电源断开),如何在 gstreamer 中录制可播放的视频文件?

c - 在 C++ 中使用 g_idle_add() 时出错,在 C 中同样有效

gstreamer - 使用 gstreamer 解码 mp4 视频

python - 从命令行向 python 程序传递参数,有什么比 sys.argv 更好的吗?