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:
@@ -6,6 +6,7 @@ import 'package:path/path.dart' as p;
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
import 'package:uuid/uuid.dart';
|
||||
|
||||
import '../player/replay_gain.dart';
|
||||
import 'categories.dart';
|
||||
import 'database.dart';
|
||||
|
||||
@@ -64,6 +65,11 @@ Future<int> scanFolders(
|
||||
// Unlesbare/kaputte Tags: Datei trotzdem mit Dateinamen aufnehmen.
|
||||
}
|
||||
|
||||
// ReplayGain steht je nach Format an unterschiedlicher Stelle und ist im
|
||||
// vereinheitlichten AudioMetadata nicht enthalten — daher der zweite,
|
||||
// gezielte Blick in die Roh-Tags.
|
||||
final gainDb = _readGain(file);
|
||||
|
||||
final rawTitle = meta?.title?.trim();
|
||||
final title = (rawTitle != null && rawTitle.isNotEmpty)
|
||||
? rawTitle
|
||||
@@ -92,6 +98,8 @@ Future<int> scanFolders(
|
||||
dateAddedMs: prev?.dateAddedMs ?? now,
|
||||
updatedAtMs: now,
|
||||
deleted: const Value(false),
|
||||
lyrics: Value(meta?.lyrics),
|
||||
gainDb: Value(gainDb),
|
||||
));
|
||||
if (prev?.categoriesEdited != true) {
|
||||
categories[id] = parseCategoryList(meta?.genres ?? const []);
|
||||
@@ -111,3 +119,25 @@ Future<int> scanFolders(
|
||||
}
|
||||
return companions.length;
|
||||
}
|
||||
|
||||
/// Liest den ReplayGain-Wert des Titels aus den Roh-Tags: bei FLAC/OGG aus
|
||||
/// dem Vorbis-Kommentar, bei MP3 aus einem TXXX-Feld. Fehlt der Tag oder
|
||||
/// lässt sich die Datei nicht lesen, gibt es keine Angleichung.
|
||||
double? _readGain(File file) {
|
||||
try {
|
||||
final tags = readAllMetadata(file, getImage: false);
|
||||
if (tags is VorbisMetadata) {
|
||||
return parseReplayGain(tags.replayGainTrackGain.firstOrNull);
|
||||
}
|
||||
if (tags is Mp3Metadata) {
|
||||
for (final entry in tags.customMetadata.entries) {
|
||||
if (entry.key.toLowerCase() == 'replaygain_track_gain') {
|
||||
return parseReplayGain(entry.value);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (_) {
|
||||
// Kein ReplayGain ist kein Fehler — dann bleibt die Lautstärke wie sie ist.
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user