From cf6e75b3126f5fed0ebfd3163136e65cdd34ae63 Mon Sep 17 00:00:00 2001 From: Honey Date: Fri, 19 Jun 2026 17:51:43 +0200 Subject: [PATCH] fix(backend): restore YTM Songs filter param for cleaner song search Re-add the ¶ms= Songs-shelf filter (the documented way to song-search YouTube Music) so results exclude videos/playlists/clips. Verified neutral for the ambiguous-artist case (yt-dlp's search can't surface that track regardless) but cleaner for normal tracks. Co-Authored-By: Claude Opus 4.8 --- backend/lib/ytdlp.js | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/backend/lib/ytdlp.js b/backend/lib/ytdlp.js index 9e63adf..f1289ca 100644 --- a/backend/lib/ytdlp.js +++ b/backend/lib/ytdlp.js @@ -193,12 +193,13 @@ async function downloadTrack({ jobId, artist, rawArtist, albumArtist, title, alb }); // Use original (raw) artist for YTM URL — better ranking since channel is in original language. - // NOTE: do NOT append the "Songs" filter param (¶ms=…). The explicit Songs-tab filter - // re-ranks results toward a same-named artist's full discography and drops the exact track. - // The default blended search (what the browser shows, even logged-out) ranks the official - // track first — which is what we want. + // Append the "Songs" filter param so results are restricted to YTM's Songs shelf + // (no videos/playlists/clips) — the documented way to song-search YTM. This is cleaner + // for normal tracks; for ambiguous artist names yt-dlp's search may still not surface the + // exact official track (a known extractor limitation — use the direct link in that case). + const YTM_SONGS_PARAM = 'EgWKAQIIAWoKEAkQBRAKEAMQBA%3D%3D'; const ytmQuery = `${rawArtist || mainArtist} ${searchTitle}${albumQuerySuffix}`; - const ytmUrl = `https://music.youtube.com/search?q=${encodeURIComponent(ytmQuery)}`; + const ytmUrl = `https://music.youtube.com/search?q=${encodeURIComponent(ytmQuery)}¶ms=${YTM_SONGS_PARAM}`; const expectedAudio = path.join(dir, `${fileBase}.${CONFIG.audioFmt}`); const hasAudio = () => fs.existsSync(expectedAudio);