104 lines
2.6 KiB
TypeScript
104 lines
2.6 KiB
TypeScript
import { ChromecastDevice } from "./ChromecastDevice";
|
|
import { FullscreenWindowConfig, FullscreenWindowDevice } from "./FullscreenWindow";
|
|
import { LocalAudioDevice } from "./LocalAudioDevice";
|
|
|
|
export type DeviceConfig = FullscreenWindowConfig;
|
|
export type Devices = FullscreenWindowDevice | ChromecastDevice;
|
|
|
|
export interface RemoteDeviceManagerOptions {
|
|
devices: (DeviceConfig)[];
|
|
}
|
|
|
|
export interface RemoteDeviceManagerCtx {
|
|
audioContext: AudioContext;
|
|
}
|
|
|
|
|
|
export class RemoteDeviceManager {
|
|
|
|
private _devices:Devices[] = [];
|
|
private localAudioDevice: LocalAudioDevice;
|
|
|
|
constructor(private options: RemoteDeviceManagerOptions, private ctx: RemoteDeviceManagerCtx) {
|
|
for (const device of options.devices) {
|
|
this.createInstance(device);
|
|
}
|
|
|
|
this.localAudioDevice = new LocalAudioDevice(ctx.audioContext);
|
|
}
|
|
|
|
get devices(): Devices[] {
|
|
return this._devices;
|
|
}
|
|
|
|
get audioDevices() {
|
|
return [
|
|
...this._devices.filter(d => d.audioSink),
|
|
this.localAudioDevice,
|
|
];
|
|
}
|
|
|
|
private async createInstance(device: DeviceConfig): Promise<Devices|undefined> {
|
|
if (device.type === 'fullscreen-window') {
|
|
const deviceInstance = new FullscreenWindowDevice(device, this.ctx);
|
|
this._devices.push(deviceInstance);
|
|
return deviceInstance;
|
|
}
|
|
}
|
|
|
|
async add(device: DeviceConfig, connect: boolean = false): Promise<void> {
|
|
const instance = await this.createInstance(device);
|
|
if (!instance) {
|
|
return;
|
|
}
|
|
this.persist();
|
|
if (connect) {
|
|
await instance.connect();
|
|
}
|
|
}
|
|
|
|
removeDevice(device: Devices) {
|
|
this._devices = this._devices.filter(d => d !== device);
|
|
this.persist()
|
|
}
|
|
|
|
async availableDevices(): Promise<DeviceConfig[]> {
|
|
return [
|
|
...(await FullscreenWindowDevice.getDevices()),
|
|
];
|
|
}
|
|
|
|
async connectChromeCast() {
|
|
new ChromecastDevice(this.ctx)
|
|
.connect()
|
|
.then((dev) => {
|
|
this._devices.push(dev);
|
|
(this._devices.at(-1) as ChromecastDevice).setup();
|
|
})
|
|
}
|
|
|
|
get config(): RemoteDeviceManagerOptions {
|
|
return {
|
|
...this.options,
|
|
devices: this._devices
|
|
.map(d => {
|
|
// @ts-ignore
|
|
return d.config;
|
|
})
|
|
.filter(d => d !== undefined) as DeviceConfig[]
|
|
};
|
|
}
|
|
|
|
persist() {
|
|
console.log('persist');
|
|
localStorage.setItem('remote-devices', JSON.stringify(this.config));
|
|
}
|
|
|
|
static restore(ctx: RemoteDeviceManagerCtx): RemoteDeviceManager {
|
|
const data = localStorage.getItem('remote-devices');
|
|
if (data) {
|
|
return new RemoteDeviceManager(JSON.parse(data), ctx);
|
|
}
|
|
return new RemoteDeviceManager({devices: []}, ctx);
|
|
}
|
|
} |