diff options
Diffstat (limited to 'src/lib/Player/Player.svelte')
-rw-r--r-- | src/lib/Player/Player.svelte | 33 |
1 files changed, 25 insertions, 8 deletions
diff --git a/src/lib/Player/Player.svelte b/src/lib/Player/Player.svelte index f6df121..3d859ea 100644 --- a/src/lib/Player/Player.svelte +++ b/src/lib/Player/Player.svelte @@ -11,7 +11,7 @@ let video = $state(undefined as Video | undefined); let frameCount = $state(0); let playing = $state(false); - let playbackStarted = $state(0); + let playbackRelativeTo = $state(0); let playbackFrameOffset = 0; let renderPromise: Promise<void> | void = void 0; let renderId = 0; @@ -66,11 +66,18 @@ let playbackLoopId = 0; const startPlaybackLoop = (id = ++playbackLoopId) => { if (video && id === playbackLoopId) { - const ms = performance.now() - playbackStarted; + const ms = performance.now() - playbackRelativeTo; let f = Math.floor((ms / 1000) * video.fps) + playbackFrameOffset; + if (audio) { + const desiredTime = frame / video.fps; + // If we get too out of lock-step with audio, we re-sync + if (Math.abs(desiredTime - audio.currentTime) > 0.3) audio.currentTime = desiredTime; + } + if (f > frameCount) { f = frameCount; + playbackRelativeTo = 0; playing = false; } frame = f; @@ -79,12 +86,16 @@ ); } }; + // State Synchronisation effect & playback starter $effect(() => { if (playing) { - playbackStarted = performance.now(); + if (frame === frameCount && playbackRelativeTo === 0) { + frame = 0; + } + playbackRelativeTo = performance.now(); playbackFrameOffset = frame; startPlaybackLoop(); - } + } else playbackRelativeTo = 0; }); let loadedFrameTimestamp = false; onMount(() => { @@ -104,7 +115,7 @@ } catch (_) {} }); $effect(() => { - if (audio && video && !playing) { + if (audio && video && !playing && !playbackFrameOffset) { try { const f = frame; audio.currentTime = frame / video.fps; @@ -144,7 +155,13 @@ }} /> -<Keybinds bind:frame {frameCount} fps={video?.fps} bind:playing bind:playbackStarted /> +<Keybinds + bind:frame + {frameCount} + fps={video?.fps} + bind:playing + bind:playbackStarted={playbackRelativeTo} +/> <div class="p-2 w-screen h-screen relative flex flex-col"> <div class="flex-1 relative"> @@ -153,9 +170,9 @@ Your browser doesn't support the canvas API. </canvas> {#if audioSource} - <audio src={audioSource} bind:this={audio}></audio> + <audio src={audioSource} bind:this={audio} preload="auto"></audio> {/if} </div> </div> - <FrameSlider bind:frame {frameCount} bind:playing bind:playbackStarted /> + <FrameSlider bind:frame {frameCount} bind:playing bind:playbackStarted={playbackRelativeTo} /> </div> |