v2.42 — Issue #7: ID3-Reader erweitern + Metadaten-Dialog verschönern
## ID3-Reader (lib/services/id3_reader.dart) - ID3v1: Jahr (Bytes 93-97) + Genre-Index (Byte 127, vollständige Genre-Liste 0-147) - ID3v2: Text-Frames TIT2 (Titel), TPE1 (Künstler), TALB (Album), TYER (Jahr), TCON (Genre), TRCK (Track) - ID3v2-Frames haben Vorrang vor ID3v1 (Füll-Logik) - UTF-16/UTF-8 Encoding-Unterstützung für Text-Frames - Genre-Bereinigung: Klammer-Präfixe entfernt, Track-Nummer extrahiert ## Song-Model (lib/models/song.dart) - Neue Felder: jahr, genre, track (nullable, optional) - Neue getter: dateiFormat (MP3/M4A/FLAC/WAV/OGG aus Dateiendung) - DB-Migration v5→v6: jahr, genre, track Spalten ## Metadaten-Dialog (lib/widgets/metadaten_dialog.dart) - Cover-Bild (128×128) mit rotem Glow-Rahmen oben falls vorhanden - Editable Felder mit Icons: Titel, Künstler, Album, Jahr, Genre - Read-Only-Info-Card: Dauer, Dateigröße, Format - Cards mit roten Akzenten + Melo-Design (schwarz/rot/dunkelgrau) - ID3-Fallback: Jahr/Genre aus Datei nachladen wenn nicht in DB - Speichern persistiert auch Jahr und Genre in die DB ## Musik-Scanner (lib/services/musik_scanner.dart) - jahr, genre, track aus ID3-Tags an Song-Model durchgereicht - _nichtLeer-Helfer für null-sichere String-Extraktion
This commit is contained in:
@@ -83,6 +83,9 @@ class MusikScanner {
|
||||
titel: (tags['titel'] as String).isNotEmpty ? tags['titel'] : _dateiNameOhneEndung(pfad),
|
||||
kuenstler: (tags['kuenstler'] as String).isNotEmpty ? tags['kuenstler'] : 'Unbekannt',
|
||||
album: tags['album'] ?? '',
|
||||
jahr: _nichtLeer(tags['jahr']),
|
||||
genre: _nichtLeer(tags['genre']),
|
||||
track: _nichtLeer(tags['track']),
|
||||
dauerSekunden: await _ermittleDauer(player, pfad),
|
||||
dateiPfad: pfad,
|
||||
coverPfad: coverPfad,
|
||||
@@ -207,6 +210,12 @@ class MusikScanner {
|
||||
return dot > 0 ? name.substring(0, dot) : name;
|
||||
}
|
||||
|
||||
String? _nichtLeer(dynamic wert) {
|
||||
if (wert == null) return null;
|
||||
final s = wert.toString().trim();
|
||||
return s.isEmpty ? null : s;
|
||||
}
|
||||
|
||||
/// Sucht YouTube-Quell-URLs für Songs ohne ytUrl (max 50 pro Scan, 1/s Rate-Limit)
|
||||
Future<void> _sucheYtUrls() async {
|
||||
const maxSuchanfragen = 50;
|
||||
|
||||
Reference in New Issue
Block a user