feat(virtual-background): Desktop share as virtual background

This commit is contained in:
tudordan7 2021-05-14 17:53:11 +03:00 committed by Jaya Allamsetty
parent dffe2316d4
commit 99f61ca2cd
5 changed files with 45 additions and 26 deletions

View File

@ -14,5 +14,6 @@ import '../prejoin/middleware';
import '../remote-control/middleware'; import '../remote-control/middleware';
import '../shared-video/middleware'; import '../shared-video/middleware';
import '../talk-while-muted/middleware'; import '../talk-while-muted/middleware';
import '../virtual-background/middleware';
import './middlewares.any'; import './middlewares.any';

View File

@ -1,5 +1,4 @@
// @flow // @flow
import { JitsiTrackEvents } from '../../base/lib-jitsi-meet';
import { import {
CLEAR_TIMEOUT, CLEAR_TIMEOUT,
@ -16,7 +15,6 @@ import {
export default class JitsiStreamBackgroundEffect { export default class JitsiStreamBackgroundEffect {
_model: Object; _model: Object;
_options: Object; _options: Object;
_screenSharing: Object;
_segmentationPixelCount: number; _segmentationPixelCount: number;
_inputVideoElement: HTMLVideoElement; _inputVideoElement: HTMLVideoElement;
_onMaskFrameTimer: Function; _onMaskFrameTimer: Function;
@ -39,21 +37,19 @@ export default class JitsiStreamBackgroundEffect {
* @class * @class
* @param {Object} model - Meet model. * @param {Object} model - Meet model.
* @param {Object} options - Segmentation dimensions. * @param {Object} options - Segmentation dimensions.
* @param {Object} screenSharing - Desktop track for displaying desktop share as virtual background.
*/ */
constructor(model: Object, options: Object, screenSharing: Object) { constructor(model: Object, options: Object) {
this._options = options; this._options = options;
this._screenSharing = screenSharing;
if (this._options.virtualBackground.backgroundType === 'image') { if (this._options.virtualBackground.backgroundType === 'image') {
this._virtualImage = document.createElement('img'); this._virtualImage = document.createElement('img');
this._virtualImage.crossOrigin = 'anonymous'; this._virtualImage.crossOrigin = 'anonymous';
this._virtualImage.src = this._options.virtualBackground.virtualSource; this._virtualImage.src = this._options.virtualBackground.virtualSource;
} }
if (this._options.virtualBackground.backgroundType === 'desktop-share' && this._screenSharing) { if (this._options.virtualBackground.backgroundType === 'desktop-share') {
this._virtualVideo = document.createElement('video'); this._virtualVideo = document.createElement('video');
this._virtualVideo.autoplay = true; this._virtualVideo.autoplay = true;
this._virtualVideo.srcObject = this._screenSharing.stream; this._virtualVideo.srcObject = this._options?.virtualBackground?.virtualSource?.stream;
} }
this._model = model; this._model = model;
this._options = options; this._options = options;
@ -252,15 +248,6 @@ export default class JitsiStreamBackgroundEffect {
this._inputVideoElement.height = parseInt(height, 10); this._inputVideoElement.height = parseInt(height, 10);
this._inputVideoElement.autoplay = true; this._inputVideoElement.autoplay = true;
this._inputVideoElement.srcObject = stream; this._inputVideoElement.srcObject = stream;
this._screenSharing && this._screenSharing.on(
JitsiTrackEvents.LOCAL_TRACK_STOPPED,
() => {
this._options.virtualBackground.enabled = false;
this._options.virtualBackground.backgroundType = 'none';
this._options.virtualBackground.selectedThumbnail = 'none';
this._options.virtualBackground.backgroundEffectEnabled = false;
this._options.virtualBackground.enabled = false;
});
this._inputVideoElement.onloadeddata = () => { this._inputVideoElement.onloadeddata = () => {
this._maskFrameTimerWorker.postMessage({ this._maskFrameTimerWorker.postMessage({
id: SET_TIMEOUT, id: SET_TIMEOUT,
@ -282,6 +269,5 @@ export default class JitsiStreamBackgroundEffect {
}); });
this._maskFrameTimerWorker.terminate(); this._maskFrameTimerWorker.terminate();
this._screenSharing && this._screenSharing.dispose();
} }
} }

View File

@ -2,8 +2,6 @@
import * as wasmCheck from 'wasm-check'; import * as wasmCheck from 'wasm-check';
import { createLocalTrack } from '../../base/lib-jitsi-meet/functions';
import JitsiStreamBackgroundEffect from './JitsiStreamBackgroundEffect'; import JitsiStreamBackgroundEffect from './JitsiStreamBackgroundEffect';
import createTFLiteModule from './vendor/tflite/tflite'; import createTFLiteModule from './vendor/tflite/tflite';
import createTFLiteSIMDModule from './vendor/tflite/tflite-simd'; import createTFLiteSIMDModule from './vendor/tflite/tflite-simd';
@ -37,7 +35,6 @@ export async function createVirtualBackgroundEffect(virtualBackground: Object) {
throw new Error('JitsiStreamBackgroundEffect not supported!'); throw new Error('JitsiStreamBackgroundEffect not supported!');
} }
let tflite; let tflite;
let screenSharing;
if (wasmCheck.feature.simd) { if (wasmCheck.feature.simd) {
tflite = await createTFLiteSIMDModule(); tflite = await createTFLiteSIMDModule();
@ -58,14 +55,10 @@ export async function createVirtualBackgroundEffect(virtualBackground: Object) {
tflite._loadModel(model.byteLength); tflite._loadModel(model.byteLength);
if (virtualBackground.backgroundType === 'desktop-share') {
screenSharing = await createLocalTrack('desktop', '');
}
const options = { const options = {
...wasmCheck.feature.simd ? segmentationDimensions.model144 : segmentationDimensions.model96, ...wasmCheck.feature.simd ? segmentationDimensions.model144 : segmentationDimensions.model96,
virtualBackground virtualBackground
}; };
return new JitsiStreamBackgroundEffect(tflite, options, screenSharing); return new JitsiStreamBackgroundEffect(tflite, options);
} }

View File

@ -8,6 +8,7 @@ import uuid from 'uuid';
import { Dialog, hideDialog } from '../../base/dialog'; import { Dialog, hideDialog } from '../../base/dialog';
import { translate } from '../../base/i18n'; import { translate } from '../../base/i18n';
import { Icon, IconCloseSmall, IconPlusCircle, IconShareDesktop } from '../../base/icons'; import { Icon, IconCloseSmall, IconPlusCircle, IconShareDesktop } from '../../base/icons';
import { createLocalTrack } from '../../base/lib-jitsi-meet/functions';
import { connect } from '../../base/redux'; import { connect } from '../../base/redux';
import { getLocalVideoTrack } from '../../base/tracks'; import { getLocalVideoTrack } from '../../base/tracks';
import { toggleBackgroundEffect } from '../actions'; import { toggleBackgroundEffect } from '../actions';
@ -120,10 +121,13 @@ function VirtualBackground({ _jitsiTrack, _selectedThumbnail, dispatch, t }: Pro
}; };
const shareDesktop = async selection => { const shareDesktop = async selection => {
const url = await createLocalTrack('desktop', '');
setOptions({ setOptions({
backgroundType: 'desktop-share', backgroundType: 'desktop-share',
enabled: true, enabled: true,
selectedThumbnail: selection selectedThumbnail: selection,
url
}); });
}; };

View File

@ -0,0 +1,35 @@
import { JitsiTrackEvents } from '../base/lib-jitsi-meet';
import { MiddlewareRegistry } from '../base/redux';
import { getLocalVideoTrack } from '../base/tracks';
import { toggleBackgroundEffect } from './actions';
/**
* Middleware which intercepts the desktop video type on
* virtual background. If the user stops the screen share
* then the default virtual background is set to 'none' option
*
* @param {Store} store - The redux store.
* @returns {Function}
*/
MiddlewareRegistry.register(store => next => action => {
const { dispatch, getState } = store;
const virtualSource = getState()['features/virtual-background'].virtualSource;
const currentLocalTrack = getLocalVideoTrack(getState()['features/base/tracks']);
if (virtualSource?.videoType === 'desktop') {
const noneOptions = {
enabled: false,
backgroundType: 'none',
selectedThumbnail: 'none',
backgroundEffectEnabled: false
};
virtualSource
&& virtualSource.on(JitsiTrackEvents.LOCAL_TRACK_STOPPED, () => {
dispatch(toggleBackgroundEffect(noneOptions, currentLocalTrack.jitsiTrack));
});
}
return next(action);
});