Browse Source

fix(virtual-background): Fix resize action and prevent mirror behavio… (#9441)

* fix(virtual-background): Fix resize action and prevent mirror behaviour on desktop share as a virtual background.
Co-authored-by: tudordan7 <tudor.pop@decagon.tech>
j8
Tudor D. Pop 3 years ago
parent
commit
74d65ff596
No account linked to committer's email address

+ 22
- 11
react/features/stream-effects/virtual-background/JitsiStreamBackgroundEffect.js View File

@@ -17,7 +17,7 @@ import {
17 17
 export default class JitsiStreamBackgroundEffect {
18 18
     _model: Object;
19 19
     _options: Object;
20
-    _desktopShareDimensions: Object;
20
+    _stream: Object;
21 21
     _segmentationPixelCount: number;
22 22
     _inputVideoElement: HTMLVideoElement;
23 23
     _onMaskFrameTimer: Function;
@@ -85,6 +85,12 @@ export default class JitsiStreamBackgroundEffect {
85 85
      * @returns {void}
86 86
      */
87 87
     runPostProcessing() {
88
+
89
+        const track = this._stream.getVideoTracks()[0];
90
+        const { height, width } = track.getSettings() ?? track.getConstraints();
91
+
92
+        this._outputCanvasElement.height = height;
93
+        this._outputCanvasElement.width = width;
88 94
         this._outputCanvasCtx.globalCompositeOperation = 'copy';
89 95
 
90 96
         // Draw segmentation mask.
@@ -130,13 +136,23 @@ export default class JitsiStreamBackgroundEffect {
130 136
             );
131 137
         }
132 138
         if (this._options.virtualBackground.backgroundType === VIRTUAL_BACKGROUND_TYPE.DESKTOP_SHARE) {
139
+
140
+            // save current context before applying transformations
141
+            this._outputCanvasCtx.save();
142
+
143
+            // flip the canvas and prevent mirror behaviour
144
+            this._outputCanvasCtx.scale(-1, 1);
145
+            this._outputCanvasCtx.translate(-this._outputCanvasElement.width, 0);
133 146
             this._outputCanvasCtx.drawImage(
134 147
                 this._virtualVideo,
135 148
                 0,
136 149
                 0,
137
-                this._desktopShareDimensions.width,
138
-                this._desktopShareDimensions.height
150
+                this._outputCanvasElement.width,
151
+                this._outputCanvasElement.height
139 152
             );
153
+
154
+            // restore the canvas
155
+            this._outputCanvasCtx.restore();
140 156
         } else {
141 157
             this._outputCanvasCtx.filter = `blur(${this._options.virtualBackground.blurValue}px)`;
142 158
             this._outputCanvasCtx.drawImage(this._inputVideoElement, 0, 0);
@@ -172,12 +188,6 @@ export default class JitsiStreamBackgroundEffect {
172 188
      * @returns {void}
173 189
      */
174 190
     _renderMask() {
175
-        const desktopShareTrack = this._options?.virtualBackground?.virtualSource?.track;
176
-
177
-        if (desktopShareTrack) {
178
-            this._desktopShareDimensions = desktopShareTrack.getSettings ? desktopShareTrack.getSettings()
179
-                : desktopShareTrack.getConstraints();
180
-        }
181 191
         this.resizeSource();
182 192
         this.runInference();
183 193
         this.runPostProcessing();
@@ -239,9 +249,10 @@ export default class JitsiStreamBackgroundEffect {
239 249
      * @returns {MediaStream} - The stream with the applied effect.
240 250
      */
241 251
     startEffect(stream: MediaStream) {
252
+        this._stream = stream;
242 253
         this._maskFrameTimerWorker = new Worker(timerWorkerScript, { name: 'Blur effect worker' });
243 254
         this._maskFrameTimerWorker.onmessage = this._onMaskFrameTimer;
244
-        const firstVideoTrack = stream.getVideoTracks()[0];
255
+        const firstVideoTrack = this._stream.getVideoTracks()[0];
245 256
         const { height, frameRate, width }
246 257
             = firstVideoTrack.getSettings ? firstVideoTrack.getSettings() : firstVideoTrack.getConstraints();
247 258
 
@@ -257,7 +268,7 @@ export default class JitsiStreamBackgroundEffect {
257 268
         this._inputVideoElement.width = parseInt(width, 10);
258 269
         this._inputVideoElement.height = parseInt(height, 10);
259 270
         this._inputVideoElement.autoplay = true;
260
-        this._inputVideoElement.srcObject = stream;
271
+        this._inputVideoElement.srcObject = this._stream;
261 272
         this._inputVideoElement.onloadeddata = () => {
262 273
             this._maskFrameTimerWorker.postMessage({
263 274
                 id: SET_TIMEOUT,

+ 16
- 1
react/features/virtual-background/components/VirtualBackgroundDialog.js View File

@@ -13,6 +13,7 @@ import { browser, JitsiTrackErrors } from '../../base/lib-jitsi-meet';
13 13
 import { createLocalTrack } from '../../base/lib-jitsi-meet/functions';
14 14
 import { VIDEO_TYPE } from '../../base/media';
15 15
 import { connect } from '../../base/redux';
16
+import { updateSettings } from '../../base/settings';
16 17
 import { Tooltip } from '../../base/tooltip';
17 18
 import { getLocalVideoTrack } from '../../base/tracks';
18 19
 import { showErrorNotification } from '../../notifications';
@@ -73,6 +74,11 @@ const images: Array<Image> = [
73 74
 ];
74 75
 type Props = {
75 76
 
77
+    /**
78
+     * The current local flip x status.
79
+     */
80
+    _localFlipX: boolean,
81
+
76 82
     /**
77 83
      * Returns the jitsi track that will have backgraund effect applied.
78 84
      */
@@ -121,7 +127,10 @@ const onError = event => {
121 127
  * @returns {{Props}}
122 128
  */
123 129
 function _mapStateToProps(state): Object {
130
+    const { localFlipX } = state['features/base/settings'];
131
+
124 132
     return {
133
+        _localFlipX: Boolean(localFlipX),
125 134
         _virtualBackground: state['features/virtual-background'],
126 135
         _selectedThumbnail: state['features/virtual-background'].selectedThumbnail,
127 136
         _jitsiTrack: getLocalVideoTrack(state['features/base/tracks'])?.jitsiTrack
@@ -136,6 +145,7 @@ const VirtualBackgroundDialog = translate(connect(_mapStateToProps)(VirtualBackg
136 145
  * @returns {ReactElement}
137 146
  */
138 147
 function VirtualBackground({
148
+    _localFlipX,
139 149
     _jitsiTrack,
140 150
     _selectedThumbnail,
141 151
     _virtualBackground,
@@ -178,7 +188,12 @@ function VirtualBackground({
178 188
         if (storedImages.length === backgroundsLimit) {
179 189
             setStoredImages(storedImages.slice(1));
180 190
         }
181
-    }, [ storedImages ]);
191
+        if (!_localFlipX) {
192
+            dispatch(updateSettings({
193
+                localFlipX: !_localFlipX
194
+            }));
195
+        }
196
+    }, [ storedImages, _localFlipX ]);
182 197
 
183 198
 
184 199
     const enableBlur = useCallback(async () => {

+ 1
- 1
react/features/virtual-background/components/VirtualBackgroundPreview.js View File

@@ -13,7 +13,7 @@ import { toggleBackgroundEffect } from '../actions';
13 13
 import { VIRTUAL_BACKGROUND_TYPE } from '../constants';
14 14
 import { localTrackStopped } from '../functions';
15 15
 
16
-const videoClassName = 'video-preview-video';
16
+const videoClassName = 'video-preview-video flipVideoX';
17 17
 
18 18
 /**
19 19
  * The type of the React {@code PureComponent} props of {@link VirtualBackgroundPreview}.

Loading…
Cancel
Save