import type { ISignalingMessage } from '../interfaces/IWebRTCClient.ts'; export class SubscriberRTCManager { private peerConnection: RTCPeerConnection | null = null; private remoteVideo: HTMLVideoElement | null = null; private onStreamReceived?: (stream: MediaStream) => void; private onConnectionStateChange?: (state: string) => void; private rtcConfiguration: RTCConfiguration = { iceServers: [ { urls: 'stun:stun.l.google.com:19302' }, { urls: 'stun:stun1.l.google.com:19302' } ] }; constructor( videoElementId: string, onStreamReceived?: (stream: MediaStream) => void, onConnectionStateChange?: (state: string) => void ) { this.remoteVideo = document.getElementById(videoElementId) as HTMLVideoElement; this.onStreamReceived = onStreamReceived; this.onConnectionStateChange = onConnectionStateChange; } async handleOffer(offer: RTCSessionDescriptionInit): Promise { this.createPeerConnection(); if (!this.peerConnection) { throw new Error('Failed to create peer connection'); } await this.peerConnection.setRemoteDescription(offer); const answer = await this.peerConnection.createAnswer(); await this.peerConnection.setLocalDescription(answer); return answer; } async handleIceCandidate(candidate: RTCIceCandidateInit): Promise { if (this.peerConnection && candidate) { await this.peerConnection.addIceCandidate(candidate); } } disconnect(): void { if (this.peerConnection) { this.peerConnection.close(); this.peerConnection = null; } if (this.remoteVideo) { this.remoteVideo.srcObject = null; } } private createPeerConnection(): void { this.peerConnection = new RTCPeerConnection(this.rtcConfiguration); this.peerConnection.onicecandidate = (event) => { if (event.candidate) { this.onIceCandidate?.(event.candidate); } }; this.peerConnection.ontrack = (event) => { console.log('Received remote stream'); const [remoteStream] = event.streams; if (this.remoteVideo) { this.remoteVideo.srcObject = remoteStream; } if (this.onStreamReceived) { this.onStreamReceived(remoteStream); } }; this.peerConnection.onconnectionstatechange = () => { const state = this.peerConnection?.connectionState || 'unknown'; console.log('Connection state changed:', state); if (this.onConnectionStateChange) { this.onConnectionStateChange(state); } }; this.peerConnection.onicegatheringstatechange = () => { console.log('ICE gathering state:', this.peerConnection?.iceGatheringState); }; } private onIceCandidate?: (candidate: RTCIceCandidate) => void; setOnIceCandidate(handler: (candidate: RTCIceCandidate) => void): void { this.onIceCandidate = handler; } }