Songtext aus Datei-Tags, Warteschlangen-Aktionen, Kategorie-Cover im

Sperrbildschirm und ReplayGain

- DB-Schema 6: lyrics + gain_db
- Songtext bevorzugt lokalen Tag, Server nur als Rueckfall; Song-ID-Bug
  beim Lyrics-Aufruf behoben
- "Als Naechstes spielen" / "Zur Warteschlange hinzufuegen" ohne Eingriff
  in Favoriten oder Wiedergabelisten
- songToMediaItem nimmt eine Cover-Vorgabe: Sperrbildschirm zeigt das
  Kategorie-Cover
- ReplayGain: Tags werden gelesen, laute Titel abgesenkt, abschaltbar

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011snPXPafPC5i87o68H14W7
This commit is contained in:
2026-08-20 18:41:36 +02:00
co-authored by Claude Opus 5
parent 1325badf90
commit 4ebd0a8dd4
17 changed files with 534 additions and 46 deletions
+24 -12
View File
@@ -3,20 +3,32 @@ import 'package:audio_service/audio_service.dart';
import '../player/audio_handler.dart';
import 'database.dart';
MediaItem songToMediaItem(Song s) => MediaItem(
id: Uri.file(s.path).toString(),
title: s.title,
artist: s.artist,
album: s.album,
duration: s.durationMs != null ? Duration(milliseconds: s.durationMs!) : null,
artUri: s.coverPath != null ? Uri.file(s.coverPath!) : null,
extras: {'songId': s.id},
);
/// [cover] überschreibt das Coverbild des Songs — damit auf Sperrbildschirm
/// und in der Benachrichtigung dasselbe Bild erscheint wie in der App
/// (Einstellung "Gleiche Kategorie = gleiches Coverbild").
MediaItem songToMediaItem(Song s, {String? cover}) {
final art = cover ?? s.coverPath;
return MediaItem(
id: Uri.file(s.path).toString(),
title: s.title,
artist: s.artist,
album: s.album,
duration: s.durationMs != null ? Duration(milliseconds: s.durationMs!) : null,
artUri: art != null ? Uri.file(art) : null,
extras: {'songId': s.id, 'gainDb': s.gainDb},
);
}
/// Spielt [songs] ab [startIndex] ab.
Future<void> playSongs(MeloAudioHandler handler, List<Song> songs, int startIndex) {
/// Spielt [songs] ab [startIndex] ab. [coverOf] liefert je Song das
/// anzuzeigende Cover (siehe [songToMediaItem]).
Future<void> playSongs(
MeloAudioHandler handler,
List<Song> songs,
int startIndex, {
String? Function(Song)? coverOf,
}) {
return handler.loadPlaylist(
songs.map(songToMediaItem).toList(),
[for (final s in songs) songToMediaItem(s, cover: coverOf?.call(s))],
startIndex: startIndex,
);
}