fix(backend): remove album suffix from YTM search query
Album words ("KAGUYA Music", "OST" etc.) appended to the search query
caused wrong or no results — "Kei Haneoka 確信 KAGUYA Music" would miss
tracks the plain "Kei Haneoka 確信" query finds immediately.
Artist + cleanTitle is sufficient for both JP and Western tracks.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
1 parent
fa4c954ab9
commit
d5b088a658
1 file changed
+2
-18
+2
-18
@@ -127,26 +127,10 @@ async function downloadTrack({ jobId, artist, rawArtist, albumArtist, title, alb
|
||||
const artistChannelPart = (artistFirstWord.length >= 3 && !JP_RE.test(artistFirstWord))
|
||||
? ` & channel ~= (?i)${escRe(artistFirstWord)}` : '';
|
||||
|
||||
// When the title is Japanese (keywords stripped to nothing) OR when we have an album that
|
||||
// provides better search context, include the album's first two words in the search query.
|
||||
// This helps YTM rank the official OST/album track above fan covers and romaji-subtitle uploads.
|
||||
// Only use album words that are ASCII (romaji/English) — Japanese album words don't help YTM ranking.
|
||||
const hasJpTitle = JP_RE.test(title);
|
||||
const GENERIC_ALBUM_WORDS = new Set(['single', 'ep', 'album', 'soundtrack', 'ost', 'edition', 'remaster', 'remastered', 'deluxe', 'bonus', 'version', 'live']);
|
||||
const titleWordSet = new Set(title.toLowerCase().split(/\s+/));
|
||||
const albumWords = (album && album !== 'Singles' && album !== 'Unknown')
|
||||
? album.split(/\s+/)
|
||||
.filter(w => /^[A-Za-z0-9]/.test(w) && !titleWordSet.has(w.toLowerCase()) && !GENERIC_ALBUM_WORDS.has(w.toLowerCase()))
|
||||
.slice(0, 2).join(' ')
|
||||
: '';
|
||||
// Only append album words for Japanese titles where title keywords are stripped to nothing.
|
||||
// For Western tracks, artist + title + duration matching is sufficient (matches spotdl behaviour).
|
||||
const albumQuerySuffix = hasJpTitle && albumWords ? ' ' + albumWords : '';
|
||||
|
||||
// Use a space (not " - ") between artist and title: this matches how users type
|
||||
// in the YTM search box and ranks the exact official track first. A dash skews
|
||||
// YTM ranking toward a same-named artist's full discography.
|
||||
const query = `${ytmArtist} ${searchTitle}${albumQuerySuffix}`;
|
||||
const query = `${ytmArtist} ${searchTitle}`;
|
||||
|
||||
const baseArgs = [
|
||||
'--extract-audio',
|
||||
@@ -195,7 +179,7 @@ async function downloadTrack({ jobId, artist, rawArtist, albumArtist, title, alb
|
||||
// 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 ytmQuery = `${rawArtist || mainArtist} ${searchTitle}`;
|
||||
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);
|
||||
|
||||
Reference in new issue
Block a user