aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/lib/Player/Keybinds.svelte1
-rw-r--r--src/lib/Player/Player.svelte33
-rw-r--r--src/lib/Renderer/Renderer.svelte4
-rw-r--r--src/routes/+page.svelte4
4 files changed, 33 insertions, 9 deletions
diff --git a/src/lib/Player/Keybinds.svelte b/src/lib/Player/Keybinds.svelte
index 756a865..778e583 100644
--- a/src/lib/Player/Keybinds.svelte
+++ b/src/lib/Player/Keybinds.svelte
@@ -20,7 +20,6 @@
case ' ':
e.preventDefault();
playing = !playing;
- if (playing) playbackStarted = performance.now();
break;
// default:
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>
diff --git a/src/lib/Renderer/Renderer.svelte b/src/lib/Renderer/Renderer.svelte
index 72c270b..3d661d8 100644
--- a/src/lib/Renderer/Renderer.svelte
+++ b/src/lib/Renderer/Renderer.svelte
@@ -127,6 +127,10 @@
onDestroy(() => (active = false));
</script>
+<svelte:head>
+ <title>{message} - Videotool Renderer</title>
+</svelte:head>
+
<div class="flex flex-col h-screen w-screen">
{#if videoUrl}
<!-- svelte-ignore a11y_media_has_caption -->
diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte
index 8d09da5..c26aca3 100644
--- a/src/routes/+page.svelte
+++ b/src/routes/+page.svelte
@@ -3,4 +3,8 @@
import Video from '$/user';
</script>
+<svelte:head>
+ <title>Videotool Player</title>
+</svelte:head>
+
<Editor {Video} />