feat(web+android): Wiedergabe fortsetzen und Streitpunkte im Duell (2.4)

Wiedergabe fortsetzen:
Im Web ueberlebten Warteschlange und letzter Titel bereits, die POSITION im
Titel aber nicht — beim Neuladen begann der Song von vorn. Android sicherte nur
den letzten Song ohne Warteschlange. Beide merken sich jetzt Warteschlange,
Listenposition und Sekunde.

Web schreibt gedrosselt (alle 5 s) waehrend der Wiedergabe und sicher beim
Pausieren, Wegwischen und Tabwechsel — pagehide/visibilitychange statt
beforeunload, das am Handy unzuverlaessig feuert. Android sichert bei jedem
Titelwechsel und beim Pausieren und stellt nach dem Verbinden wieder her:
vorbereitet, aber NICHT abgespielt, wer die App oeffnet will nicht ueberfallen
werden. Laeuft schon etwas (Android Auto), passiert nichts.

Zwei Feinheiten: lag die Position im letzten Rest des Titels, faengt er von vorn
an, statt zwei Sekunden Abspann zu spielen; und gespeichert werden nur Song-Ids,
weil Titel und Cover sich durch Metadaten-Bearbeitung aendern koennen —
verschwundene Titel werden beim Wiederherstellen uebersprungen.

Streitpunkte im Duell:
Gemeinsame Kuenstler nach groesstem Ungleichgewicht statt nach Summe, mit
Kraefteverhaeltnis-Balken. Mindestens vier gemeinsame Plays und 50 % Unwucht,
sonst gilt ein einzelner Play gegen null schon als Streit. Web und Android mit
identischen Schwellen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
marcandClaude Opus 5 committed 2026-09-06 23:20:40 +02:00
1 parent 92c3d96936
commit 65fa950043
8 files changed
+217 -2

No files matched your search

+6 -1
View File
@@ -13,7 +13,7 @@ import {
toggleShuffle, toggleRepeat, toggleQueue, setVolume, seekTo,
initProgressScrub, updateProgress, updatePreviewProgress, stopPreview,
toggleRadioMode, starCurrent, downloadCurrent, renderQueue, playPreview,
toggleStar, dlSongLocal, _applyRadioBtn, _applyShuffleRepeat, _restoreLastPlayed, setPlayIcon,
toggleStar, dlSongLocal, _applyRadioBtn, _applyShuffleRepeat, _restoreLastPlayed, persistPosition, setPlayIcon,
npToggleStar, updateMediaSession, updateNpColorMode, reconcileNativeState, initKeyboardShortcuts,
} from './player/player.js';
import {
@@ -158,6 +158,9 @@ window.addEventListener('load', () => {
let _errRetries = 0, _errTimer = null;
function bindAudioEl(el) {
el.addEventListener('timeupdate', updateProgress);
// Position mitschreiben (gedrosselt), damit ein Neuladen dort weitermacht, wo du warst.
el.addEventListener('timeupdate', () => persistPosition());
el.addEventListener('pause', () => persistPosition(true));
el.addEventListener('ended', onEnded);
el.addEventListener('play', () => {
S._trackChanging = false;
@@ -315,6 +318,8 @@ window.addEventListener('load', () => {
}
});
window.addEventListener('pagehide', () => persistPosition(true));
document.addEventListener('visibilitychange', () => { if (document.hidden) persistPosition(true); });
window.addEventListener('popstate', (e) => _navOnPopState(e.state));
document.addEventListener('keydown', e => {
if(e.key !== 'Backspace') return;