Преглед на файлове

feat: Change the screenshare capture fps from UI. (#9438)

* feat: Change the screenshare capture fps from UI.
Add the ability to change the capture frame rate for screenshare from the UI. The fps becomes effective only on screen shares that are started after the setting is changed.

* squash: add missing JSDOCs and translations for frames-per-second.
factor2
Jaya Allamsetty преди 4 години
родител
ревизия
765fbe5e1d
No account linked to committer's email address

+ 18
- 6
css/modals/settings/_settings.scss Целия файл

36
 
36
 
37
     .calendar-tab,
37
     .calendar-tab,
38
     .more-tab,
38
     .more-tab,
39
+    .box {
40
+        display: flex;
41
+        justify-content: space-between;
42
+        width: 100%;
43
+    }
44
+
39
     .profile-edit {
45
     .profile-edit {
40
         display: flex;
46
         display: flex;
41
         width: 100%;
47
         width: 100%;
45
         flex: 1;
51
         flex: 1;
46
     }
52
     }
47
     .settings-sub-pane {
53
     .settings-sub-pane {
48
-        flex-grow: 1;
54
+        flex: 1;
49
     }
55
     }
50
 
56
 
51
-    .profile-edit-field {
52
-        margin-right: 20px;
57
+    .settings-sub-pane .right {
58
+        flex: 1;
59
+    }
60
+    .settings-sub-pane .left {
61
+        flex: 1;
53
     }
62
     }
54
 
63
 
55
-    .language-settings {
56
-        max-width: 50%;
57
-        width: 35%;
64
+    .settings-sub-pane-element {
65
+        text-align: left;
66
+        flex: 1;
67
+    }
68
+    .profile-edit-field {
69
+        margin-right: 20px;
58
     }
70
     }
59
 
71
 
60
     .calendar-tab {
72
     .calendar-tab {

+ 4
- 0
lang/main.json Целия файл

719
             "signedIn": "Currently accessing calendar events for {{email}}. Click the Disconnect button below to stop accessing calendar events.",
719
             "signedIn": "Currently accessing calendar events for {{email}}. Click the Disconnect button below to stop accessing calendar events.",
720
             "title": "Calendar"
720
             "title": "Calendar"
721
         },
721
         },
722
+        "desktopShareFramerate": "Desktop sharing frame rate",
723
+        "desktopShareWarning": "You need to restart the screen share for the new settings to take effect.",
724
+        "desktopShareHighFpsWarning": "A higher frame rate for desktop sharing might affect your bandwidth. You need to restart the screen share for the new settings to take effect.",
722
         "devices": "Devices",
725
         "devices": "Devices",
723
         "followMe": "Everyone follows me",
726
         "followMe": "Everyone follows me",
727
+        "framesPerSecond": "frames-per-second",
724
         "language": "Language",
728
         "language": "Language",
725
         "loggedIn": "Logged in as {{name}}",
729
         "loggedIn": "Logged in as {{name}}",
726
         "microphones": "Microphones",
730
         "microphones": "Microphones",

+ 1
- 0
react/features/app/middlewares.web.js Целия файл

13
 import '../power-monitor/middleware';
13
 import '../power-monitor/middleware';
14
 import '../prejoin/middleware';
14
 import '../prejoin/middleware';
15
 import '../remote-control/middleware';
15
 import '../remote-control/middleware';
16
+import '../screen-share/middleware';
16
 import '../shared-video/middleware';
17
 import '../shared-video/middleware';
17
 import '../talk-while-muted/middleware';
18
 import '../talk-while-muted/middleware';
18
 import '../virtual-background/middleware';
19
 import '../virtual-background/middleware';

+ 1
- 0
react/features/app/reducers.web.js Целия файл

11
 import '../power-monitor/reducer';
11
 import '../power-monitor/reducer';
12
 import '../prejoin/reducer';
12
 import '../prejoin/reducer';
13
 import '../remote-control/reducer';
13
 import '../remote-control/reducer';
14
+import '../screen-share/reducer';
14
 import '../screenshot-capture/reducer';
15
 import '../screenshot-capture/reducer';
15
 import '../shared-video/reducer';
16
 import '../shared-video/reducer';
16
 import '../talk-while-muted/reducer';
17
 import '../talk-while-muted/reducer';

+ 8
- 0
react/features/screen-share/actionTypes.js Целия файл

10
  */
10
  */
11
 export const SET_SCREEN_AUDIO_SHARE_STATE = 'SET_SCREEN_AUDIO_SHARE_STATE';
11
 export const SET_SCREEN_AUDIO_SHARE_STATE = 'SET_SCREEN_AUDIO_SHARE_STATE';
12
 
12
 
13
+/**
14
+ * Type of action which sets the capture frame rate for screenshare.
15
+ * {
16
+ *      type: SET_SCREENSHARE_CAPTURE_FRAME_RATE,
17
+ *      captureFrameRate: number
18
+ * }
19
+ */
20
+export const SET_SCREENSHARE_CAPTURE_FRAME_RATE = 'SET_SCREENSHARE_CAPTURE_FRAME_RATE';

+ 17
- 1
react/features/screen-share/actions.js Целия файл

1
 // @flow
1
 // @flow
2
 
2
 
3
-import { SET_SCREEN_AUDIO_SHARE_STATE } from './actionTypes';
3
+import { SET_SCREEN_AUDIO_SHARE_STATE, SET_SCREENSHARE_CAPTURE_FRAME_RATE } from './actionTypes';
4
 
4
 
5
 /**
5
 /**
6
  * Updates the current known status of the shared video.
6
  * Updates the current known status of the shared video.
17
         isSharingAudio
17
         isSharingAudio
18
     };
18
     };
19
 }
19
 }
20
+
21
+/**
22
+ * Updates the capture frame rate for screenshare in redux.
23
+ *
24
+ * @param {number} captureFrameRate - The frame rate to be used for screenshare.
25
+ * @returns {{
26
+ *      type: SET_SCREENSHARE_CAPTURE_FRAME_RATE,
27
+ *      captureFrameRate: number
28
+ * }}
29
+ */
30
+export function setScreenshareFramerate(captureFrameRate: number) {
31
+    return {
32
+        type: SET_SCREENSHARE_CAPTURE_FRAME_RATE,
33
+        captureFrameRate
34
+    };
35
+}

+ 5
- 0
react/features/screen-share/logger.js Целия файл

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

+ 57
- 0
react/features/screen-share/middleware.js Целия файл

1
+// @flow
2
+
3
+import { CONFERENCE_JOINED } from '../base/conference';
4
+import { MiddlewareRegistry } from '../base/redux';
5
+
6
+import { SET_SCREENSHARE_CAPTURE_FRAME_RATE } from './actionTypes';
7
+import logger from './logger';
8
+
9
+/**
10
+ * Implements the middleware of the feature screen-share.
11
+ *
12
+ * @param {Store} store - The redux store.
13
+ * @returns {Function}
14
+ */
15
+MiddlewareRegistry.register(store => next => action => {
16
+    const result = next(action);
17
+
18
+    switch (action.type) {
19
+    case CONFERENCE_JOINED: {
20
+        _setScreenshareCaptureFps(store);
21
+        break;
22
+    }
23
+    case SET_SCREENSHARE_CAPTURE_FRAME_RATE: {
24
+        const { captureFrameRate } = action;
25
+
26
+        _setScreenshareCaptureFps(store, captureFrameRate);
27
+        break;
28
+    }
29
+    }
30
+
31
+    return result;
32
+});
33
+
34
+/**
35
+ * Sets the capture frame rate for screenshare.
36
+ *
37
+ * @param {Store} store - The redux store.
38
+ * @param {number} frameRate - Frame rate to be configured.
39
+ * @private
40
+ * @returns {void}
41
+ */
42
+function _setScreenshareCaptureFps(store, frameRate) {
43
+    const state = store.getState();
44
+    const { conference } = state['features/base/conference'];
45
+    const { captureFrameRate } = state['features/screen-share'];
46
+    const screenShareFps = frameRate ?? captureFrameRate;
47
+
48
+    if (!conference) {
49
+        return;
50
+    }
51
+
52
+    if (screenShareFps) {
53
+        logger.debug(`Setting screenshare capture frame rate as ${screenShareFps}`);
54
+        conference.setDesktopSharingFrameRate(screenShareFps);
55
+    }
56
+
57
+}

+ 8
- 2
react/features/screen-share/reducer.js Целия файл

1
 
1
 
2
 import { ReducerRegistry } from '../base/redux';
2
 import { ReducerRegistry } from '../base/redux';
3
 
3
 
4
-import { SET_SCREEN_AUDIO_SHARE_STATE } from './actionTypes';
4
+import { SET_SCREEN_AUDIO_SHARE_STATE, SET_SCREENSHARE_CAPTURE_FRAME_RATE } from './actionTypes';
5
 
5
 
6
 /**
6
 /**
7
  * Reduces the Redux actions of the feature features/screen-share.
7
  * Reduces the Redux actions of the feature features/screen-share.
8
  */
8
  */
9
 ReducerRegistry.register('features/screen-share', (state = {}, action) => {
9
 ReducerRegistry.register('features/screen-share', (state = {}, action) => {
10
-    const { isSharingAudio } = action;
10
+    const { captureFrameRate, isSharingAudio } = action;
11
 
11
 
12
     switch (action.type) {
12
     switch (action.type) {
13
     case SET_SCREEN_AUDIO_SHARE_STATE:
13
     case SET_SCREEN_AUDIO_SHARE_STATE:
16
             isSharingAudio
16
             isSharingAudio
17
         };
17
         };
18
 
18
 
19
+    case SET_SCREENSHARE_CAPTURE_FRAME_RATE:
20
+        return {
21
+            ...state,
22
+            captureFrameRate
23
+        };
24
+
19
     default:
25
     default:
20
         return state;
26
         return state;
21
     }
27
     }

+ 7
- 0
react/features/settings/actions.js Целия файл

5
 import { i18next } from '../base/i18n';
5
 import { i18next } from '../base/i18n';
6
 import { updateSettings } from '../base/settings';
6
 import { updateSettings } from '../base/settings';
7
 import { setPrejoinPageVisibility } from '../prejoin/actions';
7
 import { setPrejoinPageVisibility } from '../prejoin/actions';
8
+import { setScreenshareFramerate } from '../screen-share/actions';
8
 
9
 
9
 import {
10
 import {
10
     SET_AUDIO_SETTINGS_VISIBILITY,
11
     SET_AUDIO_SETTINGS_VISIBILITY,
99
         if (newState.currentLanguage !== currentState.currentLanguage) {
100
         if (newState.currentLanguage !== currentState.currentLanguage) {
100
             i18next.changeLanguage(newState.currentLanguage);
101
             i18next.changeLanguage(newState.currentLanguage);
101
         }
102
         }
103
+
104
+        if (newState.currentFramerate !== currentState.currentFramerate) {
105
+            const frameRate = parseInt(newState.currentFramerate, 10);
106
+
107
+            dispatch(setScreenshareFramerate(frameRate));
108
+        }
102
     };
109
     };
103
 }
110
 }
104
 
111
 

+ 151
- 32
react/features/settings/components/web/MoreTab.js Целия файл

11
 import type { Props as AbstractDialogTabProps } from '../../../base/dialog';
11
 import type { Props as AbstractDialogTabProps } from '../../../base/dialog';
12
 import { translate } from '../../../base/i18n';
12
 import { translate } from '../../../base/i18n';
13
 import TouchmoveHack from '../../../chat/components/web/TouchmoveHack';
13
 import TouchmoveHack from '../../../chat/components/web/TouchmoveHack';
14
+import { SS_DEFAULT_FRAME_RATE } from '../../constants';
14
 
15
 
15
 /**
16
 /**
16
  * The type of the React {@code Component} props of {@link MoreTab}.
17
  * The type of the React {@code Component} props of {@link MoreTab}.
18
 export type Props = {
19
 export type Props = {
19
     ...$Exact<AbstractDialogTabProps>,
20
     ...$Exact<AbstractDialogTabProps>,
20
 
21
 
22
+    /**
23
+     * The currently selected desktop share frame rate in the frame rate select dropdown.
24
+     */
25
+     currentFramerate: string,
26
+
21
     /**
27
     /**
22
      * The currently selected language to display in the language select
28
      * The currently selected language to display in the language select
23
      * dropdown.
29
      * dropdown.
24
      */
30
      */
25
     currentLanguage: string,
31
     currentLanguage: string,
26
 
32
 
33
+    /**
34
+     * All available desktop capture frame rates.
35
+     */
36
+    desktopShareFramerates: Array<number>,
37
+
27
     /**
38
     /**
28
      * Whether or not follow me is currently active (enabled by some other participant).
39
      * Whether or not follow me is currently active (enabled by some other participant).
29
      */
40
      */
59
      */
70
      */
60
     showPrejoinPage: boolean,
71
     showPrejoinPage: boolean,
61
 
72
 
62
-
63
     /**
73
     /**
64
      * Whether or not the user has selected the Start Audio Muted feature to be
74
      * Whether or not the user has selected the Start Audio Muted feature to be
65
      * enabled.
75
      * enabled.
83
  */
93
  */
84
 type State = {
94
 type State = {
85
 
95
 
96
+    /**
97
+     * Whether or not the desktop share frame rate select dropdown is open.
98
+     */
99
+     isFramerateSelectOpen: boolean,
100
+
86
     /**
101
     /**
87
      * Whether or not the language select dropdown is open.
102
      * Whether or not the language select dropdown is open.
88
      */
103
      */
105
         super(props);
120
         super(props);
106
 
121
 
107
         this.state = {
122
         this.state = {
123
+            isFramerateSelectOpen: false,
108
             isLanguageSelectOpen: false
124
             isLanguageSelectOpen: false
109
         };
125
         };
110
 
126
 
111
         // Bind event handler so it is only bound once for every instance.
127
         // Bind event handler so it is only bound once for every instance.
112
-        this._onLanguageDropdownOpenChange
113
-            = this._onLanguageDropdownOpenChange.bind(this);
128
+        this._onFramerateDropdownOpenChange = this._onFramerateDropdownOpenChange.bind(this);
129
+        this._onFramerateItemSelect = this._onFramerateItemSelect.bind(this);
130
+        this._onLanguageDropdownOpenChange = this._onLanguageDropdownOpenChange.bind(this);
114
         this._onLanguageItemSelect = this._onLanguageItemSelect.bind(this);
131
         this._onLanguageItemSelect = this._onLanguageItemSelect.bind(this);
115
         this._onStartAudioMutedChanged = this._onStartAudioMutedChanged.bind(this);
132
         this._onStartAudioMutedChanged = this._onStartAudioMutedChanged.bind(this);
116
         this._onStartVideoMutedChanged = this._onStartVideoMutedChanged.bind(this);
133
         this._onStartVideoMutedChanged = this._onStartVideoMutedChanged.bind(this);
126
      * @returns {ReactElement}
143
      * @returns {ReactElement}
127
      */
144
      */
128
     render() {
145
     render() {
129
-        const { showModeratorSettings, showLanguageSettings, showPrejoinSettings } = this.props;
130
         const content = [];
146
         const content = [];
131
 
147
 
132
-        if (showPrejoinSettings) {
133
-            content.push(this._renderPrejoinScreenSettings());
134
-        }
148
+        content.push(this._renderSettingsLeft());
149
+        content.push(this._renderSettingsRight());
135
 
150
 
136
-        content.push(this._renderKeyboardShortcutCheckbox());
151
+        return <div className = 'more-tab box'>{ content }</div>;
152
+    }
137
 
153
 
154
+    _onFramerateDropdownOpenChange: (Object) => void;
138
 
155
 
139
-        if (showModeratorSettings) {
140
-            content.push(this._renderModeratorSettings());
141
-        }
156
+    /**
157
+     * Callback invoked to toggle display of the desktop share framerate select dropdown.
158
+     *
159
+     * @param {Object} event - The event for opening or closing the dropdown.
160
+     * @private
161
+     * @returns {void}
162
+     */
163
+    _onFramerateDropdownOpenChange({ isOpen }) {
164
+        this.setState({ isFramerateSelectOpen: isOpen });
165
+    }
166
+
167
+    _onFramerateItemSelect: (Object) => void;
142
 
168
 
143
-        if (showLanguageSettings) {
144
-            content.push(this._renderLangaugeSelect());
145
-        }
169
+    /**
170
+     * Callback invoked to select a frame rate from the select dropdown.
171
+     *
172
+     * @param {Object} e - The key event to handle.
173
+     * @private
174
+     * @returns {void}
175
+     */
176
+    _onFramerateItemSelect(e) {
177
+        const frameRate = e.currentTarget.getAttribute('data-framerate');
146
 
178
 
147
-        return <div className = 'more-tab'>{ content }</div>;
179
+        super._onChange({ currentFramerate: frameRate });
148
     }
180
     }
149
 
181
 
150
     _onLanguageDropdownOpenChange: (Object) => void;
182
     _onLanguageDropdownOpenChange: (Object) => void;
246
         super._onChange({ keyboardShortcutEnable: checked });
278
         super._onChange({ keyboardShortcutEnable: checked });
247
     }
279
     }
248
 
280
 
281
+    /**
282
+     * Returns the React Element for the desktop share frame rate dropdown.
283
+     *
284
+     * @returns {ReactElement}
285
+     */
286
+    _renderFramerateSelect() {
287
+        const { currentFramerate, desktopShareFramerates, t } = this.props;
288
+        const frameRateItems = desktopShareFramerates.map(frameRate => (
289
+            <DropdownItem
290
+                data-framerate = { frameRate }
291
+                key = { frameRate }
292
+                onClick = { this._onFramerateItemSelect }>
293
+                { `${frameRate} ${t('settings.framesPerSecond')}` }
294
+            </DropdownItem>));
295
+
296
+        return (
297
+            <div
298
+                className = 'settings-sub-pane-element'
299
+                key = 'frameRate'>
300
+                <h2 className = 'mock-atlaskit-label'>
301
+                    { t('settings.desktopShareFramerate') }
302
+                </h2>
303
+                <div className = 'dropdown-menu'>
304
+                    <TouchmoveHack isModal = { true }>
305
+                        <DropdownMenu
306
+                            isOpen = { this.state.isFramerateSelectOpen }
307
+                            onOpenChange = { this._onFramerateDropdownOpenChange }
308
+                            shouldFitContainer = { true }
309
+                            trigger = { currentFramerate
310
+                                ? `${currentFramerate} ${t('settings.framesPerSecond')}`
311
+                                : '' }
312
+                            triggerButtonProps = {{
313
+                                shouldFitContainer: true
314
+                            }}
315
+                            triggerType = 'button'>
316
+                            <DropdownItemGroup>
317
+                                { frameRateItems }
318
+                            </DropdownItemGroup>
319
+                        </DropdownMenu>
320
+                    </TouchmoveHack>
321
+                </div>
322
+                <div
323
+                    className = 'mock-atlaskit-label'>
324
+                    { parseInt(currentFramerate, 10) > SS_DEFAULT_FRAME_RATE
325
+                        ? t('settings.desktopShareHighFpsWarning')
326
+                        : t('settings.desktopShareWarning') }
327
+                </div>
328
+            </div>
329
+        );
330
+    }
331
+
332
+    /**
333
+     * Returns the React Element for keyboardShortcut settings.
334
+     *
335
+     * @private
336
+     * @returns {ReactElement}
337
+     */
338
+    _renderKeyboardShortcutCheckbox() {
339
+        const { t } = this.props;
340
+
341
+        return (
342
+            <div
343
+                className = 'settings-sub-pane-element'
344
+                key = 'keyboard-shortcut'>
345
+                <h2 className = 'mock-atlaskit-label'>
346
+                    { t('keyboardShortcuts.keyboardShortcuts') }
347
+                </h2>
348
+                <Checkbox
349
+                    isChecked = { keyboardShortcut.getEnabled() }
350
+                    label = { t('prejoin.keyboardShortcuts') }
351
+                    name = 'enable-keyboard-shortcuts'
352
+                    onChange = { this._onKeyboardShortcutEnableChanged } />
353
+            </div>
354
+        );
355
+    }
356
+
249
     /**
357
     /**
250
      * Returns the menu item for changing displayed language.
358
      * Returns the menu item for changing displayed language.
251
      *
359
      *
252
      * @private
360
      * @private
253
      * @returns {ReactElement}
361
      * @returns {ReactElement}
254
      */
362
      */
255
-    _renderLangaugeSelect() {
363
+    _renderLanguageSelect() {
256
         const {
364
         const {
257
             currentLanguage,
365
             currentLanguage,
258
             languages,
366
             languages,
270
 
378
 
271
         return (
379
         return (
272
             <div
380
             <div
273
-                className = 'settings-sub-pane language-settings'
381
+                className = 'settings-sub-pane-element'
274
                 key = 'language'>
382
                 key = 'language'>
275
                 <h2 className = 'mock-atlaskit-label'>
383
                 <h2 className = 'mock-atlaskit-label'>
276
                     { t('settings.language') }
384
                     { t('settings.language') }
315
 
423
 
316
         return (
424
         return (
317
             <div
425
             <div
318
-                className = 'settings-sub-pane'
426
+                className = 'settings-sub-pane-element'
319
                 key = 'moderator'>
427
                 key = 'moderator'>
320
                 <h2 className = 'mock-atlaskit-label'>
428
                 <h2 className = 'mock-atlaskit-label'>
321
                     { t('settings.moderator') }
429
                     { t('settings.moderator') }
351
 
459
 
352
         return (
460
         return (
353
             <div
461
             <div
354
-                className = 'settings-sub-pane'
462
+                className = 'settings-sub-pane-element'
355
                 key = 'prejoin-screen'>
463
                 key = 'prejoin-screen'>
356
                 <h2 className = 'mock-atlaskit-label'>
464
                 <h2 className = 'mock-atlaskit-label'>
357
                     { t('prejoin.premeeting') }
465
                     { t('prejoin.premeeting') }
366
     }
474
     }
367
 
475
 
368
     /**
476
     /**
369
-     * Returns the React Element for keyboardShortcut settings.
477
+     * Returns the React element that needs to be displayed on the right half of the more tabs.
370
      *
478
      *
371
      * @private
479
      * @private
372
      * @returns {ReactElement}
480
      * @returns {ReactElement}
373
      */
481
      */
374
-    _renderKeyboardShortcutCheckbox() {
375
-        const { t } = this.props;
482
+    _renderSettingsRight() {
483
+        const { showLanguageSettings } = this.props;
376
 
484
 
377
         return (
485
         return (
378
             <div
486
             <div
379
-                className = 'settings-sub-pane'
380
-                key = 'keyboard-shortcut'>
381
-                <h2 className = 'mock-atlaskit-label'>
382
-                    { t('keyboardShortcuts.keyboardShortcuts') }
383
-                </h2>
384
-                <Checkbox
385
-                    isChecked = { keyboardShortcut.getEnabled() }
386
-                    label = { t('prejoin.keyboardShortcuts') }
387
-                    name = 'enable-keyboard-shortcuts'
388
-                    onChange = { this._onKeyboardShortcutEnableChanged } />
487
+                className = 'settings-sub-pane right'>
488
+                { showLanguageSettings && this._renderLanguageSelect() }
489
+                { this._renderFramerateSelect() }
490
+            </div>
491
+        );
492
+    }
493
+
494
+    /**
495
+     * Returns the React element that needs to be displayed on the left half of the more tabs.
496
+     *
497
+     * @returns {ReactElement}
498
+     */
499
+    _renderSettingsLeft() {
500
+        const { showPrejoinSettings, showModeratorSettings } = this.props;
501
+
502
+        return (
503
+            <div
504
+                className = 'settings-sub-pane left'>
505
+                { showPrejoinSettings && this._renderPrejoinScreenSettings() }
506
+                { this._renderKeyboardShortcutCheckbox() }
507
+                { showModeratorSettings && this._renderModeratorSettings() }
389
             </div>
508
             </div>
390
         );
509
         );
391
     }
510
     }

+ 1
- 0
react/features/settings/components/web/SettingsDialog.js Целия файл

194
 
194
 
195
                 return {
195
                 return {
196
                     ...newProps,
196
                     ...newProps,
197
+                    currentFramerate: tabState.currentFramerate,
197
                     currentLanguage: tabState.currentLanguage,
198
                     currentLanguage: tabState.currentLanguage,
198
                     followMeEnabled: tabState.followMeEnabled,
199
                     followMeEnabled: tabState.followMeEnabled,
199
                     showPrejoinPage: tabState.showPrejoinPage,
200
                     showPrejoinPage: tabState.showPrejoinPage,

+ 10
- 0
react/features/settings/constants.js Целия файл

9
  * View ID for the Settings modal.
9
  * View ID for the Settings modal.
10
  */
10
  */
11
 export const SETTINGS_VIEW_ID = 'SETTINGS_VIEW_ID';
11
 export const SETTINGS_VIEW_ID = 'SETTINGS_VIEW_ID';
12
+
13
+/**
14
+ * Default frame rate to be used for capturing screenshare.
15
+ */
16
+export const SS_DEFAULT_FRAME_RATE = 5;
17
+
18
+/**
19
+ * Supported framerates to be used for capturing screenshare.
20
+ */
21
+export const SS_SUPPORTED_FRAMERATES = [ 5, 15, 30 ];

+ 5
- 0
react/features/settings/functions.js Целия файл

11
 import { parseStandardURIString } from '../base/util';
11
 import { parseStandardURIString } from '../base/util';
12
 import { isFollowMeActive } from '../follow-me';
12
 import { isFollowMeActive } from '../follow-me';
13
 
13
 
14
+import { SS_DEFAULT_FRAME_RATE, SS_SUPPORTED_FRAMERATES } from './constants';
15
+
14
 declare var interfaceConfig: Object;
16
 declare var interfaceConfig: Object;
15
 
17
 
16
 /**
18
 /**
95
  */
97
  */
96
 export function getMoreTabProps(stateful: Object | Function) {
98
 export function getMoreTabProps(stateful: Object | Function) {
97
     const state = toState(stateful);
99
     const state = toState(stateful);
100
+    const framerate = state['features/screen-share'].captureFrameRate ?? SS_DEFAULT_FRAME_RATE;
98
     const language = i18next.language || DEFAULT_LANGUAGE;
101
     const language = i18next.language || DEFAULT_LANGUAGE;
99
     const {
102
     const {
100
         conference,
103
         conference,
112
             && isLocalParticipantModerator(state));
115
             && isLocalParticipantModerator(state));
113
 
116
 
114
     return {
117
     return {
118
+        currentFramerate: framerate,
115
         currentLanguage: language,
119
         currentLanguage: language,
120
+        desktopShareFramerates: SS_SUPPORTED_FRAMERATES,
116
         followMeActive: Boolean(conference && followMeActive),
121
         followMeActive: Boolean(conference && followMeActive),
117
         followMeEnabled: Boolean(conference && followMeEnabled),
122
         followMeEnabled: Boolean(conference && followMeEnabled),
118
         languages: LANGUAGES,
123
         languages: LANGUAGES,

Loading…
Отказ
Запис