最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Synchronize video on multiple clients as accurately as possible? - Stack Overflow

programmeradmin4浏览0评论

I'd like to synchronize the playing of a video on multiple clients. One client will give the server a URL to a video which can be streamed and click on play then every client is supposed to start playing the video at the exact same time. And while playing it has to be ensured that the every client is still in sync. If someone suddenly stops playing everyone else has to stop too as soon as possible. (At this point the client that stopped would be behind 1 second or so.) Then when the same person starts playing again everyone else would obviously have to wait a second until the one client caught up and then start playing too.

My first try was to set up a mySQL db and let each client constantly report their current video time to it. The server then calculated if any client in the db is behind and if so, calculated for each client how long they would have to pause to let it catch up.

But that didn't really work too well. It strongly depended on your latency and I wasn't able to get it reliably working with a delay of <300ms (a really good latency was required for that).

So what could I do to improve it? Should I change my setup (javscript<->ajax<->php<->mySQL)?

How can I reliably calculate the travel time of the response the server sends a client? I mean, I can't just assume the client's system time is the same as the server's... The best thing I could e up with would be something like this:

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;
});

Any idea how I could improve this whole concept?
Btw video cannot be on my own server.

I'd like to synchronize the playing of a video on multiple clients. One client will give the server a URL to a video which can be streamed and click on play then every client is supposed to start playing the video at the exact same time. And while playing it has to be ensured that the every client is still in sync. If someone suddenly stops playing everyone else has to stop too as soon as possible. (At this point the client that stopped would be behind 1 second or so.) Then when the same person starts playing again everyone else would obviously have to wait a second until the one client caught up and then start playing too.

My first try was to set up a mySQL db and let each client constantly report their current video time to it. The server then calculated if any client in the db is behind and if so, calculated for each client how long they would have to pause to let it catch up.

But that didn't really work too well. It strongly depended on your latency and I wasn't able to get it reliably working with a delay of <300ms (a really good latency was required for that).

So what could I do to improve it? Should I change my setup (javscript<->ajax<->php<->mySQL)?

How can I reliably calculate the travel time of the response the server sends a client? I mean, I can't just assume the client's system time is the same as the server's... The best thing I could e up with would be something like this:

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;
});

Any idea how I could improve this whole concept?
Btw video cannot be on my own server.

Share Improve this question asked Aug 16, 2015 at 9:26 ForivinForivin 15.5k30 gold badges118 silver badges211 bronze badges 3
  • How about each client report how long they have played the video? Then the server could calculate the 'pause time' based on the difference each client has played. – Grasshopper Commented Aug 18, 2015 at 12:05
  • Study the clock synchronization algorithm in NTP: en.wikipedia/wiki/… – Ghedipunk Commented Aug 18, 2015 at 15:52
  • @Grasshopper You don't get it. Let's say the server calculates that you have to pause for 2 seconds. Now what happens if (due to latency) the response containing the pause time needs 0.5 seconds to arrive on your puter? You will effectively pause 0.5 seconds too long because the server couldn't possibly subtract the packet traveling time in advance. – Forivin Commented Aug 19, 2015 at 14:52
Add a ment  | 

4 Answers 4

Reset to default 4

The most accurate way would probably be to use sockets: this way you can signal to other systems what is required and don't need to wait for ajax polling. You won't be able to exactly pensate for latency, but could average things out by measuring the round trip with some test messages.

So the plan would be:

  1. all clients pre-load video ready to roll
  2. all clients open socket to server and indicate they are ready to rumble
  3. server runs some quick test messages to measure latency.
  4. server sends the "go" message to all clients, possibly delaying to account for latency (or indicate the time for the client to pause instead; either way works)
  5. if a client stops, it send message to server; server immediately send message to another clients to stop.
  6. clients reply with where they are paused
  7. When restarting, adjust the start messages to account for both latency and the fact some clients are paused fractionally later.

I used something very similar to sync 18 projectors across 3 cars for an AV display system. (https://vimeo./97191170). Despite Xorifelse's ments in his answer, PHP was perfectly capabale of receiving, processing and handling up to 100 sockets mands 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./cars-that-feel-vivid-sydney/

I suggest to to NodeJS and sockets programming to implement. Further you can use http://www.webrtc

Have you tried using WebRTC, it is used for peer to peer connections, and for streaming as well. Using WebRTC you can make multy stream from one client to others, I have used it to stream videos to other people, and everyone that connects is getting the video, but I am not streaming it server does, I was only controlling the video, pause, sound, .....

You can try using it, but in your case every client can control the stream. Personally I have no tried something like that, but this way you have no issues regarding latency, pauses, and so on.

As someone else said, I would probably setup a little websocket server in NodeJS. The idea is to create a list of events, like "Play", "Pause". When a client connects, it asks the server where it should start playing (since the other client could have started before it) or if you want you can broadcast a "StartAgain" event to all the client every time someone connects. Once the video started, you can then listen to the HTML Audio/Video events, in order to detect if a client video stopped playing. In this case, you send a "Pause" event to your server, which will broadcast it to all the other clients to pause the playing too. When the video resume, you can send the "Play" event.

发布评论

评论列表(0)

  1. 暂无评论