Просмотр исходного кода

fix(screenshot-capture): Prevent effect initialization on each toggle

master
Mihai Uscat 5 лет назад
Родитель
Сommit
2064fc8937

+ 23
- 6
react/features/screenshot-capture/actions.js Просмотреть файл

@@ -2,9 +2,11 @@
2 2
 
3 3
 import { createScreenshotCaptureEffect } from '../stream-effects/screenshot-capture';
4 4
 import { getLocalVideoTrack } from '../../features/base/tracks';
5
-
5
+import logger from './logger';
6 6
 import { SET_SCREENSHOT_CAPTURE } from './actionTypes';
7 7
 
8
+let ongoingEffect;
9
+
8 10
 /**
9 11
  * Marks the on-off state of screenshot captures.
10 12
  *
@@ -28,19 +30,34 @@ function setScreenshotCapture(enabled) {
28 30
 * @returns {Promise}
29 31
 */
30 32
 export function toggleScreenshotCaptureEffect(enabled: boolean) {
31
-    return function(dispatch: (Object) => Object, getState: () => any) {
33
+    return async function(dispatch: (Object) => Object, getState: () => any) {
32 34
         const state = getState();
33 35
 
34 36
         if (state['features/screenshot-capture'].capturesEnabled !== enabled) {
35 37
             const { jitsiTrack } = getLocalVideoTrack(state['features/base/tracks']);
36 38
 
39
+            if (!ongoingEffect) {
40
+                ongoingEffect = await createScreenshotCaptureEffect(state);
41
+            }
42
+
37 43
             // Screenshot capture effect doesn't return a modified stream. Therefore, we don't have to
38 44
             // switch the stream at the conference level, starting/stopping the effect will suffice here.
39
-            return createScreenshotCaptureEffect(state)
40
-                .then(effect => {
41
-                    enabled ? effect.startEffect(jitsiTrack.getOriginalStream()) : effect.stopEffect();
45
+            if (enabled) {
46
+                try {
47
+                    await ongoingEffect.startEffect(
48
+                        jitsiTrack.getOriginalStream(),
49
+                        jitsiTrack.videoType
50
+                    );
42 51
                     dispatch(setScreenshotCapture(enabled));
43
-                });
52
+                } catch {
53
+
54
+                    // Handle promise rejection from {@code startEffect} due to stream type not being desktop.
55
+                    logger.error('Unsupported stream type.');
56
+                }
57
+            } else {
58
+                ongoingEffect.stopEffect();
59
+                dispatch(setScreenshotCapture(enabled));
60
+            }
44 61
         }
45 62
 
46 63
         return Promise.resolve();

+ 5
- 0
react/features/screenshot-capture/logger.js Просмотреть файл

@@ -0,0 +1,5 @@
1
+// @flow
2
+
3
+import { getLogger } from '../base/logging/functions';
4
+
5
+export default getLogger('features/screenshot-capture');

+ 25
- 29
react/features/stream-effects/screenshot-capture/ScreenshotCaptureEffect.js Просмотреть файл

@@ -50,40 +50,36 @@ export default class ScreenshotCaptureEffect {
50 50
         this._streamWorker.onmessage = this._handleWorkerAction;
51 51
     }
52 52
 
53
-    /**
54
-     * Checks if the local track supports this effect.
55
-     *
56
-     * @param {JitsiLocalTrack} jitsiLocalTrack - Targeted local track.
57
-     * @returns {boolean} - Returns true if this effect can run on the specified track, false otherwise.
58
-     */
59
-    isEnabled(jitsiLocalTrack: Object) {
60
-        return jitsiLocalTrack.isVideoTrack() && jitsiLocalTrack.videoType === 'desktop';
61
-    }
62
-
63 53
     /**
64 54
      * Starts the screenshot capture event on a loop.
65 55
      *
66 56
      * @param {MediaStream} stream - The desktop stream from which screenshots are to be sent.
67
-     * @returns {MediaStream} - The same stream, with the interval set.
57
+     * @param {string} videoType - The type of the media stream.
58
+     * @returns {Promise} - Promise that resolves once effect has started or rejects if the
59
+     * videoType parameter is not desktop.
68 60
      */
69
-    startEffect(stream: MediaStream) {
70
-        const desktopTrack = stream.getVideoTracks()[0];
71
-        const { height, width }
72
-            = desktopTrack.getSettings() ?? desktopTrack.getConstraints();
73
-
74
-        this._streamHeight = height;
75
-        this._streamWidth = width;
76
-        this._currentCanvas.height = parseInt(height, 10);
77
-        this._currentCanvas.width = parseInt(width, 10);
78
-        this._videoElement.height = parseInt(height, 10);
79
-        this._videoElement.width = parseInt(width, 10);
80
-        this._videoElement.srcObject = stream;
81
-        this._videoElement.play();
82
-
83
-        // Store first capture for comparisons in {@code this._handleScreenshot}.
84
-        this._videoElement.addEventListener('loadeddata', this._initScreenshotCapture);
85
-
86
-        return stream;
61
+    startEffect(stream: MediaStream, videoType: string) {
62
+        return new Promise<void>((resolve, reject) => {
63
+            if (videoType !== 'desktop') {
64
+                reject();
65
+            }
66
+            const desktopTrack = stream.getVideoTracks()[0];
67
+            const { height, width }
68
+                = desktopTrack.getSettings() ?? desktopTrack.getConstraints();
69
+
70
+            this._streamHeight = height;
71
+            this._streamWidth = width;
72
+            this._currentCanvas.height = parseInt(height, 10);
73
+            this._currentCanvas.width = parseInt(width, 10);
74
+            this._videoElement.height = parseInt(height, 10);
75
+            this._videoElement.width = parseInt(width, 10);
76
+            this._videoElement.srcObject = stream;
77
+            this._videoElement.play();
78
+
79
+            // Store first capture for comparisons in {@code this._handleScreenshot}.
80
+            this._videoElement.addEventListener('loadeddata', this._initScreenshotCapture);
81
+            resolve();
82
+        });
87 83
     }
88 84
 
89 85
     /**

Загрузка…
Отмена
Сохранить