openvidu-testapp: allow starting Participant Passthrough Egress

pull/914/head
pabloFuente 2026-10-08 16:30:08 +02:00
parent 884cde23b9
commit 9413108885
3 changed files with 50 additions and 0 deletions

View File

@ -62,6 +62,10 @@
<mat-label>Room</mat-label>
<input matInput id="egress-room-name-field" placeholder="Room" [(ngModel)]="egressRoomName">
</mat-form-field>
<mat-form-field class="inner-text-input" [style.fontSize.px]=14>
<mat-label>Participant</mat-label>
<input matInput id="egress-participant-identity-field" placeholder="Participant" [(ngModel)]="egressParticipantIdentity">
</mat-form-field>
<mat-form-field class="inner-text-input" [style.fontSize.px]=14>
<mat-label>Audio Track</mat-label>
<input matInput id="audio-track-id-field" placeholder="Audio Track ID" [(ngModel)]="audioTrackId">
@ -93,6 +97,11 @@
[disabled]="!egressRoomName || (!!audioTrackId && !!videoTrackId || !audioTrackId && !videoTrackId)">Start
Track Egress</button>
</span>
<span style="display: inline-block" matTooltip='"Room" and "Participant" required'
[matTooltipDisabled]="!!egressRoomName && !!egressParticipantIdentity">
<button mat-button id="start-participant-passthrough-egress-api-btn" (click)="startParticipantPassthroughEgress()"
[disabled]="!egressRoomName || !egressParticipantIdentity">Start Participant Passthrough Egress</button>
</span>
<span style="display: inline-block" matTooltip='"Egress ID" required' [matTooltipDisabled]="!!egressId">
<button mat-button id="stop-egress-api-btn" (click)="stopEgress()" [disabled]="!egressId">Stop Egress</button>
</span>

View File

@ -55,6 +55,7 @@ export class RoomApiDialogComponent {
muteTrack: boolean = true;
egressRoomName: string;
egressParticipantIdentity: string;
egressId: string;
audioTrackId: string;
videoTrackId: string;
@ -146,6 +147,7 @@ export class RoomApiDialogComponent {
.values()
.next().value?.trackSid!;
this.egressRoomName = this.room?.name;
this.egressParticipantIdentity = this.localParticipant?.identity;
this.audioTrackId = this.localParticipant?.audioTrackPublications
.values()
.next().value?.trackSid!;
@ -308,6 +310,20 @@ export class RoomApiDialogComponent {
}
}
async startParticipantPassthroughEgress() {
console.log('Starting participant passthrough egress');
try {
const egress = await this.roomApiService.startParticipantPassthroughEgress(
this.egressRoomName,
this.egressParticipantIdentity
);
this.response = JSON.stringify(egress, null, 4);
this.egressId = egress.egressId;
} catch (error: any) {
this.response = error;
}
}
async stopEgress() {
console.log('Stopping egress');
try {

View File

@ -8,6 +8,8 @@ import {
DirectFileOutput,
EgressClient,
EgressInfo,
EncodedFileOutput,
EncodedFileType,
EncodedOutputs,
EncodingOptions,
EncodingOptionsPreset,
@ -209,6 +211,29 @@ export class RoomApiService {
return await this.egressClient.startTrackEgress(roomName, output, track_id);
}
/**
* The participant's audio and video tracks, as they are published, without
* transcoding, in one Matroska file (OpenVidu egress: PASSTHROUGH for an
* audio track plus a video track). Needs exactly one file output of the
* default file type: ".webm" filepaths give WebM, anything else Matroska.
*/
async startParticipantPassthroughEgress(
roomName: string,
identity: string
): Promise<EgressInfo> {
const file = new EncodedFileOutput({
fileType: EncodedFileType.DEFAULT_FILETYPE,
filepath:
'ParticipantPassthrough-{room_id}-{room_name}-{time}-{publisher_identity}.mkv',
});
return await this.egressClient.startParticipantEgress(
roomName,
identity,
{ file },
{ encodingOptions: EncodingOptionsPreset.PASSTHROUGH }
);
}
async stopEgress(egressId: string): Promise<EgressInfo> {
return await this.egressClient.stopEgress(egressId);
}