import { HttpClient } from '@angular/common/http'; import { Component, OnDestroy, OnInit } from '@angular/core'; import { lastValueFrom, Subscription } from 'rxjs'; import { ParticipantModel, ParticipantService, OpenViduAngularModule, ApiDirectiveModule, OpenViduAngularDirectiveModule, } from 'openvidu-angular'; import { environment } from 'src/environments/environment'; import { NgClass } from '@angular/common'; @Component({ selector: 'app-root', template: `
@for (track of localParticipant.tracks; track track) {
} @for (track of remoteParticipants | tracks; track track) {
}
`, styleUrls: ['./app.component.scss'], standalone: true, imports: [ OpenViduAngularModule, ApiDirectiveModule, OpenViduAngularDirectiveModule, NgClass, ], }) export class AppComponent implements OnInit, OnDestroy { // For local development, leave these variables empty // For production, configure them with correct URLs depending on your deployment APPLICATION_SERVER_URL = ''; LIVEKIT_URL = ''; // Define the name of the room and initialize the token variable roomName = 'custom-layout'; token!: string; // Participant-related properties localParticipant!: ParticipantModel; remoteParticipants!: ParticipantModel[]; localParticipantSubs!: Subscription; remoteParticipantsSubs!: Subscription; constructor( private httpClient: HttpClient, private participantService: ParticipantService ) { this.configureUrls(); } private configureUrls() { // If APPLICATION_SERVER_URL is not configured, use default value from local development if (!this.APPLICATION_SERVER_URL) { if (window.location.hostname === 'localhost') { this.APPLICATION_SERVER_URL = 'http://localhost:6080/'; } else { this.APPLICATION_SERVER_URL = 'https://' + window.location.hostname + ':6443/'; } } // If LIVEKIT_URL is not configured, use default value from local development if (!this.LIVEKIT_URL) { if (window.location.hostname === 'localhost') { this.LIVEKIT_URL = 'ws://localhost:7880/'; } else { this.LIVEKIT_URL = 'wss://' + window.location.hostname + ':7443/'; } } } ngOnInit() { // Subscribe to participants' updates this.subscribeToParticipants(); } // Function to request a token when a participant joins the room async onTokenRequested(participantName: string) { const { token } = await this.getToken(this.roomName, participantName); this.token = token; } ngOnDestroy() { // Unsubscribe from participant updates to prevent memory leaks this.localParticipantSubs.unsubscribe(); this.remoteParticipantsSubs.unsubscribe(); } // Subscribe to updates for local and remote participants subscribeToParticipants() { this.localParticipantSubs = this.participantService.localParticipantObs.subscribe((p) => { if (p) this.localParticipant = p; }); this.remoteParticipantsSubs = this.participantService.remoteParticipantsObs.subscribe( (participants) => { this.remoteParticipants = participants; } ); } // Function to get a token from the server getToken(roomName: string, participantName: string): Promise { try { // Send a POST request to the server to obtain a token return lastValueFrom( this.httpClient.post(this.APPLICATION_SERVER_URL + 'token', { roomName, participantName, }) ); } catch (error: any) { // Handle errors, e.g., if the server is not reachable if (error.status === 404) { throw { status: error.status, message: 'Cannot connect with the backend. ' + error.url + ' not found', }; } throw error; } } }