Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Synchronize video on multiple clients as accurately as possible?

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 come 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.

like image 578
Forivin Avatar asked Aug 16 '15 09:08

Forivin


People also ask

What does sync mean in video editing?

Audio-to-video synchronization (AV synchronization, also known as lip sync, or by the lack of it: lip-sync error, lip flap) refers to the relative timing of audio (sound) and video (image) parts during creation, post-production (mixing), transmission, reception and play-back processing.


4 Answers

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 compensate 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.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/

like image 158
Robbie Avatar answered Oct 19 '22 11:10

Robbie


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

like image 38
Atul Jindal Avatar answered Oct 19 '22 11:10

Atul Jindal


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.

like image 29
Nermin Avatar answered Oct 19 '22 09:10

Nermin


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.

like image 36
Alekos Filini Avatar answered Oct 19 '22 11:10

Alekos Filini