fixed tests
This commit is contained in:
120
public/js/publisher.ts
Normal file
120
public/js/publisher.ts
Normal file
@@ -0,0 +1,120 @@
|
||||
import { WebSocketClient, WebSocketClientStatusMapping } from './services/WebSocketClient.ts';
|
||||
import { MediaHandler } from './services/MediaHandler.ts';
|
||||
import { UIController } from './services/UIController.ts';
|
||||
import { PublisherRTCManager } from './services/PublisherRTCManager.ts';
|
||||
import type { ISignalingMessage } from './interfaces/IWebRTCClient.ts';
|
||||
import { DisposableList } from '@techniker-me/tools';
|
||||
|
||||
class Publisher {
|
||||
private readonly _disposables: DisposableList = new DisposableList();
|
||||
private wsClient: WebSocketClient;
|
||||
private mediaHandler: MediaHandler;
|
||||
private uiController: UIController;
|
||||
private rtcManager: PublisherRTCManager;
|
||||
private isStreaming = false;
|
||||
|
||||
constructor() {
|
||||
this.wsClient = new WebSocketClient('publisher');
|
||||
this.mediaHandler = new MediaHandler('localVideo');
|
||||
this.uiController = new UIController('status', 'subscribersCount', 'startBtn', 'stopBtn');
|
||||
this.rtcManager = new PublisherRTCManager((count) => {
|
||||
this.uiController.updateSubscribersCount(count);
|
||||
});
|
||||
|
||||
this.setupEventHandlers();
|
||||
this.setupWebSocketHandlers();
|
||||
}
|
||||
|
||||
private setupEventHandlers(): void {
|
||||
this.uiController.onButtonClick('startBtn', () => this.startBroadcasting());
|
||||
this.uiController.onButtonClick('stopBtn', () => this.stopBroadcasting());
|
||||
}
|
||||
|
||||
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 to server', 'connected');
|
||||
});
|
||||
|
||||
this.wsClient.onMessage('answer', async (message) => {
|
||||
if (message.senderId) {
|
||||
await this.rtcManager.handleAnswer(message.senderId, message.data);
|
||||
}
|
||||
});
|
||||
|
||||
this.wsClient.onMessage('ice-candidate', async (message) => {
|
||||
if (message.senderId && message.data) {
|
||||
await this.rtcManager.handleIceCandidate(message.senderId, message.data);
|
||||
}
|
||||
});
|
||||
|
||||
this.rtcManager.setOnIceCandidate((subscriberId, candidate) => {
|
||||
const message: ISignalingMessage = {
|
||||
type: 'ice-candidate',
|
||||
data: candidate,
|
||||
targetId: subscriberId
|
||||
};
|
||||
this.wsClient.sendMessage(message);
|
||||
});
|
||||
}
|
||||
|
||||
private async startBroadcasting(): Promise<void> {
|
||||
try {
|
||||
this.uiController.updateStatus('Starting broadcast...', 'waiting');
|
||||
this.uiController.setButtonStates(false, false);
|
||||
|
||||
await this.wsClient.connect();
|
||||
const stream = await this.mediaHandler.getLocalStream();
|
||||
this.rtcManager.setLocalStream(stream);
|
||||
|
||||
this.isStreaming = true;
|
||||
this.uiController.updateStatus('Broadcasting - Ready for subscribers', 'connected');
|
||||
this.uiController.setButtonStates(false, true);
|
||||
|
||||
this.startOfferLoop();
|
||||
} catch (error) {
|
||||
console.error('Error starting broadcast:', error);
|
||||
this.uiController.updateStatus('Failed to start broadcast', 'disconnected');
|
||||
this.uiController.setButtonStates(true, false);
|
||||
}
|
||||
}
|
||||
|
||||
private stopBroadcasting(): void {
|
||||
this.isStreaming = false;
|
||||
this.mediaHandler.stopLocalStream();
|
||||
this.rtcManager.closeAllConnections();
|
||||
this.wsClient.disconnect();
|
||||
|
||||
this.uiController.updateStatus('Broadcast stopped', 'disconnected');
|
||||
this.uiController.setButtonStates(true, false);
|
||||
this.uiController.updateSubscribersCount(0);
|
||||
}
|
||||
|
||||
private async startOfferLoop(): Promise<void> {
|
||||
const offerToNewSubscribers = async () => {
|
||||
if (!this.isStreaming) return;
|
||||
|
||||
try {
|
||||
const offer = await this.rtcManager.createOfferForSubscriber('broadcast');
|
||||
const message: ISignalingMessage = {
|
||||
type: 'offer',
|
||||
data: offer
|
||||
};
|
||||
this.wsClient.sendMessage(message);
|
||||
} catch (error) {
|
||||
console.error('Error creating offer:', error);
|
||||
}
|
||||
|
||||
if (this.isStreaming) {
|
||||
setTimeout(offerToNewSubscribers, 2000);
|
||||
}
|
||||
};
|
||||
|
||||
setTimeout(offerToNewSubscribers, 1000);
|
||||
}
|
||||
}
|
||||
|
||||
new Publisher();
|
||||
Reference in New Issue
Block a user