mirror of
https://github.com/th-ch/youtube-music.git
synced 2026-01-09 01:31:46 +00:00
init webnowplaying
This commit is contained in:
@ -172,6 +172,7 @@
|
||||
"node-html-parser": "6.1.12",
|
||||
"node-id3": "0.2.6",
|
||||
"peerjs": "1.5.2",
|
||||
"reconnecting-websocket": "4.4.0",
|
||||
"semver": "7.6.0",
|
||||
"serve": "14.2.1",
|
||||
"simple-youtube-age-restriction-bypass": "github:organization/Simple-YouTube-Age-Restriction-Bypass#v2.5.9",
|
||||
@ -181,6 +182,7 @@
|
||||
"solid-transition-group": "0.2.3",
|
||||
"ts-morph": "22.0.0",
|
||||
"vudio": "2.1.1",
|
||||
"ws": "8.16.0",
|
||||
"x11": "2.3.0",
|
||||
"youtubei.js": "9.1.0"
|
||||
},
|
||||
@ -192,6 +194,7 @@
|
||||
"@types/howler": "2.2.11",
|
||||
"@types/html-to-text": "9.0.4",
|
||||
"@types/semver": "7.5.8",
|
||||
"@types/ws": "8.5.10",
|
||||
"@typescript-eslint/eslint-plugin": "7.4.0",
|
||||
"bufferutil": "4.0.8",
|
||||
"builtin-modules": "3.3.0",
|
||||
@ -217,8 +220,7 @@
|
||||
"vite": "5.2.6",
|
||||
"vite-plugin-inspect": "0.8.3",
|
||||
"vite-plugin-resolve": "2.5.1",
|
||||
"vite-plugin-solid": "2.10.2",
|
||||
"ws": "8.16.0"
|
||||
"vite-plugin-solid": "2.10.2"
|
||||
},
|
||||
"auto-changelog": {
|
||||
"hideCredit": true,
|
||||
|
||||
23
pnpm-lock.yaml
generated
23
pnpm-lock.yaml
generated
@ -129,6 +129,9 @@ dependencies:
|
||||
peerjs:
|
||||
specifier: 1.5.2
|
||||
version: 1.5.2
|
||||
reconnecting-websocket:
|
||||
specifier: 4.4.0
|
||||
version: 4.4.0
|
||||
semver:
|
||||
specifier: 7.6.0
|
||||
version: 7.6.0
|
||||
@ -156,6 +159,9 @@ dependencies:
|
||||
vudio:
|
||||
specifier: 2.1.1
|
||||
version: 2.1.1(patch_hash=7iux5msqpgl3octdmwy4uspwoe)
|
||||
ws:
|
||||
specifier: 8.16.0
|
||||
version: 8.16.0(bufferutil@4.0.8)(utf-8-validate@6.0.3)
|
||||
x11:
|
||||
specifier: 2.3.0
|
||||
version: 2.3.0
|
||||
@ -185,6 +191,9 @@ devDependencies:
|
||||
'@types/semver':
|
||||
specifier: 7.5.8
|
||||
version: 7.5.8
|
||||
'@types/ws':
|
||||
specifier: 8.5.10
|
||||
version: 8.5.10
|
||||
'@typescript-eslint/eslint-plugin':
|
||||
specifier: 7.4.0
|
||||
version: 7.4.0(@typescript-eslint/parser@7.4.0)(eslint@8.57.0)(typescript@5.4.3)
|
||||
@ -263,9 +272,6 @@ devDependencies:
|
||||
vite-plugin-solid:
|
||||
specifier: 2.10.2
|
||||
version: 2.10.2(solid-js@1.8.16)(vite@5.2.6)
|
||||
ws:
|
||||
specifier: 8.16.0
|
||||
version: 8.16.0(bufferutil@4.0.8)(utf-8-validate@6.0.3)
|
||||
|
||||
packages:
|
||||
|
||||
@ -1747,6 +1753,12 @@ packages:
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@types/ws@8.5.10:
|
||||
resolution: {integrity: sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A==}
|
||||
dependencies:
|
||||
'@types/node': 20.11.30
|
||||
dev: true
|
||||
|
||||
/@types/yauzl@2.10.3:
|
||||
resolution: {integrity: sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==}
|
||||
requiresBuild: true
|
||||
@ -5711,6 +5723,10 @@ packages:
|
||||
util-deprecate: 1.0.2
|
||||
dev: true
|
||||
|
||||
/reconnecting-websocket@4.4.0:
|
||||
resolution: {integrity: sha512-D2E33ceRPga0NvTDhJmphEgJ7FUYF0v4lr1ki0csq06OdlxKfugGzN0dSkxM/NfqCxYELK4KcaTOUOjTV6Dcng==}
|
||||
dev: false
|
||||
|
||||
/redent@4.0.0:
|
||||
resolution: {integrity: sha512-tYkDkVVtYkSVhuQ4zBgfvciymHaeuel+zFKXShfDnFP5SyVEP7qo70Rf1jTOTCx3vGNAbnEi/xFkcfQVMIBWag==}
|
||||
engines: {node: '>=12'}
|
||||
@ -6851,6 +6867,7 @@ packages:
|
||||
dependencies:
|
||||
bufferutil: 4.0.8
|
||||
utf-8-validate: 6.0.3
|
||||
dev: false
|
||||
|
||||
/x11@2.3.0:
|
||||
resolution: {integrity: sha512-Ep4DbqZkVHvZNVht+vvELcfdpGKnfh2kZuKdXqyZdtJx3UdvgUGrMQ9lwPNV33tDs86MF4YagC6+E2fZXikF6A==}
|
||||
|
||||
145
src/plugins/webnowplaying/index.ts
Normal file
145
src/plugins/webnowplaying/index.ts
Normal file
@ -0,0 +1,145 @@
|
||||
import { net } from 'electron';
|
||||
|
||||
import is from 'electron-is';
|
||||
|
||||
import { createPlugin } from '@/utils';
|
||||
import registerCallback from '@/providers/song-info';
|
||||
import { t } from '@/i18n';
|
||||
|
||||
import { WebSocket } from 'ws';
|
||||
|
||||
import ReconnectingWebSocket from 'reconnecting-websocket';
|
||||
|
||||
import type { RepeatMode } from '@/types/datahost-get-state';
|
||||
|
||||
interface Data {
|
||||
player: string;
|
||||
state: 'PLAYING' | 'PAUSED' | 'STOPPED';
|
||||
title: string;
|
||||
artist: string;
|
||||
album: string;
|
||||
cover: string;
|
||||
duration: string;
|
||||
position: string;
|
||||
volume: number;
|
||||
rating: number;
|
||||
repeat: 'ALL' | 'ONE' | 'NONE';
|
||||
shuffle: boolean;
|
||||
}
|
||||
|
||||
export default createPlugin({
|
||||
name: () => t('plugins.webnowplaying.name'),
|
||||
description: () => t('plugins.webnowplaying.description'),
|
||||
restartNeeded: true,
|
||||
config: {
|
||||
enabled: false,
|
||||
},
|
||||
backend: {
|
||||
liteMode: false,
|
||||
data: {
|
||||
player: 'YouTube Music',
|
||||
state: 'STOPPED',
|
||||
title: '',
|
||||
artist: '',
|
||||
album: '',
|
||||
cover: '',
|
||||
duration: '0:00',
|
||||
// position and volume are fetched in sendUpdate()
|
||||
position: '0:00',
|
||||
volume: 100,
|
||||
rating: 0,
|
||||
repeat: 'NONE',
|
||||
shuffle: false
|
||||
} as Data,
|
||||
start({ ipc }) {
|
||||
const timeInSecondsToString = (timeInSeconds: number) => {
|
||||
const timeInMinutes = Math.floor(timeInSeconds / 60);
|
||||
if (timeInMinutes < 60) return `${timeInMinutes}:${Math.floor(timeInSeconds % 60).toString().padStart(2, '0')}`;
|
||||
|
||||
return `${Math.floor(timeInMinutes / 60)}:${Math.floor(timeInMinutes % 60).toString().padStart(2, '0')}:${Math.floor(timeInSeconds % 60).toString().padStart(2, '0')}`;
|
||||
};
|
||||
|
||||
const ws = new ReconnectingWebSocket('ws://localhost:8974', undefined, {
|
||||
WebSocket: WebSocket,
|
||||
maxEnqueuedMessages: 0,
|
||||
});
|
||||
ws.onmessage = () => {
|
||||
|
||||
};
|
||||
|
||||
const post = (data: Data) => {
|
||||
const port = 1608;
|
||||
const headers = {
|
||||
'Content-Type': 'application/json',
|
||||
'Accept': 'application/json',
|
||||
'Access-Control-Allow-Headers': '*',
|
||||
'Access-Control-Allow-Origin': '*',
|
||||
};
|
||||
const url = `http://127.0.0.1:${port}/`;
|
||||
net
|
||||
.fetch(url, {
|
||||
method: this.liteMode ? 'OPTIONS' : 'POST',
|
||||
headers,
|
||||
keepalive: true,
|
||||
body: this.liteMode ? undefined : JSON.stringify({ data }),
|
||||
})
|
||||
.then(() => {
|
||||
if (this.liteMode) {
|
||||
this.liteMode = false;
|
||||
console.debug(
|
||||
`obs-tuna webserver at port ${port} is now accessible. disable lite mode`,
|
||||
);
|
||||
post(data);
|
||||
}
|
||||
})
|
||||
.catch((error: { code: number; errno: number }) => {
|
||||
if (!this.liteMode && is.dev()) {
|
||||
console.debug(
|
||||
`Error: '${
|
||||
error.code || error.errno
|
||||
}' - when trying to access obs-tuna webserver at port ${port}. enable lite mode`,
|
||||
);
|
||||
this.liteMode = true;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
ipc.on('ytmd:player-api-loaded', () => {
|
||||
ipc.send('ytmd:setup-time-changed-listener');
|
||||
ipc.send('ytmd:setup-repeat-changed-listener');
|
||||
ipc.send('ytmd:setup-volume-changed-listener');
|
||||
});
|
||||
ipc.on('ytmd:time-changed', (t: number) => {
|
||||
if (!this.data.title) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.data.position = timeInSecondsToString(t);
|
||||
post(this.data);
|
||||
});
|
||||
ipc.on('ytmd:repeat-changed', (mode: RepeatMode) => {
|
||||
this.data.repeat = mode;
|
||||
post(this.data);
|
||||
});
|
||||
ipc.on('ytmd:volume-changed', (newVolume: number) => {
|
||||
this.data.volume = newVolume;
|
||||
post(this.data);
|
||||
});
|
||||
|
||||
registerCallback((songInfo) => {
|
||||
if (!songInfo.title && !songInfo.artist) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.data.duration = timeInSecondsToString(songInfo.songDuration);
|
||||
this.data.position = timeInSecondsToString(songInfo.elapsedSeconds ?? 0);
|
||||
this.data.cover = songInfo.imageSrc ?? '';
|
||||
this.data.title = songInfo.title;
|
||||
this.data.artist = songInfo.artist;
|
||||
this.data.state = songInfo.isPaused ? 'PAUSED' : 'PLAYING';
|
||||
this.data.album = songInfo.album ?? '';
|
||||
post(this.data);
|
||||
});
|
||||
},
|
||||
},
|
||||
});
|
||||
Reference in New Issue
Block a user