mirror of https://github.com/OpenVidu/openvidu.git
openvidu-testapp: update and refactor all RoomEvent, ParticipantEvent and TrackEvent management
- Updates all available events to latest - Refactor event listeners to use shared utilities with early registration and safe add/remove patternpull/900/head
parent
052b110776
commit
f037f31da1
|
|
@ -6,40 +6,49 @@ import { MatSlideToggleModule } from '@angular/material/slide-toggle';
|
||||||
import { MatDividerModule } from '@angular/material/divider';
|
import { MatDividerModule } from '@angular/material/divider';
|
||||||
import { MatButtonModule } from '@angular/material/button';
|
import { MatButtonModule } from '@angular/material/button';
|
||||||
|
|
||||||
|
export interface EventGroup {
|
||||||
|
label: string;
|
||||||
|
eventCollection: Map<string, boolean>;
|
||||||
|
eventArray: string[];
|
||||||
|
checkAll: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-events-dialog',
|
selector: 'app-events-dialog',
|
||||||
template: `
|
template: `
|
||||||
<h2 mat-dialog-title>{{target}} events</h2>
|
<h2 mat-dialog-title>{{target}} events</h2>
|
||||||
<mat-dialog-content>
|
<mat-dialog-content>
|
||||||
<mat-slide-toggle [(ngModel)]="checkAll" (change)="updateAll()" [color]="'warn'"><i>ALL</i></mat-slide-toggle>
|
@for (group of eventGroups; track group.label) {
|
||||||
<mat-divider></mat-divider>
|
<h3 class="group-label">{{group.label}}</h3>
|
||||||
<div class="row no-wrap-row">
|
<mat-slide-toggle [(ngModel)]="group.checkAll" (change)="updateAll(group)" [color]="'warn'"><i>ALL</i></mat-slide-toggle>
|
||||||
<div class="col-50">
|
<mat-divider></mat-divider>
|
||||||
@for (event of eventArray | slice:0:(eventArray.length/2); track event) {
|
<div class="row no-wrap-row">
|
||||||
<div class="toggle">
|
<div class="col-50">
|
||||||
<mat-slide-toggle
|
@for (event of group.eventArray | slice:0:Math.ceil(group.eventArray.length/2); track event) {
|
||||||
(change)="toggleEvent($event)"
|
<div class="toggle">
|
||||||
[checked]="eventCollection.get(event)"
|
<mat-slide-toggle
|
||||||
[name]="event"
|
(change)="toggleEvent($event, group)"
|
||||||
color="warn">{{event}}
|
[checked]="group.eventCollection.get(event)"
|
||||||
</mat-slide-toggle>
|
[name]="event"
|
||||||
</div>
|
color="warn">{{event}}
|
||||||
}
|
</mat-slide-toggle>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
<div class="col-50">
|
||||||
|
@for (event of group.eventArray | slice:Math.ceil(group.eventArray.length/2):group.eventArray.length; track event) {
|
||||||
|
<div class="toggle">
|
||||||
|
<mat-slide-toggle
|
||||||
|
(change)="toggleEvent($event, group)"
|
||||||
|
[checked]="group.eventCollection.get(event)"
|
||||||
|
[name]="event"
|
||||||
|
color="warn">{{event}}
|
||||||
|
</mat-slide-toggle>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-50">
|
}
|
||||||
@for (event of eventArray | slice:(eventArray.length/2 + 1):(eventArray.length); track event) {
|
|
||||||
<div class="toggle">
|
|
||||||
<mat-slide-toggle
|
|
||||||
(change)="toggleEvent($event)"
|
|
||||||
[checked]="eventCollection.get(event)"
|
|
||||||
[name]="event"
|
|
||||||
color="warn">{{event}}
|
|
||||||
</mat-slide-toggle>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</mat-dialog-content>
|
</mat-dialog-content>
|
||||||
<mat-dialog-actions>
|
<mat-dialog-actions>
|
||||||
<button mat-button id="close-dialog-btn" mat-dialog-close="">CLOSE</button>
|
<button mat-button id="close-dialog-btn" mat-dialog-close="">CLOSE</button>
|
||||||
|
|
@ -49,34 +58,50 @@ import { MatButtonModule } from '@angular/material/button';
|
||||||
'mat-dialog-content { display: inline; }',
|
'mat-dialog-content { display: inline; }',
|
||||||
'mat-divider { margin-top: 5px; margin-bottom: 5px; }',
|
'mat-divider { margin-top: 5px; margin-bottom: 5px; }',
|
||||||
'.col-50 {flex-basis: 50%; box-sizing: border-box; padding-left: 20px; }',
|
'.col-50 {flex-basis: 50%; box-sizing: border-box; padding-left: 20px; }',
|
||||||
'.toggle { }'
|
'.toggle { }',
|
||||||
|
'.group-label { margin-top: 15px; margin-bottom: 5px; }',
|
||||||
|
'.group-label:first-child { margin-top: 0; }'
|
||||||
],
|
],
|
||||||
imports: [SlicePipe, FormsModule, MatDialogModule, MatSlideToggleModule, MatDividerModule, MatButtonModule],
|
imports: [SlicePipe, FormsModule, MatDialogModule, MatSlideToggleModule, MatDividerModule, MatButtonModule],
|
||||||
})
|
})
|
||||||
export class EventsDialogComponent {
|
export class EventsDialogComponent {
|
||||||
|
|
||||||
|
Math = Math;
|
||||||
target = '';
|
target = '';
|
||||||
checkAll = true;
|
eventGroups: EventGroup[] = [];
|
||||||
eventCollection: Map<string, boolean>;
|
|
||||||
eventArray: string[];
|
|
||||||
|
|
||||||
private dialogData = inject(MAT_DIALOG_DATA);
|
private dialogData = inject(MAT_DIALOG_DATA);
|
||||||
|
|
||||||
constructor(public dialogRef: MatDialogRef<EventsDialogComponent>) {
|
constructor(public dialogRef: MatDialogRef<EventsDialogComponent>) {
|
||||||
const data = this.dialogData;
|
const data = this.dialogData;
|
||||||
this.target = data.target;
|
this.target = data.target;
|
||||||
this.eventCollection = data.eventCollection;
|
if (data.eventGroups) {
|
||||||
this.eventArray = Array.from(this.eventCollection.keys());
|
this.eventGroups = data.eventGroups.map((g: { label: string; eventCollection: Map<string, boolean> }) => ({
|
||||||
|
label: g.label,
|
||||||
|
eventCollection: g.eventCollection,
|
||||||
|
eventArray: Array.from(g.eventCollection.keys()),
|
||||||
|
checkAll: Array.from(g.eventCollection.values()).every(v => v),
|
||||||
|
}));
|
||||||
|
} else {
|
||||||
|
// Backward compatibility: single eventCollection
|
||||||
|
const eventCollection = data.eventCollection;
|
||||||
|
this.eventGroups = [{
|
||||||
|
label: data.target,
|
||||||
|
eventCollection,
|
||||||
|
eventArray: Array.from(eventCollection.keys()),
|
||||||
|
checkAll: Array.from(eventCollection.values()).every(v => v),
|
||||||
|
}];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
updateAll() {
|
updateAll(group: EventGroup) {
|
||||||
this.eventCollection.forEach((value: boolean, key: string) => {
|
group.eventCollection.forEach((_value: boolean, key: string) => {
|
||||||
this.eventCollection.set(key, this.checkAll);
|
group.eventCollection.set(key, group.checkAll);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
toggleEvent(event: any) {
|
toggleEvent(event: any, group: EventGroup) {
|
||||||
this.eventCollection.set(event.source.name, event.checked);
|
group.eventCollection.set(event.source.name, event.checked);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@
|
||||||
<mat-icon class="mat-icon-custom-ic" aria-label="Room API button">cloud_circle</mat-icon>
|
<mat-icon class="mat-icon-custom-ic" aria-label="Room API button">cloud_circle</mat-icon>
|
||||||
</button>
|
</button>
|
||||||
<button mat-icon-button title="Room events" [id]="'room-events-btn-' + index"
|
<button mat-icon-button title="Room events" [id]="'room-events-btn-' + index"
|
||||||
class="mat-icon-custom" (click)="openRoomEventsDialog()">
|
class="mat-icon-custom" (click)="openAllEventsDialog()">
|
||||||
<mat-icon class="mat-icon-custom-ic"
|
<mat-icon class="mat-icon-custom-ic"
|
||||||
aria-label="Room events button">notifications</mat-icon>
|
aria-label="Room events button">notifications</mat-icon>
|
||||||
</button>
|
</button>
|
||||||
|
|
@ -89,10 +89,15 @@
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<app-participant class="local-participant" [participant]="room.localParticipant" [room]="room"
|
<app-participant class="local-participant" [participant]="room.localParticipant" [room]="room"
|
||||||
[index]="index"></app-participant>
|
[index]="index" [participantEvents]="participantEvents" [trackEvents]="trackEvents"
|
||||||
|
[earlyParticipantEvents]="earlyParticipantEvents" [earlyParticipantListeners]="earlyParticipantListeners"
|
||||||
|
[earlyTrackEvents]="earlyTrackEvents" [earlyTrackListeners]="earlyTrackListeners"></app-participant>
|
||||||
@for (participant of room.remoteParticipants | keyvalue; track participant) {
|
@for (participant of room.remoteParticipants | keyvalue; track participant) {
|
||||||
<app-participant class="remote-participant"
|
<app-participant class="remote-participant"
|
||||||
[participant]="participant.value" [room]="room" [index]="index"
|
[participant]="participant.value" [room]="room" [index]="index"
|
||||||
|
[participantEvents]="participantEvents" [trackEvents]="trackEvents"
|
||||||
|
[earlyParticipantEvents]="earlyParticipantEvents" [earlyParticipantListeners]="earlyParticipantListeners"
|
||||||
|
[earlyTrackEvents]="earlyTrackEvents" [earlyTrackListeners]="earlyTrackListeners"
|
||||||
(sendReliableDataToOneParticipant)="sendDataReliable($event)"
|
(sendReliableDataToOneParticipant)="sendDataReliable($event)"
|
||||||
(sendLossyDataToOneParticipant)="sendDataLossy($event)"></app-participant>
|
(sendLossyDataToOneParticipant)="sendDataLossy($event)"></app-participant>
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,7 @@ import {
|
||||||
LocalVideoTrack,
|
LocalVideoTrack,
|
||||||
MediaDeviceFailure,
|
MediaDeviceFailure,
|
||||||
Participant,
|
Participant,
|
||||||
|
ParticipantEvent,
|
||||||
RemoteAudioTrack,
|
RemoteAudioTrack,
|
||||||
RemoteDataTrack,
|
RemoteDataTrack,
|
||||||
RemoteParticipant,
|
RemoteParticipant,
|
||||||
|
|
@ -42,6 +43,7 @@ import {
|
||||||
SubscriptionError,
|
SubscriptionError,
|
||||||
TextStreamReader,
|
TextStreamReader,
|
||||||
Track,
|
Track,
|
||||||
|
TrackEvent,
|
||||||
TrackPublication,
|
TrackPublication,
|
||||||
TrackPublishOptions,
|
TrackPublishOptions,
|
||||||
} from 'livekit-client';
|
} from 'livekit-client';
|
||||||
|
|
@ -58,6 +60,11 @@ import { InfoDialogComponent } from '../dialogs/info-dialog/info-dialog.componen
|
||||||
import { ParticipantComponent } from '../participant/participant.component';
|
import { ParticipantComponent } from '../participant/participant.component';
|
||||||
import { RoomEventCallbacks } from 'node_modules/livekit-client/dist/src/room/Room';
|
import { RoomEventCallbacks } from 'node_modules/livekit-client/dist/src/room/Room';
|
||||||
import PCTransport from 'node_modules/livekit-client/dist/src/room/PCTransport';
|
import PCTransport from 'node_modules/livekit-client/dist/src/room/PCTransport';
|
||||||
|
import {
|
||||||
|
registerParticipantEventListeners,
|
||||||
|
registerTrackEventListeners,
|
||||||
|
removeAllManagedListeners,
|
||||||
|
} from 'src/app/utils/event-listener-utils';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-openvidu-instance',
|
selector: 'app-openvidu-instance',
|
||||||
|
|
@ -74,6 +81,18 @@ export class OpenviduInstanceComponent {
|
||||||
|
|
||||||
room?: Room;
|
room?: Room;
|
||||||
roomEvents: Map<RoomEvent, Boolean> = new Map<RoomEvent, boolean>();
|
roomEvents: Map<RoomEvent, Boolean> = new Map<RoomEvent, boolean>();
|
||||||
|
participantEvents: Map<ParticipantEvent, boolean> = new Map<ParticipantEvent, boolean>();
|
||||||
|
trackEvents: Map<TrackEvent, boolean> = new Map<TrackEvent, boolean>();
|
||||||
|
|
||||||
|
private roomEventListeners: Map<string, (...args: any[]) => void> = new Map();
|
||||||
|
|
||||||
|
// Early event registration: buffers events for participant/track components
|
||||||
|
// that don't yet exist when the SDK fires events during connect()
|
||||||
|
earlyParticipantEvents: Map<string, TestAppEvent[]> = new Map();
|
||||||
|
earlyParticipantListeners: Map<string, Map<string, (...args: any[]) => void>> = new Map();
|
||||||
|
earlyTrackEvents: Map<string, TestAppEvent[]> = new Map();
|
||||||
|
earlyTrackListeners: Map<string, Map<string, (...args: any[]) => void>> = new Map();
|
||||||
|
private earlyParticipantConnectedListener: ((...args: any[]) => void) | undefined;
|
||||||
|
|
||||||
roomName: string = 'TestRoom';
|
roomName: string = 'TestRoom';
|
||||||
participantName: string = 'TestParticipant';
|
participantName: string = 'TestParticipant';
|
||||||
|
|
@ -142,6 +161,14 @@ export class OpenviduInstanceComponent {
|
||||||
this.roomEvents.set(RoomEvent[event as keyof typeof RoomEvent], true);
|
this.roomEvents.set(RoomEvent[event as keyof typeof RoomEvent], true);
|
||||||
this.roomEvents.set(RoomEvent.ActiveSpeakersChanged, false);
|
this.roomEvents.set(RoomEvent.ActiveSpeakersChanged, false);
|
||||||
}
|
}
|
||||||
|
for (let event of Object.keys(ParticipantEvent)) {
|
||||||
|
this.participantEvents.set(ParticipantEvent[event as keyof typeof ParticipantEvent], true);
|
||||||
|
this.participantEvents.set(ParticipantEvent.IsSpeakingChanged, false);
|
||||||
|
}
|
||||||
|
for (let event of Object.keys(TrackEvent)) {
|
||||||
|
this.trackEvents.set(TrackEvent[event as keyof typeof TrackEvent], true);
|
||||||
|
this.trackEvents.set(TrackEvent.TimeSyncUpdate, false);
|
||||||
|
}
|
||||||
this.participantName += this.index;
|
this.participantName += this.index;
|
||||||
if (this.roomConf.startSession) {
|
if (this.roomConf.startSession) {
|
||||||
const token = await this.roomApiService.createToken(
|
const token = await this.roomApiService.createToken(
|
||||||
|
|
@ -177,6 +204,16 @@ export class OpenviduInstanceComponent {
|
||||||
this.room = new Room(this.roomOptions);
|
this.room = new Room(this.roomOptions);
|
||||||
(window as any)['room_' + this.index] = this.room;
|
(window as any)['room_' + this.index] = this.room;
|
||||||
|
|
||||||
|
// Register early participant event listeners on local participant BEFORE connect
|
||||||
|
this.registerEarlyParticipantListeners(this.room.localParticipant);
|
||||||
|
|
||||||
|
// Register early participant event listeners on remote participants as they connect
|
||||||
|
// This fires during connect() for participants already in the room
|
||||||
|
this.earlyParticipantConnectedListener = (participant: RemoteParticipant) => {
|
||||||
|
this.registerEarlyParticipantListeners(participant);
|
||||||
|
};
|
||||||
|
this.room.addListener(RoomEvent.ParticipantConnected, this.earlyParticipantConnectedListener as any);
|
||||||
|
|
||||||
this.setupRoomEventListeners(new Map(), true);
|
this.setupRoomEventListeners(new Map(), true);
|
||||||
|
|
||||||
// connect to room
|
// connect to room
|
||||||
|
|
@ -216,6 +253,19 @@ export class OpenviduInstanceComponent {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private registerRoomListener(event: RoomEvent, listener: (...args: any[]) => void) {
|
||||||
|
this.room!.addListener(event, listener as any);
|
||||||
|
this.roomEventListeners.set(event, listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
private unregisterRoomListener(event: RoomEvent | string) {
|
||||||
|
const existing = this.roomEventListeners.get(event as string);
|
||||||
|
if (existing) {
|
||||||
|
this.room?.removeListener(event as RoomEvent, existing as any);
|
||||||
|
this.roomEventListeners.delete(event as string);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
setupRoomEventListeners(oldValues: Map<string, boolean>, firstTime: boolean) {
|
setupRoomEventListeners(oldValues: Map<string, boolean>, firstTime: boolean) {
|
||||||
// This is a link to the complete list of Room events
|
// This is a link to the complete list of Room events
|
||||||
let callbacks: RoomEventCallbacks;
|
let callbacks: RoomEventCallbacks;
|
||||||
|
|
@ -226,9 +276,9 @@ export class OpenviduInstanceComponent {
|
||||||
this.roomEvents.get(RoomEvent.Connected) !==
|
this.roomEvents.get(RoomEvent.Connected) !==
|
||||||
oldValues.get(RoomEvent.Connected)
|
oldValues.get(RoomEvent.Connected)
|
||||||
) {
|
) {
|
||||||
this.room?.removeAllListeners(RoomEvent.Connected);
|
this.unregisterRoomListener(RoomEvent.Connected);
|
||||||
if (this.roomEvents.get(RoomEvent.Connected)) {
|
if (this.roomEvents.get(RoomEvent.Connected)) {
|
||||||
this.room!.on(RoomEvent.Connected, () => {
|
this.registerRoomListener(RoomEvent.Connected, () => {
|
||||||
this.updateEventList(RoomEvent.Connected, {}, '');
|
this.updateEventList(RoomEvent.Connected, {}, '');
|
||||||
this.room!.remoteParticipants.forEach(
|
this.room!.remoteParticipants.forEach(
|
||||||
(remoteParticipant: RemoteParticipant) => {
|
(remoteParticipant: RemoteParticipant) => {
|
||||||
|
|
@ -251,22 +301,35 @@ export class OpenviduInstanceComponent {
|
||||||
this.roomEvents.get(RoomEvent.Reconnecting) !==
|
this.roomEvents.get(RoomEvent.Reconnecting) !==
|
||||||
oldValues.get(RoomEvent.Reconnecting)
|
oldValues.get(RoomEvent.Reconnecting)
|
||||||
) {
|
) {
|
||||||
this.room?.removeAllListeners(RoomEvent.Reconnecting);
|
this.unregisterRoomListener(RoomEvent.Reconnecting);
|
||||||
if (this.roomEvents.get(RoomEvent.Reconnecting)) {
|
if (this.roomEvents.get(RoomEvent.Reconnecting)) {
|
||||||
this.room!.on(RoomEvent.Reconnecting, () => {
|
this.registerRoomListener(RoomEvent.Reconnecting, () => {
|
||||||
this.updateEventList(RoomEvent.Reconnecting, {}, '');
|
this.updateEventList(RoomEvent.Reconnecting, {}, '');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
firstTime ||
|
||||||
|
this.roomEvents.get(RoomEvent.SignalReconnecting) !==
|
||||||
|
oldValues.get(RoomEvent.SignalReconnecting)
|
||||||
|
) {
|
||||||
|
this.unregisterRoomListener(RoomEvent.SignalReconnecting);
|
||||||
|
if (this.roomEvents.get(RoomEvent.SignalReconnecting)) {
|
||||||
|
this.registerRoomListener(RoomEvent.SignalReconnecting, () => {
|
||||||
|
this.updateEventList(RoomEvent.SignalReconnecting, {}, '');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
firstTime ||
|
firstTime ||
|
||||||
this.roomEvents.get(RoomEvent.Reconnected) !==
|
this.roomEvents.get(RoomEvent.Reconnected) !==
|
||||||
oldValues.get(RoomEvent.Reconnected)
|
oldValues.get(RoomEvent.Reconnected)
|
||||||
) {
|
) {
|
||||||
this.room?.removeAllListeners(RoomEvent.Reconnected);
|
this.unregisterRoomListener(RoomEvent.Reconnected);
|
||||||
if (this.roomEvents.get(RoomEvent.Reconnected)) {
|
if (this.roomEvents.get(RoomEvent.Reconnected)) {
|
||||||
this.room!.on(RoomEvent.Reconnected, () => {
|
this.registerRoomListener(RoomEvent.Reconnected, () => {
|
||||||
this.updateEventList(RoomEvent.Reconnected, {}, '');
|
this.updateEventList(RoomEvent.Reconnected, {}, '');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -277,9 +340,9 @@ export class OpenviduInstanceComponent {
|
||||||
this.roomEvents.get(RoomEvent.Disconnected) !==
|
this.roomEvents.get(RoomEvent.Disconnected) !==
|
||||||
oldValues.get(RoomEvent.Disconnected)
|
oldValues.get(RoomEvent.Disconnected)
|
||||||
) {
|
) {
|
||||||
this.room?.removeAllListeners(RoomEvent.Disconnected);
|
this.unregisterRoomListener(RoomEvent.Disconnected);
|
||||||
if (this.roomEvents.get(RoomEvent.Disconnected)) {
|
if (this.roomEvents.get(RoomEvent.Disconnected)) {
|
||||||
this.room!.on(RoomEvent.Disconnected, (reason?: DisconnectReason) => {
|
this.registerRoomListener(RoomEvent.Disconnected, (reason?: DisconnectReason) => {
|
||||||
this.updateEventList(
|
this.updateEventList(
|
||||||
RoomEvent.Disconnected,
|
RoomEvent.Disconnected,
|
||||||
{},
|
{},
|
||||||
|
|
@ -294,9 +357,9 @@ export class OpenviduInstanceComponent {
|
||||||
this.roomEvents.get(RoomEvent.ConnectionStateChanged) !==
|
this.roomEvents.get(RoomEvent.ConnectionStateChanged) !==
|
||||||
oldValues.get(RoomEvent.ConnectionStateChanged)
|
oldValues.get(RoomEvent.ConnectionStateChanged)
|
||||||
) {
|
) {
|
||||||
this.room?.removeAllListeners(RoomEvent.ConnectionStateChanged);
|
this.unregisterRoomListener(RoomEvent.ConnectionStateChanged);
|
||||||
if (this.roomEvents.get(RoomEvent.ConnectionStateChanged)) {
|
if (this.roomEvents.get(RoomEvent.ConnectionStateChanged)) {
|
||||||
this.room!.on(
|
this.registerRoomListener(
|
||||||
RoomEvent.ConnectionStateChanged,
|
RoomEvent.ConnectionStateChanged,
|
||||||
(state: ConnectionState) => {
|
(state: ConnectionState) => {
|
||||||
this.updateEventList(
|
this.updateEventList(
|
||||||
|
|
@ -309,14 +372,31 @@ export class OpenviduInstanceComponent {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
firstTime ||
|
||||||
|
this.roomEvents.get(RoomEvent.Moved) !==
|
||||||
|
oldValues.get(RoomEvent.Moved)
|
||||||
|
) {
|
||||||
|
this.unregisterRoomListener(RoomEvent.Moved);
|
||||||
|
if (this.roomEvents.get(RoomEvent.Moved)) {
|
||||||
|
this.registerRoomListener(RoomEvent.Moved, (name: string) => {
|
||||||
|
this.updateEventList(
|
||||||
|
RoomEvent.Moved,
|
||||||
|
{ name },
|
||||||
|
`moved to room: ${name}`
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
firstTime ||
|
firstTime ||
|
||||||
this.roomEvents.get(RoomEvent.MediaDevicesChanged) !==
|
this.roomEvents.get(RoomEvent.MediaDevicesChanged) !==
|
||||||
oldValues.get(RoomEvent.MediaDevicesChanged)
|
oldValues.get(RoomEvent.MediaDevicesChanged)
|
||||||
) {
|
) {
|
||||||
this.room?.removeAllListeners(RoomEvent.MediaDevicesChanged);
|
this.unregisterRoomListener(RoomEvent.MediaDevicesChanged);
|
||||||
if (this.roomEvents.get(RoomEvent.MediaDevicesChanged)) {
|
if (this.roomEvents.get(RoomEvent.MediaDevicesChanged)) {
|
||||||
this.room!.on(RoomEvent.MediaDevicesChanged, () => {
|
this.registerRoomListener(RoomEvent.MediaDevicesChanged, () => {
|
||||||
this.updateEventList(RoomEvent.MediaDevicesChanged, {}, '');
|
this.updateEventList(RoomEvent.MediaDevicesChanged, {}, '');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -327,9 +407,9 @@ export class OpenviduInstanceComponent {
|
||||||
this.roomEvents.get(RoomEvent.ParticipantConnected) !==
|
this.roomEvents.get(RoomEvent.ParticipantConnected) !==
|
||||||
oldValues.get(RoomEvent.ParticipantConnected)
|
oldValues.get(RoomEvent.ParticipantConnected)
|
||||||
) {
|
) {
|
||||||
this.room?.removeAllListeners(RoomEvent.ParticipantConnected);
|
this.unregisterRoomListener(RoomEvent.ParticipantConnected);
|
||||||
if (this.roomEvents.get(RoomEvent.ParticipantConnected)) {
|
if (this.roomEvents.get(RoomEvent.ParticipantConnected)) {
|
||||||
this.room!.on(
|
this.registerRoomListener(
|
||||||
RoomEvent.ParticipantConnected,
|
RoomEvent.ParticipantConnected,
|
||||||
(participant: RemoteParticipant) => {
|
(participant: RemoteParticipant) => {
|
||||||
this.updateEventList(
|
this.updateEventList(
|
||||||
|
|
@ -347,9 +427,9 @@ export class OpenviduInstanceComponent {
|
||||||
this.roomEvents.get(RoomEvent.ParticipantActive) !==
|
this.roomEvents.get(RoomEvent.ParticipantActive) !==
|
||||||
oldValues.get(RoomEvent.ParticipantActive)
|
oldValues.get(RoomEvent.ParticipantActive)
|
||||||
) {
|
) {
|
||||||
this.room?.removeAllListeners(RoomEvent.ParticipantActive);
|
this.unregisterRoomListener(RoomEvent.ParticipantActive);
|
||||||
if (this.roomEvents.get(RoomEvent.ParticipantActive)) {
|
if (this.roomEvents.get(RoomEvent.ParticipantActive)) {
|
||||||
this.room!.on(
|
this.registerRoomListener(
|
||||||
RoomEvent.ParticipantActive,
|
RoomEvent.ParticipantActive,
|
||||||
(participant: Participant) => {
|
(participant: Participant) => {
|
||||||
this.updateEventList(
|
this.updateEventList(
|
||||||
|
|
@ -367,9 +447,9 @@ export class OpenviduInstanceComponent {
|
||||||
this.roomEvents.get(RoomEvent.ParticipantDisconnected) !==
|
this.roomEvents.get(RoomEvent.ParticipantDisconnected) !==
|
||||||
oldValues.get(RoomEvent.ParticipantDisconnected)
|
oldValues.get(RoomEvent.ParticipantDisconnected)
|
||||||
) {
|
) {
|
||||||
this.room?.removeAllListeners(RoomEvent.ParticipantDisconnected);
|
this.unregisterRoomListener(RoomEvent.ParticipantDisconnected);
|
||||||
if (this.roomEvents.get(RoomEvent.ParticipantDisconnected)) {
|
if (this.roomEvents.get(RoomEvent.ParticipantDisconnected)) {
|
||||||
this.room!.on(
|
this.registerRoomListener(
|
||||||
RoomEvent.ParticipantDisconnected,
|
RoomEvent.ParticipantDisconnected,
|
||||||
(participant: RemoteParticipant) => {
|
(participant: RemoteParticipant) => {
|
||||||
this.updateEventList(
|
this.updateEventList(
|
||||||
|
|
@ -388,9 +468,9 @@ export class OpenviduInstanceComponent {
|
||||||
this.roomEvents.get(RoomEvent.TrackPublished) !==
|
this.roomEvents.get(RoomEvent.TrackPublished) !==
|
||||||
oldValues.get(RoomEvent.TrackPublished)
|
oldValues.get(RoomEvent.TrackPublished)
|
||||||
) {
|
) {
|
||||||
this.room?.removeAllListeners(RoomEvent.TrackPublished);
|
this.unregisterRoomListener(RoomEvent.TrackPublished);
|
||||||
if (this.roomEvents.get(RoomEvent.TrackPublished)) {
|
if (this.roomEvents.get(RoomEvent.TrackPublished)) {
|
||||||
this.room!.on(
|
this.registerRoomListener(
|
||||||
RoomEvent.TrackPublished,
|
RoomEvent.TrackPublished,
|
||||||
(
|
(
|
||||||
publication: RemoteTrackPublication,
|
publication: RemoteTrackPublication,
|
||||||
|
|
@ -414,9 +494,9 @@ export class OpenviduInstanceComponent {
|
||||||
this.roomEvents.get(RoomEvent.TrackSubscribed) !==
|
this.roomEvents.get(RoomEvent.TrackSubscribed) !==
|
||||||
oldValues.get(RoomEvent.TrackSubscribed)
|
oldValues.get(RoomEvent.TrackSubscribed)
|
||||||
) {
|
) {
|
||||||
this.room?.removeAllListeners(RoomEvent.TrackSubscribed);
|
this.unregisterRoomListener(RoomEvent.TrackSubscribed);
|
||||||
if (this.roomEvents.get(RoomEvent.TrackSubscribed)) {
|
if (this.roomEvents.get(RoomEvent.TrackSubscribed)) {
|
||||||
this.room!.on(
|
this.registerRoomListener(
|
||||||
RoomEvent.TrackSubscribed,
|
RoomEvent.TrackSubscribed,
|
||||||
(
|
(
|
||||||
track: RemoteTrack,
|
track: RemoteTrack,
|
||||||
|
|
@ -453,9 +533,9 @@ export class OpenviduInstanceComponent {
|
||||||
this.roomEvents.get(RoomEvent.TrackSubscriptionFailed) !==
|
this.roomEvents.get(RoomEvent.TrackSubscriptionFailed) !==
|
||||||
oldValues.get(RoomEvent.TrackSubscriptionFailed)
|
oldValues.get(RoomEvent.TrackSubscriptionFailed)
|
||||||
) {
|
) {
|
||||||
this.room?.removeAllListeners(RoomEvent.TrackSubscriptionFailed);
|
this.unregisterRoomListener(RoomEvent.TrackSubscriptionFailed);
|
||||||
if (this.roomEvents.get(RoomEvent.TrackSubscriptionFailed)) {
|
if (this.roomEvents.get(RoomEvent.TrackSubscriptionFailed)) {
|
||||||
this.room!.on(
|
this.registerRoomListener(
|
||||||
RoomEvent.TrackSubscriptionFailed,
|
RoomEvent.TrackSubscriptionFailed,
|
||||||
(
|
(
|
||||||
trackSid: string,
|
trackSid: string,
|
||||||
|
|
@ -479,9 +559,9 @@ export class OpenviduInstanceComponent {
|
||||||
this.roomEvents.get(RoomEvent.TrackUnpublished) !==
|
this.roomEvents.get(RoomEvent.TrackUnpublished) !==
|
||||||
oldValues.get(RoomEvent.TrackUnpublished)
|
oldValues.get(RoomEvent.TrackUnpublished)
|
||||||
) {
|
) {
|
||||||
this.room?.removeAllListeners(RoomEvent.TrackUnpublished);
|
this.unregisterRoomListener(RoomEvent.TrackUnpublished);
|
||||||
if (this.roomEvents.get(RoomEvent.TrackUnpublished)) {
|
if (this.roomEvents.get(RoomEvent.TrackUnpublished)) {
|
||||||
this.room!.on(
|
this.registerRoomListener(
|
||||||
RoomEvent.TrackUnpublished,
|
RoomEvent.TrackUnpublished,
|
||||||
(
|
(
|
||||||
publication: RemoteTrackPublication,
|
publication: RemoteTrackPublication,
|
||||||
|
|
@ -502,9 +582,9 @@ export class OpenviduInstanceComponent {
|
||||||
this.roomEvents.get(RoomEvent.TrackUnsubscribed) !==
|
this.roomEvents.get(RoomEvent.TrackUnsubscribed) !==
|
||||||
oldValues.get(RoomEvent.TrackUnsubscribed)
|
oldValues.get(RoomEvent.TrackUnsubscribed)
|
||||||
) {
|
) {
|
||||||
this.room?.removeAllListeners(RoomEvent.TrackUnsubscribed);
|
this.unregisterRoomListener(RoomEvent.TrackUnsubscribed);
|
||||||
if (this.roomEvents.get(RoomEvent.TrackUnsubscribed)) {
|
if (this.roomEvents.get(RoomEvent.TrackUnsubscribed)) {
|
||||||
this.room!.on(
|
this.registerRoomListener(
|
||||||
RoomEvent.TrackUnsubscribed,
|
RoomEvent.TrackUnsubscribed,
|
||||||
(
|
(
|
||||||
track: Track,
|
track: Track,
|
||||||
|
|
@ -543,9 +623,9 @@ export class OpenviduInstanceComponent {
|
||||||
this.roomEvents.get(RoomEvent.TrackMuted) !==
|
this.roomEvents.get(RoomEvent.TrackMuted) !==
|
||||||
oldValues.get(RoomEvent.TrackMuted)
|
oldValues.get(RoomEvent.TrackMuted)
|
||||||
) {
|
) {
|
||||||
this.room?.removeAllListeners(RoomEvent.TrackMuted);
|
this.unregisterRoomListener(RoomEvent.TrackMuted);
|
||||||
if (this.roomEvents.get(RoomEvent.TrackMuted)) {
|
if (this.roomEvents.get(RoomEvent.TrackMuted)) {
|
||||||
this.room!.on(
|
this.registerRoomListener(
|
||||||
RoomEvent.TrackMuted,
|
RoomEvent.TrackMuted,
|
||||||
(publication: TrackPublication, participant: Participant) => {
|
(publication: TrackPublication, participant: Participant) => {
|
||||||
this.updateEventList(
|
this.updateEventList(
|
||||||
|
|
@ -563,9 +643,9 @@ export class OpenviduInstanceComponent {
|
||||||
this.roomEvents.get(RoomEvent.TrackUnmuted) !==
|
this.roomEvents.get(RoomEvent.TrackUnmuted) !==
|
||||||
oldValues.get(RoomEvent.TrackUnmuted)
|
oldValues.get(RoomEvent.TrackUnmuted)
|
||||||
) {
|
) {
|
||||||
this.room?.removeAllListeners(RoomEvent.TrackUnmuted);
|
this.unregisterRoomListener(RoomEvent.TrackUnmuted);
|
||||||
if (this.roomEvents.get(RoomEvent.TrackUnmuted)) {
|
if (this.roomEvents.get(RoomEvent.TrackUnmuted)) {
|
||||||
this.room!.on(
|
this.registerRoomListener(
|
||||||
RoomEvent.TrackUnmuted,
|
RoomEvent.TrackUnmuted,
|
||||||
(publication: TrackPublication, participant: Participant) => {
|
(publication: TrackPublication, participant: Participant) => {
|
||||||
this.updateEventList(
|
this.updateEventList(
|
||||||
|
|
@ -583,9 +663,9 @@ export class OpenviduInstanceComponent {
|
||||||
this.roomEvents.get(RoomEvent.LocalTrackPublished) !==
|
this.roomEvents.get(RoomEvent.LocalTrackPublished) !==
|
||||||
oldValues.get(RoomEvent.LocalTrackPublished)
|
oldValues.get(RoomEvent.LocalTrackPublished)
|
||||||
) {
|
) {
|
||||||
this.room?.removeAllListeners(RoomEvent.LocalTrackPublished);
|
this.unregisterRoomListener(RoomEvent.LocalTrackPublished);
|
||||||
if (this.roomEvents.get(RoomEvent.LocalTrackPublished)) {
|
if (this.roomEvents.get(RoomEvent.LocalTrackPublished)) {
|
||||||
this.room!.on(
|
this.registerRoomListener(
|
||||||
RoomEvent.LocalTrackPublished,
|
RoomEvent.LocalTrackPublished,
|
||||||
(
|
(
|
||||||
publication: LocalTrackPublication,
|
publication: LocalTrackPublication,
|
||||||
|
|
@ -611,9 +691,9 @@ export class OpenviduInstanceComponent {
|
||||||
this.roomEvents.get(RoomEvent.LocalTrackUnpublished) !==
|
this.roomEvents.get(RoomEvent.LocalTrackUnpublished) !==
|
||||||
oldValues.get(RoomEvent.LocalTrackUnpublished)
|
oldValues.get(RoomEvent.LocalTrackUnpublished)
|
||||||
) {
|
) {
|
||||||
this.room?.removeAllListeners(RoomEvent.LocalTrackUnpublished);
|
this.unregisterRoomListener(RoomEvent.LocalTrackUnpublished);
|
||||||
if (this.roomEvents.get(RoomEvent.LocalTrackUnpublished)) {
|
if (this.roomEvents.get(RoomEvent.LocalTrackUnpublished)) {
|
||||||
this.room!.on(
|
this.registerRoomListener(
|
||||||
RoomEvent.LocalTrackUnpublished,
|
RoomEvent.LocalTrackUnpublished,
|
||||||
(
|
(
|
||||||
publication: LocalTrackPublication,
|
publication: LocalTrackPublication,
|
||||||
|
|
@ -635,9 +715,9 @@ export class OpenviduInstanceComponent {
|
||||||
this.roomEvents.get(RoomEvent.LocalAudioSilenceDetected) !==
|
this.roomEvents.get(RoomEvent.LocalAudioSilenceDetected) !==
|
||||||
oldValues.get(RoomEvent.LocalAudioSilenceDetected)
|
oldValues.get(RoomEvent.LocalAudioSilenceDetected)
|
||||||
) {
|
) {
|
||||||
this.room?.removeAllListeners(RoomEvent.LocalAudioSilenceDetected);
|
this.unregisterRoomListener(RoomEvent.LocalAudioSilenceDetected);
|
||||||
if (this.roomEvents.get(RoomEvent.LocalAudioSilenceDetected)) {
|
if (this.roomEvents.get(RoomEvent.LocalAudioSilenceDetected)) {
|
||||||
this.room!.on(
|
this.registerRoomListener(
|
||||||
RoomEvent.LocalAudioSilenceDetected,
|
RoomEvent.LocalAudioSilenceDetected,
|
||||||
(publication: LocalTrackPublication) => {
|
(publication: LocalTrackPublication) => {
|
||||||
this.updateEventList(
|
this.updateEventList(
|
||||||
|
|
@ -655,9 +735,9 @@ export class OpenviduInstanceComponent {
|
||||||
this.roomEvents.get(RoomEvent.ParticipantMetadataChanged) !==
|
this.roomEvents.get(RoomEvent.ParticipantMetadataChanged) !==
|
||||||
oldValues.get(RoomEvent.ParticipantMetadataChanged)
|
oldValues.get(RoomEvent.ParticipantMetadataChanged)
|
||||||
) {
|
) {
|
||||||
this.room?.removeAllListeners(RoomEvent.ParticipantMetadataChanged);
|
this.unregisterRoomListener(RoomEvent.ParticipantMetadataChanged);
|
||||||
if (this.roomEvents.get(RoomEvent.ParticipantMetadataChanged)) {
|
if (this.roomEvents.get(RoomEvent.ParticipantMetadataChanged)) {
|
||||||
this.room!.on(
|
this.registerRoomListener(
|
||||||
RoomEvent.ParticipantMetadataChanged,
|
RoomEvent.ParticipantMetadataChanged,
|
||||||
(metadata: string | undefined, participant: Participant) => {
|
(metadata: string | undefined, participant: Participant) => {
|
||||||
this.updateEventList(
|
this.updateEventList(
|
||||||
|
|
@ -675,9 +755,9 @@ export class OpenviduInstanceComponent {
|
||||||
this.roomEvents.get(RoomEvent.ParticipantNameChanged) !==
|
this.roomEvents.get(RoomEvent.ParticipantNameChanged) !==
|
||||||
oldValues.get(RoomEvent.ParticipantNameChanged)
|
oldValues.get(RoomEvent.ParticipantNameChanged)
|
||||||
) {
|
) {
|
||||||
this.room?.removeAllListeners(RoomEvent.ParticipantNameChanged);
|
this.unregisterRoomListener(RoomEvent.ParticipantNameChanged);
|
||||||
if (this.roomEvents.get(RoomEvent.ParticipantNameChanged)) {
|
if (this.roomEvents.get(RoomEvent.ParticipantNameChanged)) {
|
||||||
this.room!.on(
|
this.registerRoomListener(
|
||||||
RoomEvent.ParticipantNameChanged,
|
RoomEvent.ParticipantNameChanged,
|
||||||
(name: string, participant: Participant) => {
|
(name: string, participant: Participant) => {
|
||||||
this.updateEventList(
|
this.updateEventList(
|
||||||
|
|
@ -690,14 +770,37 @@ export class OpenviduInstanceComponent {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
firstTime ||
|
||||||
|
this.roomEvents.get(RoomEvent.ParticipantAttributesChanged) !==
|
||||||
|
oldValues.get(RoomEvent.ParticipantAttributesChanged)
|
||||||
|
) {
|
||||||
|
this.unregisterRoomListener(RoomEvent.ParticipantAttributesChanged);
|
||||||
|
if (this.roomEvents.get(RoomEvent.ParticipantAttributesChanged)) {
|
||||||
|
this.registerRoomListener(
|
||||||
|
RoomEvent.ParticipantAttributesChanged,
|
||||||
|
(
|
||||||
|
changedAttributes: Record<string, string>,
|
||||||
|
participant: RemoteParticipant | LocalParticipant
|
||||||
|
) => {
|
||||||
|
this.updateEventList(
|
||||||
|
RoomEvent.ParticipantAttributesChanged,
|
||||||
|
{ changedAttributes, participant },
|
||||||
|
`${participant.identity} ${JSON.stringify(changedAttributes)}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
firstTime ||
|
firstTime ||
|
||||||
this.roomEvents.get(RoomEvent.ParticipantPermissionsChanged) !==
|
this.roomEvents.get(RoomEvent.ParticipantPermissionsChanged) !==
|
||||||
oldValues.get(RoomEvent.ParticipantPermissionsChanged)
|
oldValues.get(RoomEvent.ParticipantPermissionsChanged)
|
||||||
) {
|
) {
|
||||||
this.room?.removeAllListeners(RoomEvent.ParticipantPermissionsChanged);
|
this.unregisterRoomListener(RoomEvent.ParticipantPermissionsChanged);
|
||||||
if (this.roomEvents.get(RoomEvent.ParticipantPermissionsChanged)) {
|
if (this.roomEvents.get(RoomEvent.ParticipantPermissionsChanged)) {
|
||||||
this.room!.on(
|
this.registerRoomListener(
|
||||||
RoomEvent.ParticipantPermissionsChanged,
|
RoomEvent.ParticipantPermissionsChanged,
|
||||||
(
|
(
|
||||||
prevPermissions: ParticipantPermission | undefined,
|
prevPermissions: ParticipantPermission | undefined,
|
||||||
|
|
@ -722,9 +825,9 @@ export class OpenviduInstanceComponent {
|
||||||
this.roomEvents.get(RoomEvent.ActiveSpeakersChanged) !==
|
this.roomEvents.get(RoomEvent.ActiveSpeakersChanged) !==
|
||||||
oldValues.get(RoomEvent.ActiveSpeakersChanged)
|
oldValues.get(RoomEvent.ActiveSpeakersChanged)
|
||||||
) {
|
) {
|
||||||
this.room?.removeAllListeners(RoomEvent.ActiveSpeakersChanged);
|
this.unregisterRoomListener(RoomEvent.ActiveSpeakersChanged);
|
||||||
if (this.roomEvents.get(RoomEvent.ActiveSpeakersChanged)) {
|
if (this.roomEvents.get(RoomEvent.ActiveSpeakersChanged)) {
|
||||||
this.room!.on(
|
this.registerRoomListener(
|
||||||
RoomEvent.ActiveSpeakersChanged,
|
RoomEvent.ActiveSpeakersChanged,
|
||||||
(speakers: Participant[]) => {
|
(speakers: Participant[]) => {
|
||||||
this.updateEventList(
|
this.updateEventList(
|
||||||
|
|
@ -746,9 +849,9 @@ export class OpenviduInstanceComponent {
|
||||||
this.roomEvents.get(RoomEvent.RoomMetadataChanged) !==
|
this.roomEvents.get(RoomEvent.RoomMetadataChanged) !==
|
||||||
oldValues.get(RoomEvent.RoomMetadataChanged)
|
oldValues.get(RoomEvent.RoomMetadataChanged)
|
||||||
) {
|
) {
|
||||||
this.room?.removeAllListeners(RoomEvent.RoomMetadataChanged);
|
this.unregisterRoomListener(RoomEvent.RoomMetadataChanged);
|
||||||
if (this.roomEvents.get(RoomEvent.RoomMetadataChanged)) {
|
if (this.roomEvents.get(RoomEvent.RoomMetadataChanged)) {
|
||||||
this.room!.on(RoomEvent.RoomMetadataChanged, (metadata: string) => {
|
this.registerRoomListener(RoomEvent.RoomMetadataChanged, (metadata: string) => {
|
||||||
this.updateEventList(
|
this.updateEventList(
|
||||||
RoomEvent.RoomMetadataChanged,
|
RoomEvent.RoomMetadataChanged,
|
||||||
{ metadata },
|
{ metadata },
|
||||||
|
|
@ -763,9 +866,9 @@ export class OpenviduInstanceComponent {
|
||||||
this.roomEvents.get(RoomEvent.DataReceived) !==
|
this.roomEvents.get(RoomEvent.DataReceived) !==
|
||||||
oldValues.get(RoomEvent.DataReceived)
|
oldValues.get(RoomEvent.DataReceived)
|
||||||
) {
|
) {
|
||||||
this.room?.removeAllListeners(RoomEvent.DataReceived);
|
this.unregisterRoomListener(RoomEvent.DataReceived);
|
||||||
if (this.roomEvents.get(RoomEvent.DataReceived)) {
|
if (this.roomEvents.get(RoomEvent.DataReceived)) {
|
||||||
this.room!.on(
|
this.registerRoomListener(
|
||||||
RoomEvent.DataReceived,
|
RoomEvent.DataReceived,
|
||||||
(
|
(
|
||||||
payload: Uint8Array,
|
payload: Uint8Array,
|
||||||
|
|
@ -785,14 +888,34 @@ export class OpenviduInstanceComponent {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
firstTime ||
|
||||||
|
this.roomEvents.get(RoomEvent.SipDTMFReceived) !==
|
||||||
|
oldValues.get(RoomEvent.SipDTMFReceived)
|
||||||
|
) {
|
||||||
|
this.unregisterRoomListener(RoomEvent.SipDTMFReceived);
|
||||||
|
if (this.roomEvents.get(RoomEvent.SipDTMFReceived)) {
|
||||||
|
this.registerRoomListener(
|
||||||
|
RoomEvent.SipDTMFReceived,
|
||||||
|
(dtmf: any, participant?: RemoteParticipant) => {
|
||||||
|
this.updateEventList(
|
||||||
|
RoomEvent.SipDTMFReceived,
|
||||||
|
{ dtmf, participant },
|
||||||
|
`${participant?.identity ?? 'unknown'} ${JSON.stringify(dtmf)}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
firstTime ||
|
firstTime ||
|
||||||
this.roomEvents.get(RoomEvent.ConnectionQualityChanged) !==
|
this.roomEvents.get(RoomEvent.ConnectionQualityChanged) !==
|
||||||
oldValues.get(RoomEvent.ConnectionQualityChanged)
|
oldValues.get(RoomEvent.ConnectionQualityChanged)
|
||||||
) {
|
) {
|
||||||
this.room?.removeAllListeners(RoomEvent.ConnectionQualityChanged);
|
this.unregisterRoomListener(RoomEvent.ConnectionQualityChanged);
|
||||||
if (this.roomEvents.get(RoomEvent.ConnectionQualityChanged)) {
|
if (this.roomEvents.get(RoomEvent.ConnectionQualityChanged)) {
|
||||||
this.room!.on(
|
this.registerRoomListener(
|
||||||
RoomEvent.ConnectionQualityChanged,
|
RoomEvent.ConnectionQualityChanged,
|
||||||
(quality: ConnectionQuality, participant: Participant) => {
|
(quality: ConnectionQuality, participant: Participant) => {
|
||||||
this.updateEventList(
|
this.updateEventList(
|
||||||
|
|
@ -810,9 +933,9 @@ export class OpenviduInstanceComponent {
|
||||||
this.roomEvents.get(RoomEvent.MediaDevicesError) !==
|
this.roomEvents.get(RoomEvent.MediaDevicesError) !==
|
||||||
oldValues.get(RoomEvent.MediaDevicesError)
|
oldValues.get(RoomEvent.MediaDevicesError)
|
||||||
) {
|
) {
|
||||||
this.room?.removeAllListeners(RoomEvent.MediaDevicesError);
|
this.unregisterRoomListener(RoomEvent.MediaDevicesError);
|
||||||
if (this.roomEvents.get(RoomEvent.MediaDevicesError)) {
|
if (this.roomEvents.get(RoomEvent.MediaDevicesError)) {
|
||||||
this.room!.on(RoomEvent.MediaDevicesError, (error: Error) => {
|
this.registerRoomListener(RoomEvent.MediaDevicesError, (error: Error) => {
|
||||||
this.updateEventList(
|
this.updateEventList(
|
||||||
RoomEvent.MediaDevicesError,
|
RoomEvent.MediaDevicesError,
|
||||||
{
|
{
|
||||||
|
|
@ -830,9 +953,9 @@ export class OpenviduInstanceComponent {
|
||||||
this.roomEvents.get(RoomEvent.TrackStreamStateChanged) !==
|
this.roomEvents.get(RoomEvent.TrackStreamStateChanged) !==
|
||||||
oldValues.get(RoomEvent.TrackStreamStateChanged)
|
oldValues.get(RoomEvent.TrackStreamStateChanged)
|
||||||
) {
|
) {
|
||||||
this.room?.removeAllListeners(RoomEvent.TrackStreamStateChanged);
|
this.unregisterRoomListener(RoomEvent.TrackStreamStateChanged);
|
||||||
if (this.roomEvents.get(RoomEvent.TrackStreamStateChanged)) {
|
if (this.roomEvents.get(RoomEvent.TrackStreamStateChanged)) {
|
||||||
this.room!.on(
|
this.registerRoomListener(
|
||||||
RoomEvent.TrackStreamStateChanged,
|
RoomEvent.TrackStreamStateChanged,
|
||||||
(
|
(
|
||||||
publication: RemoteTrackPublication,
|
publication: RemoteTrackPublication,
|
||||||
|
|
@ -854,11 +977,11 @@ export class OpenviduInstanceComponent {
|
||||||
this.roomEvents.get(RoomEvent.TrackSubscriptionPermissionChanged) !==
|
this.roomEvents.get(RoomEvent.TrackSubscriptionPermissionChanged) !==
|
||||||
oldValues.get(RoomEvent.TrackSubscriptionPermissionChanged)
|
oldValues.get(RoomEvent.TrackSubscriptionPermissionChanged)
|
||||||
) {
|
) {
|
||||||
this.room?.removeAllListeners(
|
this.unregisterRoomListener(
|
||||||
RoomEvent.TrackSubscriptionPermissionChanged
|
RoomEvent.TrackSubscriptionPermissionChanged
|
||||||
);
|
);
|
||||||
if (this.roomEvents.get(RoomEvent.TrackSubscriptionPermissionChanged)) {
|
if (this.roomEvents.get(RoomEvent.TrackSubscriptionPermissionChanged)) {
|
||||||
this.room!.on(
|
this.registerRoomListener(
|
||||||
RoomEvent.TrackSubscriptionPermissionChanged,
|
RoomEvent.TrackSubscriptionPermissionChanged,
|
||||||
(
|
(
|
||||||
publication: RemoteTrackPublication,
|
publication: RemoteTrackPublication,
|
||||||
|
|
@ -880,9 +1003,9 @@ export class OpenviduInstanceComponent {
|
||||||
this.roomEvents.get(RoomEvent.TrackSubscriptionStatusChanged) !==
|
this.roomEvents.get(RoomEvent.TrackSubscriptionStatusChanged) !==
|
||||||
oldValues.get(RoomEvent.TrackSubscriptionStatusChanged)
|
oldValues.get(RoomEvent.TrackSubscriptionStatusChanged)
|
||||||
) {
|
) {
|
||||||
this.room?.removeAllListeners(RoomEvent.TrackSubscriptionStatusChanged);
|
this.unregisterRoomListener(RoomEvent.TrackSubscriptionStatusChanged);
|
||||||
if (this.roomEvents.get(RoomEvent.TrackSubscriptionStatusChanged)) {
|
if (this.roomEvents.get(RoomEvent.TrackSubscriptionStatusChanged)) {
|
||||||
this.room!.on(
|
this.registerRoomListener(
|
||||||
RoomEvent.TrackSubscriptionStatusChanged,
|
RoomEvent.TrackSubscriptionStatusChanged,
|
||||||
(
|
(
|
||||||
publication: RemoteTrackPublication,
|
publication: RemoteTrackPublication,
|
||||||
|
|
@ -904,9 +1027,9 @@ export class OpenviduInstanceComponent {
|
||||||
this.roomEvents.get(RoomEvent.AudioPlaybackStatusChanged) !==
|
this.roomEvents.get(RoomEvent.AudioPlaybackStatusChanged) !==
|
||||||
oldValues.get(RoomEvent.AudioPlaybackStatusChanged)
|
oldValues.get(RoomEvent.AudioPlaybackStatusChanged)
|
||||||
) {
|
) {
|
||||||
this.room?.removeAllListeners(RoomEvent.AudioPlaybackStatusChanged);
|
this.unregisterRoomListener(RoomEvent.AudioPlaybackStatusChanged);
|
||||||
if (this.roomEvents.get(RoomEvent.AudioPlaybackStatusChanged)) {
|
if (this.roomEvents.get(RoomEvent.AudioPlaybackStatusChanged)) {
|
||||||
this.room!.on(
|
this.registerRoomListener(
|
||||||
RoomEvent.AudioPlaybackStatusChanged,
|
RoomEvent.AudioPlaybackStatusChanged,
|
||||||
(playing: boolean) => {
|
(playing: boolean) => {
|
||||||
this.updateEventList(
|
this.updateEventList(
|
||||||
|
|
@ -919,14 +1042,34 @@ export class OpenviduInstanceComponent {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
firstTime ||
|
||||||
|
this.roomEvents.get(RoomEvent.VideoPlaybackStatusChanged) !==
|
||||||
|
oldValues.get(RoomEvent.VideoPlaybackStatusChanged)
|
||||||
|
) {
|
||||||
|
this.unregisterRoomListener(RoomEvent.VideoPlaybackStatusChanged);
|
||||||
|
if (this.roomEvents.get(RoomEvent.VideoPlaybackStatusChanged)) {
|
||||||
|
this.registerRoomListener(
|
||||||
|
RoomEvent.VideoPlaybackStatusChanged,
|
||||||
|
(playing: boolean) => {
|
||||||
|
this.updateEventList(
|
||||||
|
RoomEvent.VideoPlaybackStatusChanged,
|
||||||
|
{ playing },
|
||||||
|
`canPlaybackVideo: ${playing}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
firstTime ||
|
firstTime ||
|
||||||
this.roomEvents.get(RoomEvent.SignalConnected) !==
|
this.roomEvents.get(RoomEvent.SignalConnected) !==
|
||||||
oldValues.get(RoomEvent.SignalConnected)
|
oldValues.get(RoomEvent.SignalConnected)
|
||||||
) {
|
) {
|
||||||
this.room?.removeAllListeners(RoomEvent.SignalConnected);
|
this.unregisterRoomListener(RoomEvent.SignalConnected);
|
||||||
if (this.roomEvents.get(RoomEvent.SignalConnected)) {
|
if (this.roomEvents.get(RoomEvent.SignalConnected)) {
|
||||||
this.room!.on(RoomEvent.SignalConnected, () => {
|
this.registerRoomListener(RoomEvent.SignalConnected, () => {
|
||||||
this.updateEventList(RoomEvent.SignalConnected, {}, '');
|
this.updateEventList(RoomEvent.SignalConnected, {}, '');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -937,9 +1080,9 @@ export class OpenviduInstanceComponent {
|
||||||
this.roomEvents.get(RoomEvent.RecordingStatusChanged) !==
|
this.roomEvents.get(RoomEvent.RecordingStatusChanged) !==
|
||||||
oldValues.get(RoomEvent.RecordingStatusChanged)
|
oldValues.get(RoomEvent.RecordingStatusChanged)
|
||||||
) {
|
) {
|
||||||
this.room?.removeAllListeners(RoomEvent.RecordingStatusChanged);
|
this.unregisterRoomListener(RoomEvent.RecordingStatusChanged);
|
||||||
if (this.roomEvents.get(RoomEvent.RecordingStatusChanged)) {
|
if (this.roomEvents.get(RoomEvent.RecordingStatusChanged)) {
|
||||||
this.room!.on(
|
this.registerRoomListener(
|
||||||
RoomEvent.RecordingStatusChanged,
|
RoomEvent.RecordingStatusChanged,
|
||||||
(recording: boolean) => {
|
(recording: boolean) => {
|
||||||
this.updateEventList(
|
this.updateEventList(
|
||||||
|
|
@ -957,11 +1100,11 @@ export class OpenviduInstanceComponent {
|
||||||
this.roomEvents.get(RoomEvent.ParticipantEncryptionStatusChanged) !==
|
this.roomEvents.get(RoomEvent.ParticipantEncryptionStatusChanged) !==
|
||||||
oldValues.get(RoomEvent.ParticipantEncryptionStatusChanged)
|
oldValues.get(RoomEvent.ParticipantEncryptionStatusChanged)
|
||||||
) {
|
) {
|
||||||
this.room?.removeAllListeners(
|
this.unregisterRoomListener(
|
||||||
RoomEvent.ParticipantEncryptionStatusChanged
|
RoomEvent.ParticipantEncryptionStatusChanged
|
||||||
);
|
);
|
||||||
if (this.roomEvents.get(RoomEvent.ParticipantEncryptionStatusChanged)) {
|
if (this.roomEvents.get(RoomEvent.ParticipantEncryptionStatusChanged)) {
|
||||||
this.room!.on(
|
this.registerRoomListener(
|
||||||
RoomEvent.ParticipantEncryptionStatusChanged,
|
RoomEvent.ParticipantEncryptionStatusChanged,
|
||||||
(encrypted: boolean, participant?: Participant) => {
|
(encrypted: boolean, participant?: Participant) => {
|
||||||
this.updateEventList(
|
this.updateEventList(
|
||||||
|
|
@ -979,9 +1122,9 @@ export class OpenviduInstanceComponent {
|
||||||
this.roomEvents.get(RoomEvent.EncryptionError) !==
|
this.roomEvents.get(RoomEvent.EncryptionError) !==
|
||||||
oldValues.get(RoomEvent.EncryptionError)
|
oldValues.get(RoomEvent.EncryptionError)
|
||||||
) {
|
) {
|
||||||
this.room?.removeAllListeners(RoomEvent.EncryptionError);
|
this.unregisterRoomListener(RoomEvent.EncryptionError);
|
||||||
if (this.roomEvents.get(RoomEvent.EncryptionError)) {
|
if (this.roomEvents.get(RoomEvent.EncryptionError)) {
|
||||||
this.room!.on(RoomEvent.EncryptionError, (error: Error) => {
|
this.registerRoomListener(RoomEvent.EncryptionError, (error: Error) => {
|
||||||
this.updateEventList(
|
this.updateEventList(
|
||||||
RoomEvent.EncryptionError,
|
RoomEvent.EncryptionError,
|
||||||
{ error: error.message },
|
{ error: error.message },
|
||||||
|
|
@ -996,9 +1139,9 @@ export class OpenviduInstanceComponent {
|
||||||
this.roomEvents.get(RoomEvent.DCBufferStatusChanged) !==
|
this.roomEvents.get(RoomEvent.DCBufferStatusChanged) !==
|
||||||
oldValues.get(RoomEvent.DCBufferStatusChanged)
|
oldValues.get(RoomEvent.DCBufferStatusChanged)
|
||||||
) {
|
) {
|
||||||
this.room?.removeAllListeners(RoomEvent.DCBufferStatusChanged);
|
this.unregisterRoomListener(RoomEvent.DCBufferStatusChanged);
|
||||||
if (this.roomEvents.get(RoomEvent.DCBufferStatusChanged)) {
|
if (this.roomEvents.get(RoomEvent.DCBufferStatusChanged)) {
|
||||||
this.room!.on(
|
this.registerRoomListener(
|
||||||
RoomEvent.DCBufferStatusChanged,
|
RoomEvent.DCBufferStatusChanged,
|
||||||
(isLow: boolean, kind: any) => {
|
(isLow: boolean, kind: any) => {
|
||||||
this.updateEventList(
|
this.updateEventList(
|
||||||
|
|
@ -1016,9 +1159,9 @@ export class OpenviduInstanceComponent {
|
||||||
this.roomEvents.get(RoomEvent.ActiveDeviceChanged) !==
|
this.roomEvents.get(RoomEvent.ActiveDeviceChanged) !==
|
||||||
oldValues.get(RoomEvent.ActiveDeviceChanged)
|
oldValues.get(RoomEvent.ActiveDeviceChanged)
|
||||||
) {
|
) {
|
||||||
this.room?.removeAllListeners(RoomEvent.ActiveDeviceChanged);
|
this.unregisterRoomListener(RoomEvent.ActiveDeviceChanged);
|
||||||
if (this.roomEvents.get(RoomEvent.ActiveDeviceChanged)) {
|
if (this.roomEvents.get(RoomEvent.ActiveDeviceChanged)) {
|
||||||
this.room!.on(
|
this.registerRoomListener(
|
||||||
RoomEvent.ActiveDeviceChanged,
|
RoomEvent.ActiveDeviceChanged,
|
||||||
(kind: MediaDeviceKind, deviceId: string) => {
|
(kind: MediaDeviceKind, deviceId: string) => {
|
||||||
this.updateEventList(
|
this.updateEventList(
|
||||||
|
|
@ -1036,9 +1179,9 @@ export class OpenviduInstanceComponent {
|
||||||
this.roomEvents.get(RoomEvent.LocalTrackSubscribed) !==
|
this.roomEvents.get(RoomEvent.LocalTrackSubscribed) !==
|
||||||
oldValues.get(RoomEvent.LocalTrackSubscribed)
|
oldValues.get(RoomEvent.LocalTrackSubscribed)
|
||||||
) {
|
) {
|
||||||
this.room?.removeAllListeners(RoomEvent.LocalTrackSubscribed);
|
this.unregisterRoomListener(RoomEvent.LocalTrackSubscribed);
|
||||||
if (this.roomEvents.get(RoomEvent.LocalTrackSubscribed)) {
|
if (this.roomEvents.get(RoomEvent.LocalTrackSubscribed)) {
|
||||||
this.room!.on(
|
this.registerRoomListener(
|
||||||
RoomEvent.LocalTrackSubscribed,
|
RoomEvent.LocalTrackSubscribed,
|
||||||
(
|
(
|
||||||
publication: LocalTrackPublication,
|
publication: LocalTrackPublication,
|
||||||
|
|
@ -1054,6 +1197,46 @@ export class OpenviduInstanceComponent {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
firstTime ||
|
||||||
|
this.roomEvents.get(RoomEvent.ChatMessage) !==
|
||||||
|
oldValues.get(RoomEvent.ChatMessage)
|
||||||
|
) {
|
||||||
|
this.unregisterRoomListener(RoomEvent.ChatMessage);
|
||||||
|
if (this.roomEvents.get(RoomEvent.ChatMessage)) {
|
||||||
|
this.registerRoomListener(
|
||||||
|
RoomEvent.ChatMessage,
|
||||||
|
(message: any, participant?: RemoteParticipant | LocalParticipant) => {
|
||||||
|
this.updateEventList(
|
||||||
|
RoomEvent.ChatMessage,
|
||||||
|
{ message, participant },
|
||||||
|
`${participant?.identity ?? 'unknown'}: ${message.message}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
firstTime ||
|
||||||
|
this.roomEvents.get(RoomEvent.MetricsReceived) !==
|
||||||
|
oldValues.get(RoomEvent.MetricsReceived)
|
||||||
|
) {
|
||||||
|
this.unregisterRoomListener(RoomEvent.MetricsReceived);
|
||||||
|
if (this.roomEvents.get(RoomEvent.MetricsReceived)) {
|
||||||
|
this.registerRoomListener(
|
||||||
|
RoomEvent.MetricsReceived,
|
||||||
|
(metrics: any, participant?: Participant) => {
|
||||||
|
this.updateEventList(
|
||||||
|
RoomEvent.MetricsReceived,
|
||||||
|
{ metrics, participant },
|
||||||
|
`${participant?.identity ?? 'unknown'}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
firstTime ||
|
firstTime ||
|
||||||
this.roomEvents.get(RoomEvent.TranscriptionReceived) !==
|
this.roomEvents.get(RoomEvent.TranscriptionReceived) !==
|
||||||
|
|
@ -1087,9 +1270,9 @@ export class OpenviduInstanceComponent {
|
||||||
this.roomEvents.get(RoomEvent.DataTrackPublished) !==
|
this.roomEvents.get(RoomEvent.DataTrackPublished) !==
|
||||||
oldValues.get(RoomEvent.DataTrackPublished)
|
oldValues.get(RoomEvent.DataTrackPublished)
|
||||||
) {
|
) {
|
||||||
this.room?.removeAllListeners(RoomEvent.DataTrackPublished);
|
this.unregisterRoomListener(RoomEvent.DataTrackPublished);
|
||||||
if (this.roomEvents.get(RoomEvent.DataTrackPublished)) {
|
if (this.roomEvents.get(RoomEvent.DataTrackPublished)) {
|
||||||
this.room!.on(
|
this.registerRoomListener(
|
||||||
RoomEvent.DataTrackPublished,
|
RoomEvent.DataTrackPublished,
|
||||||
(track: RemoteDataTrack) => {
|
(track: RemoteDataTrack) => {
|
||||||
this.updateEventList(
|
this.updateEventList(
|
||||||
|
|
@ -1107,9 +1290,9 @@ export class OpenviduInstanceComponent {
|
||||||
this.roomEvents.get(RoomEvent.DataTrackUnpublished) !==
|
this.roomEvents.get(RoomEvent.DataTrackUnpublished) !==
|
||||||
oldValues.get(RoomEvent.DataTrackUnpublished)
|
oldValues.get(RoomEvent.DataTrackUnpublished)
|
||||||
) {
|
) {
|
||||||
this.room?.removeAllListeners(RoomEvent.DataTrackUnpublished);
|
this.unregisterRoomListener(RoomEvent.DataTrackUnpublished);
|
||||||
if (this.roomEvents.get(RoomEvent.DataTrackUnpublished)) {
|
if (this.roomEvents.get(RoomEvent.DataTrackUnpublished)) {
|
||||||
this.room!.on(
|
this.registerRoomListener(
|
||||||
RoomEvent.DataTrackUnpublished,
|
RoomEvent.DataTrackUnpublished,
|
||||||
(sid: string) => {
|
(sid: string) => {
|
||||||
this.updateEventList(
|
this.updateEventList(
|
||||||
|
|
@ -1127,9 +1310,9 @@ export class OpenviduInstanceComponent {
|
||||||
this.roomEvents.get(RoomEvent.LocalDataTrackPublished) !==
|
this.roomEvents.get(RoomEvent.LocalDataTrackPublished) !==
|
||||||
oldValues.get(RoomEvent.LocalDataTrackPublished)
|
oldValues.get(RoomEvent.LocalDataTrackPublished)
|
||||||
) {
|
) {
|
||||||
this.room?.removeAllListeners(RoomEvent.LocalDataTrackPublished);
|
this.unregisterRoomListener(RoomEvent.LocalDataTrackPublished);
|
||||||
if (this.roomEvents.get(RoomEvent.LocalDataTrackPublished)) {
|
if (this.roomEvents.get(RoomEvent.LocalDataTrackPublished)) {
|
||||||
this.room!.on(
|
this.registerRoomListener(
|
||||||
RoomEvent.LocalDataTrackPublished,
|
RoomEvent.LocalDataTrackPublished,
|
||||||
(track: LocalDataTrack) => {
|
(track: LocalDataTrack) => {
|
||||||
this.updateEventList(
|
this.updateEventList(
|
||||||
|
|
@ -1147,9 +1330,9 @@ export class OpenviduInstanceComponent {
|
||||||
this.roomEvents.get(RoomEvent.LocalDataTrackUnpublished) !==
|
this.roomEvents.get(RoomEvent.LocalDataTrackUnpublished) !==
|
||||||
oldValues.get(RoomEvent.LocalDataTrackUnpublished)
|
oldValues.get(RoomEvent.LocalDataTrackUnpublished)
|
||||||
) {
|
) {
|
||||||
this.room?.removeAllListeners(RoomEvent.LocalDataTrackUnpublished);
|
this.unregisterRoomListener(RoomEvent.LocalDataTrackUnpublished);
|
||||||
if (this.roomEvents.get(RoomEvent.LocalDataTrackUnpublished)) {
|
if (this.roomEvents.get(RoomEvent.LocalDataTrackUnpublished)) {
|
||||||
this.room!.on(
|
this.registerRoomListener(
|
||||||
RoomEvent.LocalDataTrackUnpublished,
|
RoomEvent.LocalDataTrackUnpublished,
|
||||||
(sid: string) => {
|
(sid: string) => {
|
||||||
this.updateEventList(
|
this.updateEventList(
|
||||||
|
|
@ -1181,6 +1364,32 @@ export class OpenviduInstanceComponent {
|
||||||
|
|
||||||
async disconnectRoom() {
|
async disconnectRoom() {
|
||||||
if (this.room) {
|
if (this.room) {
|
||||||
|
// Clean up early listeners that were never handed off
|
||||||
|
if (this.earlyParticipantConnectedListener) {
|
||||||
|
this.room.removeListener(
|
||||||
|
RoomEvent.ParticipantConnected,
|
||||||
|
this.earlyParticipantConnectedListener as any
|
||||||
|
);
|
||||||
|
this.earlyParticipantConnectedListener = undefined;
|
||||||
|
}
|
||||||
|
for (const [key, listeners] of this.earlyParticipantListeners) {
|
||||||
|
const participant =
|
||||||
|
this.room.localParticipant.sid === key || this.room.localParticipant.identity === key
|
||||||
|
? this.room.localParticipant
|
||||||
|
: this.room.remoteParticipants.get(key);
|
||||||
|
if (participant) {
|
||||||
|
removeAllManagedListeners(participant, listeners);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.earlyParticipantEvents.clear();
|
||||||
|
this.earlyParticipantListeners.clear();
|
||||||
|
for (const [, listeners] of this.earlyTrackListeners) {
|
||||||
|
// Track listeners are cleaned up by disconnect, but clear maps
|
||||||
|
listeners.clear();
|
||||||
|
}
|
||||||
|
this.earlyTrackEvents.clear();
|
||||||
|
this.earlyTrackListeners.clear();
|
||||||
|
|
||||||
await this.room.disconnect();
|
await this.room.disconnect();
|
||||||
delete this.room;
|
delete this.room;
|
||||||
delete this.localTracks.audioTrack;
|
delete this.localTracks.audioTrack;
|
||||||
|
|
@ -1189,6 +1398,58 @@ export class OpenviduInstanceComponent {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private registerEarlyParticipantListeners(participant: Participant) {
|
||||||
|
const key = participant.sid || participant.identity;
|
||||||
|
const buffer: TestAppEvent[] = [];
|
||||||
|
this.earlyParticipantEvents.set(key, buffer);
|
||||||
|
|
||||||
|
const listeners = registerParticipantEventListeners(
|
||||||
|
participant,
|
||||||
|
(eventType, eventContent, eventDescription) => {
|
||||||
|
if (this.participantEvents.size > 0 && !this.participantEvents.get(eventType)) return;
|
||||||
|
const event: TestAppEvent = {
|
||||||
|
eventType,
|
||||||
|
eventCategory: 'ParticipantEvent',
|
||||||
|
eventContent,
|
||||||
|
eventDescription,
|
||||||
|
};
|
||||||
|
buffer.push(event);
|
||||||
|
this.testFeedService.pushNewEvent({ user: this.index, event });
|
||||||
|
|
||||||
|
// When a track becomes available during early registration, register early track listeners too
|
||||||
|
if (eventType === ParticipantEvent.TrackSubscribed && eventContent.track) {
|
||||||
|
this.registerEarlyTrackListeners(eventContent.track);
|
||||||
|
} else if (eventType === ParticipantEvent.LocalTrackPublished && eventContent.publication?.track) {
|
||||||
|
this.registerEarlyTrackListeners(eventContent.publication.track);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
this.decoder
|
||||||
|
);
|
||||||
|
this.earlyParticipantListeners.set(key, listeners);
|
||||||
|
}
|
||||||
|
|
||||||
|
private registerEarlyTrackListeners(track: Track) {
|
||||||
|
const key = track.sid || track.mediaStreamID;
|
||||||
|
const buffer: TestAppEvent[] = [];
|
||||||
|
this.earlyTrackEvents.set(key, buffer);
|
||||||
|
|
||||||
|
const listeners = registerTrackEventListeners(
|
||||||
|
track,
|
||||||
|
(eventType, eventContent, eventDescription) => {
|
||||||
|
if (this.trackEvents.size > 0 && !this.trackEvents.get(eventType)) return;
|
||||||
|
const event: TestAppEvent = {
|
||||||
|
eventType,
|
||||||
|
eventCategory: 'TrackEvent',
|
||||||
|
eventContent,
|
||||||
|
eventDescription,
|
||||||
|
};
|
||||||
|
buffer.push(event);
|
||||||
|
this.testFeedService.pushNewEvent({ user: this.index, event });
|
||||||
|
}
|
||||||
|
);
|
||||||
|
this.earlyTrackListeners.set(key, listeners);
|
||||||
|
}
|
||||||
|
|
||||||
async setCameraEnabled() {
|
async setCameraEnabled() {
|
||||||
this.room!.localParticipant.setCameraEnabled(true);
|
this.room!.localParticipant.setCameraEnabled(true);
|
||||||
}
|
}
|
||||||
|
|
@ -1253,15 +1514,18 @@ export class OpenviduInstanceComponent {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
openRoomEventsDialog() {
|
openAllEventsDialog() {
|
||||||
const oldValues: Map<string, boolean> = new Map(
|
const oldRoomValues: Map<string, boolean> = new Map(
|
||||||
JSON.parse(JSON.stringify([...this.roomEvents]))
|
JSON.parse(JSON.stringify([...this.roomEvents]))
|
||||||
);
|
);
|
||||||
|
|
||||||
const dialogRef = this.dialog.open(EventsDialogComponent, {
|
const dialogRef = this.dialog.open(EventsDialogComponent, {
|
||||||
data: {
|
data: {
|
||||||
eventCollection: this.roomEvents,
|
eventGroups: [
|
||||||
target: 'Session',
|
{ label: 'RoomEvent', eventCollection: this.roomEvents },
|
||||||
|
{ label: 'ParticipantEvent', eventCollection: this.participantEvents },
|
||||||
|
{ label: 'TrackEvent', eventCollection: this.trackEvents },
|
||||||
|
],
|
||||||
|
target: 'All',
|
||||||
},
|
},
|
||||||
width: '800px',
|
width: '800px',
|
||||||
autoFocus: false,
|
autoFocus: false,
|
||||||
|
|
@ -1272,9 +1536,9 @@ export class OpenviduInstanceComponent {
|
||||||
if (
|
if (
|
||||||
!!this.room &&
|
!!this.room &&
|
||||||
JSON.stringify(Array.from(this.roomEvents.entries())) !==
|
JSON.stringify(Array.from(this.roomEvents.entries())) !==
|
||||||
JSON.stringify(Array.from(oldValues.entries()))
|
JSON.stringify(Array.from(oldRoomValues.entries()))
|
||||||
) {
|
) {
|
||||||
this.setupRoomEventListeners(oldValues, false);
|
this.setupRoomEventListeners(oldRoomValues, false);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -105,13 +105,17 @@
|
||||||
@for (trackPublication of participant.audioTrackPublications| keyvalue; track trackPublication) {
|
@for (trackPublication of participant.audioTrackPublications| keyvalue; track trackPublication) {
|
||||||
<app-audio-track
|
<app-audio-track
|
||||||
[index]="index" [trackPublication]="trackPublication.value" [track]="trackPublication.value.audioTrack"
|
[index]="index" [trackPublication]="trackPublication.value" [track]="trackPublication.value.audioTrack"
|
||||||
[localParticipant]="localParticipant" (newTrackEvent)="onTrackEvent($event)"></app-audio-track>
|
[localParticipant]="localParticipant"
|
||||||
|
[earlyTrackEvents]="earlyTrackEvents" [earlyTrackListeners]="earlyTrackListeners"
|
||||||
|
(newTrackEvent)="onTrackEvent($event)"></app-audio-track>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
@for (trackPublication of participant.videoTrackPublications | keyvalue; track trackPublication) {
|
@for (trackPublication of participant.videoTrackPublications | keyvalue; track trackPublication) {
|
||||||
<app-video-track
|
<app-video-track
|
||||||
[index]="index" [trackPublication]="trackPublication.value" [track]="trackPublication.value.videoTrack"
|
[index]="index" [trackPublication]="trackPublication.value" [track]="trackPublication.value.videoTrack"
|
||||||
[localParticipant]="localParticipant" (newTrackEvent)="onTrackEvent($event)"></app-video-track>
|
[localParticipant]="localParticipant"
|
||||||
|
[earlyTrackEvents]="earlyTrackEvents" [earlyTrackListeners]="earlyTrackListeners"
|
||||||
|
(newTrackEvent)="onTrackEvent($event)"></app-video-track>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,9 +6,7 @@ import { MatTooltipModule } from '@angular/material/tooltip';
|
||||||
import { MatExpansionModule } from '@angular/material/expansion';
|
import { MatExpansionModule } from '@angular/material/expansion';
|
||||||
import {
|
import {
|
||||||
AudioCaptureOptions,
|
AudioCaptureOptions,
|
||||||
ConnectionQuality,
|
|
||||||
CreateLocalTracksOptions,
|
CreateLocalTracksOptions,
|
||||||
DataPacket_Kind,
|
|
||||||
LocalAudioTrack,
|
LocalAudioTrack,
|
||||||
LocalDataTrack,
|
LocalDataTrack,
|
||||||
LocalParticipant,
|
LocalParticipant,
|
||||||
|
|
@ -23,7 +21,6 @@ import {
|
||||||
Room,
|
Room,
|
||||||
RoomEvent,
|
RoomEvent,
|
||||||
ScreenShareCaptureOptions,
|
ScreenShareCaptureOptions,
|
||||||
SubscriptionError,
|
|
||||||
Track,
|
Track,
|
||||||
TrackEvent,
|
TrackEvent,
|
||||||
TrackPublication,
|
TrackPublication,
|
||||||
|
|
@ -33,7 +30,6 @@ import {
|
||||||
createLocalScreenTracks,
|
createLocalScreenTracks,
|
||||||
createLocalVideoTrack,
|
createLocalVideoTrack,
|
||||||
} from 'livekit-client';
|
} from 'livekit-client';
|
||||||
import { ParticipantPermission } from 'livekit-server-sdk';
|
|
||||||
import {
|
import {
|
||||||
TestAppEvent,
|
TestAppEvent,
|
||||||
TestFeedService,
|
TestFeedService,
|
||||||
|
|
@ -42,7 +38,10 @@ import { OptionsDialogComponent } from '../dialogs/options-dialog/options-dialog
|
||||||
import { VideoTrackComponent } from '../video-track/video-track.component';
|
import { VideoTrackComponent } from '../video-track/video-track.component';
|
||||||
import { AudioTrackComponent } from '../audio-track/audio-track.component';
|
import { AudioTrackComponent } from '../audio-track/audio-track.component';
|
||||||
import { DataTrackComponent } from '../data-track/data-track.component';
|
import { DataTrackComponent } from '../data-track/data-track.component';
|
||||||
import { ParticipantEventCallbacks } from 'node_modules/livekit-client/dist/src/room/participant/Participant';
|
import {
|
||||||
|
registerParticipantEventListeners,
|
||||||
|
removeAllManagedListeners,
|
||||||
|
} from 'src/app/utils/event-listener-utils';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-participant',
|
selector: 'app-participant',
|
||||||
|
|
@ -60,6 +59,24 @@ export class ParticipantComponent {
|
||||||
@Input()
|
@Input()
|
||||||
index: number;
|
index: number;
|
||||||
|
|
||||||
|
@Input()
|
||||||
|
participantEvents: Map<string, boolean> = new Map();
|
||||||
|
|
||||||
|
@Input()
|
||||||
|
trackEvents: Map<string, boolean> = new Map();
|
||||||
|
|
||||||
|
@Input()
|
||||||
|
earlyParticipantEvents: Map<string, TestAppEvent[]> = new Map();
|
||||||
|
|
||||||
|
@Input()
|
||||||
|
earlyParticipantListeners: Map<string, Map<string, (...args: any[]) => void>> = new Map();
|
||||||
|
|
||||||
|
@Input()
|
||||||
|
earlyTrackEvents: Map<string, TestAppEvent[]> = new Map();
|
||||||
|
|
||||||
|
@Input()
|
||||||
|
earlyTrackListeners: Map<string, Map<string, (...args: any[]) => void>> = new Map();
|
||||||
|
|
||||||
@Output()
|
@Output()
|
||||||
sendReliableDataToOneParticipant = new EventEmitter<string>();
|
sendReliableDataToOneParticipant = new EventEmitter<string>();
|
||||||
|
|
||||||
|
|
@ -80,6 +97,8 @@ export class ParticipantComponent {
|
||||||
trackPublishOptions?: TrackPublishOptions;
|
trackPublishOptions?: TrackPublishOptions;
|
||||||
|
|
||||||
private decoder = new TextDecoder();
|
private decoder = new TextDecoder();
|
||||||
|
private participantEventListeners: Map<string, (...args: any[]) => void> = new Map();
|
||||||
|
private roomListenersFromParticipant: Map<string, (...args: any[]) => void> = new Map();
|
||||||
|
|
||||||
private dialog = inject(MatDialog);
|
private dialog = inject(MatDialog);
|
||||||
|
|
||||||
|
|
@ -89,6 +108,19 @@ export class ParticipantComponent {
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
|
// Drain early participant events buffered before this component existed
|
||||||
|
const key = this.participant.sid || this.participant.identity;
|
||||||
|
const earlyEvents = this.earlyParticipantEvents?.get(key);
|
||||||
|
if (earlyEvents) {
|
||||||
|
this.events.push(...earlyEvents);
|
||||||
|
this.earlyParticipantEvents.delete(key);
|
||||||
|
}
|
||||||
|
// Remove early listeners and replace with component-owned ones
|
||||||
|
const earlyListeners = this.earlyParticipantListeners?.get(key);
|
||||||
|
if (earlyListeners) {
|
||||||
|
removeAllManagedListeners(this.participant, earlyListeners);
|
||||||
|
this.earlyParticipantListeners.delete(key);
|
||||||
|
}
|
||||||
this.setupParticipantEventListeners();
|
this.setupParticipantEventListeners();
|
||||||
this.localParticipant = this.participant.isLocal
|
this.localParticipant = this.participant.isLocal
|
||||||
? (this.participant as LocalParticipant)
|
? (this.participant as LocalParticipant)
|
||||||
|
|
@ -106,7 +138,11 @@ export class ParticipantComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
onTrackEvent(event: TestAppEvent) {
|
onTrackEvent(event: TestAppEvent) {
|
||||||
|
if (this.trackEvents.size > 0 && !this.trackEvents.get(event.eventType)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
this.events.push(event);
|
this.events.push(event);
|
||||||
|
this.testFeedService.pushNewEvent({ user: this.index, event });
|
||||||
this.cdr.detectChanges();
|
this.cdr.detectChanges();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -246,251 +282,16 @@ export class ParticipantComponent {
|
||||||
* [ParticipantEventCallbacks]
|
* [ParticipantEventCallbacks]
|
||||||
*/
|
*/
|
||||||
setupParticipantEventListeners() {
|
setupParticipantEventListeners() {
|
||||||
// This is a link to the complete list of Participant events
|
// Remove any previous listeners
|
||||||
let callbacks: ParticipantEventCallbacks;
|
removeAllManagedListeners(this.participant, this.participantEventListeners);
|
||||||
let events: ParticipantEvent;
|
|
||||||
|
|
||||||
this.participant
|
this.participantEventListeners = registerParticipantEventListeners(
|
||||||
|
this.participant,
|
||||||
.on(
|
(eventType, eventContent, eventDescription) => {
|
||||||
ParticipantEvent.TrackPublished,
|
this.updateEventList(eventType, 'ParticipantEvent', eventContent, eventDescription);
|
||||||
(publication: RemoteTrackPublication) => {
|
},
|
||||||
this.updateEventList(
|
this.decoder
|
||||||
ParticipantEvent.TrackPublished,
|
);
|
||||||
'ParticipantEvent',
|
|
||||||
{ publication },
|
|
||||||
publication.source
|
|
||||||
);
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
.on(
|
|
||||||
ParticipantEvent.TrackSubscribed,
|
|
||||||
(track: RemoteTrack, publication: RemoteTrackPublication) => {
|
|
||||||
this.updateEventList(
|
|
||||||
ParticipantEvent.TrackSubscribed,
|
|
||||||
'ParticipantEvent',
|
|
||||||
{ track, publication },
|
|
||||||
publication.source
|
|
||||||
);
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
.on(
|
|
||||||
ParticipantEvent.TrackSubscriptionFailed,
|
|
||||||
(trackSid: string, reason?: SubscriptionError) => {
|
|
||||||
this.updateEventList(
|
|
||||||
ParticipantEvent.TrackSubscriptionFailed,
|
|
||||||
'ParticipantEvent',
|
|
||||||
{ trackSid, reason },
|
|
||||||
trackSid +
|
|
||||||
' . Reason: ' +
|
|
||||||
(reason ? SubscriptionError[reason] : reason)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
.on(
|
|
||||||
ParticipantEvent.TrackUnpublished,
|
|
||||||
(publication: RemoteTrackPublication) => {
|
|
||||||
this.updateEventList(
|
|
||||||
ParticipantEvent.TrackUnpublished,
|
|
||||||
'ParticipantEvent',
|
|
||||||
{ publication },
|
|
||||||
publication.source
|
|
||||||
);
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
.on(
|
|
||||||
ParticipantEvent.TrackUnsubscribed,
|
|
||||||
(track: RemoteTrack, publication: RemoteTrackPublication) => {
|
|
||||||
this.updateEventList(
|
|
||||||
ParticipantEvent.TrackUnsubscribed,
|
|
||||||
'ParticipantEvent',
|
|
||||||
{ track, publication },
|
|
||||||
track.source
|
|
||||||
);
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
.on(ParticipantEvent.TrackMuted, (publication: TrackPublication) => {
|
|
||||||
this.updateEventList(
|
|
||||||
ParticipantEvent.TrackMuted,
|
|
||||||
'ParticipantEvent',
|
|
||||||
{ publication },
|
|
||||||
publication.source
|
|
||||||
);
|
|
||||||
})
|
|
||||||
|
|
||||||
.on(ParticipantEvent.TrackUnmuted, (publication: TrackPublication) => {
|
|
||||||
this.updateEventList(
|
|
||||||
ParticipantEvent.TrackUnmuted,
|
|
||||||
'ParticipantEvent',
|
|
||||||
{ publication },
|
|
||||||
publication.source
|
|
||||||
);
|
|
||||||
})
|
|
||||||
|
|
||||||
.on(
|
|
||||||
ParticipantEvent.LocalTrackPublished,
|
|
||||||
(publication: LocalTrackPublication) => {
|
|
||||||
this.updateEventList(
|
|
||||||
ParticipantEvent.LocalTrackPublished,
|
|
||||||
'ParticipantEvent',
|
|
||||||
{ publication },
|
|
||||||
publication.source
|
|
||||||
);
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
.on(
|
|
||||||
ParticipantEvent.LocalTrackUnpublished,
|
|
||||||
(publication: LocalTrackPublication) => {
|
|
||||||
this.updateEventList(
|
|
||||||
ParticipantEvent.LocalTrackUnpublished,
|
|
||||||
'ParticipantEvent',
|
|
||||||
{ publication },
|
|
||||||
publication.source
|
|
||||||
);
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
.on(
|
|
||||||
ParticipantEvent.ParticipantMetadataChanged,
|
|
||||||
(prevMetadata: string | undefined) => {
|
|
||||||
this.updateEventList(
|
|
||||||
ParticipantEvent.ParticipantMetadataChanged,
|
|
||||||
'ParticipantEvent',
|
|
||||||
{ prevMetadata },
|
|
||||||
`previous: ${prevMetadata}, new: ${this.participant.metadata}`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
.on(ParticipantEvent.ParticipantNameChanged, (name: string) => {
|
|
||||||
this.updateEventList(
|
|
||||||
ParticipantEvent.ParticipantNameChanged,
|
|
||||||
'ParticipantEvent',
|
|
||||||
{ name },
|
|
||||||
`${name}`
|
|
||||||
);
|
|
||||||
})
|
|
||||||
|
|
||||||
.on(
|
|
||||||
ParticipantEvent.DataReceived,
|
|
||||||
(payload: Uint8Array, kind: DataPacket_Kind) => {
|
|
||||||
let decodedPayload = this.decoder.decode(payload);
|
|
||||||
decodedPayload += ` (kind: ${DataPacket_Kind[kind]})`;
|
|
||||||
this.updateEventList(
|
|
||||||
ParticipantEvent.DataReceived,
|
|
||||||
'ParticipantEvent',
|
|
||||||
{ payload: decodedPayload, kind },
|
|
||||||
decodedPayload
|
|
||||||
);
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
.on(ParticipantEvent.IsSpeakingChanged, (speaking: boolean) => {
|
|
||||||
this.updateEventList(
|
|
||||||
ParticipantEvent.IsSpeakingChanged,
|
|
||||||
'ParticipantEvent',
|
|
||||||
{ speaking },
|
|
||||||
`${speaking}`
|
|
||||||
);
|
|
||||||
})
|
|
||||||
|
|
||||||
.on(
|
|
||||||
ParticipantEvent.ConnectionQualityChanged,
|
|
||||||
(connectionQuality: ConnectionQuality) => {
|
|
||||||
this.updateEventList(
|
|
||||||
ParticipantEvent.ConnectionQualityChanged,
|
|
||||||
'ParticipantEvent',
|
|
||||||
{ connectionQuality },
|
|
||||||
`${connectionQuality}`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
.on(
|
|
||||||
ParticipantEvent.TrackStreamStateChanged,
|
|
||||||
(
|
|
||||||
publication: RemoteTrackPublication,
|
|
||||||
streamState: Track.StreamState
|
|
||||||
) => {
|
|
||||||
this.updateEventList(
|
|
||||||
ParticipantEvent.TrackStreamStateChanged,
|
|
||||||
'ParticipantEvent',
|
|
||||||
{ publication, streamState },
|
|
||||||
`${publication.source}: ${streamState}`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
.on(
|
|
||||||
ParticipantEvent.TrackSubscriptionPermissionChanged,
|
|
||||||
(
|
|
||||||
publication: RemoteTrackPublication,
|
|
||||||
status: TrackPublication.PermissionStatus
|
|
||||||
) => {
|
|
||||||
this.updateEventList(
|
|
||||||
ParticipantEvent.TrackSubscriptionPermissionChanged,
|
|
||||||
'ParticipantEvent',
|
|
||||||
{ publication, status },
|
|
||||||
`${publication.source}: ${status}`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
.on(ParticipantEvent.MediaDevicesError, (error: Error) => {
|
|
||||||
this.updateEventList(
|
|
||||||
ParticipantEvent.MediaDevicesError,
|
|
||||||
'ParticipantEvent',
|
|
||||||
{ error },
|
|
||||||
`${error.message}`
|
|
||||||
);
|
|
||||||
})
|
|
||||||
|
|
||||||
.on(
|
|
||||||
ParticipantEvent.ParticipantPermissionsChanged,
|
|
||||||
(prevPermissions?: ParticipantPermission) => {
|
|
||||||
this.updateEventList(
|
|
||||||
ParticipantEvent.ParticipantPermissionsChanged,
|
|
||||||
'ParticipantEvent',
|
|
||||||
{ prevPermissions },
|
|
||||||
`previous: ${prevPermissions}, new: ${JSON.stringify(
|
|
||||||
this.participant.permissions
|
|
||||||
)}`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
.on(
|
|
||||||
ParticipantEvent.TrackSubscriptionStatusChanged,
|
|
||||||
(
|
|
||||||
publication: RemoteTrackPublication,
|
|
||||||
status: TrackPublication.SubscriptionStatus
|
|
||||||
) => {
|
|
||||||
this.updateEventList(
|
|
||||||
ParticipantEvent.TrackSubscriptionStatusChanged,
|
|
||||||
'ParticipantEvent',
|
|
||||||
{ publication, status },
|
|
||||||
`${publication.source}: ${status}`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
.on(
|
|
||||||
ParticipantEvent.LocalTrackSubscribed,
|
|
||||||
(trackPublication: LocalTrackPublication) => {
|
|
||||||
this.updateEventList(
|
|
||||||
ParticipantEvent.LocalTrackSubscribed,
|
|
||||||
'ParticipantEvent',
|
|
||||||
{ trackPublication },
|
|
||||||
trackPublication.source
|
|
||||||
);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
updateEventList(
|
updateEventList(
|
||||||
|
|
@ -499,6 +300,9 @@ export class ParticipantComponent {
|
||||||
eventContent: any,
|
eventContent: any,
|
||||||
eventDescription: string
|
eventDescription: string
|
||||||
) {
|
) {
|
||||||
|
if (this.participantEvents.size > 0 && !this.participantEvents.get(eventType)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
const event: TestAppEvent = {
|
const event: TestAppEvent = {
|
||||||
eventType,
|
eventType,
|
||||||
eventCategory,
|
eventCategory,
|
||||||
|
|
@ -518,23 +322,22 @@ export class ParticipantComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
private setupDataTrackListeners() {
|
private setupDataTrackListeners() {
|
||||||
this.room.on(
|
const publishedListener = (track: RemoteDataTrack) => {
|
||||||
RoomEvent.DataTrackPublished,
|
if (track.publisherIdentity === this.participant.identity) {
|
||||||
(track: RemoteDataTrack) => {
|
this.remoteDataTracks.push(track);
|
||||||
if (track.publisherIdentity === this.participant.identity) {
|
|
||||||
this.remoteDataTracks.push(track);
|
|
||||||
this.cdr.detectChanges();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
this.room.on(
|
|
||||||
RoomEvent.DataTrackUnpublished,
|
|
||||||
(sid: string) => {
|
|
||||||
this.remoteDataTracks = this.remoteDataTracks.filter(
|
|
||||||
(t) => t.info.sid !== sid
|
|
||||||
);
|
|
||||||
this.cdr.detectChanges();
|
this.cdr.detectChanges();
|
||||||
}
|
}
|
||||||
);
|
};
|
||||||
|
this.room.addListener(RoomEvent.DataTrackPublished, publishedListener);
|
||||||
|
this.roomListenersFromParticipant.set(RoomEvent.DataTrackPublished, publishedListener as any);
|
||||||
|
|
||||||
|
const unpublishedListener = (sid: string) => {
|
||||||
|
this.remoteDataTracks = this.remoteDataTracks.filter(
|
||||||
|
(t) => t.info.sid !== sid
|
||||||
|
);
|
||||||
|
this.cdr.detectChanges();
|
||||||
|
};
|
||||||
|
this.room.addListener(RoomEvent.DataTrackUnpublished, unpublishedListener);
|
||||||
|
this.roomListenersFromParticipant.set(RoomEvent.DataTrackUnpublished, unpublishedListener as any);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,6 @@ import {
|
||||||
TrackEvent,
|
TrackEvent,
|
||||||
LocalTrack,
|
LocalTrack,
|
||||||
RemoteTrack,
|
RemoteTrack,
|
||||||
TrackEventCallbacks,
|
|
||||||
RemoteTrackPublication,
|
RemoteTrackPublication,
|
||||||
AudioTrack,
|
AudioTrack,
|
||||||
VideoTrack,
|
VideoTrack,
|
||||||
|
|
@ -22,6 +21,10 @@ import {
|
||||||
TestAppEvent,
|
TestAppEvent,
|
||||||
TestFeedService,
|
TestFeedService,
|
||||||
} from 'src/app/services/test-feed.service';
|
} from 'src/app/services/test-feed.service';
|
||||||
|
import {
|
||||||
|
registerTrackEventListeners,
|
||||||
|
removeAllManagedListeners,
|
||||||
|
} from 'src/app/utils/event-listener-utils';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-track',
|
selector: 'app-track',
|
||||||
|
|
@ -42,6 +45,12 @@ export class TrackComponent {
|
||||||
@Input()
|
@Input()
|
||||||
localParticipant: LocalParticipant | undefined;
|
localParticipant: LocalParticipant | undefined;
|
||||||
|
|
||||||
|
@Input()
|
||||||
|
earlyTrackEvents: Map<string, TestAppEvent[]> = new Map();
|
||||||
|
|
||||||
|
@Input()
|
||||||
|
earlyTrackListeners: Map<string, Map<string, (...args: any[]) => void>> = new Map();
|
||||||
|
|
||||||
protected finalElementRefId: string = '';
|
protected finalElementRefId: string = '';
|
||||||
private indexId: string;
|
private indexId: string;
|
||||||
private trackId: string;
|
private trackId: string;
|
||||||
|
|
@ -52,6 +61,8 @@ export class TrackComponent {
|
||||||
trackSubscribed: boolean = true;
|
trackSubscribed: boolean = true;
|
||||||
trackEnabled: boolean = true;
|
trackEnabled: boolean = true;
|
||||||
|
|
||||||
|
private trackEventListeners: Map<string, (...args: any[]) => void> = new Map();
|
||||||
|
|
||||||
constructor(protected testFeedService: TestFeedService) {}
|
constructor(protected testFeedService: TestFeedService) {}
|
||||||
|
|
||||||
@Input() set index(index: number) {
|
@Input() set index(index: number) {
|
||||||
|
|
@ -62,6 +73,23 @@ export class TrackComponent {
|
||||||
@Input() set track(track: AudioTrack | VideoTrack | undefined) {
|
@Input() set track(track: AudioTrack | VideoTrack | undefined) {
|
||||||
this._track = track;
|
this._track = track;
|
||||||
|
|
||||||
|
// Drain early track events buffered before this component existed
|
||||||
|
if (this._track) {
|
||||||
|
const key = this._track.sid || this._track.mediaStreamID;
|
||||||
|
const earlyEvents = this.earlyTrackEvents?.get(key);
|
||||||
|
if (earlyEvents) {
|
||||||
|
for (const event of earlyEvents) {
|
||||||
|
this.newTrackEvent.emit(event as any);
|
||||||
|
}
|
||||||
|
this.earlyTrackEvents.delete(key);
|
||||||
|
}
|
||||||
|
const earlyListeners = this.earlyTrackListeners?.get(key);
|
||||||
|
if (earlyListeners) {
|
||||||
|
removeAllManagedListeners(this._track, earlyListeners);
|
||||||
|
this.earlyTrackListeners.delete(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
this.setupTrackEventListeners();
|
this.setupTrackEventListeners();
|
||||||
|
|
||||||
this.trackId = `-${this.getTrackOrigin()}--${this._track?.kind}--${
|
this.trackId = `-${this.getTrackOrigin()}--${this._track?.kind}--${
|
||||||
|
|
@ -115,93 +143,22 @@ export class TrackComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected setupTrackEventListeners() {
|
protected setupTrackEventListeners() {
|
||||||
// This is a link to the complete list of Track events
|
if (!this._track) return;
|
||||||
let callbacks: TrackEventCallbacks;
|
|
||||||
let events: TrackEvent;
|
|
||||||
|
|
||||||
this._track
|
// Clear previous listeners (in case track changed)
|
||||||
?.on(TrackEvent.Message, () => {
|
removeAllManagedListeners(this._track, this.trackEventListeners);
|
||||||
|
|
||||||
|
this.trackEventListeners = registerTrackEventListeners(
|
||||||
|
this._track,
|
||||||
|
(eventType, eventContent, eventDescription) => {
|
||||||
this.newTrackEvent.emit({
|
this.newTrackEvent.emit({
|
||||||
eventType: TrackEvent.Message,
|
eventType,
|
||||||
eventCategory: 'TrackEvent',
|
eventCategory: 'TrackEvent',
|
||||||
eventContent: {},
|
eventContent,
|
||||||
eventDescription: this._track!.source,
|
eventDescription,
|
||||||
});
|
});
|
||||||
})
|
}
|
||||||
.on(TrackEvent.Muted, () => {
|
);
|
||||||
this.newTrackEvent.emit({
|
|
||||||
eventType: TrackEvent.Muted,
|
|
||||||
eventCategory: 'TrackEvent',
|
|
||||||
eventContent: {},
|
|
||||||
eventDescription: this._track!.source,
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.on(TrackEvent.Unmuted, () => {
|
|
||||||
this.newTrackEvent.emit({
|
|
||||||
eventType: TrackEvent.Unmuted,
|
|
||||||
eventCategory: 'TrackEvent',
|
|
||||||
eventContent: {},
|
|
||||||
eventDescription: this._track!.source,
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.on(TrackEvent.AudioSilenceDetected, () => {
|
|
||||||
this.newTrackEvent.emit({
|
|
||||||
eventType: TrackEvent.AudioSilenceDetected,
|
|
||||||
eventCategory: 'TrackEvent',
|
|
||||||
eventContent: {},
|
|
||||||
eventDescription: this._track!.source,
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.on(TrackEvent.Restarted, () => {
|
|
||||||
this.newTrackEvent.emit({
|
|
||||||
eventType: TrackEvent.Restarted,
|
|
||||||
eventCategory: 'TrackEvent',
|
|
||||||
eventContent: {},
|
|
||||||
eventDescription: this._track!.source,
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.on(TrackEvent.Ended, () => {
|
|
||||||
this.newTrackEvent.emit({
|
|
||||||
eventType: TrackEvent.Ended,
|
|
||||||
eventCategory: 'TrackEvent',
|
|
||||||
eventContent: {},
|
|
||||||
eventDescription: this._track!.source,
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.on(TrackEvent.VisibilityChanged, (visible: boolean) => {
|
|
||||||
this.newTrackEvent.emit({
|
|
||||||
eventType: TrackEvent.VisibilityChanged,
|
|
||||||
eventCategory: 'TrackEvent',
|
|
||||||
eventContent: { visible, track: this._track },
|
|
||||||
eventDescription: `${this._track!.source} is visible: ${visible}`,
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.on(TrackEvent.VideoDimensionsChanged, (dimensions: Track.Dimensions) => {
|
|
||||||
this.newTrackEvent.emit({
|
|
||||||
eventType: TrackEvent.VideoDimensionsChanged,
|
|
||||||
eventCategory: 'TrackEvent',
|
|
||||||
eventContent: { dimensions, track: this._track },
|
|
||||||
eventDescription: `${this._track?.source} ${JSON.stringify(
|
|
||||||
dimensions
|
|
||||||
)}`,
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.on(TrackEvent.UpstreamPaused, () => {
|
|
||||||
this.newTrackEvent.emit({
|
|
||||||
eventType: TrackEvent.UpstreamPaused,
|
|
||||||
eventCategory: 'TrackEvent',
|
|
||||||
eventContent: {},
|
|
||||||
eventDescription: this._track!.source,
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.on(TrackEvent.UpstreamResumed, () => {
|
|
||||||
this.newTrackEvent.emit({
|
|
||||||
eventType: TrackEvent.UpstreamResumed,
|
|
||||||
eventCategory: 'TrackEvent',
|
|
||||||
eventContent: {},
|
|
||||||
eventDescription: this._track!.source,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected getTrackOrigin(): string {
|
protected getTrackOrigin(): string {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,331 @@
|
||||||
|
import {
|
||||||
|
ConnectionQuality,
|
||||||
|
DataPacket_Kind,
|
||||||
|
LocalTrackPublication,
|
||||||
|
LocalVideoTrack,
|
||||||
|
Participant,
|
||||||
|
ParticipantEvent,
|
||||||
|
RemoteTrack,
|
||||||
|
RemoteTrackPublication,
|
||||||
|
SubscriptionError,
|
||||||
|
Track,
|
||||||
|
TrackEvent,
|
||||||
|
TrackPublication,
|
||||||
|
} from 'livekit-client';
|
||||||
|
import type { TranscriptionSegment, ChatMessage } from 'livekit-client';
|
||||||
|
import { ParticipantPermission } from 'livekit-server-sdk';
|
||||||
|
|
||||||
|
export type ParticipantOnEvent = (
|
||||||
|
eventType: ParticipantEvent,
|
||||||
|
eventContent: any,
|
||||||
|
eventDescription: string
|
||||||
|
) => void;
|
||||||
|
|
||||||
|
export type TrackOnEvent = (
|
||||||
|
eventType: TrackEvent,
|
||||||
|
eventContent: any,
|
||||||
|
eventDescription: string
|
||||||
|
) => void;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers ALL participant event listeners on the given participant.
|
||||||
|
* Returns the listener map for later cleanup/replacement.
|
||||||
|
*/
|
||||||
|
export function registerParticipantEventListeners(
|
||||||
|
participant: Participant,
|
||||||
|
onEvent: ParticipantOnEvent,
|
||||||
|
decoder: TextDecoder
|
||||||
|
): Map<string, (...args: any[]) => void> {
|
||||||
|
const listeners = new Map<string, (...args: any[]) => void>();
|
||||||
|
|
||||||
|
const reg = (event: ParticipantEvent, listener: (...args: any[]) => void) => {
|
||||||
|
participant.addListener(event as any, listener as any);
|
||||||
|
listeners.set(event, listener);
|
||||||
|
};
|
||||||
|
|
||||||
|
reg(ParticipantEvent.TrackPublished, (publication: RemoteTrackPublication) => {
|
||||||
|
onEvent(ParticipantEvent.TrackPublished, { publication }, publication.source);
|
||||||
|
});
|
||||||
|
|
||||||
|
reg(ParticipantEvent.TrackSubscribed, (track: RemoteTrack, publication: RemoteTrackPublication) => {
|
||||||
|
onEvent(ParticipantEvent.TrackSubscribed, { track, publication }, publication.source);
|
||||||
|
});
|
||||||
|
|
||||||
|
reg(ParticipantEvent.TrackSubscriptionFailed, (trackSid: string, reason?: SubscriptionError) => {
|
||||||
|
onEvent(
|
||||||
|
ParticipantEvent.TrackSubscriptionFailed,
|
||||||
|
{ trackSid, reason },
|
||||||
|
trackSid + ' . Reason: ' + (reason ? SubscriptionError[reason] : reason)
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
reg(ParticipantEvent.TrackUnpublished, (publication: RemoteTrackPublication) => {
|
||||||
|
onEvent(ParticipantEvent.TrackUnpublished, { publication }, publication.source);
|
||||||
|
});
|
||||||
|
|
||||||
|
reg(ParticipantEvent.TrackUnsubscribed, (track: RemoteTrack, publication: RemoteTrackPublication) => {
|
||||||
|
onEvent(ParticipantEvent.TrackUnsubscribed, { track, publication }, track.source);
|
||||||
|
});
|
||||||
|
|
||||||
|
reg(ParticipantEvent.TrackMuted, (publication: TrackPublication) => {
|
||||||
|
onEvent(ParticipantEvent.TrackMuted, { publication }, publication.source);
|
||||||
|
});
|
||||||
|
|
||||||
|
reg(ParticipantEvent.TrackUnmuted, (publication: TrackPublication) => {
|
||||||
|
onEvent(ParticipantEvent.TrackUnmuted, { publication }, publication.source);
|
||||||
|
});
|
||||||
|
|
||||||
|
reg(ParticipantEvent.LocalTrackPublished, (publication: LocalTrackPublication) => {
|
||||||
|
onEvent(ParticipantEvent.LocalTrackPublished, { publication }, publication.source);
|
||||||
|
});
|
||||||
|
|
||||||
|
reg(ParticipantEvent.LocalTrackUnpublished, (publication: LocalTrackPublication) => {
|
||||||
|
onEvent(ParticipantEvent.LocalTrackUnpublished, { publication }, publication.source);
|
||||||
|
});
|
||||||
|
|
||||||
|
reg(ParticipantEvent.ParticipantMetadataChanged, (prevMetadata: string | undefined) => {
|
||||||
|
onEvent(
|
||||||
|
ParticipantEvent.ParticipantMetadataChanged,
|
||||||
|
{ prevMetadata },
|
||||||
|
`previous: ${prevMetadata}, new: ${participant.metadata}`
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
reg(ParticipantEvent.ParticipantNameChanged, (name: string) => {
|
||||||
|
onEvent(ParticipantEvent.ParticipantNameChanged, { name }, `${name}`);
|
||||||
|
});
|
||||||
|
|
||||||
|
reg(ParticipantEvent.DataReceived, (payload: Uint8Array, kind: DataPacket_Kind) => {
|
||||||
|
let decodedPayload = decoder.decode(payload);
|
||||||
|
decodedPayload += ` (kind: ${DataPacket_Kind[kind]})`;
|
||||||
|
onEvent(ParticipantEvent.DataReceived, { payload: decodedPayload, kind }, decodedPayload);
|
||||||
|
});
|
||||||
|
|
||||||
|
reg(ParticipantEvent.IsSpeakingChanged, (speaking: boolean) => {
|
||||||
|
onEvent(ParticipantEvent.IsSpeakingChanged, { speaking }, `${speaking}`);
|
||||||
|
});
|
||||||
|
|
||||||
|
reg(ParticipantEvent.ConnectionQualityChanged, (connectionQuality: ConnectionQuality) => {
|
||||||
|
onEvent(ParticipantEvent.ConnectionQualityChanged, { connectionQuality }, `${connectionQuality}`);
|
||||||
|
});
|
||||||
|
|
||||||
|
reg(
|
||||||
|
ParticipantEvent.TrackStreamStateChanged,
|
||||||
|
(publication: RemoteTrackPublication, streamState: Track.StreamState) => {
|
||||||
|
onEvent(
|
||||||
|
ParticipantEvent.TrackStreamStateChanged,
|
||||||
|
{ publication, streamState },
|
||||||
|
`${publication.source}: ${streamState}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
reg(
|
||||||
|
ParticipantEvent.TrackSubscriptionPermissionChanged,
|
||||||
|
(publication: RemoteTrackPublication, status: TrackPublication.PermissionStatus) => {
|
||||||
|
onEvent(
|
||||||
|
ParticipantEvent.TrackSubscriptionPermissionChanged,
|
||||||
|
{ publication, status },
|
||||||
|
`${publication.source}: ${status}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
reg(ParticipantEvent.MediaDevicesError, (error: Error) => {
|
||||||
|
onEvent(ParticipantEvent.MediaDevicesError, { error }, `${error.message}`);
|
||||||
|
});
|
||||||
|
|
||||||
|
reg(ParticipantEvent.ParticipantPermissionsChanged, (prevPermissions?: ParticipantPermission) => {
|
||||||
|
onEvent(
|
||||||
|
ParticipantEvent.ParticipantPermissionsChanged,
|
||||||
|
{ prevPermissions },
|
||||||
|
`previous: ${prevPermissions}, new: ${JSON.stringify(participant.permissions)}`
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
reg(
|
||||||
|
ParticipantEvent.TrackSubscriptionStatusChanged,
|
||||||
|
(publication: RemoteTrackPublication, status: TrackPublication.SubscriptionStatus) => {
|
||||||
|
onEvent(
|
||||||
|
ParticipantEvent.TrackSubscriptionStatusChanged,
|
||||||
|
{ publication, status },
|
||||||
|
`${publication.source}: ${status}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
reg(ParticipantEvent.LocalTrackSubscribed, (trackPublication: LocalTrackPublication) => {
|
||||||
|
onEvent(ParticipantEvent.LocalTrackSubscribed, { trackPublication }, trackPublication.source);
|
||||||
|
});
|
||||||
|
|
||||||
|
reg(
|
||||||
|
ParticipantEvent.LocalTrackCpuConstrained,
|
||||||
|
(track: LocalVideoTrack, publication: LocalTrackPublication) => {
|
||||||
|
onEvent(ParticipantEvent.LocalTrackCpuConstrained, { track, publication }, publication.source);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
reg(ParticipantEvent.SipDTMFReceived, (dtmf: any) => {
|
||||||
|
onEvent(ParticipantEvent.SipDTMFReceived, { dtmf }, JSON.stringify(dtmf));
|
||||||
|
});
|
||||||
|
|
||||||
|
reg(
|
||||||
|
ParticipantEvent.TranscriptionReceived,
|
||||||
|
(transcription: TranscriptionSegment[], publication?: TrackPublication) => {
|
||||||
|
onEvent(
|
||||||
|
ParticipantEvent.TranscriptionReceived,
|
||||||
|
{ transcription, publication },
|
||||||
|
`segments: ${transcription.length}, source: ${publication?.source ?? 'unknown'}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
reg(ParticipantEvent.AudioStreamAcquired, () => {
|
||||||
|
onEvent(ParticipantEvent.AudioStreamAcquired, {}, '');
|
||||||
|
});
|
||||||
|
|
||||||
|
reg(ParticipantEvent.AttributesChanged, (changedAttributes: Record<string, string>) => {
|
||||||
|
onEvent(ParticipantEvent.AttributesChanged, { changedAttributes }, JSON.stringify(changedAttributes));
|
||||||
|
});
|
||||||
|
|
||||||
|
reg(ParticipantEvent.ChatMessage, (msg: ChatMessage) => {
|
||||||
|
onEvent(ParticipantEvent.ChatMessage, { msg }, msg.message);
|
||||||
|
});
|
||||||
|
|
||||||
|
reg(ParticipantEvent.Active, () => {
|
||||||
|
onEvent(ParticipantEvent.Active, {}, '');
|
||||||
|
});
|
||||||
|
|
||||||
|
return listeners;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes all listeners in the given map from the target emitter.
|
||||||
|
*/
|
||||||
|
export function removeAllManagedListeners(
|
||||||
|
target: any,
|
||||||
|
listeners: Map<string, (...args: any[]) => void>
|
||||||
|
) {
|
||||||
|
for (const [event, listener] of listeners) {
|
||||||
|
target.removeListener(event, listener);
|
||||||
|
}
|
||||||
|
listeners.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers ALL track event listeners on the given track.
|
||||||
|
* Returns the listener map for later cleanup/replacement.
|
||||||
|
*/
|
||||||
|
export function registerTrackEventListeners(
|
||||||
|
track: Track,
|
||||||
|
onEvent: TrackOnEvent
|
||||||
|
): Map<string, (...args: any[]) => void> {
|
||||||
|
const listeners = new Map<string, (...args: any[]) => void>();
|
||||||
|
|
||||||
|
const reg = (event: TrackEvent, listener: (...args: any[]) => void) => {
|
||||||
|
track.addListener(event as any, listener as any);
|
||||||
|
listeners.set(event, listener);
|
||||||
|
};
|
||||||
|
|
||||||
|
reg(TrackEvent.Message, () => {
|
||||||
|
onEvent(TrackEvent.Message, {}, track.source);
|
||||||
|
});
|
||||||
|
|
||||||
|
reg(TrackEvent.Muted, () => {
|
||||||
|
onEvent(TrackEvent.Muted, {}, track.source);
|
||||||
|
});
|
||||||
|
|
||||||
|
reg(TrackEvent.Unmuted, () => {
|
||||||
|
onEvent(TrackEvent.Unmuted, {}, track.source);
|
||||||
|
});
|
||||||
|
|
||||||
|
reg(TrackEvent.Restarted, () => {
|
||||||
|
onEvent(TrackEvent.Restarted, {}, track.source);
|
||||||
|
});
|
||||||
|
|
||||||
|
reg(TrackEvent.Ended, () => {
|
||||||
|
onEvent(TrackEvent.Ended, {}, track.source);
|
||||||
|
});
|
||||||
|
|
||||||
|
reg(TrackEvent.CpuConstrained, () => {
|
||||||
|
onEvent(TrackEvent.CpuConstrained, {}, track.source);
|
||||||
|
});
|
||||||
|
|
||||||
|
reg(TrackEvent.UpdateSettings, () => {
|
||||||
|
onEvent(TrackEvent.UpdateSettings, {}, track.source);
|
||||||
|
});
|
||||||
|
|
||||||
|
reg(TrackEvent.UpdateSubscription, () => {
|
||||||
|
onEvent(TrackEvent.UpdateSubscription, {}, track.source);
|
||||||
|
});
|
||||||
|
|
||||||
|
reg(TrackEvent.AudioPlaybackStarted, () => {
|
||||||
|
onEvent(TrackEvent.AudioPlaybackStarted, {}, track.source);
|
||||||
|
});
|
||||||
|
|
||||||
|
reg(TrackEvent.AudioPlaybackFailed, (error?: Error) => {
|
||||||
|
onEvent(TrackEvent.AudioPlaybackFailed, { error }, `${track.source} ${error?.message ?? ''}`);
|
||||||
|
});
|
||||||
|
|
||||||
|
reg(TrackEvent.AudioSilenceDetected, () => {
|
||||||
|
onEvent(TrackEvent.AudioSilenceDetected, {}, track.source);
|
||||||
|
});
|
||||||
|
|
||||||
|
reg(TrackEvent.VisibilityChanged, (visible: boolean) => {
|
||||||
|
onEvent(TrackEvent.VisibilityChanged, { visible, track }, `${track.source} is visible: ${visible}`);
|
||||||
|
});
|
||||||
|
|
||||||
|
reg(TrackEvent.VideoDimensionsChanged, (dimensions: Track.Dimensions) => {
|
||||||
|
onEvent(
|
||||||
|
TrackEvent.VideoDimensionsChanged,
|
||||||
|
{ dimensions, track },
|
||||||
|
`${track.source} ${JSON.stringify(dimensions)}`
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
reg(TrackEvent.VideoPlaybackStarted, () => {
|
||||||
|
onEvent(TrackEvent.VideoPlaybackStarted, {}, track.source);
|
||||||
|
});
|
||||||
|
|
||||||
|
reg(TrackEvent.VideoPlaybackFailed, (error?: Error) => {
|
||||||
|
onEvent(TrackEvent.VideoPlaybackFailed, { error }, `${track.source} ${error?.message ?? ''}`);
|
||||||
|
});
|
||||||
|
|
||||||
|
reg(TrackEvent.ElementAttached, (element: HTMLMediaElement) => {
|
||||||
|
onEvent(TrackEvent.ElementAttached, { element }, track.source);
|
||||||
|
});
|
||||||
|
|
||||||
|
reg(TrackEvent.ElementDetached, (element: HTMLMediaElement) => {
|
||||||
|
onEvent(TrackEvent.ElementDetached, { element }, track.source);
|
||||||
|
});
|
||||||
|
|
||||||
|
reg(TrackEvent.UpstreamPaused, () => {
|
||||||
|
onEvent(TrackEvent.UpstreamPaused, {}, track.source);
|
||||||
|
});
|
||||||
|
|
||||||
|
reg(TrackEvent.UpstreamResumed, () => {
|
||||||
|
onEvent(TrackEvent.UpstreamResumed, {}, track.source);
|
||||||
|
});
|
||||||
|
|
||||||
|
reg(TrackEvent.TrackProcessorUpdate, (processor?: any) => {
|
||||||
|
onEvent(TrackEvent.TrackProcessorUpdate, { processor }, track.source);
|
||||||
|
});
|
||||||
|
|
||||||
|
reg(TrackEvent.AudioTrackFeatureUpdate, (_track: any, feature: any, enabled: boolean) => {
|
||||||
|
onEvent(
|
||||||
|
TrackEvent.AudioTrackFeatureUpdate,
|
||||||
|
{ feature, enabled },
|
||||||
|
`${track.source} feature: ${feature}, enabled: ${enabled}`
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
reg(TrackEvent.TimeSyncUpdate, (update: { timestamp: number; rtpTimestamp: number }) => {
|
||||||
|
onEvent(TrackEvent.TimeSyncUpdate, { update }, `${track.source} timestamp: ${update.timestamp}`);
|
||||||
|
});
|
||||||
|
|
||||||
|
reg(TrackEvent.PreConnectBufferFlushed, (buffer: any) => {
|
||||||
|
onEvent(TrackEvent.PreConnectBufferFlushed, { buffer }, track.source);
|
||||||
|
});
|
||||||
|
|
||||||
|
return listeners;
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue