ソースを参照

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

j8
tudordan7 4年前
コミット
7f020a1107

+ 14
- 8
react/features/stream-effects/virtual-background/JitsiStreamBackgroundEffect.js ファイルの表示

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

+ 4
- 3
react/features/toolbox/components/web/Toolbox.js ファイルの表示

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

+ 11
- 6
react/features/virtual-background/components/VirtualBackgroundDialog.js ファイルの表示

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

+ 4
- 2
react/features/virtual-background/components/VirtualBackgroundPreview.js ファイルの表示

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

+ 11
- 0
react/features/virtual-background/constants.js ファイルの表示

@@ -0,0 +1,11 @@
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 ファイルの表示

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

+ 2
- 1
react/features/virtual-background/reducer.js ファイルの表示

@@ -3,6 +3,7 @@
3 3
 import { PersistenceRegistry, ReducerRegistry } from '../base/redux';
4 4
 
5 5
 import { BACKGROUND_ENABLED, SET_VIRTUAL_BACKGROUND } from './actionTypes';
6
+import { VIRTUAL_BACKGROUND_TYPE } from './constants';
6 7
 
7 8
 const STORE_NAME = 'features/virtual-background';
8 9
 
@@ -23,7 +24,7 @@ ReducerRegistry.register(STORE_NAME, (state = {}, action) => {
23 24
     /**
24 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 29
     switch (action.type) {
29 30
     case SET_VIRTUAL_BACKGROUND: {

読み込み中…
キャンセル
保存