Przeglądaj źródła

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

j8
tudordan7 4 lat temu
rodzic
commit
7f020a1107

+ 14
- 8
react/features/stream-effects/virtual-background/JitsiStreamBackgroundEffect.js Wyświetl plik

1
 // @flow
1
 // @flow
2
 
2
 
3
+import { VIRTUAL_BACKGROUND_TYPE } from '../../virtual-background/constants';
4
+
3
 import {
5
 import {
4
     CLEAR_TIMEOUT,
6
     CLEAR_TIMEOUT,
5
     TIMEOUT_TICK,
7
     TIMEOUT_TICK,
15
 export default class JitsiStreamBackgroundEffect {
17
 export default class JitsiStreamBackgroundEffect {
16
     _model: Object;
18
     _model: Object;
17
     _options: Object;
19
     _options: Object;
20
+    _desktopShareDimensions: Object;
18
     _segmentationPixelCount: number;
21
     _segmentationPixelCount: number;
19
     _inputVideoElement: HTMLVideoElement;
22
     _inputVideoElement: HTMLVideoElement;
20
     _onMaskFrameTimer: Function;
23
     _onMaskFrameTimer: Function;
41
     constructor(model: Object, options: Object) {
44
     constructor(model: Object, options: Object) {
42
         this._options = options;
45
         this._options = options;
43
 
46
 
44
-        if (this._options.virtualBackground.backgroundType === 'image') {
47
+        if (this._options.virtualBackground.backgroundType === VIRTUAL_BACKGROUND_TYPE.IMAGE) {
45
             this._virtualImage = document.createElement('img');
48
             this._virtualImage = document.createElement('img');
46
             this._virtualImage.crossOrigin = 'anonymous';
49
             this._virtualImage.crossOrigin = 'anonymous';
47
             this._virtualImage.src = this._options.virtualBackground.virtualSource;
50
             this._virtualImage.src = this._options.virtualBackground.virtualSource;
48
         }
51
         }
49
-        if (this._options.virtualBackground.backgroundType === 'desktop-share') {
52
+        if (this._options.virtualBackground.backgroundType === VIRTUAL_BACKGROUND_TYPE.DESKTOP_SHARE) {
53
+            const desktopShareTrack = this._options?.virtualBackground?.virtualSource?.track;
54
+
50
             this._virtualVideo = document.createElement('video');
55
             this._virtualVideo = document.createElement('video');
51
             this._virtualVideo.autoplay = true;
56
             this._virtualVideo.autoplay = true;
52
             this._virtualVideo.srcObject = this._options?.virtualBackground?.virtualSource?.stream;
57
             this._virtualVideo.srcObject = this._options?.virtualBackground?.virtualSource?.stream;
58
+            this._desktopShareDimensions = desktopShareTrack.getSettings ? desktopShareTrack.getSettings()
59
+                : desktopShareTrack.getConstraints();
53
         }
60
         }
54
         this._model = model;
61
         this._model = model;
55
-        this._options = options;
56
         this._segmentationPixelCount = this._options.width * this._options.height;
62
         this._segmentationPixelCount = this._options.width * this._options.height;
57
 
63
 
58
         // Bind event handler so it is only bound once for every instance.
64
         // Bind event handler so it is only bound once for every instance.
89
         //
95
         //
90
 
96
 
91
         // Smooth out the edges.
97
         // Smooth out the edges.
92
-        if (this._options.virtualBackground.backgroundType === 'image') {
98
+        if (this._options.virtualBackground.backgroundType === VIRTUAL_BACKGROUND_TYPE.IMAGE) {
93
             this._outputCanvasCtx.filter = 'blur(4px)';
99
             this._outputCanvasCtx.filter = 'blur(4px)';
94
         } else {
100
         } else {
95
             this._outputCanvasCtx.filter = 'blur(8px)';
101
             this._outputCanvasCtx.filter = 'blur(8px)';
118
         //
124
         //
119
 
125
 
120
         this._outputCanvasCtx.globalCompositeOperation = 'destination-over';
126
         this._outputCanvasCtx.globalCompositeOperation = 'destination-over';
121
-        if (this._options.virtualBackground.backgroundType === 'image') {
127
+        if (this._options.virtualBackground.backgroundType === VIRTUAL_BACKGROUND_TYPE.IMAGE) {
122
             this._outputCanvasCtx.drawImage(
128
             this._outputCanvasCtx.drawImage(
123
                 this._virtualImage,
129
                 this._virtualImage,
124
                 0,
130
                 0,
127
                 this._inputVideoElement.height
133
                 this._inputVideoElement.height
128
             );
134
             );
129
         }
135
         }
130
-        if (this._options.virtualBackground.backgroundType === 'desktop-share') {
136
+        if (this._options.virtualBackground.backgroundType === VIRTUAL_BACKGROUND_TYPE.DESKTOP_SHARE) {
131
             this._outputCanvasCtx.drawImage(
137
             this._outputCanvasCtx.drawImage(
132
                 this._virtualVideo,
138
                 this._virtualVideo,
133
                 0,
139
                 0,
134
                 0,
140
                 0,
135
-                this._inputVideoElement.width,
136
-                this._inputVideoElement.height
141
+                this._desktopShareDimensions.width,
142
+                this._desktopShareDimensions.height
137
             );
143
             );
138
         } else {
144
         } else {
139
             this._outputCanvasCtx.filter = `blur(${this._options.virtualBackground.blurValue}px)`;
145
             this._outputCanvasCtx.filter = `blur(${this._options.virtualBackground.blurValue}px)`;

+ 4
- 3
react/features/toolbox/components/web/Toolbox.js Wyświetl plik

75
 } from '../../../video-quality';
75
 } from '../../../video-quality';
76
 import { VideoBackgroundButton } from '../../../virtual-background';
76
 import { VideoBackgroundButton } from '../../../virtual-background';
77
 import { toggleBackgroundEffect } from '../../../virtual-background/actions';
77
 import { toggleBackgroundEffect } from '../../../virtual-background/actions';
78
+import { VIRTUAL_BACKGROUND_TYPE } from '../../../virtual-background/constants';
78
 import { checkBlurSupport } from '../../../virtual-background/functions';
79
 import { checkBlurSupport } from '../../../virtual-background/functions';
79
 import {
80
 import {
80
     setFullScreen,
81
     setFullScreen,
907
      * @returns {void}
908
      * @returns {void}
908
      */
909
      */
909
     _onToolbarToggleScreenshare() {
910
     _onToolbarToggleScreenshare() {
910
-        if (this.props._backgroundType === 'desktop-share') {
911
+        if (this.props._backgroundType === VIRTUAL_BACKGROUND_TYPE.DESKTOP_SHARE) {
911
             const noneOptions = {
912
             const noneOptions = {
912
                 enabled: false,
913
                 enabled: false,
913
-                backgroundType: 'none',
914
-                selectedThumbnail: 'none',
914
+                backgroundType: VIRTUAL_BACKGROUND_TYPE.NONE,
915
+                selectedThumbnail: VIRTUAL_BACKGROUND_TYPE.NONE,
915
                 backgroundEffectEnabled: false
916
                 backgroundEffectEnabled: false
916
             };
917
             };
917
 
918
 

+ 11
- 6
react/features/virtual-background/components/VirtualBackgroundDialog.js Wyświetl plik

9
 import { translate } from '../../base/i18n';
9
 import { translate } from '../../base/i18n';
10
 import { Icon, IconCloseSmall, IconPlusCircle, IconShareDesktop } from '../../base/icons';
10
 import { Icon, IconCloseSmall, IconPlusCircle, IconShareDesktop } from '../../base/icons';
11
 import { createLocalTrack } from '../../base/lib-jitsi-meet/functions';
11
 import { createLocalTrack } from '../../base/lib-jitsi-meet/functions';
12
+import { VIDEO_TYPE } from '../../base/media';
12
 import { connect } from '../../base/redux';
13
 import { connect } from '../../base/redux';
13
 import { getLocalVideoTrack } from '../../base/tracks';
14
 import { getLocalVideoTrack } from '../../base/tracks';
14
 import { toggleBackgroundEffect } from '../actions';
15
 import { toggleBackgroundEffect } from '../actions';
16
+import { VIRTUAL_BACKGROUND_TYPE } from '../constants';
15
 import { resizeImage, toDataURL } from '../functions';
17
 import { resizeImage, toDataURL } from '../functions';
16
 import logger from '../logger';
18
 import logger from '../logger';
17
 
19
 
89
     const localImages = jitsiLocalStorage.getItem('virtualBackgrounds');
91
     const localImages = jitsiLocalStorage.getItem('virtualBackgrounds');
90
     const [ storedImages, setStoredImages ] = useState((localImages && JSON.parse(localImages)) || []);
92
     const [ storedImages, setStoredImages ] = useState((localImages && JSON.parse(localImages)) || []);
91
     const [ loading, isloading ] = useState(false);
93
     const [ loading, isloading ] = useState(false);
92
-    const [ activeDesktopVideo ] = useState(_virtualSource?.videoType === 'desktop' ? _virtualSource : null);
94
+    const [ activeDesktopVideo ] = useState(_virtualSource?.videoType === VIDEO_TYPE.DESKTOP ? _virtualSource : null);
93
 
95
 
94
     const deleteStoredImage = image => {
96
     const deleteStoredImage = image => {
95
         setStoredImages(storedImages.filter(item => item !== image));
97
         setStoredImages(storedImages.filter(item => item !== image));
112
 
114
 
113
     const enableBlur = async (blurValue, selection) => {
115
     const enableBlur = async (blurValue, selection) => {
114
         setOptions({
116
         setOptions({
115
-            backgroundType: 'blur',
117
+            backgroundType: VIRTUAL_BACKGROUND_TYPE.BLUR,
116
             enabled: true,
118
             enabled: true,
117
             blurValue,
119
             blurValue,
118
             selectedThumbnail: selection
120
             selectedThumbnail: selection
129
     const shareDesktop = async selection => {
131
     const shareDesktop = async selection => {
130
         const url = await createLocalTrack('desktop', '');
132
         const url = await createLocalTrack('desktop', '');
131
 
133
 
134
+        if (!url) {
135
+            throw new Error('Could not create desktop local track!');
136
+        }
132
         setOptions({
137
         setOptions({
133
-            backgroundType: 'desktop-share',
138
+            backgroundType: VIRTUAL_BACKGROUND_TYPE.DESKTOP_SHARE,
134
             enabled: true,
139
             enabled: true,
135
             selectedThumbnail: selection,
140
             selectedThumbnail: selection,
136
             url
141
             url
139
 
144
 
140
     const setUploadedImageBackground = async image => {
145
     const setUploadedImageBackground = async image => {
141
         setOptions({
146
         setOptions({
142
-            backgroundType: 'image',
147
+            backgroundType: VIRTUAL_BACKGROUND_TYPE.IMAGE,
143
             enabled: true,
148
             enabled: true,
144
             url: image.src,
149
             url: image.src,
145
             selectedThumbnail: image.id
150
             selectedThumbnail: image.id
150
         const url = await toDataURL(image.src);
155
         const url = await toDataURL(image.src);
151
 
156
 
152
         setOptions({
157
         setOptions({
153
-            backgroundType: 'image',
158
+            backgroundType: VIRTUAL_BACKGROUND_TYPE.IMAGE,
154
             enabled: true,
159
             enabled: true,
155
             url,
160
             url,
156
             selectedThumbnail: image.id
161
             selectedThumbnail: image.id
173
                 }
178
                 }
174
             ]);
179
             ]);
175
             setOptions({
180
             setOptions({
176
-                backgroundType: 'image',
181
+                backgroundType: VIRTUAL_BACKGROUND_TYPE.IMAGE,
177
                 enabled: true,
182
                 enabled: true,
178
                 url,
183
                 url,
179
                 selectedThumbnail: uuId
184
                 selectedThumbnail: uuId

+ 4
- 2
react/features/virtual-background/components/VirtualBackgroundPreview.js Wyświetl plik

4
 import React, { PureComponent } from 'react';
4
 import React, { PureComponent } from 'react';
5
 
5
 
6
 import { translate } from '../../base/i18n';
6
 import { translate } from '../../base/i18n';
7
+import { VIDEO_TYPE } from '../../base/media';
7
 import Video from '../../base/media/components/Video';
8
 import Video from '../../base/media/components/Video';
8
 import { connect, equals } from '../../base/redux';
9
 import { connect, equals } from '../../base/redux';
9
 import { getCurrentCameraDeviceId } from '../../base/settings';
10
 import { getCurrentCameraDeviceId } from '../../base/settings';
10
 import { createLocalTracksF } from '../../base/tracks/functions';
11
 import { createLocalTracksF } from '../../base/tracks/functions';
11
 import { toggleBackgroundEffect } from '../actions';
12
 import { toggleBackgroundEffect } from '../actions';
13
+import { VIRTUAL_BACKGROUND_TYPE } from '../constants';
12
 import { localTrackStopped } from '../functions';
14
 import { localTrackStopped } from '../functions';
13
 
15
 
14
 const videoClassName = 'video-preview-video';
16
 const videoClassName = 'video-preview-video';
207
             this._setTracks();
209
             this._setTracks();
208
         }
210
         }
209
         if (!equals(this.props.options, prevProps.options)) {
211
         if (!equals(this.props.options, prevProps.options)) {
210
-            if (prevProps.options.backgroundType === 'desktop-share') {
212
+            if (prevProps.options.backgroundType === VIRTUAL_BACKGROUND_TYPE.DESKTOP_SHARE) {
211
                 prevProps.options.url.dispose();
213
                 prevProps.options.url.dispose();
212
             }
214
             }
213
             this._applyBackgroundEffect();
215
             this._applyBackgroundEffect();
214
         }
216
         }
215
-        if (this.props.options.url?.videoType === 'desktop') {
217
+        if (this.props.options.url?.videoType === VIDEO_TYPE.DESKTOP) {
216
             localTrackStopped(this.props.dispatch, this.props.options.url, this.state.jitsiTrack);
218
             localTrackStopped(this.props.dispatch, this.props.options.url, this.state.jitsiTrack);
217
         }
219
         }
218
     }
220
     }

+ 11
- 0
react/features/virtual-background/constants.js Wyświetl plik

1
+/**
2
+ * An enumeration of the different virtual background types.
3
+ *
4
+ * @enum {string}
5
+ */
6
+export const VIRTUAL_BACKGROUND_TYPE = {
7
+    IMAGE: 'image',
8
+    DESKTOP_SHARE: 'desktop-share',
9
+    BLUR: 'blur',
10
+    NONE: 'none'
11
+};

+ 2
- 1
react/features/virtual-background/middleware.js Wyświetl plik

1
 // @flow
1
 // @flow
2
 
2
 
3
+import { VIDEO_TYPE } from '../base/media';
3
 import { MiddlewareRegistry } from '../base/redux';
4
 import { MiddlewareRegistry } from '../base/redux';
4
 import { getLocalVideoTrack } from '../base/tracks';
5
 import { getLocalVideoTrack } from '../base/tracks';
5
 
6
 
18
     const virtualSource = getState()['features/virtual-background'].virtualSource;
19
     const virtualSource = getState()['features/virtual-background'].virtualSource;
19
     const currentLocalTrack = getLocalVideoTrack(getState()['features/base/tracks']);
20
     const currentLocalTrack = getLocalVideoTrack(getState()['features/base/tracks']);
20
 
21
 
21
-    if (virtualSource?.videoType === 'desktop') {
22
+    if (virtualSource?.videoType === VIDEO_TYPE.DESKTOP && currentLocalTrack) {
22
         localTrackStopped(dispatch, virtualSource, currentLocalTrack.jitsiTrack);
23
         localTrackStopped(dispatch, virtualSource, currentLocalTrack.jitsiTrack);
23
     }
24
     }
24
 
25
 

+ 2
- 1
react/features/virtual-background/reducer.js Wyświetl plik

3
 import { PersistenceRegistry, ReducerRegistry } from '../base/redux';
3
 import { PersistenceRegistry, ReducerRegistry } from '../base/redux';
4
 
4
 
5
 import { BACKGROUND_ENABLED, SET_VIRTUAL_BACKGROUND } from './actionTypes';
5
 import { BACKGROUND_ENABLED, SET_VIRTUAL_BACKGROUND } from './actionTypes';
6
+import { VIRTUAL_BACKGROUND_TYPE } from './constants';
6
 
7
 
7
 const STORE_NAME = 'features/virtual-background';
8
 const STORE_NAME = 'features/virtual-background';
8
 
9
 
23
     /**
24
     /**
24
      * Sets up the persistence of the feature {@code virtual-background}.
25
      * Sets up the persistence of the feature {@code virtual-background}.
25
      */
26
      */
26
-    PersistenceRegistry.register(STORE_NAME, state.backgroundType !== 'desktop-share');
27
+    PersistenceRegistry.register(STORE_NAME, state.backgroundType !== VIRTUAL_BACKGROUND_TYPE.DESKTOP_SHARE);
27
 
28
 
28
     switch (action.type) {
29
     switch (action.type) {
29
     case SET_VIRTUAL_BACKGROUND: {
30
     case SET_VIRTUAL_BACKGROUND: {

Ładowanie…
Anuluj
Zapisz