UNPKG

webrtc2-peer

Version:

WebRTC2 Peer - Low-level WebRTC peer connection management for cross-platform real-time communication with signaling, ICE handling, and media streaming

100 lines (80 loc) 2.87 kB
/** * PeerConnection - WebRTC peer connection management */ import { EventEmitter } from 'eventemitter3'; export interface PeerConnectionEvents { 'connection-state-change': (state: RTCPeerConnectionState) => void; 'ice-candidate': (candidate: RTCIceCandidate) => void; 'remote-stream': (stream: MediaStream) => void; 'data-channel': (channel: RTCDataChannel) => void; } export class PeerConnection extends EventEmitter<PeerConnectionEvents> { private pc: RTCPeerConnection; private localStream?: MediaStream; private remoteStream?: MediaStream; constructor(config?: RTCConfiguration) { super(); this.pc = new RTCPeerConnection(config || { iceServers: [ { urls: 'stun:stun.l.google.com:19302' } ] }); this.setupEventHandlers(); } private setupEventHandlers(): void { this.pc.onconnectionstatechange = () => { this.emit('connection-state-change', this.pc.connectionState); }; this.pc.onicecandidate = (event) => { if (event.candidate) { this.emit('ice-candidate', event.candidate); } }; this.pc.ontrack = (event) => { const [stream] = event.streams; this.remoteStream = stream; this.emit('remote-stream', stream); }; this.pc.ondatachannel = (event) => { this.emit('data-channel', event.channel); }; } async createOffer(): Promise<RTCSessionDescriptionInit> { const offer = await this.pc.createOffer(); await this.pc.setLocalDescription(offer); return offer; } async createAnswer(): Promise<RTCSessionDescriptionInit> { const answer = await this.pc.createAnswer(); await this.pc.setLocalDescription(answer); return answer; } async setRemoteDescription(description: RTCSessionDescriptionInit): Promise<void> { await this.pc.setRemoteDescription(description); } async addIceCandidate(candidate: RTCIceCandidateInit): Promise<void> { await this.pc.addIceCandidate(candidate); } addLocalStream(stream: MediaStream): void { this.localStream = stream; stream.getTracks().forEach(track => { this.pc.addTrack(track, stream); }); } createDataChannel(label: string, options?: RTCDataChannelInit): RTCDataChannel { return this.pc.createDataChannel(label, options); } getConnectionState(): RTCPeerConnectionState { return this.pc.connectionState; } getLocalStream(): MediaStream | undefined { return this.localStream; } getRemoteStream(): MediaStream | undefined { return this.remoteStream; } close(): void { this.pc.close(); this.removeAllListeners(); } }