- Introduced a new `ScreenShareController` to manage YouTube screenshare functionality. - Updated `DiscordPlayer` to track ownership of audio streams, preventing conflicts between music playback and screenshare. - Added error handling for various states including voice connection checks and media busy states. - Created unit tests for `ScreenShareController` and `DiscordPlayer` ownership rules to ensure correct functionality. - Added documentation for the new media echo fix and screenshare design.
65 lines
1.5 KiB
TypeScript
65 lines
1.5 KiB
TypeScript
import type {
|
|
MediaMode,
|
|
MediaQueueItem,
|
|
MediaState,
|
|
ResolvedMediaSource,
|
|
} from "./mediaTypes";
|
|
|
|
export class MediaQueue {
|
|
private current: MediaQueueItem | null = null;
|
|
private readonly items: MediaQueueItem[] = [];
|
|
|
|
constructor(
|
|
private readonly createId: () => string = () => crypto.randomUUID(),
|
|
private readonly now = () => Date.now(),
|
|
) {}
|
|
|
|
add(
|
|
source: ResolvedMediaSource,
|
|
mode: MediaQueueItem["mode"] = "music",
|
|
requestedBy = "dashboard",
|
|
): MediaQueueItem {
|
|
const item: MediaQueueItem = {
|
|
id: this.createId(),
|
|
mode,
|
|
requestedBy,
|
|
addedAt: this.now(),
|
|
status: "queued",
|
|
...source,
|
|
};
|
|
this.items.push(item);
|
|
return { ...item };
|
|
}
|
|
|
|
startNext(): MediaQueueItem | null {
|
|
if (this.current) return { ...this.current };
|
|
const next = this.items.shift();
|
|
if (!next) return null;
|
|
this.current = { ...next, status: "playing" };
|
|
return { ...this.current };
|
|
}
|
|
|
|
completeCurrent(): void {
|
|
this.current = null;
|
|
}
|
|
|
|
failCurrent(): MediaQueueItem | null {
|
|
if (!this.current) return null;
|
|
const failed = { ...this.current, status: "failed" as const };
|
|
this.current = null;
|
|
return failed;
|
|
}
|
|
|
|
clear(): void {
|
|
this.current = null;
|
|
this.items.length = 0;
|
|
}
|
|
|
|
snapshot(): Pick<MediaState, "current" | "queue"> {
|
|
return {
|
|
current: this.current ? { ...this.current } : null,
|
|
queue: this.items.map((item) => ({ ...item })),
|
|
};
|
|
}
|
|
}
|