random bs
This commit is contained in:
@@ -3,11 +3,12 @@
|
|||||||
import { tables, reducers } from "$lib/st-bindings";
|
import { tables, reducers } from "$lib/st-bindings";
|
||||||
import "@videojs/html/video/player";
|
import "@videojs/html/video/player";
|
||||||
import "@videojs/html/video/skin";
|
import "@videojs/html/video/skin";
|
||||||
|
import { untrack } from "svelte";
|
||||||
|
|
||||||
const conn = useSpacetimeDB();
|
const conn = useSpacetimeDB();
|
||||||
|
|
||||||
const [videoStates] = useTable(tables.videoState);
|
const [syncStates] = useTable(tables.videoState.where((r) => r.id.eq(1n)));
|
||||||
const videoState = $derived($videoStates.find((state) => state.id === 1n));
|
const syncState = $derived($syncStates.at(0));
|
||||||
|
|
||||||
const setUrlReducer = useReducer(reducers.setUrl);
|
const setUrlReducer = useReducer(reducers.setUrl);
|
||||||
const setSubtitleUrlReducer = useReducer(reducers.setSubtitleUrl);
|
const setSubtitleUrlReducer = useReducer(reducers.setSubtitleUrl);
|
||||||
@@ -16,6 +17,9 @@
|
|||||||
const seekReducer = useReducer(reducers.seek);
|
const seekReducer = useReducer(reducers.seek);
|
||||||
|
|
||||||
let videoElement: HTMLVideoElement | undefined = $state();
|
let videoElement: HTMLVideoElement | undefined = $state();
|
||||||
|
let videoPaused = $state(false);
|
||||||
|
let videoCurrentTime = $state(0.0);
|
||||||
|
|
||||||
let newUrl = $state("");
|
let newUrl = $state("");
|
||||||
let newSubtitleUrl = $state("");
|
let newSubtitleUrl = $state("");
|
||||||
|
|
||||||
@@ -32,23 +36,20 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
$effect(() => {
|
$effect(() => {
|
||||||
if (!videoElement || !videoState) return;
|
untrack(() => videoElement);
|
||||||
|
if (!videoElement || !syncState) return;
|
||||||
const el = videoElement;
|
const el = videoElement;
|
||||||
const state = videoState;
|
|
||||||
|
|
||||||
if (el.src !== state.url) {
|
|
||||||
el.src = state.url;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Account for server to client clock drift slightly, but MVP assumes relatively synced clocks.
|
// Account for server to client clock drift slightly, but MVP assumes relatively synced clocks.
|
||||||
const timeElapsedMicros = BigInt(Date.now()) * 1000n - state.lastUpdatedAt.microsSinceUnixEpoch;
|
const timeElapsedMicros =
|
||||||
const expectedTime = state.isPlaying
|
BigInt(Date.now()) * 1000n - syncState.lastUpdatedAt.microsSinceUnixEpoch;
|
||||||
? state.timePosition + Number(timeElapsedMicros) / 1_000_000
|
const expectedTime = syncState.isPlaying
|
||||||
: state.timePosition;
|
? syncState.timePosition + Number(timeElapsedMicros) / 1_000_000
|
||||||
|
: syncState.timePosition;
|
||||||
|
|
||||||
const diff = Math.abs(el.currentTime - expectedTime);
|
const diff = Math.abs(el.currentTime - expectedTime);
|
||||||
|
|
||||||
if (!state.isPlaying) {
|
if (!syncState.isPlaying) {
|
||||||
if (el.currentTime < expectedTime && diff <= 2) {
|
if (el.currentTime < expectedTime && diff <= 2) {
|
||||||
// Behind pause point. Keep playing to catch up. (timeupdate will pause it)
|
// Behind pause point. Keep playing to catch up. (timeupdate will pause it)
|
||||||
// If locally paused, stay paused (we likely dispatched the pause event + buffer)
|
// If locally paused, stay paused (we likely dispatched the pause event + buffer)
|
||||||
@@ -93,11 +94,11 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function handleTimeUpdate() {
|
function handleTimeUpdate() {
|
||||||
if (!videoElement || !videoState) return;
|
if (!videoElement || !syncState) return;
|
||||||
const el = videoElement;
|
const el = videoElement;
|
||||||
|
|
||||||
if (!videoState.isPlaying) {
|
if (!syncState.isPlaying) {
|
||||||
const expectedTime = videoState.timePosition;
|
const expectedTime = syncState.timePosition;
|
||||||
if (!el.paused && el.currentTime >= expectedTime) {
|
if (!el.paused && el.currentTime >= expectedTime) {
|
||||||
syncAction(() => {
|
syncAction(() => {
|
||||||
el.pause();
|
el.pause();
|
||||||
@@ -122,6 +123,8 @@
|
|||||||
setSubtitleUrlReducer({ url: newSubtitleUrl });
|
setSubtitleUrlReducer({ url: newSubtitleUrl });
|
||||||
newSubtitleUrl = "";
|
newSubtitleUrl = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$inspect(syncState?.url);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="p-4">
|
<div class="p-4">
|
||||||
@@ -165,14 +168,15 @@
|
|||||||
bind:this={videoElement}
|
bind:this={videoElement}
|
||||||
muted
|
muted
|
||||||
crossorigin="anonymous"
|
crossorigin="anonymous"
|
||||||
|
src={syncState?.url}
|
||||||
onplay={handlePlay}
|
onplay={handlePlay}
|
||||||
onpause={handlePause}
|
onpause={handlePause}
|
||||||
onseeked={handleSeeked}
|
onseeked={handleSeeked}
|
||||||
ontimeupdate={handleTimeUpdate}
|
ontimeupdate={handleTimeUpdate}
|
||||||
>
|
>
|
||||||
{#if videoState?.subtitleUrl}
|
{#if syncState?.subtitleUrl}
|
||||||
<track
|
<track
|
||||||
src={videoState.subtitleUrl}
|
src={syncState.subtitleUrl}
|
||||||
kind="subtitles"
|
kind="subtitles"
|
||||||
srclang="en"
|
srclang="en"
|
||||||
label="English"
|
label="English"
|
||||||
|
|||||||
Reference in New Issue
Block a user