Files
Melo/lib/library/song_media.dart
dustinandClaude Opus 5 4ebd0a8dd4 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
2026-08-20 18:41:36 +02:00

35 lines
1.1 KiB
Dart

import 'package:audio_service/audio_service.dart';
import '../player/audio_handler.dart';
import 'database.dart';
/// [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. [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(
[for (final s in songs) songToMediaItem(s, cover: coverOf?.call(s))],
startIndex: startIndex,
);
}