diff --git a/docker/Dockerfile b/docker/Dockerfile index 7f9be97eb..0b7998f2b 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -118,7 +118,7 @@ RUN apt-get -qq update \ ENV PATH=$PATH:/usr/lib/btbn-ffmpeg/bin # install go2rtc -RUN wget -O go2rtc "https://github.com/AlexxIT/go2rtc/releases/download/v0.1-rc.1/go2rtc_linux_${TARGETARCH}" \ +RUN wget -O go2rtc "https://github.com/AlexxIT/go2rtc/releases/download/v0.1-rc.2/go2rtc_linux_${TARGETARCH}" \ && chmod +x go2rtc \ && mkdir -p /usr/local/go2rtc/sbin/ \ && mv go2rtc /usr/local/go2rtc/sbin/go2rtc diff --git a/web/src/components/MsePlayer.jsx b/web/src/components/MsePlayer.jsx index cc5ba61f5..a1b2ed9ea 100644 --- a/web/src/components/MsePlayer.jsx +++ b/web/src/components/MsePlayer.jsx @@ -11,12 +11,11 @@ export default function MsePlayer({ camera, width, height }) { // support api_path const ws = new WebSocket(url); ws.binaryType = 'arraybuffer'; - - let mediaSource; + let mediaSource, + sourceBuffer, + queueBuffer = []; ws.onopen = () => { - // https://web.dev/i18n/en/fast-playback-with-preload/#manual_buffering - // https://developer.mozilla.org/en-US/docs/Web/API/Media_Source_Extensions_API mediaSource = new MediaSource(); video.src = URL.createObjectURL(mediaSource); mediaSource.onsourceopen = () => { @@ -26,63 +25,49 @@ export default function MsePlayer({ camera, width, height }) { }; }; - let sourceBuffer, - queueBuffer = []; - ws.onmessage = (ev) => { if (typeof ev.data === 'string') { const data = JSON.parse(ev.data); if (data.type === 'mse') { sourceBuffer = mediaSource.addSourceBuffer(data.value); - // important: segments supports TrackFragDecodeTime - // sequence supports only TrackFragRunEntry Duration - sourceBuffer.mode = 'segments'; + sourceBuffer.mode = 'segments'; // segments or sequence sourceBuffer.onupdateend = () => { if (!sourceBuffer.updating && queueBuffer.length > 0) { - sourceBuffer.appendBuffer(queueBuffer.shift()); + try { + sourceBuffer.appendBuffer(queueBuffer.shift()); + } catch (e) { + // console.warn(e); + } } }; } - } else if (sourceBuffer.updating) { + } else if (sourceBuffer.updating || queueBuffer.length > 0) { queueBuffer.push(ev.data); } else { - sourceBuffer.appendBuffer(ev.data); + try { + sourceBuffer.appendBuffer(ev.data); + } catch (e) { + // console.warn(e); + } + } + + if (video.seekable.length > 0) { + const delay = video.seekable.end(video.seekable.length - 1) - video.currentTime; + if (delay < 1) { + video.playbackRate = 1; + } else if (delay > 10) { + video.playbackRate = 10; + } else if (delay > 2) { + video.playbackRate = Math.floor(delay); + } } }; - let offsetTime = 1, - noWaiting = 0; - - setInterval(() => { - if (video.paused || video.seekable.length === 0) return; - - if (noWaiting < 0) { - offsetTime = Math.min(offsetTime * 1.1, 5); - } else if (noWaiting >= 30) { - noWaiting = 0; - offsetTime = Math.max(offsetTime * 0.9, 0.5); - } - noWaiting += 1; - - const endTime = video.seekable.end(video.seekable.length - 1); - let playbackRate = (endTime - video.currentTime) / offsetTime; - if (playbackRate < 0.1) { - // video.currentTime = endTime - offsetTime; - playbackRate = 0.1; - } else if (playbackRate > 10) { - // video.currentTime = endTime - offsetTime; - playbackRate = 10; - } - // https://github.com/GoogleChrome/developer.chrome.com/issues/135 - video.playbackRate = playbackRate; - }, 1000); - - video.onwaiting = () => { - const endTime = video.seekable.end(video.seekable.length - 1); - video.currentTime = endTime - offsetTime; - noWaiting = -1; - }; + video.onpause = () => { + ws.close(); + video.src = null; + } }, [url]); return (