From 86d399962861da24053e07e06b10dabb45b4b4b0 Mon Sep 17 00:00:00 2001 From: Honey Date: Fri, 19 Jun 2026 09:55:17 +0200 Subject: [PATCH] fix(download): pass Spotify durationMs through to yt-dlp duration filter - downloads.js: use durationMs (Spotify) before trackTimeMillis (iTunes) - server: read durationMs from top-level body, not only from tracks[0] - server: also grab durationMs + trackNum from iTunes in the Spotify path Without durationMs the duration filter never ran, allowing a 58s fan video to pass all text filters and be downloaded instead of the actual song. Co-Authored-By: Claude Sonnet 4.6 --- backend/novasonic-server.js | 4 +++- src/ui/downloads.js | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/backend/novasonic-server.js b/backend/novasonic-server.js index 80f3eed..ecf25dc 100644 --- a/backend/novasonic-server.js +++ b/backend/novasonic-server.js @@ -567,7 +567,7 @@ app.post('/api/download', async (req, res) => { discTotal: sp.discCount || bodyDiscTotal || undefined, genre: sp.primaryGenreName || sp.genre || undefined, artworkUrl: spArt, explicit: sp.trackExplicitness === 'explicit' || !!explicit, - durationMs: sp.durationMs || undefined, + durationMs: sp.durationMs || req.body.durationMs || undefined, }; const searchArtist = artist.split(',')[0].trim(); if (!meta.album) { @@ -584,6 +584,8 @@ app.post('/api/download', async (req, res) => { if (!meta.totalTracks && genreMeta.totalTracks) { meta.totalTracks = genreMeta.totalTracks; } if (!meta.discNum && genreMeta.discNum) { meta.discNum = genreMeta.discNum; } if (!meta.discTotal && genreMeta.discTotal) { meta.discTotal = genreMeta.discTotal; } + if (!meta.durationMs && genreMeta.durationMs) { meta.durationMs = genreMeta.durationMs; } + if (!meta.trackNum && genreMeta.trackNum) { meta.trackNum = genreMeta.trackNum; } } } const finalArtist = meta.itunesArtistName || artist; diff --git a/src/ui/downloads.js b/src/ui/downloads.js index 4f881f3..cd9aac5 100644 --- a/src/ui/downloads.js +++ b/src/ui/downloads.js @@ -42,7 +42,7 @@ export async function executeDownload() { totalTracks: S.downloadTarget.trackCount || undefined, discNum: S.downloadTarget.discNumber || undefined, discTotal: S.downloadTarget.discCount || undefined, - durationMs: S.downloadTarget.trackTimeMillis || undefined, + durationMs: S.downloadTarget.durationMs || S.downloadTarget.trackTimeMillis || undefined, ...(ov[_artist] && { artistSort: ov[_artist], albumArtistSort: ov[_artist] }), ...(ov[_title] && { titleSort: ov[_title] }), ...(ov[_album] && { albumSort: ov[_album] }),