mirror of
https://github.com/th-ch/youtube-music.git
synced 2026-01-13 19:31:46 +00:00
feat(synced-lyrics): romanization (#2790)
* feat(synced-lyrics): init romanization! * remove debug logs and add TODO * feat(synced-lyrics/romanization): Mandarin! * feat(synced-lyrics/romanization): improve japanese detection * feat(synced-lyrics/romanization): Korean! * qol(synced-lyrics/romanization): canonicalize punctuation and symbols * feat(synced-lyrics/romanization): handle japanese+korean and korean+chinese lyrics * revert formatting on electron.vite.config.mts * feat(synced-lyrics/romanization): romanize plain lyrics * apply fix by @kimjammer * fix lockfile due to rebase * feat(synced-lyrics): improve lyric processing and formatting; * feat(synced-lyrics/romanization): add option to enable/disable romanization * chore: move default value for --lyrics-duration to the declaration * update lockfile * fix: improvement 1. improved language detection logic 2. changed code to work in the renderer process * fix: fix regression (canonicalize) --------- Co-authored-by: JellyBrick <shlee1503@naver.com>
This commit is contained in:
@ -30,15 +30,16 @@ export class LyricsGenius implements LyricProvider {
|
||||
title: titleA,
|
||||
primary_artist: { name: artistA },
|
||||
},
|
||||
},
|
||||
{
|
||||
}, {
|
||||
result: {
|
||||
title: titleB,
|
||||
primary_artist: { name: artistB },
|
||||
},
|
||||
}) => {
|
||||
const pointsA = (titleA === title ? 1 : 0) + (artistA.includes(artist) ? 1 : 0);
|
||||
const pointsB = (titleB === title ? 1 : 0) + (artistB.includes(artist) ? 1 : 0);
|
||||
const pointsA = (titleA === title ? 1 : 0) +
|
||||
(artistA.includes(artist) ? 1 : 0);
|
||||
const pointsB = (titleB === title ? 1 : 0) +
|
||||
(artistB.includes(artist) ? 1 : 0);
|
||||
|
||||
return pointsB - pointsA;
|
||||
},
|
||||
@ -51,14 +52,21 @@ export class LyricsGenius implements LyricProvider {
|
||||
|
||||
const { result: { path } } = closestHit;
|
||||
|
||||
const html = await fetch(`${this.baseUrl}${path}`).then((res) => res.text());
|
||||
const html = await fetch(`${this.baseUrl}${path}`).then((res) =>
|
||||
res.text()
|
||||
);
|
||||
const doc = this.domParser.parseFromString(html, 'text/html');
|
||||
|
||||
const preloadedStateScript = Array.prototype.find.call(doc.querySelectorAll('script'), (script: HTMLScriptElement) => {
|
||||
return script.textContent?.includes('window.__PRELOADED_STATE__');
|
||||
}) as HTMLScriptElement;
|
||||
const preloadedStateScript = Array.prototype.find.call(
|
||||
doc.querySelectorAll('script'),
|
||||
(script: HTMLScriptElement) => {
|
||||
return script.textContent?.includes('window.__PRELOADED_STATE__');
|
||||
},
|
||||
) as HTMLScriptElement;
|
||||
|
||||
const preloadedState = preloadedStateScript.textContent?.match(preloadedStateRegex)?.[1]?.replace(/\\"/g, '"');
|
||||
const preloadedState = preloadedStateScript.textContent?.match(
|
||||
preloadedStateRegex,
|
||||
)?.[1]?.replace(/\\"/g, '"');
|
||||
|
||||
const lyricsHtml = preloadedState?.match(preloadHtmlRegex)?.[1]
|
||||
?.replace(/\\\//g, '/')
|
||||
@ -67,12 +75,19 @@ export class LyricsGenius implements LyricProvider {
|
||||
?.replace(/\\'/g, "'")
|
||||
?.replace(/\\"/g, '"');
|
||||
|
||||
if (!lyricsHtml) throw new Error('Failed to extract lyrics from preloaded state.');
|
||||
const hasUnreleasedPlaceholder = preloadedState &&
|
||||
/lyricsPlaceholderReason.{1,5}unreleased/.test(preloadedState);
|
||||
if (!lyricsHtml) {
|
||||
if (hasUnreleasedPlaceholder) return null;
|
||||
throw new Error('Failed to extract lyrics from preloaded state.');
|
||||
}
|
||||
|
||||
const lyricsDoc = this.domParser.parseFromString(lyricsHtml, 'text/html');
|
||||
const lyrics = lyricsDoc.body.innerText;
|
||||
|
||||
if (lyrics.trim().toLowerCase().replace(/[[\]]/g, '') === 'instrumental') return null;
|
||||
if (lyrics.trim().toLowerCase().replace(/[[\]]/g, '') === 'instrumental') {
|
||||
return null;
|
||||
}
|
||||
|
||||
return {
|
||||
title: closestHit.result.title,
|
||||
|
||||
Reference in New Issue
Block a user