📊 Feature: History-Sync vom Navidrome-Server (Phase 2, Part 5/X)
- Neue NavidromeService APIs: scrobble() + getBookmark() - Lädt Wiedergabe-Position vom Server beim Song-Start (Subsonic-API) - Sendet Position alle 5s zum Server wenn verbunden - Priorisiert Server-Position über lokale Position - Full Sync: lokal speichern + Server synchen parallel Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XJzQjUtnvYUtHdnTs3iCru
This commit is contained in:
co-authored by
Claude Haiku 4.5
parent
5202b130c5
commit
f93b2d35da
@@ -38,10 +38,15 @@ class MeloAudioHandler extends BaseAudioHandler with QueueHandler, SeekHandler {
|
||||
_player.playbackEventStream.map(_transformEvent).pipe(playbackState);
|
||||
|
||||
// Wiedergabeposition alle ~5s persistieren, solange aktiv abgespielt wird.
|
||||
// Synche auch zum Server wenn verbunden.
|
||||
_positionRecordTimer = Timer.periodic(const Duration(seconds: 5), (_) {
|
||||
final songId = mediaItem.value?.extras?['songId'] as String?;
|
||||
if (_player.playing && songId != null) {
|
||||
db.recordPlayback(songId, _player.position.inMilliseconds);
|
||||
final posMs = _player.position.inMilliseconds;
|
||||
db.recordPlayback(songId, posMs);
|
||||
if (_nav.istVerbunden) {
|
||||
_nav.scrobble(songId, (posMs ~/ 1000).toInt());
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -86,12 +91,28 @@ class MeloAudioHandler extends BaseAudioHandler with QueueHandler, SeekHandler {
|
||||
await _player.setAudioSources(sources, initialIndex: startIndex);
|
||||
|
||||
// Bei bekannter letzter Position an dieser Stelle fortsetzen,
|
||||
// statt immer von vorne zu beginnen.
|
||||
final songId = items[startIndex].extras?['songId'] as String?;
|
||||
// statt immer von vorne zu beginnen. Priorisiert Server-Position über lokal.
|
||||
final item = items[startIndex];
|
||||
final songId = item.extras?['songId'] as String?;
|
||||
if (songId != null) {
|
||||
final lastMs = await db.lastPosition(songId);
|
||||
if (lastMs != null && shouldResumeAt(lastMs, items[startIndex].duration)) {
|
||||
await _player.seek(Duration(milliseconds: lastMs), index: startIndex);
|
||||
int? resumeMs;
|
||||
|
||||
if (_nav.istVerbunden) {
|
||||
final serverMs = await _nav.getBookmark(songId);
|
||||
if (serverMs != null && shouldResumeAt(serverMs, item.duration)) {
|
||||
resumeMs = serverMs;
|
||||
}
|
||||
}
|
||||
|
||||
if (resumeMs == null) {
|
||||
final localMs = await db.lastPosition(songId);
|
||||
if (localMs != null && shouldResumeAt(localMs, item.duration)) {
|
||||
resumeMs = localMs;
|
||||
}
|
||||
}
|
||||
|
||||
if (resumeMs != null) {
|
||||
await _player.seek(Duration(milliseconds: resumeMs), index: startIndex);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user