mirror of
https://github.com/th-ch/youtube-music.git
synced 2026-01-13 19:31:46 +00:00
feat: migrate to new plugin api
Co-authored-by: Su-Yong <simssy2205@gmail.com>
This commit is contained in:
32
src/plugins/sponsorblock/index.ts
Normal file
32
src/plugins/sponsorblock/index.ts
Normal file
@ -0,0 +1,32 @@
|
||||
import { createPluginBuilder } from '../utils/builder';
|
||||
|
||||
export type SponsorBlockPluginConfig = {
|
||||
enabled: boolean;
|
||||
apiURL: string;
|
||||
categories: ('sponsor' | 'intro' | 'outro' | 'interaction' | 'selfpromo' | 'music_offtopic')[];
|
||||
};
|
||||
|
||||
const builder = createPluginBuilder('sponsorblock', {
|
||||
name: 'SponsorBlock',
|
||||
restartNeeded: true,
|
||||
config: {
|
||||
enabled: false,
|
||||
apiURL: 'https://sponsor.ajay.app',
|
||||
categories: [
|
||||
'sponsor',
|
||||
'intro',
|
||||
'outro',
|
||||
'interaction',
|
||||
'selfpromo',
|
||||
'music_offtopic',
|
||||
],
|
||||
} as SponsorBlockPluginConfig,
|
||||
});
|
||||
|
||||
export default builder;
|
||||
|
||||
declare global {
|
||||
interface PluginBuilderList {
|
||||
[builder.id]: typeof builder;
|
||||
}
|
||||
}
|
||||
@ -1,26 +1,12 @@
|
||||
import { BrowserWindow, ipcMain } from 'electron';
|
||||
import is from 'electron-is';
|
||||
|
||||
import { sortSegments } from './segments';
|
||||
|
||||
import { SkipSegment } from './types';
|
||||
|
||||
import defaultConfig from '../../config/defaults';
|
||||
import builder from './index';
|
||||
|
||||
import type { GetPlayerResponse } from '../../types/get-player-response';
|
||||
import type { ConfigType } from '../../config/dynamic';
|
||||
|
||||
export default (win: BrowserWindow, options: ConfigType<'sponsorblock'>) => {
|
||||
const { apiURL, categories } = {
|
||||
...defaultConfig.plugins.sponsorblock,
|
||||
...options,
|
||||
};
|
||||
|
||||
ipcMain.on('video-src-changed', async (_, data: GetPlayerResponse) => {
|
||||
const segments = await fetchSegments(apiURL, categories, data?.videoDetails?.videoId);
|
||||
win.webContents.send('sponsorblock-skip', segments);
|
||||
});
|
||||
};
|
||||
|
||||
const fetchSegments = async (apiURL: string, categories: string[], videoId: string) => {
|
||||
const sponsorBlockURL = `${apiURL}/api/skipSegments?videoID=${videoId}&categories=${JSON.stringify(
|
||||
@ -50,3 +36,16 @@ const fetchSegments = async (apiURL: string, categories: string[], videoId: stri
|
||||
return [];
|
||||
}
|
||||
};
|
||||
|
||||
export default builder.createMain(({ getConfig, on, send }) => ({
|
||||
async onLoad() {
|
||||
const config = await getConfig();
|
||||
|
||||
const { apiURL, categories } = config;
|
||||
|
||||
on('video-src-changed', async (_, data: GetPlayerResponse) => {
|
||||
const segments = await fetchSegments(apiURL, categories, data?.videoDetails?.videoId);
|
||||
send('sponsorblock-skip', segments);
|
||||
});
|
||||
}
|
||||
}));
|
||||
|
||||
@ -1,34 +1,50 @@
|
||||
import { Segment } from './types';
|
||||
import builder from './index';
|
||||
|
||||
let currentSegments: Segment[] = [];
|
||||
export default builder.createRenderer(({ on }) => {
|
||||
let currentSegments: Segment[] = [];
|
||||
|
||||
export default () => {
|
||||
window.ipcRenderer.on('sponsorblock-skip', (_, segments: Segment[]) => {
|
||||
currentSegments = segments;
|
||||
});
|
||||
const timeUpdateListener = (e: Event) => {
|
||||
if (e.target instanceof HTMLVideoElement) {
|
||||
const target = e.target;
|
||||
|
||||
document.addEventListener('apiLoaded', () => {
|
||||
const video = document.querySelector<HTMLVideoElement>('video');
|
||||
if (!video) return;
|
||||
|
||||
video.addEventListener('timeupdate', (e) => {
|
||||
if (e.target instanceof HTMLVideoElement) {
|
||||
const target = e.target;
|
||||
|
||||
for (const segment of currentSegments) {
|
||||
if (
|
||||
target.currentTime >= segment[0]
|
||||
&& target.currentTime < segment[1]
|
||||
) {
|
||||
target.currentTime = segment[1];
|
||||
if (window.electronIs.dev()) {
|
||||
console.log('SponsorBlock: skipping segment', segment);
|
||||
}
|
||||
for (const segment of currentSegments) {
|
||||
if (
|
||||
target.currentTime >= segment[0]
|
||||
&& target.currentTime < segment[1]
|
||||
) {
|
||||
target.currentTime = segment[1];
|
||||
if (window.electronIs.dev()) {
|
||||
console.log('SponsorBlock: skipping segment', segment);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
// Reset segments on song end
|
||||
video.addEventListener('emptied', () => currentSegments = []);
|
||||
}, { once: true, passive: true });
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
const resetSegments = () => currentSegments = [];
|
||||
|
||||
return ({
|
||||
onLoad() {
|
||||
on('sponsorblock-skip', (_, segments: Segment[]) => {
|
||||
currentSegments = segments;
|
||||
});
|
||||
|
||||
document.addEventListener('apiLoaded', () => {
|
||||
const video = document.querySelector<HTMLVideoElement>('video');
|
||||
if (!video) return;
|
||||
|
||||
video.addEventListener('timeupdate', timeUpdateListener);
|
||||
// Reset segments on song end
|
||||
video.addEventListener('emptied', resetSegments);
|
||||
}, { once: true, passive: true });
|
||||
},
|
||||
onUnload() {
|
||||
const video = document.querySelector<HTMLVideoElement>('video');
|
||||
if (!video) return;
|
||||
|
||||
video.removeEventListener('timeupdate', timeUpdateListener);
|
||||
video.removeEventListener('emptied', resetSegments);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user