fixed tests

This commit is contained in:
2025-09-05 00:36:54 -04:00
commit a536668a0b
48 changed files with 8187 additions and 0 deletions

153
public/js/subscriber.ts Normal file
View File

@@ -0,0 +1,153 @@
import { WebSocketClient, WebSocketClientStatusMapping } from './services/WebSocketClient.ts';
import { UIController } from './services/UIController.ts';
import { SubscriberRTCManager } from './services/SubscriberRTCManager.ts';
import type { ISignalingMessage } from './interfaces/IWebRTCClient.ts';
import { DisposableList } from '@techniker-me/tools';
class Subscriber {
private readonly _disposables: DisposableList = new DisposableList();
private wsClient: WebSocketClient;
private uiController: UIController;
private rtcManager: SubscriberRTCManager;
private isConnected = false;
private videoPlaceholder: HTMLElement | null;
private remoteVideo: HTMLVideoElement | null;
constructor() {
this.wsClient = new WebSocketClient('subscriber');
this.uiController = new UIController('status', undefined, 'connectBtn', 'disconnectBtn');
this.videoPlaceholder = document.getElementById('videoPlaceholder');
this.remoteVideo = document.getElementById('remoteVideo') as HTMLVideoElement;
this.rtcManager = new SubscriberRTCManager(
'remoteVideo',
(stream) => this.onStreamReceived(stream),
(state) => this.onConnectionStateChange(state)
);
this.setupEventHandlers();
this.setupWebSocketHandlers();
}
private setupEventHandlers(): void {
this.uiController.onButtonClick('connectBtn', () => this.connect());
this.uiController.onButtonClick('disconnectBtn', () => this.disconnect());
}
private setupWebSocketHandlers(): void {
this._disposables.add(this.wsClient.status.subscribe((status) => {
this.uiController.updateStatus(WebSocketClientStatusMapping.convertWebSocketClientStatusToWebSocketClientStatusType(status), status);
}));
this.wsClient.onMessage('join', (message) => {
this.uiController.updateStatus('Connected - Waiting for publisher', 'waiting');
this.isConnected = true;
this.uiController.setButtonStates(false, true);
});
this.wsClient.onMessage('publisher-joined', (message) => {
this.uiController.updateStatus('Publisher available - Requesting stream', 'waiting');
});
this.wsClient.onMessage('publisher-left', (message) => {
this.uiController.updateStatus('Publisher disconnected', 'disconnected');
this.showVideoPlaceholder();
});
this.wsClient.onMessage('offer', async (message) => {
try {
const answer = await this.rtcManager.handleOffer(message.data);
const answerMessage: ISignalingMessage = {
type: 'answer',
data: answer,
targetId: message.senderId
};
this.wsClient.sendMessage(answerMessage);
this.uiController.updateStatus('Connecting to stream...', 'waiting');
} catch (error) {
console.error('Error handling offer:', error);
this.uiController.updateStatus('Failed to connect to stream', 'disconnected');
}
});
this.wsClient.onMessage('ice-candidate', async (message) => {
if (message.data) {
await this.rtcManager.handleIceCandidate(message.data);
}
});
this.rtcManager.setOnIceCandidate((candidate) => {
const message: ISignalingMessage = {
type: 'ice-candidate',
data: candidate
};
this.wsClient.sendMessage(message);
});
}
private async connect(): Promise<void> {
try {
this.uiController.updateStatus('Connecting to server...', 'waiting');
this.uiController.setButtonStates(false, false);
await this.wsClient.connect();
} catch (error) {
console.error('Error connecting:', error);
this.uiController.updateStatus('Failed to connect to server', 'disconnected');
this.uiController.setButtonStates(true, false);
}
}
private disconnect(): void {
this.isConnected = false;
this.rtcManager.disconnect();
this.wsClient.disconnect();
this.uiController.updateStatus('Disconnected', 'disconnected');
this.uiController.setButtonStates(true, false);
this.showVideoPlaceholder();
}
private onStreamReceived(stream: MediaStream): void {
console.log('Stream received, showing video');
this.uiController.updateStatus('Connected - Receiving stream', 'connected');
this.hideVideoPlaceholder();
}
private onConnectionStateChange(state: string): void {
switch (state) {
case 'connected':
this.uiController.updateStatus('Connected - Receiving stream', 'connected');
break;
case 'connecting':
this.uiController.updateStatus('Connecting to stream...', 'waiting');
break;
case 'disconnected':
case 'failed':
this.uiController.updateStatus('Connection lost', 'disconnected');
this.showVideoPlaceholder();
break;
}
}
private hideVideoPlaceholder(): void {
if (this.videoPlaceholder) {
this.videoPlaceholder.style.display = 'none';
}
if (this.remoteVideo) {
this.remoteVideo.style.display = 'block';
}
}
private showVideoPlaceholder(): void {
if (this.videoPlaceholder) {
this.videoPlaceholder.style.display = 'flex';
}
if (this.remoteVideo) {
this.remoteVideo.style.display = 'none';
}
}
}
new Subscriber();