mirror of https://github.com/OpenVidu/openvidu.git
openvidu-browser: re-apply VB filter automatically after unmute
parent
99cd4cdfd7
commit
f735819ae2
|
@ -168,68 +168,88 @@ 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
|
* 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.
|
* 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): Promise<void> {
|
||||||
|
|
||||||
if (this.stream.videoActive !== enabled) {
|
return new Promise(async (resolve, reject) => {
|
||||||
|
|
||||||
const affectedMediaStream: MediaStream = this.stream.displayMyRemote() ? this.stream.localMediaStreamWhenSubscribedToRemote! : this.stream.getMediaStream();
|
if (this.stream.videoActive !== enabled) {
|
||||||
let mustRestartMediaStream = false;
|
|
||||||
affectedMediaStream.getVideoTracks().forEach((track) => {
|
const affectedMediaStream: MediaStream = this.stream.displayMyRemote() ? this.stream.localMediaStreamWhenSubscribedToRemote! : this.stream.getMediaStream();
|
||||||
track.enabled = enabled;
|
let mustRestartMediaStream = false;
|
||||||
if (!enabled && resource === true) {
|
affectedMediaStream.getVideoTracks().forEach((track) => {
|
||||||
track.stop();
|
track.enabled = enabled;
|
||||||
} else if (enabled && track.readyState === 'ended') {
|
if (!enabled && resource === true) {
|
||||||
// Resource was freed
|
track.stop();
|
||||||
mustRestartMediaStream = true;
|
} else if (enabled && track.readyState === 'ended') {
|
||||||
|
// Resource was freed
|
||||||
|
mustRestartMediaStream = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// There is a Virtual Background filter applied that must be removed in case the hardware must be freed
|
||||||
|
if (!enabled && resource === true && !!this.stream.filter && this.stream.filter.type.startsWith('VB:')) {
|
||||||
|
this.stream.lastVBFilter = this.stream.filter; // Save the filter to be re-applied in case of unmute
|
||||||
|
await this.stream.removeFilterAux(true);
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
|
||||||
if (mustRestartMediaStream) {
|
if (mustRestartMediaStream) {
|
||||||
const oldVideoTrack = affectedMediaStream.getVideoTracks()[0];
|
const oldVideoTrack = affectedMediaStream.getVideoTracks()[0];
|
||||||
affectedMediaStream.removeTrack(oldVideoTrack);
|
affectedMediaStream.removeTrack(oldVideoTrack);
|
||||||
|
|
||||||
const replaceVideoTrack = (tr: MediaStreamTrack) => {
|
const replaceVideoTrack = async (tr: MediaStreamTrack) => {
|
||||||
affectedMediaStream.addTrack(tr);
|
affectedMediaStream.addTrack(tr);
|
||||||
if (this.stream.isLocalStreamPublished) {
|
if (this.stream.isLocalStreamPublished) {
|
||||||
this.replaceTrackInRtcRtpSender(tr);
|
await this.replaceTrackInRtcRtpSender(tr);
|
||||||
|
}
|
||||||
|
if (!!this.stream.lastVBFilter) {
|
||||||
|
setTimeout(async () => {
|
||||||
|
let options = this.stream.lastVBFilter!.options;
|
||||||
|
const lastExecMethod = this.stream.lastVBFilter!.lastExecMethod;
|
||||||
|
if (!!lastExecMethod && lastExecMethod.method === 'update') {
|
||||||
|
options = Object.assign({}, options, lastExecMethod.params);
|
||||||
|
}
|
||||||
|
await this.stream.applyFilter(this.stream.lastVBFilter!.type, options);
|
||||||
|
delete this.stream.lastVBFilter;
|
||||||
|
}, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!!resource && resource instanceof MediaStreamTrack) {
|
||||||
|
await replaceVideoTrack(resource);
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
const mediaStream = await navigator.mediaDevices.getUserMedia({ audio: false, video: this.stream.lastVideoTrackConstraints });
|
||||||
|
await replaceVideoTrack(mediaStream.getVideoTracks()[0]);
|
||||||
|
} catch (error) {
|
||||||
|
return reject(error);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!!resource && resource instanceof MediaStreamTrack) {
|
if (!!this.session && !!this.stream.streamId) {
|
||||||
replaceVideoTrack(resource);
|
this.session.openvidu.sendRequest(
|
||||||
} else {
|
'streamPropertyChanged',
|
||||||
navigator.mediaDevices.getUserMedia({ audio: false, video: this.stream.lastVideoTrackConstraints })
|
{
|
||||||
.then(mediaStream => {
|
streamId: this.stream.streamId,
|
||||||
replaceVideoTrack(mediaStream.getVideoTracks()[0]);
|
property: 'videoActive',
|
||||||
})
|
newValue: enabled,
|
||||||
.catch(error => {
|
reason: 'publishVideo'
|
||||||
console.error(error);
|
},
|
||||||
|
(error, response) => {
|
||||||
|
if (error) {
|
||||||
|
logger.error("Error sending 'streamPropertyChanged' event", error);
|
||||||
|
} else {
|
||||||
|
this.session.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent(this.session, this.stream, 'videoActive', enabled, !enabled, 'publishVideo')]);
|
||||||
|
this.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent(this, this.stream, 'videoActive', enabled, !enabled, 'publishVideo')]);
|
||||||
|
this.session.sendVideoData(this.stream.streamManager);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
this.stream.videoActive = enabled;
|
||||||
|
logger.info("'Publisher' has " + (enabled ? 'published' : 'unpublished') + ' its video stream');
|
||||||
|
return resolve();
|
||||||
}
|
}
|
||||||
|
});
|
||||||
if (!!this.session && !!this.stream.streamId) {
|
|
||||||
this.session.openvidu.sendRequest(
|
|
||||||
'streamPropertyChanged',
|
|
||||||
{
|
|
||||||
streamId: this.stream.streamId,
|
|
||||||
property: 'videoActive',
|
|
||||||
newValue: enabled,
|
|
||||||
reason: 'publishVideo'
|
|
||||||
},
|
|
||||||
(error, response) => {
|
|
||||||
if (error) {
|
|
||||||
logger.error("Error sending 'streamPropertyChanged' event", error);
|
|
||||||
} else {
|
|
||||||
this.session.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent(this.session, this.stream, 'videoActive', enabled, !enabled, 'publishVideo')]);
|
|
||||||
this.emitEvent('streamPropertyChanged', [new StreamPropertyChangedEvent(this, this.stream, 'videoActive', enabled, !enabled, 'publishVideo')]);
|
|
||||||
this.session.sendVideoData(this.stream.streamManager);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
this.stream.videoActive = enabled;
|
|
||||||
logger.info("'Publisher' has " + (enabled ? 'published' : 'unpublished') + ' its video stream');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -232,6 +232,10 @@ export class Stream {
|
||||||
* @hidden
|
* @hidden
|
||||||
*/
|
*/
|
||||||
lastVideoTrackConstraints: MediaTrackConstraints | boolean | undefined;
|
lastVideoTrackConstraints: MediaTrackConstraints | boolean | undefined;
|
||||||
|
/**
|
||||||
|
* @hidden
|
||||||
|
*/
|
||||||
|
lastVBFilter?: Filter;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in New Issue