Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(synced-lyrics): multiple lyric sources #2383

Merged
merged 29 commits into from
Dec 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
53b4af5
introduce multi-source lyric searching
ArjixWasTaken Sep 1, 2024
3f41d25
chore: some progress
ArjixWasTaken Sep 21, 2024
8ac04ae
fighting with solid's reactivity x1
ArjixWasTaken Sep 21, 2024
4fbda63
use a store instead of multiple signals
ArjixWasTaken Oct 20, 2024
765ce5c
improve UX of the lyrics-picker
ArjixWasTaken Oct 20, 2024
7d14b04
add stubs for more lyrics providers
ArjixWasTaken Oct 20, 2024
738115d
progress!
ArjixWasTaken Oct 21, 2024
e86ff96
feat(synced-lyrics): Megalobiz provider
ArjixWasTaken Oct 24, 2024
7650540
fix(synced-lyrics): Megalobiz lyric index issue
ArjixWasTaken Oct 24, 2024
85b47d0
make the lyrics picker react to mouse movement
ArjixWasTaken Oct 24, 2024
d556a47
refactor + better error messages
ArjixWasTaken Oct 28, 2024
32a5016
fix(lrc): recalculate timings before inserting blank line
ArjixWasTaken Oct 28, 2024
ab2c165
kaomoji for the win
ArjixWasTaken Oct 28, 2024
77832ac
feat: plain lyrics
ArjixWasTaken Oct 28, 2024
8024ebb
LyricsGenius: unescape single and double quotes
ArjixWasTaken Oct 28, 2024
ec75a97
feat: auto-switch provider when current one has no result
ArjixWasTaken Oct 28, 2024
808ea82
doc: IMPORTANT WARNING
ArjixWasTaken Oct 31, 2024
006e38f
fix security issue
ArjixWasTaken Nov 1, 2024
a93b318
synced-lyrics(provider): YTMusic
ArjixWasTaken Nov 1, 2024
4e51cf3
fix: properly hide lyrics-picker at smaller resolutions
ArjixWasTaken Nov 1, 2024
7349559
lrclib: add support for plain lyrics
ArjixWasTaken Nov 2, 2024
02fa0c6
Merge branch 'th-ch:master' into synced-lyrics
ArjixWasTaken Dec 15, 2024
30a2c6f
plugins(refined-lyrics): ytmusic: handle edge cases
ArjixWasTaken Dec 15, 2024
99fd703
plugin(refined-lyrics): disable Megalobiz because it is too unstable
ArjixWasTaken Dec 15, 2024
1cfcbf6
stuff
ArjixWasTaken Dec 16, 2024
45ddf9a
Merge branch 'master' into synced-lyrics
JellyBrick Dec 24, 2024
df9396d
fix: prettier
JellyBrick Dec 24, 2024
e8318d9
fix: YTM Lyrics feature availability in South Korea
JellyBrick Dec 24, 2024
418f8c8
fix: minor improve code quality
JellyBrick Dec 24, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,7 @@
"start": "electron-vite preview",
"start:debug": "cross-env ELECTRON_ENABLE_LOGGING=1 pnpm start",
"dev": "cross-env NODE_OPTIONS=--enable-source-maps electron-vite dev --watch",
"dev:renderer": "cross-env NODE_OPTIONS=--enable-source-maps electron-vite dev",
"dev:debug": "cross-env ELECTRON_ENABLE_LOGGING=1 pnpm dev",
"clean": "del-cli dist && del-cli pack && del-cli .vite-inspect",
"dist": "pnpm clean && pnpm build && pnpm electron-builder --win --mac --linux -p never",
Expand Down
4 changes: 2 additions & 2 deletions src/i18n/resources/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -714,8 +714,8 @@
"synced-lyrics": {
"description": "Provides synced lyrics to songs, using providers like LRClib.",
"errors": {
"fetch": "⚠️ - An error occurred while fetching the lyrics. Please try again later.",
"not-found": "⚠️ - No lyrics found for this song."
"fetch": "⚠️\tAn error occurred while fetching the lyrics.\n\tPlease try again later.",
"not-found": "⚠️ No lyrics found for this song."
},
"menu": {
"default-text-string": {
Expand Down
18 changes: 14 additions & 4 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ if (config.get('options.disableHardwareAcceleration')) {

if (is.linux()) {
// Overrides WM_CLASS for X11 to correspond to icon filename
app.setName("com.github.th_ch.youtube_music");
app.setName('com.github.th_ch.youtube_music');

// Workaround for issue #2248
if (
Expand Down Expand Up @@ -904,9 +904,19 @@ function removeContentSecurityPolicy(
betterSession.webRequest.onHeadersReceived((details, callback) => {
details.responseHeaders ??= {};

// Remove the content security policy
delete details.responseHeaders['content-security-policy-report-only'];
delete details.responseHeaders['content-security-policy'];
// prettier-ignore
if (new URL(details.url).protocol === 'https:') {
// Remove the content security policy
delete details.responseHeaders['content-security-policy-report-only'];
delete details.responseHeaders['Content-Security-Policy-Report-Only'];
delete details.responseHeaders['content-security-policy'];
delete details.responseHeaders['Content-Security-Policy'];

// Only allow cross-origin requests from music.youtube.com
delete details.responseHeaders['access-control-allow-origin'];
delete details.responseHeaders['Access-Control-Allow-Origin'];
details.responseHeaders['access-control-allow-origin'] = ['https://music.youtube.com'];
}

callback({ cancel: false, responseHeaders: details.responseHeaders });
});
Expand Down
12 changes: 4 additions & 8 deletions src/plugins/lyrics-genius/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ export interface Section {

export interface Hit {
highlights: Highlight[];
index: Index;
type: Index;
index: ResultType;
type: ResultType;
result: Result;
}

Expand All @@ -35,14 +35,10 @@ export interface Range {
end: number;
}

export enum Index {
Album = 'album',
Lyric = 'lyric',
Song = 'song',
}
export type ResultType = 'song' | 'album' | 'lyric';

export interface Result {
_type: Index;
_type: ResultType;
annotation_count?: number;
api_path: string;
artist_names?: string;
Expand Down
2 changes: 1 addition & 1 deletion src/plugins/synced-lyrics/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export default createPlugin({
showTimeCodes: false,
defaultTextString: '♪',
lineEffect: 'scale',
} satisfies SyncedLyricsPluginConfig,
} as SyncedLyricsPluginConfig,

menu,
renderer,
Expand Down
27 changes: 12 additions & 15 deletions src/plugins/synced-lyrics/menu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,10 @@ import { t } from '@/i18n';
import type { MenuContext } from '@/types/contexts';
import type { SyncedLyricsPluginConfig } from './types';

export const menu = async ({
getConfig,
setConfig,
}: MenuContext<SyncedLyricsPluginConfig>): Promise<
export const menu = async (ctx: MenuContext<SyncedLyricsPluginConfig>): Promise<
MenuItemConstructorOptions[]
> => {
const config = await getConfig();
const config = await ctx.getConfig();

return [
{
Expand All @@ -20,7 +17,7 @@ export const menu = async ({
type: 'checkbox',
checked: config.preciseTiming,
click(item) {
setConfig({
ctx.setConfig({
preciseTiming: item.checked,
});
},
Expand All @@ -40,7 +37,7 @@ export const menu = async ({
type: 'radio',
checked: config.lineEffect === 'scale',
click() {
setConfig({
ctx.setConfig({
lineEffect: 'scale',
});
},
Expand All @@ -55,7 +52,7 @@ export const menu = async ({
type: 'radio',
checked: config.lineEffect === 'offset',
click() {
setConfig({
ctx.setConfig({
lineEffect: 'offset',
});
},
Expand All @@ -70,7 +67,7 @@ export const menu = async ({
type: 'radio',
checked: config.lineEffect === 'focus',
click() {
setConfig({
ctx.setConfig({
lineEffect: 'focus',
});
},
Expand All @@ -87,7 +84,7 @@ export const menu = async ({
type: 'radio',
checked: config.defaultTextString === '♪',
click() {
setConfig({
ctx.setConfig({
defaultTextString: '♪',
});
},
Expand All @@ -97,7 +94,7 @@ export const menu = async ({
type: 'radio',
checked: config.defaultTextString === ' ',
click() {
setConfig({
ctx.setConfig({
defaultTextString: ' ',
});
},
Expand All @@ -107,7 +104,7 @@ export const menu = async ({
type: 'radio',
checked: config.defaultTextString === '...',
click() {
setConfig({
ctx.setConfig({
defaultTextString: '...',
});
},
Expand All @@ -117,7 +114,7 @@ export const menu = async ({
type: 'radio',
checked: config.defaultTextString === '———',
click() {
setConfig({
ctx.setConfig({
defaultTextString: '———',
});
},
Expand All @@ -130,7 +127,7 @@ export const menu = async ({
type: 'checkbox',
checked: config.showTimeCodes,
click(item) {
setConfig({
ctx.setConfig({
showTimeCodes: item.checked,
});
},
Expand All @@ -143,7 +140,7 @@ export const menu = async ({
type: 'checkbox',
checked: config.showLyricsEvenIfInexact,
click(item) {
setConfig({
ctx.setConfig({
showLyricsEvenIfInexact: item.checked,
});
},
Expand Down
89 changes: 89 additions & 0 deletions src/plugins/synced-lyrics/parsers/lrc.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
interface LRCTag {
tag: string;
value: string;
}

interface LRCLine {
time: string;
timeInMs: number;
duration: number;
text: string;
}

interface LRC {
tags: LRCTag[];
lines: LRCLine[];
}

const tagRegex = /^\[(?<tag>\w+):\s*(?<value>.+?)\s*\]$/;
// prettier-ignore
const lyricRegex = /^\[(?<minutes>\d+):(?<seconds>\d+)\.(?<milliseconds>\d+)\](?<text>.+)$/;

export const LRC = {
parse: (text: string): LRC => {
const lrc: LRC = {
tags: [],
lines: [],
};

let offset = 0;
let previousLine: LRCLine | null = null;

for (const line of text.split('\n')) {
if (!line.trim().startsWith('[')) continue;

const lyric = line.match(lyricRegex)?.groups;
if (!lyric) {
const tag = line.match(tagRegex)?.groups;
if (tag) {
if (tag.tag === 'offset') {
offset = parseInt(tag.value);
continue;
}

lrc.tags.push({
tag: tag.tag,
value: tag.value,
});
}
continue;
}

const { minutes, seconds, milliseconds, text } = lyric;
const timeInMs =
parseInt(minutes) * 60 * 1000 +
parseInt(seconds) * 1000 +
parseInt(milliseconds);

const currentLine: LRCLine = {
time: `${minutes}:${seconds}:${milliseconds}`,
timeInMs,
text: text.trim(),
duration: Infinity,
};

if (previousLine) {
previousLine.duration = timeInMs - previousLine.timeInMs;
}

previousLine = currentLine;
lrc.lines.push(currentLine);
}

for (const line of lrc.lines) {
line.timeInMs += offset;
}

const first = lrc.lines.at(0);
if (first && first.timeInMs > 300) {
lrc.lines.unshift({
time: '0:0:0',
timeInMs: 0,
duration: first.timeInMs,
text: '',
});
}

return lrc;
},
};
Loading
Loading