openvidu-browser: refactor replaceTrack to not override last constraints

pull/721/head
pabloFuente 2022-05-04 19:55:08 +02:00
parent 066810be17
commit 99cd4cdfd7
4 changed files with 44 additions and 33 deletions

View File

@ -168,7 +168,7 @@ export class Publisher extends StreamManager {
* useful if the Publisher was unpublished freeing the hardware resource, and openvidu-browser is not able to successfully re-create the video track as it was before unpublishing. In this way previous track settings will be ignored and this MediaStreamTrack
* will be used instead.
*/
publishVideo<T extends boolean>(enabled: T, resource?: T extends false ? boolean : MediaStreamTrack): void {
publishVideo<T extends boolean>(enabled: T, resource?: T extends false ? boolean : MediaStreamTrack): void {
if (this.stream.videoActive !== enabled) {
@ -329,27 +329,7 @@ export class Publisher extends StreamManager {
* @returns A Promise (to which you can optionally subscribe to) that is resolved if the track was successfully replaced and rejected with an Error object in other case
*/
async replaceTrack(track: MediaStreamTrack): Promise<void> {
// Set field "enabled" of the new track to the previous value
const trackOriginalEnabledValue: boolean = track.enabled;
if (track.kind === 'video') {
track.enabled = this.stream.videoActive;
} else if (track.kind === 'audio') {
track.enabled = this.stream.audioActive;
}
try {
if (this.stream.isLocalStreamPublished) {
// Only if the Publisher has been published is necessary to call native Web API RTCRtpSender.replaceTrack
// If it has not been published yet, replacing it on the MediaStream object is enough
await this.replaceTrackInMediaStream(track);
return await this.replaceTrackInRtcRtpSender(track);
} else {
// Publisher not published. Simply replace the track on the local MediaStream
return await this.replaceTrackInMediaStream(track);
}
} catch (error) {
track.enabled = trackOriginalEnabledValue;
throw error;
}
return this.replaceTrackAux(track, true);
}
/* Hidden methods */
@ -636,6 +616,33 @@ export class Publisher extends StreamManager {
});
}
/**
* @hidden
*/
async replaceTrackAux(track: MediaStreamTrack, updateLastConstraints: boolean): Promise<void> {
// Set field "enabled" of the new track to the previous value
const trackOriginalEnabledValue: boolean = track.enabled;
if (track.kind === 'video') {
track.enabled = this.stream.videoActive;
} else if (track.kind === 'audio') {
track.enabled = this.stream.audioActive;
}
try {
if (this.stream.isLocalStreamPublished) {
// Only if the Publisher has been published is necessary to call native Web API RTCRtpSender.replaceTrack
// If it has not been published yet, replacing it on the MediaStream object is enough
await this.replaceTrackInMediaStream(track, updateLastConstraints);
return await this.replaceTrackInRtcRtpSender(track);
} else {
// Publisher not published. Simply replace the track on the local MediaStream
return await this.replaceTrackInMediaStream(track, updateLastConstraints);
}
} catch (error) {
track.enabled = trackOriginalEnabledValue;
throw error;
}
}
/**
* @hidden
*
@ -729,12 +736,14 @@ export class Publisher extends StreamManager {
/**
* @hidden
*/
async replaceTrackInMediaStream(track: MediaStreamTrack): Promise<void> {
async replaceTrackInMediaStream(track: MediaStreamTrack, updateLastConstraints: boolean): Promise<void> {
const mediaStream: MediaStream = this.stream.displayMyRemote() ? this.stream.localMediaStreamWhenSubscribedToRemote! : this.stream.getMediaStream();
let removedTrack: MediaStreamTrack;
if (track.kind === 'video') {
removedTrack = mediaStream.getVideoTracks()[0];
this.stream.lastVideoTrackConstraints = track.getConstraints();
if (updateLastConstraints) {
this.stream.lastVideoTrackConstraints = track.getConstraints();
}
} else {
removedTrack = mediaStream.getAudioTracks()[0];
}

View File

@ -421,9 +421,9 @@ export class Stream {
videoClone.style.display = 'none';
if (this.streamManager.remote) {
this.streamManager.replaceTrackInMediaStream((this.virtualBackgroundSinkElements.video.srcObject as MediaStream).getVideoTracks()[0]);
this.streamManager.replaceTrackInMediaStream((this.virtualBackgroundSinkElements.video.srcObject as MediaStream).getVideoTracks()[0], false);
} else {
(this.streamManager as Publisher).replaceTrack((this.virtualBackgroundSinkElements.video.srcObject as MediaStream).getVideoTracks()[0]);
(this.streamManager as Publisher).replaceTrackAux((this.virtualBackgroundSinkElements.video.srcObject as MediaStream).getVideoTracks()[0], false);
}
resolveApplyFilter(undefined, false);
@ -541,7 +541,7 @@ export class Stream {
}
if (!!this.filter) {
// There is a filter applied
if (this.filter?.type.startsWith('VB:')) {
@ -553,9 +553,9 @@ export class Stream {
const mediaStreamClone = this.virtualBackgroundSourceElements!.mediaStreamClone;
if (!isDisposing) {
if (this.streamManager.remote) {
await this.streamManager.replaceTrackInMediaStream(mediaStreamClone.getVideoTracks()[0]);
await this.streamManager.replaceTrackInMediaStream(mediaStreamClone.getVideoTracks()[0], false);
} else {
await (this.streamManager as Publisher).replaceTrack(mediaStreamClone.getVideoTracks()[0]);
await (this.streamManager as Publisher).replaceTrackAux(mediaStreamClone.getVideoTracks()[0], false);
}
} else {
mediaStreamClone.getTracks().forEach((track) => track.stop());
@ -591,7 +591,7 @@ export class Stream {
}
} else {
// There is no filter applied
return reject(new OpenViduError(OpenViduErrorName.GENERIC_ERROR, "Stream " + this.streamId + " has no filter applied"));

View File

@ -529,7 +529,7 @@ export abstract class StreamManager extends EventDispatcher {
/**
* @hidden
*/
abstract replaceTrackInMediaStream(track: MediaStreamTrack): Promise<void>;
abstract replaceTrackInMediaStream(track: MediaStreamTrack, updateLastConstraints: boolean): Promise<void>;
/* Private methods */

View File

@ -78,12 +78,14 @@ export class Subscriber extends StreamManager {
/**
* @hidden
*/
async replaceTrackInMediaStream(track: MediaStreamTrack): Promise<void> {
async replaceTrackInMediaStream(track: MediaStreamTrack, updateLastConstraints: boolean): Promise<void> {
const mediaStream: MediaStream = this.stream.getMediaStream();
let removedTrack: MediaStreamTrack;
if (track.kind === 'video') {
removedTrack = mediaStream.getVideoTracks()[0];
this.stream.lastVideoTrackConstraints = track.getConstraints();
if (updateLastConstraints) {
this.stream.lastVideoTrackConstraints = track.getConstraints();
}
} else {
removedTrack = mediaStream.getAudioTracks()[0];
}