fix(downloads): handle MP3_320 format in bulk downloads

This commit is contained in:
Daniel 2026-02-27 20:27:31 +00:00 committed by GitHub
parent 4aaffd2c22
commit 353ced831b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -15,6 +15,7 @@ import { lyricsSettings, bulkDownloadSettings, playlistSettings } from './storag
import { addMetadataToAudio } from './metadata.js'; import { addMetadataToAudio } from './metadata.js';
import { DashDownloader } from './dash-downloader.js'; import { DashDownloader } from './dash-downloader.js';
import { generateM3U, generateM3U8, generateCUE, generateNFO, generateJSON } from './playlist-generator.js'; import { generateM3U, generateM3U8, generateCUE, generateNFO, generateJSON } from './playlist-generator.js';
import { encodeToMp3 } from './mp3-encoder.js';
const downloadTasks = new Map(); const downloadTasks = new Map();
const bulkDownloadTasks = new Map(); const bulkDownloadTasks = new Map();
@ -272,6 +273,9 @@ async function downloadTrackBlob(track, quality, api, lyricsManager = null, sign
artist: track.artist || (track.artists && track.artists.length > 0 ? track.artists[0] : null), artist: track.artist || (track.artists && track.artists.length > 0 ? track.artists[0] : null),
}; };
// MP3_320 is not a native TIDAL quality, we download LOSSLESS and convert
const downloadQuality = quality === 'MP3_320' ? 'LOSSLESS' : quality;
try { try {
const fullTrack = await api.getTrackMetadata(track.id); const fullTrack = await api.getTrackMetadata(track.id);
if (fullTrack) { if (fullTrack) {
@ -306,7 +310,7 @@ async function downloadTrackBlob(track, quality, api, lyricsManager = null, sign
} }
} }
const lookup = await api.getTrack(track.id, quality); const lookup = await api.getTrack(track.id, downloadQuality);
let streamUrl; let streamUrl;
if (lookup.originalTrackUrl) { if (lookup.originalTrackUrl) {
@ -327,7 +331,7 @@ async function downloadTrackBlob(track, quality, api, lyricsManager = null, sign
} catch (dashError) { } catch (dashError) {
console.error('DASH download failed:', dashError); console.error('DASH download failed:', dashError);
// Fallback // Fallback
if (quality !== 'LOSSLESS') { if (downloadQuality !== 'LOSSLESS') {
console.warn('Falling back to LOSSLESS (16-bit) download.'); console.warn('Falling back to LOSSLESS (16-bit) download.');
return downloadTrackBlob(track, 'LOSSLESS', api, lyricsManager, signal); return downloadTrackBlob(track, 'LOSSLESS', api, lyricsManager, signal);
} }
@ -341,6 +345,11 @@ async function downloadTrackBlob(track, quality, api, lyricsManager = null, sign
blob = await response.blob(); blob = await response.blob();
} }
// Convert to MP3 320kbps if requested
if (quality === 'MP3_320') {
blob = await encodeToMp3(blob, () => undefined, signal);
}
// Detect actual format from blob signature BEFORE adding metadata // Detect actual format from blob signature BEFORE adding metadata
const extension = await getExtensionFromBlob(blob); const extension = await getExtensionFromBlob(blob);