From c4b548111f4bcf58aeed3d42c53a6c374c2b2914 Mon Sep 17 00:00:00 2001 From: Josh Hawkins <32435876+hawkeye217@users.noreply.github.com> Date: Wed, 14 Aug 2024 16:12:23 -0500 Subject: [PATCH] Try adjusting playback rate instead of jumping to live --- web/src/components/player/MsePlayer.tsx | 50 +++++++++++++++++++++++-- 1 file changed, 46 insertions(+), 4 deletions(-) diff --git a/web/src/components/player/MsePlayer.tsx b/web/src/components/player/MsePlayer.tsx index a41d752f7..a53474278 100644 --- a/web/src/components/player/MsePlayer.tsx +++ b/web/src/components/player/MsePlayer.tsx @@ -49,6 +49,10 @@ function MSEPlayer({ const [isPlaying, setIsPlaying] = useState(false); const lastJumpTimeRef = useRef(0); + const MAX_BUFFER_ENTRIES = 10; // Size of the rolling window + const bufferTimes = useRef([]); + const bufferIndex = useRef(0); + const [wsState, setWsState] = useState(WebSocket.CLOSED); const [connectTS, setConnectTS] = useState(0); const [bufferTimeout, setBufferTimeout] = useState(); @@ -324,6 +328,13 @@ function MSEPlayer({ } }; + const calculateAdaptiveBufferThreshold = () => { + const filledEntries = bufferTimes.current.length; + const sum = bufferTimes.current.reduce((a, b) => a + b, 0); + const averageBufferTime = filledEntries ? sum / filledEntries : 0; + return averageBufferTime * 1.5; + }; + useEffect(() => { if (!playbackEnabled) { return; @@ -415,6 +426,18 @@ function MSEPlayer({ onProgress={() => { const bufferTime = getBufferedTime(videoRef.current); + if (videoRef.current && videoRef.current.playbackRate === 1) { + if (bufferTimes.current.length < MAX_BUFFER_ENTRIES) { + bufferTimes.current.push(bufferTime); + } else { + bufferTimes.current[bufferIndex.current] = bufferTime; + bufferIndex.current = + (bufferIndex.current + 1) % MAX_BUFFER_ENTRIES; + } + } + + const bufferThreshold = calculateAdaptiveBufferThreshold(); + // if we have > 3 seconds of buffered data and we're still not playing, // something might be wrong - maybe codec issue, no audio, etc // so mark the player as playing so that error handlers will fire @@ -424,15 +447,34 @@ function MSEPlayer({ onPlaying?.(); } - // if we have > 2 seconds of buffered data and we're playing, we may have - // drifted from actual live time, so seek to the end of buffered data + // if we're above our rolling average threshold or have > 3 seconds of + // buffered data and we're playing, we may have drifted from actual live + // time, so increase playback rate to compensate if ( videoRef.current && isPlaying && playbackEnabled && - bufferTime > 2 + (bufferTime > bufferThreshold || bufferTime > 3) && + Date.now() - lastJumpTimeRef.current > BUFFERING_COOLDOWN_TIMEOUT ) { - jumpToLive(); + // jumpToLive(); + videoRef.current.playbackRate = 1.1; + console.log( + camera, + "increasing playback rate", + bufferTime, + bufferThreshold, + ); + } else { + if (videoRef.current) { + console.log( + camera, + "normal playback rate", + bufferTime, + bufferThreshold, + ); + videoRef.current.playbackRate = 1; + } } if (onError != undefined) {