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

时间:2013-04-21 19:32:27

标签: python gstreamer

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

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

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

    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. 调用之后,队列中存储的所有数据都将丢失。播放开始就像队列根本不存在一样。
    3. 我认为我对这件事的运作方式有一个根本的误解。有谁知道我做错了什么,或者可以提供(可能)更好的方法来做到这一点? 我在这里使用python,但欢迎使用任何语言的任何解决方案。

      感谢。

2 个答案:

答案 0 :(得分:3)

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

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

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

  1. 将队列的“max-size-bytes”属性设置为所需的值。
  2. 在缓冲区变满时收听“溢出”信号通知您,或使用gst_message_parse_buffering()查找缓冲级别。
  3. 缓冲区已满后,将管道设置为 PLAYING 状态,然后忽略所有进一步的缓冲消息。
  4. 最后,有关完整的流媒体示例,您可以参考本教程:https://gstreamer.freedesktop.org/documentation/tutorials/basic/streaming.html 代码在C中,但演练应该可以帮助您。

答案 1 :(得分:0)

我遇到了与使用不同管道(appsrc)完全相同的问题,并且在花了几天时间试图找到一个优雅的解决方案(并最终得到与您发布的代码非常相似的代码)...我所做的只是将标志is-live切换为False,缓冲自动完成。 (不需要min-threshold-time或其他任何东西)

希望这有帮助。