From eba86080324e5c3154753259cdc322e4fabd0695 Mon Sep 17 00:00:00 2001 From: Radon Rosborough Date: Thu, 10 Nov 2022 21:48:17 -0800 Subject: [PATCH] Fix flickering (I think) --- extension/CHANGELOG.md | 7 +++++++ extension/content-script.js | 33 ++++++++++++++++++++++++++++++--- 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/extension/CHANGELOG.md b/extension/CHANGELOG.md index 96a2404..0a19931 100644 --- a/extension/CHANGELOG.md +++ b/extension/CHANGELOG.md @@ -5,6 +5,13 @@ The format is based on [Keep a Changelog]. [keep a changelog]: https://keepachangelog.com/en/1.0.0/ +## 0.0.8 + +In some cases video playback would flicker back and forth between +multiple positions when seeking, especially with a large number of +clients connected. This has been made much less likely by implementing +a slightly modified synchronization algorithm. + ## 0.0.7 End-to-end encryption is now used, so the server has no knowledge of diff --git a/extension/content-script.js b/extension/content-script.js index b23d5e3..192e5c4 100644 --- a/extension/content-script.js +++ b/extension/content-script.js @@ -71,14 +71,36 @@ const detectPrimaryVideo = () => { const instrumentVideo = (video, callback) => { log(`Video instrumentation: installing event listeners`); + let lastSetPlaying = null; + let lastSetVideoTimeSeconds = null; + let lastSetRealTimeSeconds = null; for (const event of ["play", "pause", "seeked"]) { - video.addEventListener(event, () => + video.addEventListener(event, () => { + if ( + // If we have previously applied an event... + lastSetRealTimeSeconds && + // ... in the last 500 milliseconds ... + lastSetRealTimeSeconds - new Date() / 1000 < 0.5 && + // ... and that event matches the current pause state ... + lastSetPlaying == !video.paused && + // ... and current playback time ... + Math.abs(lastSetVideoTimeSeconds - video.currentTime < 0.5) + // ... then: + ) { + // This event is probably just the result of our applying an + // event that we received from another client, so there is no + // need to send it back out as an additional update. If + // multiple messages get to be in flight at the same time, + // this kind of echoing can cause flickering back and forth as + // the clients fail to reach consensus. + return; + } callback({ playing: !video.paused, videoTimeSeconds: video.currentTime, realTimeSeconds: new Date() / 1000, - }) - ); + }); + }); } return ({ playing, videoTimeSeconds, realTimeSeconds }) => { if (playing && video.paused) { @@ -94,6 +116,11 @@ const instrumentVideo = (video, callback) => { if (Math.abs(video.currentTime - expectedVideoTime) > 0.5) { video.currentTime = expectedVideoTime; } + // Read the attributes back out from the video in case they were + // automatically rounded or something. + lastSetPlaying = !video.paused; + lastSetVideoTimeSeconds = video.currentTime; + lastSetRealTimeSeconds = new Date() / 1000; }; };