player scrubber sync attempt
This commit is contained in:
@@ -62,11 +62,6 @@
|
||||
let currentTime = $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
|
||||
let isMobile = $state(false);
|
||||
|
||||
@@ -129,20 +124,8 @@
|
||||
},
|
||||
});
|
||||
|
||||
function onScrubInput(e: Event) {
|
||||
if (!audioEl) return;
|
||||
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;
|
||||
}
|
||||
// Scrubber is now driven by `bind:currentTime` on the <audio> element and
|
||||
// `bind:value={currentTime}` on the sliders, so we don't need explicit handlers.
|
||||
|
||||
function syncAudioToCurrentTrack() {
|
||||
if (!audioEl) return;
|
||||
@@ -258,13 +241,9 @@
|
||||
media.setPlaybackState("paused");
|
||||
}
|
||||
function onAudioTimeUpdate() {
|
||||
// `currentTime` is synced via `bind:currentTime` on <audio>.
|
||||
// Keep Media Session position state updated whenever we get timeupdate.
|
||||
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({
|
||||
duration,
|
||||
@@ -273,13 +252,8 @@
|
||||
});
|
||||
}
|
||||
function onAudioLoadedMetadata() {
|
||||
// `duration` is synced via `bind:duration` on <audio>.
|
||||
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({
|
||||
duration,
|
||||
@@ -560,13 +534,8 @@
|
||||
min="0"
|
||||
max={Math.max(0, duration)}
|
||||
step="0.1"
|
||||
value={Math.min(scrubValue, duration || 0)}
|
||||
bind:value={currentTime}
|
||||
disabled={!snap.currentTrack || duration <= 0}
|
||||
oninput={onScrubInput}
|
||||
onchange={onScrubCommit}
|
||||
onpointerup={onScrubCommit}
|
||||
ontouchend={onScrubCommit}
|
||||
onkeyup={onScrubCommit}
|
||||
/>
|
||||
</label>
|
||||
</div>
|
||||
@@ -819,13 +788,8 @@
|
||||
min="0"
|
||||
max={Math.max(0, duration)}
|
||||
step="0.1"
|
||||
value={Math.min(scrubValue, duration || 0)}
|
||||
bind:value={currentTime}
|
||||
disabled={!snap.currentTrack || duration <= 0}
|
||||
oninput={onScrubInput}
|
||||
onchange={onScrubCommit}
|
||||
onpointerup={onScrubCommit}
|
||||
ontouchend={onScrubCommit}
|
||||
onkeyup={onScrubCommit}
|
||||
/>
|
||||
</label>
|
||||
|
||||
@@ -971,6 +935,8 @@
|
||||
bind:this={audioEl}
|
||||
class="hidden"
|
||||
preload="metadata"
|
||||
bind:currentTime
|
||||
bind:duration
|
||||
onplay={onAudioPlay}
|
||||
onpause={onAudioPause}
|
||||
ontimeupdate={onAudioTimeUpdate}
|
||||
|
||||
Reference in New Issue
Block a user