mirror of
https://github.com/zarzet/SpotiFLAC-Mobile.git
synced 2026-09-30 13:19:44 +02:00
feat: add M4A metadata/cover embed support across all Flutter screens
Add FFmpegService.embedMetadataToM4a() for writing tags and cover art into M4A files via FFmpeg. Fix two bugs in the same function: - Remove '-disposition:v:0 attached_pic' which is only valid for Matroska/WebM containers and causes FFmpeg to error on MP4/M4A - Apply same fix to _convertToAlac which had the identical issue Add M4A handling (isM4A branch) to all four embed call-sites: track_metadata_screen (lyrics embed, re-enrich, edit metadata sheet, format conversion), queue_tab, local_album_screen, and downloaded_album_screen. Add 'LYRICS'/'UNSYNCEDLYRICS' to _mapMetadataForTagEmbed so existing lyrics survive a re-enrich cycle on M4A/MP3/Opus files. Preserve existing lyrics before overwriting tags in the edit metadata sheet (best-effort readFileMetadata before FFmpeg pass). Extract mergePlatformMetadataForTagEmbed() into lyrics_metadata_helper to deduplicate the identical metadata-mapping loops that existed in queue_tab, local_album_screen, downloaded_album_screen, and track_metadata_screen. Wire ensureLyricsMetadataForConversion into the format conversion path in track_metadata_screen so lyrics are carried through conversions. Add ISRC and LABEL/ORGANIZATION mappings to _convertToM4aTags.
This commit is contained in:
1 parent
4cf885a52e
commit
12be560cb8
6 files changed
+235
-54
No files matched your search
@@ -4400,6 +4400,11 @@ class _QueueTabState extends ConsumerState<QueueTab> {
|
||||
final format = item.format?.toLowerCase();
|
||||
final lowerPath = item.filePath.toLowerCase();
|
||||
final isMp3 = format == 'mp3' || lowerPath.endsWith('.mp3');
|
||||
final isM4A =
|
||||
format == 'm4a' ||
|
||||
format == 'aac' ||
|
||||
lowerPath.endsWith('.m4a') ||
|
||||
lowerPath.endsWith('.aac');
|
||||
final isOpus =
|
||||
format == 'opus' ||
|
||||
format == 'ogg' ||
|
||||
@@ -4413,6 +4418,12 @@ class _QueueTabState extends ConsumerState<QueueTab> {
|
||||
coverPath: effectiveCoverPath,
|
||||
metadata: metadata,
|
||||
);
|
||||
} else if (isM4A) {
|
||||
ffmpegResult = await FFmpegService.embedMetadataToM4a(
|
||||
m4aPath: ffmpegTarget,
|
||||
coverPath: effectiveCoverPath,
|
||||
metadata: metadata,
|
||||
);
|
||||
} else if (isOpus) {
|
||||
ffmpegResult = await FFmpegService.embedMetadataToOpus(
|
||||
opusPath: ffmpegTarget,
|
||||
@@ -5090,12 +5101,7 @@ class _QueueTabState extends ConsumerState<QueueTab> {
|
||||
try {
|
||||
final result = await PlatformBridge.readFileMetadata(item.filePath);
|
||||
if (result['error'] == null) {
|
||||
result.forEach((key, value) {
|
||||
if (key == 'error' || value == null) return;
|
||||
final v = value.toString().trim();
|
||||
if (v.isEmpty) return;
|
||||
metadata[key.toUpperCase()] = v;
|
||||
});
|
||||
mergePlatformMetadataForTagEmbed(target: metadata, source: result);
|
||||
}
|
||||
} catch (_) {}
|
||||
await ensureLyricsMetadataForConversion(
|
||||
@@ -5473,7 +5479,8 @@ class _QueueTabState extends ConsumerState<QueueTab> {
|
||||
icon: Icons.download_for_offline_outlined,
|
||||
label:
|
||||
'${context.l10n.queueFlacAction} ($flacEligibleCount)',
|
||||
onPressed: () => _queueSelectedLocalAsFlac(unifiedItems),
|
||||
onPressed: () =>
|
||||
_queueSelectedLocalAsFlac(unifiedItems),
|
||||
colorScheme: colorScheme,
|
||||
),
|
||||
),
|
||||
|
||||
Reference in new issue
Block a user