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:
@@ -20,7 +20,7 @@ class DbHelper {
|
||||
final pfad = await getDatabasesPath();
|
||||
return openDatabase(
|
||||
p.join(pfad, 'melo.db'),
|
||||
version: 5,
|
||||
version: 6,
|
||||
onCreate: (db, version) async {
|
||||
await db.execute('''
|
||||
CREATE TABLE songs (
|
||||
@@ -38,7 +38,10 @@ class DbHelper {
|
||||
download_quelle TEXT DEFAULT 'local',
|
||||
stream_url TEXT,
|
||||
yt_url TEXT,
|
||||
zuletzt_position INTEGER
|
||||
zuletzt_position INTEGER,
|
||||
jahr TEXT,
|
||||
genre TEXT,
|
||||
track TEXT
|
||||
)
|
||||
''');
|
||||
await db.execute('''
|
||||
@@ -134,6 +137,11 @@ class DbHelper {
|
||||
''');
|
||||
} catch (_) {}
|
||||
}
|
||||
if (oldVersion < 6) {
|
||||
try { await db.execute('ALTER TABLE songs ADD COLUMN jahr TEXT'); } catch (_) {}
|
||||
try { await db.execute('ALTER TABLE songs ADD COLUMN genre TEXT'); } catch (_) {}
|
||||
try { await db.execute('ALTER TABLE songs ADD COLUMN track TEXT'); } catch (_) {}
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
@@ -361,12 +369,14 @@ class DbHelper {
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> metadatenAktualisieren(int songId, {String? titel, String? kuenstler, String? album}) async {
|
||||
Future<void> metadatenAktualisieren(int songId, {String? titel, String? kuenstler, String? album, String? jahr, String? genre}) async {
|
||||
final d = await db;
|
||||
final update = <String, dynamic>{};
|
||||
if (titel != null) update['titel'] = titel;
|
||||
if (kuenstler != null) update['kuenstler'] = kuenstler;
|
||||
if (album != null) update['album'] = album;
|
||||
if (jahr != null) update['jahr'] = jahr;
|
||||
if (genre != null) update['genre'] = genre;
|
||||
if (update.isNotEmpty) {
|
||||
await d.update('songs', update, where: 'id = ?', whereArgs: [songId]);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user