mirror of
https://github.com/th-ch/youtube-music.git
synced 2026-01-11 10:31:47 +00:00
feat(amuse): song query api (add amuse plugin) (#2723)
Co-authored-by: JellyBrick <shlee1503@naver.com>
This commit is contained in:
@ -279,6 +279,13 @@
|
|||||||
},
|
},
|
||||||
"name": "Ambient Mode"
|
"name": "Ambient Mode"
|
||||||
},
|
},
|
||||||
|
"amuse": {
|
||||||
|
"description": "Adds YouTube Music support for the Amuse now playing widget by 6K Labs",
|
||||||
|
"name": "Amuse",
|
||||||
|
"response": {
|
||||||
|
"query": "Amuse API server is running. GET /query to get song info."
|
||||||
|
}
|
||||||
|
},
|
||||||
"api-server": {
|
"api-server": {
|
||||||
"description": "Adds an API server to control the player",
|
"description": "Adds an API server to control the player",
|
||||||
"dialog": {
|
"dialog": {
|
||||||
|
|||||||
71
src/plugins/amuse/backend.ts
Normal file
71
src/plugins/amuse/backend.ts
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
import { t } from 'i18next';
|
||||||
|
|
||||||
|
import { type Context, Hono } from 'hono';
|
||||||
|
import { cors } from 'hono/cors';
|
||||||
|
import { serve } from '@hono/node-server';
|
||||||
|
|
||||||
|
import registerCallback, { type SongInfo } from '@/providers/song-info';
|
||||||
|
import { createBackend } from '@/utils';
|
||||||
|
|
||||||
|
import type { AmuseSongInfo } from './types';
|
||||||
|
|
||||||
|
const amusePort = 9863;
|
||||||
|
|
||||||
|
const formatSongInfo = (info: SongInfo) => {
|
||||||
|
const formattedSongInfo: AmuseSongInfo = {
|
||||||
|
player: {
|
||||||
|
hasSong: !!(info.artist && info.title),
|
||||||
|
isPaused: info.isPaused ?? false,
|
||||||
|
seekbarCurrentPosition: info.elapsedSeconds ?? 0,
|
||||||
|
},
|
||||||
|
track: {
|
||||||
|
duration: info.songDuration,
|
||||||
|
title: info.title,
|
||||||
|
author: info.artist,
|
||||||
|
cover: info.imageSrc ?? '',
|
||||||
|
url: info.url ?? '',
|
||||||
|
id: info.videoId,
|
||||||
|
isAdvertisement: false,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
return formattedSongInfo;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default createBackend({
|
||||||
|
currentSongInfo: {} as SongInfo,
|
||||||
|
app: null as Hono | null,
|
||||||
|
server: null as ReturnType<typeof serve> | null,
|
||||||
|
start() {
|
||||||
|
registerCallback((songInfo) => {
|
||||||
|
this.currentSongInfo = songInfo;
|
||||||
|
});
|
||||||
|
|
||||||
|
this.app = new Hono();
|
||||||
|
this.app.use('*', cors());
|
||||||
|
this.app.get('/', (ctx) =>
|
||||||
|
ctx.body(t('plugins.amuse.response.query'), 200),
|
||||||
|
);
|
||||||
|
|
||||||
|
const queryAndApiHandler = (ctx: Context) => {
|
||||||
|
return ctx.json(formatSongInfo(this.currentSongInfo), 200);
|
||||||
|
};
|
||||||
|
|
||||||
|
this.app.get('/query', queryAndApiHandler);
|
||||||
|
this.app.get('/api', queryAndApiHandler);
|
||||||
|
|
||||||
|
try {
|
||||||
|
this.server = serve({
|
||||||
|
fetch: this.app.fetch.bind(this.app),
|
||||||
|
port: amusePort,
|
||||||
|
});
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
stop() {
|
||||||
|
if (this.server) {
|
||||||
|
this.server?.close();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
20
src/plugins/amuse/index.ts
Normal file
20
src/plugins/amuse/index.ts
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
import { createPlugin } from '@/utils';
|
||||||
|
import backend from './backend';
|
||||||
|
import { t } from '@/i18n';
|
||||||
|
|
||||||
|
export interface MusicWidgetConfig {
|
||||||
|
enabled: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const defaultConfig: MusicWidgetConfig = {
|
||||||
|
enabled: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default createPlugin({
|
||||||
|
name: () => t('plugins.amuse.name'),
|
||||||
|
description: () => t('plugins.amuse.description'),
|
||||||
|
addedVersion: '3.7.X',
|
||||||
|
restartNeeded: true,
|
||||||
|
config: defaultConfig,
|
||||||
|
backend,
|
||||||
|
});
|
||||||
20
src/plugins/amuse/types.ts
Normal file
20
src/plugins/amuse/types.ts
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
export interface PlayerInfo {
|
||||||
|
hasSong: boolean;
|
||||||
|
isPaused: boolean;
|
||||||
|
seekbarCurrentPosition: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface TrackInfo {
|
||||||
|
author: string;
|
||||||
|
title: string;
|
||||||
|
cover: string;
|
||||||
|
duration: number;
|
||||||
|
url: string;
|
||||||
|
id: string;
|
||||||
|
isAdvertisement: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface AmuseSongInfo {
|
||||||
|
player: PlayerInfo;
|
||||||
|
track: TrackInfo;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user