mirror of
https://github.com/zarzet/SpotiFLAC-Mobile.git
synced 2026-09-30 13:19:44 +02:00
fix(download): align native metadata preparation and ReplayGain support
This commit is contained in:
1 parent
c0997de19c
commit
e61e54f93f
11 files changed
+288
-117
No files matched your search
@@ -44,6 +44,7 @@ import 'package:spotiflac_android/utils/progress_stream_poller.dart';
|
||||
|
||||
import 'package:spotiflac_android/providers/download_history_provider.dart';
|
||||
import 'package:spotiflac_android/services/native_download_history.dart';
|
||||
import 'package:spotiflac_android/services/download_track_metadata.dart';
|
||||
|
||||
export 'package:spotiflac_android/providers/download_history_provider.dart';
|
||||
export 'package:spotiflac_android/providers/download_queue_state.dart';
|
||||
|
||||
@@ -22,6 +22,13 @@ class _DeezerExtendedMetadataFields {
|
||||
}
|
||||
|
||||
extension _DownloadQueueEmbedding on DownloadQueueNotifier {
|
||||
Future<Track> _prepareDownloadSourceTrack(Track track) async {
|
||||
if (!track.id.startsWith('deezer:')) return track;
|
||||
final id = track.id.substring('deezer:'.length);
|
||||
final enriched = await enrichIncompleteDownloadTrack(track, 'deezer', id);
|
||||
return identical(enriched, track) ? track : enriched.copyWith(deezerId: id);
|
||||
}
|
||||
|
||||
Future<Track> _resolveDownloadAlbumCredit(
|
||||
Track track,
|
||||
AppSettings settings,
|
||||
|
||||
@@ -877,8 +877,9 @@ extension _DownloadQueueNativeWorker on DownloadQueueNotifier {
|
||||
return null;
|
||||
}
|
||||
|
||||
final sourceTrack = await _prepareDownloadSourceTrack(item.track);
|
||||
item = item.copyWith(
|
||||
track: await _resolveDownloadAlbumCredit(item.track, settings),
|
||||
track: await _resolveDownloadAlbumCredit(sourceTrack, settings),
|
||||
);
|
||||
|
||||
final isSafMode = _isSafMode(settings);
|
||||
@@ -915,12 +916,6 @@ extension _DownloadQueueNativeWorker on DownloadQueueNotifier {
|
||||
}
|
||||
|
||||
final outputExt = _determineOutputExt(quality, item.service);
|
||||
if (settings.embedReplayGain &&
|
||||
outputExt != '.flac' &&
|
||||
outputExt != '.m4a') {
|
||||
return null;
|
||||
}
|
||||
|
||||
String? safFileName;
|
||||
final safOutputExt = isSafMode ? outputExt : '';
|
||||
final baseFilenameFormat = _shouldTreatAsSingleRelease(item.track)
|
||||
@@ -992,7 +987,7 @@ extension _DownloadQueueNativeWorker on DownloadQueueNotifier {
|
||||
).withStrategy(useExtensions: true, useFallback: state.autoFallback);
|
||||
|
||||
return _NativeWorkerRequestContext(
|
||||
item: item,
|
||||
item: item.copyWith(track: trackForPayload),
|
||||
requestJson: jsonEncode(payload.toJson()),
|
||||
outputDir: outputDir,
|
||||
quality: quality,
|
||||
|
||||
@@ -307,107 +307,8 @@ class _DownloadRun {
|
||||
}
|
||||
|
||||
Future<bool> _enrichDeezerTrackIfNeeded() async {
|
||||
final needsEnrichment =
|
||||
trackToDownload.id.startsWith('deezer:') &&
|
||||
(trackToDownload.isrc == null ||
|
||||
trackToDownload.isrc!.isEmpty ||
|
||||
trackToDownload.trackNumber == null ||
|
||||
trackToDownload.trackNumber == 0 ||
|
||||
trackToDownload.totalTracks == null ||
|
||||
trackToDownload.totalTracks == 0 ||
|
||||
(trackToDownload.composer == null ||
|
||||
trackToDownload.composer!.isEmpty));
|
||||
|
||||
if (needsEnrichment) {
|
||||
try {
|
||||
_log.d(
|
||||
'Enriching incomplete metadata for Deezer track: ${trackToDownload.name}',
|
||||
);
|
||||
_log.d(
|
||||
'Current ISRC: ${trackToDownload.isrc}, TrackNumber: ${trackToDownload.trackNumber}',
|
||||
);
|
||||
final rawId = trackToDownload.id.split(':')[1];
|
||||
_log.d('Fetching full metadata for Deezer ID: $rawId');
|
||||
final fullData = await PlatformBridge.getProviderMetadata(
|
||||
'deezer',
|
||||
'track',
|
||||
rawId,
|
||||
);
|
||||
_log.d('Got response keys: ${fullData.keys.toList()}');
|
||||
|
||||
if (fullData.containsKey('track')) {
|
||||
final trackData = fullData['track'];
|
||||
_log.d('Track data type: ${trackData.runtimeType}');
|
||||
if (trackData is Map<String, dynamic>) {
|
||||
final data = trackData;
|
||||
_log.d('Track data keys: ${data.keys.toList()}');
|
||||
_log.d('ISRC from API: ${data['isrc']}');
|
||||
_log.d('album_type from API: ${data['album_type']}');
|
||||
final enrichedTotalTracks = readPositiveInt(data['total_tracks']);
|
||||
final enrichedTotalDiscs = readPositiveInt(data['total_discs']);
|
||||
final enrichedComposer = normalizeOptionalString(
|
||||
data['composer']?.toString(),
|
||||
);
|
||||
trackToDownload = trackToDownload.copyWith(
|
||||
id: (data['spotify_id'] as String?) ?? trackToDownload.id,
|
||||
name: (data['name'] as String?) ?? trackToDownload.name,
|
||||
artistName:
|
||||
(data['artists'] as String?) ?? trackToDownload.artistName,
|
||||
albumName:
|
||||
(data['album_name'] as String?) ?? trackToDownload.albumName,
|
||||
albumArtist: data['album_artist'] as String?,
|
||||
artistId:
|
||||
(data['artist_id'] ?? data['artistId'])?.toString() ??
|
||||
trackToDownload.artistId,
|
||||
albumId: data['album_id']?.toString() ?? trackToDownload.albumId,
|
||||
coverUrl: data['images'] as String?,
|
||||
duration:
|
||||
((data['duration_ms'] as int?) ??
|
||||
(trackToDownload.duration * 1000)) ~/
|
||||
1000,
|
||||
isrc: (data['isrc'] as String?) ?? trackToDownload.isrc,
|
||||
trackNumber: data['track_number'] as int?,
|
||||
discNumber: data['disc_number'] as int?,
|
||||
totalDiscs: enrichedTotalDiscs ?? trackToDownload.totalDiscs,
|
||||
releaseDate: data['release_date'] as String?,
|
||||
deezerId: rawId,
|
||||
albumType:
|
||||
(data['album_type'] as String?) ?? trackToDownload.albumType,
|
||||
totalTracks: enrichedTotalTracks ?? trackToDownload.totalTracks,
|
||||
composer: enrichedComposer ?? trackToDownload.composer,
|
||||
genre: data['genre']?.toString() ?? trackToDownload.genre,
|
||||
label: data['label']?.toString() ?? trackToDownload.label,
|
||||
copyright:
|
||||
data['copyright']?.toString() ?? trackToDownload.copyright,
|
||||
comment: data['comment']?.toString() ?? trackToDownload.comment,
|
||||
explicit:
|
||||
parseExplicitFlag(data['explicit']) ??
|
||||
trackToDownload.explicit,
|
||||
upc:
|
||||
(data['upc'] ?? data['barcode'])?.toString() ??
|
||||
trackToDownload.upc,
|
||||
);
|
||||
_log.d(
|
||||
'Metadata enriched: Track ${trackToDownload.trackNumber}, Disc ${trackToDownload.discNumber}, ISRC ${trackToDownload.isrc}, AlbumType ${trackToDownload.albumType}',
|
||||
);
|
||||
} else {
|
||||
_log.w('Unexpected track data type: ${trackData.runtimeType}');
|
||||
}
|
||||
} else {
|
||||
_log.w('Response does not contain track key');
|
||||
}
|
||||
} catch (e, stack) {
|
||||
_log.w('Failed to enrich metadata: $e');
|
||||
_log.w('Stack trace: $stack');
|
||||
}
|
||||
|
||||
if (await _shouldAbort('during metadata enrichment')) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
_log.d('Track coverUrl after enrichment: ${trackToDownload.coverUrl}');
|
||||
return true;
|
||||
trackToDownload = await n._prepareDownloadSourceTrack(trackToDownload);
|
||||
return !await _shouldAbort('during metadata enrichment');
|
||||
}
|
||||
|
||||
Future<void> _resolveOutputTarget() async {
|
||||
|
||||
Reference in new issue
Block a user