diff options
Diffstat (limited to 'packages/meshbay-hub/src')
| -rw-r--r-- | packages/meshbay-hub/src/meshbay_hub/static/app.js | 28 |
1 files changed, 23 insertions, 5 deletions
diff --git a/packages/meshbay-hub/src/meshbay_hub/static/app.js b/packages/meshbay-hub/src/meshbay_hub/static/app.js index 5a50010..3d87275 100644 --- a/packages/meshbay-hub/src/meshbay_hub/static/app.js +++ b/packages/meshbay-hub/src/meshbay_hub/static/app.js @@ -1481,6 +1481,7 @@ function VideoPlayer({ entry, transportRef, gekRef, onClose }) { const queueRef = useRef([]); const appendingRef = useRef(false); const endedRef = useRef(false); + const durationRef = useRef(0); const flushQueue = useCallback(() => { const sb = sbRef.current; @@ -1510,25 +1511,34 @@ function VideoPlayer({ entry, transportRef, gekRef, onClose }) { return; } + const onSeeking = () => { + const v = videoRef.current; + if (!v || !v.buffered.length) return; + const target = v.currentTime; + const end = v.buffered.end(v.buffered.length - 1); + const start = v.buffered.start(0); + if (target > end) v.currentTime = Math.max(end - 0.5, start); + else if (target < start) v.currentTime = start; + }; + const startStream = async () => { if (!gekRef.current && window.MeshBayCrypto) { const gekB64 = await transport.fetchGEK(); gekRef.current = await window.MeshBayCrypto.importGEK(gekB64); } - let streamCodec = null; - transport.onStreamInit = (msg) => { if (cancelled) return; - streamCodec = msg.codec; - const mime = `video/mp4; codecs="${streamCodec}"`; + const mime = `video/mp4; codecs="${msg.codec}"`; if (!window.MediaSource || !MediaSource.isTypeSupported(mime)) { - setError(t('video.err_mse', { codec: streamCodec })); + setError(t('video.err_mse', { codec: msg.codec })); setPhase('error'); return; } + durationRef.current = msg.duration || 0; + const ms = new MediaSource(); msRef.current = ms; const url = URL.createObjectURL(ms); @@ -1536,8 +1546,12 @@ function VideoPlayer({ entry, transportRef, gekRef, onClose }) { ms.addEventListener('sourceopen', () => { if (cancelled) return; + if (durationRef.current > 0) { + ms.duration = durationRef.current; + } const sb = ms.addSourceBuffer(mime); sbRef.current = sb; + sb.mode = 'sequence'; sb.addEventListener('updateend', () => { appendingRef.current = false; flushQueue(); @@ -1548,6 +1562,7 @@ function VideoPlayer({ entry, transportRef, gekRef, onClose }) { if (videoRef.current) { videoRef.current.src = url; + videoRef.current.addEventListener('seeking', onSeeking); } }; @@ -1578,6 +1593,9 @@ function VideoPlayer({ entry, transportRef, gekRef, onClose }) { return () => { cancelled = true; + if (videoRef.current) { + videoRef.current.removeEventListener('seeking', onSeeking); + } if (transport) { transport.onStreamInit = null; transport.onStreamData = null; |