This project is a proof of concept for synchronizing youtube-videos (nearly) frame-accurate on different devices via a website.
The youtube video Rendering at 5am was my inspiration.
You can try it out like this:
- Open the deployed site (either in two browsers/windows or even on different devices).
- Choose the same unique channel-id for all your opened sites.
- Click
Start
. - One window should have a heading with
Leader
. The others should beFollowers
. By clicking on the Video-id field, you can paste the video id of any Youtube video (or choose from a small list of recommended ones). - Click
Play Client
on each window - Wait a bit - it can take up to 1 minute until the videos synchronize
- Each follower has a
System time offset
. On the same device, it should be nearly 0ms. TheSystem time offset
specifies the difference between the system time (Date. now()
) in the browser and the system time on the Leader window. - On the top left of each video, you can see a time that changes every few seconds and should be between
-10ms
and10ms
(after the videos are synchronized). It specifies how much the video feed differs from its optimal time, assuming the system times are synchronized.
The synchronization happens in two steps:
I implemented the NTP (Network time protocol) Algorithm in JS via WebSockets or Pusher JS as my communication channel between each follower- and the Leader-clients. Look under Clock synchronization algorithm
in the Wikipedia article.
At the currentTime
(= synchronized system time) we want the currentVideoTime
to be at currentTime % videoLength
. Because the currentTime
or system time has been synchronized between the clients in Step 1 and the videoLength
is the same in all the clients (because they are supposed to play the same video) the currentVideoTime
is the same too. We call currentTime % videoLength
from now on the reference time
.
If I would start the video at the correct time on all clients (via setTimeout()
), they probably wouldn't play at the same time (the referenceTime
) because one system has, e.g., network problems and the video still buffers or another program wants at this moment the processing power of the OS. Depending on the device, the time between calling the start function of the video player and the actual starting of the video differs too.
I'm solving this by checking whether the video is in the correct position (= referenceTime
). If the difference to the correct position is higher than 10ms, I'm stopping the video, skipping the video to the position where it should be in 5s plus the time it was late before, and starting it again.
The code is more sophisticated (and complicated) than this, but this is the main idea.
- The site is currently deployed via Netlify and uses Pusher. The Free tier only allows 100 concurrent connections and 200,000 messages sent per day and is deployed in the EU (Ireland)
- The synchronization technic is not 100% reliable
- Be aware that each open window streams the youtube video. This is not very resource-friendly and could potentially stress your network and internet connection.
- The frontend is written in Angular
- Pusher.js is used for the communication between the clients
- The authentication of the pusher clients is done via a lambda function that is deployed on Netlify
The videos are synchronized to be not more than ca. 20ms
off.
One could measure this empirically by analyzing films or photos of the synchronized video.