I have made a media player that plays basically anything that's scheduled to it via a text file. The player can also play the exact same clip on multiple machines(PC's). The problem is the syncing. The same video starts playing on each of the machines, but they are out by about 400ms, which looks crap and if there's sound it's even worse.
What I do at the moment is:
One machine is set up as the master and all other machines are开发者_运维百科 set up as slaves. The master decides what item will be played. It waits for a message from each of the slaves, once all slaves are connected (or after the timeout), it broadcasts the item id of the file that needs to be played. All machines then start playing that file.
What I also tried:
I thought that the file loading time might be the major driving factor in the sync mismatch, so I chankged the code to do the following.
The master still decides what file to play. It waits for the connect message from each slave (or timeout) and transmits the item id of the file to play. All machines start playing that file but pauses it immediately. The master then again waits for a ready message from each of the slaves. As soon as all slaves responded the master sends a play message to all slaves. All machines then continue the file.
This unfortunately did not improve the problem. I am now pretty sure the sync mismatch is due to network delay. How can I compensate for this? Or maybe determine the delay to each slave?
All network comms are done with winsock.
Any thoughts or ideas is much appreciated.
The closest approximation to perfectly syncing them, as far as I figure, is this.
Partial Solution:
Master: Send the play message with a timestamp to clients.
Clients: When the play message is received, respond with an acknowledgment . Read the timestamp, calculate how long the message took to arrive, and delay starting the playback by that time difference.
Master: When the acknowledgment message is received, play immediately.
The problem is that you'll still have multiple acknowledgments, so if the average deviation in round-trip-time to is too high, you'll still have a large de-synchronization. One solution for this might be to keep track of some kind of smoothed round-trip-time estimator for each client.
Alternative Solution:
Master: When you send a play message, send a start time (the highest round-trip-time among all clients) for the clients to begin playback, and should schedule playback for the provided time.
Clients: When the play message is received, they should schedule playback for the provided time.
You can use the known streaming protocols, such as RTP (or others) to do the job. Reading a file over the network (which is what it seems that you're doing) is prone to network delays, and if the precision required is in milliseconds - you've got real time constraints there.
you could ping the slave machines from the master to get a delay offset... if it's all local it might not make a difference.
Also you're probably going round robin with your message to play the file, so that would introduce a delay too depending on which machines you speak to first.
You could maybe broadcast to all listening machines at the same time to avoid this.
精彩评论