diff --git a/openvidu-browser/src/OpenVidu/Publisher.ts b/openvidu-browser/src/OpenVidu/Publisher.ts index 9e6c083e..3e679b1c 100644 --- a/openvidu-browser/src/OpenVidu/Publisher.ts +++ b/openvidu-browser/src/OpenVidu/Publisher.ts @@ -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(enabled: T, resource?: T extends false ? boolean : MediaStreamTrack): void { + publishVideo(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 { - // 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 { + // 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 { + async replaceTrackInMediaStream(track: MediaStreamTrack, updateLastConstraints: boolean): Promise { 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]; } diff --git a/openvidu-browser/src/OpenVidu/Stream.ts b/openvidu-browser/src/OpenVidu/Stream.ts index d44fca64..464052f3 100644 --- a/openvidu-browser/src/OpenVidu/Stream.ts +++ b/openvidu-browser/src/OpenVidu/Stream.ts @@ -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")); diff --git a/openvidu-browser/src/OpenVidu/StreamManager.ts b/openvidu-browser/src/OpenVidu/StreamManager.ts index e9dd81a0..dc08529e 100644 --- a/openvidu-browser/src/OpenVidu/StreamManager.ts +++ b/openvidu-browser/src/OpenVidu/StreamManager.ts @@ -529,7 +529,7 @@ export abstract class StreamManager extends EventDispatcher { /** * @hidden */ - abstract replaceTrackInMediaStream(track: MediaStreamTrack): Promise; + abstract replaceTrackInMediaStream(track: MediaStreamTrack, updateLastConstraints: boolean): Promise; /* Private methods */ diff --git a/openvidu-browser/src/OpenVidu/Subscriber.ts b/openvidu-browser/src/OpenVidu/Subscriber.ts index a8af2c2e..5039ccfd 100644 --- a/openvidu-browser/src/OpenVidu/Subscriber.ts +++ b/openvidu-browser/src/OpenVidu/Subscriber.ts @@ -78,12 +78,14 @@ export class Subscriber extends StreamManager { /** * @hidden */ - async replaceTrackInMediaStream(track: MediaStreamTrack): Promise { + async replaceTrackInMediaStream(track: MediaStreamTrack, updateLastConstraints: boolean): Promise { 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]; }