mirror of
https://github.com/th-ch/youtube-music.git
synced 2026-01-11 18:41:47 +00:00
77 lines
2.1 KiB
TypeScript
77 lines
2.1 KiB
TypeScript
import { createRenderer } from '@/utils';
|
|
|
|
import type { YoutubePlayer } from '@/types/youtube-player';
|
|
import type { RendererContext } from '@/types/contexts';
|
|
import type { CustomOutputPluginConfig } from './index';
|
|
|
|
const updateDeviceList = async (
|
|
context: RendererContext<CustomOutputPluginConfig>,
|
|
) => {
|
|
const newDevices: Record<string, string> = {};
|
|
const devices = await navigator.mediaDevices
|
|
.enumerateDevices()
|
|
.then((devices) =>
|
|
devices.filter((device) => device.kind === 'audiooutput'),
|
|
);
|
|
for (const device of devices) {
|
|
newDevices[device.deviceId] = device.label;
|
|
}
|
|
const options = await context.getConfig();
|
|
options.devices = newDevices;
|
|
context.setConfig(options);
|
|
};
|
|
|
|
const updateSinkId = async (
|
|
audioContext?: AudioContext & {
|
|
setSinkId?: (sinkId: string) => Promise<void>;
|
|
},
|
|
sinkId?: string,
|
|
) => {
|
|
if (!audioContext || !sinkId) return;
|
|
if (!('setSinkId' in audioContext)) return;
|
|
|
|
if (typeof audioContext.setSinkId === 'function') {
|
|
await audioContext.setSinkId(sinkId);
|
|
}
|
|
};
|
|
|
|
export const renderer = createRenderer<
|
|
{
|
|
options?: CustomOutputPluginConfig;
|
|
audioContext?: AudioContext;
|
|
audioCanPlayHandler: (event: CustomEvent<Compressor>) => Promise<void>;
|
|
},
|
|
CustomOutputPluginConfig
|
|
>({
|
|
async audioCanPlayHandler({ detail: { audioContext } }) {
|
|
this.audioContext = audioContext;
|
|
await updateSinkId(audioContext, this.options!.output);
|
|
},
|
|
|
|
async onPlayerApiReady(_: YoutubePlayer, context) {
|
|
this.options = await context.getConfig();
|
|
await navigator.mediaDevices.getUserMedia({ audio: true, video: false });
|
|
navigator.mediaDevices.ondevicechange = async () =>
|
|
await updateDeviceList(context);
|
|
|
|
document.addEventListener('ytmd:audio-can-play', this.audioCanPlayHandler, {
|
|
once: true,
|
|
passive: true,
|
|
});
|
|
await updateDeviceList(context);
|
|
},
|
|
|
|
stop() {
|
|
document.removeEventListener(
|
|
'ytmd:audio-can-play',
|
|
this.audioCanPlayHandler,
|
|
);
|
|
navigator.mediaDevices.ondevicechange = null;
|
|
},
|
|
|
|
async onConfigChange(config) {
|
|
this.options = config;
|
|
await updateSinkId(this.audioContext, config.output);
|
|
},
|
|
});
|