尽可能准确地同步多个客户端上的视频?

Synchronize video on multiple clients as accurately as possible?

我想在多个客户端上同步播放一个视频。 一个客户端会给服务器一个 URL 到一个可以流式传输的视频,然后点击播放,然后每个客户端都应该同时开始播放视频。在播放时必须确保每个客户端仍然同步。如果有人突然停止演奏,其他人也必须尽快停止演奏。 (此时停止的客户将落后 1 秒左右。)然后当同一个人再次开始玩时,其他人显然必须等待一秒钟,直到一个客户赶上然后也开始玩。

我的第一个尝试是建立一个 mySQL 数据库,让每个客户端不断地向它报告他们当前的视频时间。然后服务器计算数据库中是否有任何客户端落后,如果是,则为每个客户端计算他们必须暂停多长时间才能赶上进度。

但这并没有真正奏效。这在很大程度上取决于您的延迟,我无法让它以 <300 毫秒的延迟可靠地工作(这需要非常好的延迟)。

那么我可以做些什么来改进它呢?我应该更改设置 (javscript<->ajax<->php<->mySQL) 吗?

如何可靠地计算服务器发送给客户端的响应的传输时间?我的意思是,我不能假设客户端的系统时间与服务器的系统时间相同...... 我能想到的最好的事情是这样的:

var start = new Date().getTime()
$.post( "sync.php", "")
.done(function(data) {
    var end = new Date().getTime()/1000;
    var clientServerClientTravelTime = (end-start);
    var estimatedServerClientTravelTime = clientServerClientTravelTime/2;
});

知道如何改进整个概念吗?
顺便说一句,视频不能在我自己的服务器上。

您是否尝试过使用 WebRTC,它用于点对点连接,也用于流式传输。使用 WebRTC,您可以从一个客户端向其他客户端制作多个流,我用它向其他人流式传输视频,并且连接的每个人都在获取视频,但我没有流式传输服务器,我只是控制视频,暂停, 声音, .....

您可以尝试使用它,但在您的情况下,每个客户端都可以控制流。就个人而言,我没有尝试过类似的东西,但这样你就不会遇到延迟、暂停等问题。

最准确的方法可能是使用套接字:这样您就可以向其他系统发出所需的信号,而无需等待 ajax 轮询。您将无法完全补偿延迟,但可以通过使用一些测试消息测量往返来平均。

所以计划是:

  1. 所有客户都预加载视频准备播放
  2. 所有客户端都打开到服务器的套接字并表明它们已准备好发出隆隆声
  3. 服务器运行一些快速测试消息来测量延迟。
  4. 服务器向所有客户端发送 "go" 消息,可能会延迟以解决延迟(或指示客户端暂停的时间;两种方式都有效)
  5. 如果客户端停止,它会向服务器发送消息;服务器立即向另一个客户端发送消息以停止。
  6. 客户回复他们暂停的地方
  7. 重新启动时,调整启动消息以考虑延迟和一些客户端稍后暂停的事实。

我使用了非常类似于在 3 辆车上同步 18 台投影仪的 AV 显示系统。 (https://vimeo.com/97191170). Despite Xorifelse's comments in his answer, PHP was perfectly capabale of receiving, processing and handling up to 100 sockets commands per second from a controller (jquery based application in a browser, connected by sockets), filtering out duplicates, logging them all to mySQL for a second process to poll on demand (approx 10 times per second, triggered by socket request from a Flash (Adobe Air) script and then also passed on light instructions to under-car lighting (also through sockets) or to other cars (also through sockets). In fact, the PHP/MySQL solution was far more robust than trying to pump socket instructions directly into Flash. It's very possible. Tech details for the project are here: http://labs.soapcreative.com/cars-that-feel-vivid-sydney/

我建议以NodeJS和sockets编程来实现。此外,您可以使用 http://www.webrtc.org

正如其他人所说,我可能会在 NodeJS 中设置一个小型 websocket 服务器。 这个想法是创建一个事件列表,例如 "Play"、"Pause"。当一个客户端连接时,它会询问服务器它应该从哪里开始播放(因为另一个客户端可能先于它开始播放)或者如果您愿意,您可以在每次有人连接时向所有客户端广播一个 "StartAgain" 事件。 视频开始播放后,您可以收听 HTML Audio/Video 事件,以检测客户端视频是否停止播放。在这种情况下,您向服务器发送一个 "Pause" 事件,服务器会将其广播给所有其他客户端以暂停播放。当视频恢复时,您可以发送 "Play" 事件。