import { EventEmitter } from "eventemitter3"; import { IPlatformWebRTC } from "../platform"; import { IMediaManager } from "./media.interface"; import { MediaManagerEventMap } from "./media.types"; export class MediaManager extends EventEmitter implements IMediaManager { private localStream?: MediaStream; private audioMuted: boolean = false; private cameraFront: boolean = true; constructor(private platform: IPlatformWebRTC) { super(); } async initialize(): Promise { try { this.localStream = await this.platform.getUserMedia(); this.emit("stream:ready", this.localStream); } catch (error) { console.error("[MediaManager] Cannot find MediaStream: ", error); this.emit("stream:error", new Error(`error: ${error}`)); } } getLocalStream(): MediaStream | null { return this.localStream || null; } toggleAudio(): boolean { if (!this.localStream) { console.warn("[MediaManager] Cannot toggle audio: no local stream"); return false; } const audioTrack = this.localStream.getAudioTracks()[0]; if (audioTrack) { audioTrack.enabled = !audioTrack.enabled; this.audioMuted = !audioTrack.enabled; this.emit("audio:toggled", this.audioMuted); } return this.audioMuted; } isMuted(): boolean { return this.audioMuted; } async switchCamera(): Promise { if (!this.localStream) { return; } const result = await this.platform.switchCamera(this.localStream); if (result) { this.cameraFront = !this.cameraFront; this.emit("camera:switched", this.cameraFront); } } isCameraFront(): boolean { return this.cameraFront; } dispose(): void { if (this.localStream) { this.localStream.getTracks().forEach((track) => track.stop()); this.localStream = undefined; this.audioMuted = false; this.emit("stream:ended"); } this.removeAllListeners(); } }