diff --git a/application-client/openvidu-angular/src/app/app.component.html b/application-client/openvidu-angular/src/app/app.component.html index 5a0f12b4..f341b6a5 100644 --- a/application-client/openvidu-angular/src/app/app.component.html +++ b/application-client/openvidu-angular/src/app/app.component.html @@ -22,25 +22,21 @@
- @if (room.localParticipant) { - @for (trackPublication of room.localParticipant.videoTrackPublications.values(); track trackPublication.trackSid) { - - } + @if (localTrack) { + } - @for (participant of room.remoteParticipants.values(); track participant.identity) { - @for (trackPublication of participant.trackPublications.values(); track trackPublication.trackSid) { - @if (trackPublication.kind === 'video') { - - } @else { - - } + @for (remoteTrack of remoteTracksMap.values(); track remoteTrack.trackPublication.trackSid) { + @if (remoteTrack.trackPublication.kind === 'video') { + + } @else { + } }
diff --git a/application-client/openvidu-angular/src/app/app.component.ts b/application-client/openvidu-angular/src/app/app.component.ts index 5c8e6ab9..a813f894 100644 --- a/application-client/openvidu-angular/src/app/app.component.ts +++ b/application-client/openvidu-angular/src/app/app.component.ts @@ -1,11 +1,23 @@ import { Component, HostListener, OnDestroy } from '@angular/core'; import { ReactiveFormsModule, FormControl, FormGroup, Validators } from '@angular/forms'; -import { Room } from 'livekit-client'; +import { + LocalVideoTrack, + RemoteParticipant, + RemoteTrack, + RemoteTrackPublication, + Room, + RoomEvent, +} from 'livekit-client'; import { VideoComponent } from './video/video.component'; import { AudioComponent } from './audio/audio.component'; import { HttpClient } from '@angular/common/http'; import { lastValueFrom } from 'rxjs'; +type TrackInfo = { + trackPublication: RemoteTrackPublication; + participantIdentity: string; +}; + // For local development, leave these variables empty // For production, configure them with correct URLs depending on your deployment var APPLICATION_SERVER_URL = ''; @@ -25,6 +37,8 @@ export class AppComponent implements OnDestroy { }); room?: Room; + localTrack?: LocalVideoTrack; + remoteTracksMap: Map = new Map(); constructor(private httpClient: HttpClient) { this.configureUrls(); @@ -54,6 +68,23 @@ export class AppComponent implements OnDestroy { // Initialize a new Room object this.room = new Room(); + // Specify the actions when events take place in the room + // On every new Track received... + this.room.on( + RoomEvent.TrackSubscribed, + (_track: RemoteTrack, publication: RemoteTrackPublication, participant: RemoteParticipant) => { + this.remoteTracksMap.set(publication.trackSid, { + trackPublication: publication, + participantIdentity: participant.identity, + }); + } + ); + + // On every new Track destroyed... + this.room.on(RoomEvent.TrackUnsubscribed, (_track: RemoteTrack, publication: RemoteTrackPublication) => { + this.remoteTracksMap.delete(publication.trackSid); + }); + try { // Get the room name and participant name from the form const roomName = this.roomForm.value.roomName!; @@ -67,8 +98,12 @@ export class AppComponent implements OnDestroy { // Publish your camera and microphone await this.room.localParticipant.enableCameraAndMicrophone(); + this.localTrack = this.room.localParticipant.videoTrackPublications.values().next().value.videoTrack; } catch (error: any) { - console.log('There was an error connecting to the room:', error?.error?.errorMessage || error?.message || error); + console.log( + 'There was an error connecting to the room:', + error?.error?.errorMessage || error?.message || error + ); await this.leaveRoom(); } } @@ -77,6 +112,8 @@ export class AppComponent implements OnDestroy { // Leave the room by calling 'disconnect' method over the Room object await this.room?.disconnect(); delete this.room; + delete this.localTrack; + this.remoteTracksMap.clear(); } @HostListener('window:beforeunload')