import { MediaManager } from './media.manager'; import { LatencyProfile } from '../realtime.constants'; import { VoiceStateSnapshot } from '../realtime.types'; interface VoiceSessionControllerDependencies { mediaManager: MediaManager; getIsScreenSharing(): boolean; setVoiceConnected(connected: boolean): void; setMuted(muted: boolean): void; setDeafened(deafened: boolean): void; setNoiseReductionEnabled(enabled: boolean): void; } export class VoiceSessionController { private voiceServerId: string | null = null; constructor( private readonly dependencies: VoiceSessionControllerDependencies ) {} getVoiceServerId(): string | null { return this.voiceServerId; } getEffectiveServerId(activeServerId: string | null): string | null { return this.voiceServerId || activeServerId; } handleVoiceConnected(): void { this.dependencies.setVoiceConnected(true); } getCurrentVoiceState(): VoiceStateSnapshot { return { isConnected: this.dependencies.mediaManager.getIsVoiceActive(), isMuted: this.dependencies.mediaManager.getIsMicMuted(), isDeafened: this.dependencies.mediaManager.getIsSelfDeafened(), isScreenSharing: this.dependencies.getIsScreenSharing(), roomId: this.dependencies.mediaManager.getCurrentVoiceRoomId(), serverId: this.dependencies.mediaManager.getCurrentVoiceServerId() }; } async enableVoice(): Promise { const stream = await this.dependencies.mediaManager.enableVoice(); this.syncMediaSignals(); return stream; } disableVoice(): void { this.voiceServerId = null; this.dependencies.mediaManager.disableVoice(); this.dependencies.setVoiceConnected(false); } async setLocalStream(stream: MediaStream): Promise { await this.dependencies.mediaManager.setLocalStream(stream); this.syncMediaSignals(); } toggleMute(muted?: boolean): void { this.dependencies.mediaManager.toggleMute(muted); this.dependencies.setMuted(this.dependencies.mediaManager.getIsMicMuted()); } toggleDeafen(deafened?: boolean): void { this.dependencies.mediaManager.toggleDeafen(deafened); this.dependencies.setDeafened(this.dependencies.mediaManager.getIsSelfDeafened()); } async toggleNoiseReduction(enabled?: boolean): Promise { await this.dependencies.mediaManager.toggleNoiseReduction(enabled); this.dependencies.setNoiseReductionEnabled(this.dependencies.mediaManager.getIsNoiseReductionEnabled()); } setOutputVolume(volume: number): void { this.dependencies.mediaManager.setOutputVolume(volume); } setInputVolume(volume: number): void { this.dependencies.mediaManager.setInputVolume(volume); } async setAudioBitrate(kbps: number): Promise { return await this.dependencies.mediaManager.setAudioBitrate(kbps); } async setLatencyProfile(profile: LatencyProfile): Promise { return await this.dependencies.mediaManager.setLatencyProfile(profile); } startVoiceHeartbeat(roomId?: string, serverId?: string): void { if (serverId) { this.voiceServerId = serverId; } this.dependencies.mediaManager.startVoiceHeartbeat(roomId, serverId); } stopVoiceHeartbeat(): void { this.dependencies.mediaManager.stopVoiceHeartbeat(); } resetVoiceSession(): void { this.voiceServerId = null; this.dependencies.mediaManager.stopVoiceHeartbeat(); this.dependencies.mediaManager.disableVoice(); this.dependencies.setVoiceConnected(false); } private syncMediaSignals(): void { this.dependencies.setVoiceConnected(this.dependencies.mediaManager.getIsVoiceActive()); this.dependencies.setMuted(this.dependencies.mediaManager.getIsMicMuted()); this.dependencies.setDeafened(this.dependencies.mediaManager.getIsSelfDeafened()); } }