refactor: migrate audio metadata tagging from ts to rust

- Add id3 and metaflac crates for native audio tagging
- Create tagger.rs with separate tag_mp3() and tag_flac() functions
- Implement tag_audio_file Tauri command for unified tagging interface
- Support full metadata: title, artist, album, track#, ISRC, BPM, lyrics, cover art
- Create TypeScript wrapper (tagger.ts) for calling Rust backend
- Update downloader.ts to use Rust tagging for both MP3 and FLAC
- Remove browser-id3-writer dependency (no browser FLAC support)
- Inline lyrics parsing in addToQueue.ts (no longer needed in tagger)
This commit is contained in:
2025-10-02 11:39:56 -04:00
parent 36c0bc7dc7
commit 0d7361db4b
9 changed files with 492 additions and 215 deletions

View File

@@ -6,7 +6,7 @@ import { fetch } from '@tauri-apps/plugin-http';
import { writeFile, mkdir, remove, rename, exists } from '@tauri-apps/plugin-fs';
import { generateBlowfishKey, decryptChunk } from './crypto';
import { generateTrackPath } from './paths';
import { tagMP3 } from './tagger';
import { tagAudioFile } from './tagger';
import { downloadCover, saveCoverToAlbumFolder } from './imageDownload';
import { settings } from '$lib/stores/settings';
import { get } from 'svelte/store';
@@ -106,22 +106,9 @@ export async function downloadTrack(
}
}
// Apply tags (currently MP3 only)
let finalData = decryptedData;
if (format === 'MP3_320' || format === 'MP3_128') {
console.log('Tagging MP3 file...');
finalData = await tagMP3(
decryptedData,
track,
appSettings.embedCoverArt ? coverData : undefined,
appSettings.embedLyrics
);
}
// TODO: Add FLAC tagging when library is ready
// Write tagged file to temp
console.log('Writing tagged file to temp...');
await writeFile(paths.tempPath, finalData);
// Write untagged file to temp first
console.log('Writing untagged file to temp...');
await writeFile(paths.tempPath, decryptedData);
// Move to final location
const finalPath = `${paths.filepath}/${paths.filename}`;
@@ -135,6 +122,21 @@ export async function downloadTrack(
await rename(paths.tempPath, finalPath);
// Apply tags (works for both MP3 and FLAC)
console.log('Tagging audio file...');
try {
await tagAudioFile(
finalPath,
track,
appSettings.embedCoverArt ? coverData : undefined,
appSettings.embedLyrics
);
console.log('Tagging complete!');
} catch (error) {
console.error('Failed to tag audio file:', error);
// Non-fatal error - file is still downloaded, just not tagged
}
// Save LRC sidecar file if enabled
if (appSettings.saveLrcFile && track.lyrics?.sync) {
try {