fix(wip): add fallback format support for unavailable tracks

Add support for selecting a fallback audio format if the requested
track format is unavailable. Users can now choose to fall back
to MP3_320, MP3_128, or the highest available format, or opt to fail
if the requested format is not found. The queue manager and downloader
now fetch fresh track data just-in-time, handle dz fallback
parameters, and ensure the correct track ID is used for decryption.
Settings UI and store are updated to allow configuring the fallback format.
This commit is contained in:
2025-10-03 10:28:56 -04:00
parent d74bf7e828
commit 90053b67c5
6 changed files with 220 additions and 33 deletions

View File

@@ -29,7 +29,8 @@ export async function downloadTrack(
musicFolder: string,
format: string,
onProgress?: ProgressCallback,
retryCount: number = 0
retryCount: number = 0,
decryptionTrackId?: string
): Promise<string> {
// Generate paths
const paths = generateTrackPath(track, musicFolder, format, false);
@@ -87,10 +88,13 @@ export async function downloadTrack(
if (isCrypted) {
console.log('Decrypting track using Rust...');
// Use the provided decryption track ID (for fallback tracks) or the original track ID
const trackIdForDecryption = decryptionTrackId || track.id.toString();
console.log(`Decrypting with track ID: ${trackIdForDecryption}`);
// Call Rust decryption function
const decrypted = await invoke<number[]>('decrypt_deezer_track', {
data: Array.from(encryptedData),
trackId: track.id.toString()
trackId: trackIdForDecryption
});
decryptedData = new Uint8Array(decrypted);
} else {
@@ -180,7 +184,7 @@ export async function downloadTrack(
const errorType = isTimeout ? 'timeout' : error.code;
console.log(`[DEBUG] Download ${errorType}, waiting 2s before retry (${retryCount + 1}/3)...`);
await new Promise(resolve => setTimeout(resolve, 2000));
return downloadTrack(track, downloadURL, musicFolder, format, onProgress, retryCount + 1);
return downloadTrack(track, downloadURL, musicFolder, format, onProgress, retryCount + 1, decryptionTrackId);
}
throw error;