Mobile remote: per-track trim (in/out) + waveform + times + scrub/seek + gap

- Queue cards expand to a detail panel with the waveform, elapsed/total/remaining
  times, draggable in/out handles, scrub-to-seek and a 'pausa dopo' gap.
- /api/peaks now also returns exact duration (samples/8000) so non-playing tracks
  have correct times/trim without relying on the output media probe.
- Service worker switched to network-first (+v2) so UI updates aren't masked by
  a stale cache; output.js probeDurations hardened (load()+timeout fallback).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
lucianoandClaude Opus 4.8 committed 2026-06-29 14:37:43 +02:00
1 parent f3f4d0f81e
commit c0230ee1d6
5 files changed
+167 -19

No files matched your search

+7 -3
View File
@@ -287,10 +287,14 @@ function probeDurations(paths) {
paths.forEach(p => {
// A <video> element reads duration for both audio and video files.
const a = document.createElement('video');
a.preload = 'metadata';
a.onloadedmetadata = () => { results.push({ path: p, duration: isFinite(a.duration) ? a.duration : 0 }); finish(); };
a.onerror = () => { results.push({ path: p, duration: 0 }); finish(); };
a.preload = 'metadata'; a.muted = true;
let done = false;
const ok = (dur) => { if (done) return; done = true; results.push({ path: p, duration: isFinite(dur) && dur > 0 ? dur : 0 }); finish(); };
a.onloadedmetadata = () => ok(a.duration);
a.onerror = () => ok(0);
setTimeout(() => ok(0), 6000); // never hang if metadata never fires
a.src = toFileURL(p);
a.load(); // some Chromium builds need an explicit load() for detached media
});
}