player scrubber sync attempt
This commit is contained in:
@@ -62,11 +62,6 @@
|
|||||||
let currentTime = $state(0);
|
let currentTime = $state(0);
|
||||||
let duration = $state(0);
|
let duration = $state(0);
|
||||||
|
|
||||||
// Seek scrubber value that both mobile + desktop sliders bind to.
|
|
||||||
// We keep it in sync with `currentTime` unless the user is actively dragging.
|
|
||||||
let scrubValue = $state(0);
|
|
||||||
let isScrubbing = $state(false);
|
|
||||||
|
|
||||||
// local UI derived from viewport; not persisted
|
// local UI derived from viewport; not persisted
|
||||||
let isMobile = $state(false);
|
let isMobile = $state(false);
|
||||||
|
|
||||||
@@ -129,20 +124,8 @@
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
function onScrubInput(e: Event) {
|
// Scrubber is now driven by `bind:currentTime` on the <audio> element and
|
||||||
if (!audioEl) return;
|
// `bind:value={currentTime}` on the sliders, so we don't need explicit handlers.
|
||||||
const next = Number((e.currentTarget as HTMLInputElement).value);
|
|
||||||
if (!Number.isFinite(next)) return;
|
|
||||||
|
|
||||||
isScrubbing = true;
|
|
||||||
scrubValue = next;
|
|
||||||
audioEl.currentTime = Math.max(0, next);
|
|
||||||
}
|
|
||||||
|
|
||||||
function onScrubCommit() {
|
|
||||||
// Release "user is dragging" mode so timeupdate can drive the UI again.
|
|
||||||
isScrubbing = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
function syncAudioToCurrentTrack() {
|
function syncAudioToCurrentTrack() {
|
||||||
if (!audioEl) return;
|
if (!audioEl) return;
|
||||||
@@ -258,13 +241,9 @@
|
|||||||
media.setPlaybackState("paused");
|
media.setPlaybackState("paused");
|
||||||
}
|
}
|
||||||
function onAudioTimeUpdate() {
|
function onAudioTimeUpdate() {
|
||||||
|
// `currentTime` is synced via `bind:currentTime` on <audio>.
|
||||||
|
// Keep Media Session position state updated whenever we get timeupdate.
|
||||||
if (!audioEl) return;
|
if (!audioEl) return;
|
||||||
currentTime = audioEl.currentTime || 0;
|
|
||||||
|
|
||||||
// Keep the shared scrubber value synced to playback time unless the user is dragging.
|
|
||||||
if (!isScrubbing) {
|
|
||||||
scrubValue = currentTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
media.updatePositionState({
|
media.updatePositionState({
|
||||||
duration,
|
duration,
|
||||||
@@ -273,13 +252,8 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
function onAudioLoadedMetadata() {
|
function onAudioLoadedMetadata() {
|
||||||
|
// `duration` is synced via `bind:duration` on <audio>.
|
||||||
if (!audioEl) return;
|
if (!audioEl) return;
|
||||||
duration = Number.isFinite(audioEl.duration) ? audioEl.duration : 0;
|
|
||||||
|
|
||||||
// On metadata load (track change), ensure scrubber aligns with currentTime.
|
|
||||||
if (!isScrubbing) {
|
|
||||||
scrubValue = currentTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
media.updatePositionState({
|
media.updatePositionState({
|
||||||
duration,
|
duration,
|
||||||
@@ -560,13 +534,8 @@
|
|||||||
min="0"
|
min="0"
|
||||||
max={Math.max(0, duration)}
|
max={Math.max(0, duration)}
|
||||||
step="0.1"
|
step="0.1"
|
||||||
value={Math.min(scrubValue, duration || 0)}
|
bind:value={currentTime}
|
||||||
disabled={!snap.currentTrack || duration <= 0}
|
disabled={!snap.currentTrack || duration <= 0}
|
||||||
oninput={onScrubInput}
|
|
||||||
onchange={onScrubCommit}
|
|
||||||
onpointerup={onScrubCommit}
|
|
||||||
ontouchend={onScrubCommit}
|
|
||||||
onkeyup={onScrubCommit}
|
|
||||||
/>
|
/>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
@@ -819,13 +788,8 @@
|
|||||||
min="0"
|
min="0"
|
||||||
max={Math.max(0, duration)}
|
max={Math.max(0, duration)}
|
||||||
step="0.1"
|
step="0.1"
|
||||||
value={Math.min(scrubValue, duration || 0)}
|
bind:value={currentTime}
|
||||||
disabled={!snap.currentTrack || duration <= 0}
|
disabled={!snap.currentTrack || duration <= 0}
|
||||||
oninput={onScrubInput}
|
|
||||||
onchange={onScrubCommit}
|
|
||||||
onpointerup={onScrubCommit}
|
|
||||||
ontouchend={onScrubCommit}
|
|
||||||
onkeyup={onScrubCommit}
|
|
||||||
/>
|
/>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
@@ -971,6 +935,8 @@
|
|||||||
bind:this={audioEl}
|
bind:this={audioEl}
|
||||||
class="hidden"
|
class="hidden"
|
||||||
preload="metadata"
|
preload="metadata"
|
||||||
|
bind:currentTime
|
||||||
|
bind:duration
|
||||||
onplay={onAudioPlay}
|
onplay={onAudioPlay}
|
||||||
onpause={onAudioPause}
|
onpause={onAudioPause}
|
||||||
ontimeupdate={onAudioTimeUpdate}
|
ontimeupdate={onAudioTimeUpdate}
|
||||||
|
|||||||
Reference in New Issue
Block a user