8

Motivation: I am currently trying to synchronize two videos on two networked raspis. I tried live streaming from a desktop (http and udp) but each raspi still opened the stream with a noticeable delay. I next tried installing vlc on the raspi and synchronizing with the desktop vlc, but that did not work either. I tried using a shell script to launch omxplayer at near the same time on both raspis, and that failed too. Finally I used a C script to launch the two omxplayers at near identical times, which also failed. Ultimately, I don't think it is possible to control when omxplayer starts actually playing the video file.

Current Progress: Therefore, now, I am modifying omxplayer's code to synchronize two omxplayers using sockets, but I want to know what approach something like vlc takes when synchronizing its video clients, so as to not reinvent the wheel. I could be wrong but I noticed, by looking at the verbose output and debug statements, that one player would lose time with respect to the other, such that as the video played, this difference would build up and after 2-3 minutes exceeded 200 ms. I find this extremely disturbing. It would mean that after 2 hours, the difference would be 60*200ms=12000ms or around 12s. I thought the precision of modern day computing would be more like that of an atomic clock, losing maybe 1s after 1000 hours of footage, hence why I thought it would be sufficient to merely synchronize the feeds once.

Question: If the different players have to be synchronized constnatly, how does something like vlc do it?

  1. Does it wait until there is a noticeable delay and fast forward/rewind?
  2. Does it fast forward/rewind whenever there is any difference?
  3. Does rectifying this difference (ie. socket signals) itself cause further delays?
  4. Since moving to a distant time in the video takes longer than playing continuously, how does it predict how many seconds to fast forward/rewind?
  5. I hear a lot of people talking about ticks (not the insects), and about how the master vlc sends out ticks. However, what I don't understand is how those ticks are interpretted: do you momentarily pause all other players until the next tick, or do you modulate the speed of the video somehow (if that is even possible on the fly)?

NOTE: I am not streaming the actual video files as they are all accessed remotely via NFS on each of the raspis.

4

1 回答 1

9

对不起,我没有直接回答你的问题,而是我会这样做:

我会使用 MCI(我对 Windows 很友好,但我认为所有其他玩家都必须是类似的东西)

  1. 时间必须在所有客户端上同步,这可能非常棘手
    • 在具有小延迟的快速 LAN 上,您可以通过服务器向所有客户端发送时间,仅此而已
    • 在未知延迟(如互联网)上,您不能相反,您可以开始多次从服务器向每个客户端发送时间。在客户端计算服务器和客户端时间之间的平均时间偏移,然后将其添加到客户端时间,就是这样。
    • 如果客户端连接延迟太不稳定,那你就不走运了
  2. 打开流但未开始播放
  3. 等待一段时间以确保视频已准备好播放...
  4. 在精确的服务器时间开始在每个客户端上播放

    不要期望精确的同步(没有精确的时间同步)。播放命令也可以在不同的机器上以不同的速度执行,但没有打开流命令的差异那么大(因此在第 3 条上会有延迟)

这种方法的问题是它假设播放与时间同步

这通常不是真的,尤其是在网络流媒体上。大多数播放器会丢帧以进行补偿,但有时如果流长时间未解码,可能会导致累积偏移。在这种情况下,您可以实现播放进度(您的抽动)

抽动可以是:

  • 播放帧
  • 播放进度时间
  • 播放进度百分比

抽动同步:

在所有情况下,您都必须从项目符号 #1 或任何其他实现时间同步。有以下三种基本方法:

  1. 最好的是帧同步

    但是需要实现自己的播放器或能够进行帧导航的播放器,这很难正确实现。

  2. 播放进度时间

    是下一个最好的事情。如果您发现偏移量大于某个阈值,则暂停或倒退/前进。

    倒带的问题在于它需要多少时间是不可预测的,因此您可以测量它所花费的时间并通过应用此时间以匹配同步播放时间(它有点棘手)在几个步骤中迭代倒带。

  3. 播放进度百分比

    与播放进度时间几乎相同,但分辨率要差得多。它仅适用于非常大的时间偏移。不适用于同步本身,仅适用于问题检测。如果检测到问题,则停止所有客户端并以新的确切服务器时间开始,或者在重新开始播放之前倒带 + 延迟。我知道这很糟糕,但并非所有播放器都支持播放帧/时间公告。

希望它有一点帮助。

于 2013-12-03T09:52:58.850 回答