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

ref(video-quality): update video quality post redux update

Move away from middleware and instead update video quality
when the selected video quality updates in redux. This also
lead to removing of automatically exiting audio only because
with the change it's not so readily possible to tell if the
user switched off audio only by re-selecting the already
preferred video quality. Removing this automagic removed
some additional checking done for mobile.
master
Leonard Kim преди 7 години
родител
ревизия
0b1224495b

+ 47
- 75
react/features/base/conference/middleware.js Целия файл

17
     getPinnedParticipant,
17
     getPinnedParticipant,
18
     PIN_PARTICIPANT
18
     PIN_PARTICIPANT
19
 } from '../participants';
19
 } from '../participants';
20
-import { MiddlewareRegistry } from '../redux';
20
+import { MiddlewareRegistry, StateListenerRegistry } from '../redux';
21
 import UIEvents from '../../../../service/UI/UIEvents';
21
 import UIEvents from '../../../../service/UI/UIEvents';
22
 import { TRACK_ADDED, TRACK_REMOVED } from '../tracks';
22
 import { TRACK_ADDED, TRACK_REMOVED } from '../tracks';
23
 
23
 
25
     conferenceFailed,
25
     conferenceFailed,
26
     conferenceLeft,
26
     conferenceLeft,
27
     createConference,
27
     createConference,
28
-    setLastN,
29
-    toggleAudioOnly
28
+    setLastN
30
 } from './actions';
29
 } from './actions';
31
 import {
30
 import {
32
     CONFERENCE_FAILED,
31
     CONFERENCE_FAILED,
34
     DATA_CHANNEL_OPENED,
33
     DATA_CHANNEL_OPENED,
35
     SET_AUDIO_ONLY,
34
     SET_AUDIO_ONLY,
36
     SET_LASTN,
35
     SET_LASTN,
37
-    SET_MAX_RECEIVER_VIDEO_QUALITY,
38
-    SET_PREFERRED_RECEIVER_VIDEO_QUALITY,
39
     SET_ROOM
36
     SET_ROOM
40
 } from './actionTypes';
37
 } from './actionTypes';
41
 import {
38
 import {
81
     case SET_LASTN:
78
     case SET_LASTN:
82
         return _setLastN(store, next, action);
79
         return _setLastN(store, next, action);
83
 
80
 
84
-    case SET_MAX_RECEIVER_VIDEO_QUALITY:
85
-        return _setMaximumReceiverVideoQuality(store, next, action);
86
-
87
-    case SET_PREFERRED_RECEIVER_VIDEO_QUALITY:
88
-        return _setPreferredReceiverVideoQuality(store, next, action);
89
-
90
     case SET_ROOM:
81
     case SET_ROOM:
91
         return _setRoom(store, next, action);
82
         return _setRoom(store, next, action);
92
 
83
 
98
     return next(action);
89
     return next(action);
99
 });
90
 });
100
 
91
 
92
+/**
93
+ * Registers a change handler for state['features/base/conference'] to update
94
+ * the preferred video quality levels based on user preferred and internal
95
+ * settings.
96
+ */
97
+StateListenerRegistry.register(
98
+    /* selector */ state => state['features/base/conference'],
99
+    /* listener */ (currentState, store, previousState = {}) => {
100
+        const {
101
+            conference,
102
+            maxReceiverVideoQuality,
103
+            preferredReceiverVideoQuality
104
+        } = currentState;
105
+        const changedPreferredVideoQuality = preferredReceiverVideoQuality
106
+            !== previousState.preferredReceiverVideoQuality;
107
+        const changedMaxVideoQuality = maxReceiverVideoQuality
108
+            !== previousState.maxReceiverVideoQuality;
109
+
110
+        if (changedPreferredVideoQuality || changedMaxVideoQuality) {
111
+            _setReceiverVideoConstraint(
112
+                conference,
113
+                preferredReceiverVideoQuality,
114
+                maxReceiverVideoQuality);
115
+        }
116
+    });
117
+
101
 /**
118
 /**
102
  * Makes sure to leave a failed conference in order to release any allocated
119
  * Makes sure to leave a failed conference in order to release any allocated
103
  * resources like peer connections, emit participant left events, etc.
120
  * resources like peer connections, emit participant left events, etc.
438
 }
455
 }
439
 
456
 
440
 /**
457
 /**
441
- * Sets an internal maximum for the video frame height to receive from remote
442
- * videos. This maximum acts as a cap so user preferences cannot exceed a
443
- * specified frame height.
458
+ * Helper function for updating the preferred receiver video constraint, based
459
+ * on the user preference and the internal maximum.
444
  *
460
  *
445
- * @private
446
- * @param {Store} store - The redux store in which the specified {@code action}
447
- * is being dispatched.
448
- * @param {Dispatch} next - The redux {@code dispatch} function to dispatch the
449
- * specified {@code action} to the specified {@code store}.
450
- * @param {Action} action - The redux action
451
- * {@code SET_MAXIMUM_RECEIVER_VIDEO_QUALITY} which is being dispatched in the
452
- * specified {@code store}.
453
- * @private
454
- * @returns {Object} The value returned by {@code next(action)}.
461
+ * @param {JitsiConference} conference - The JitsiConference instance for the
462
+ * current call.
463
+ * @param {number} preferred - The user preferred max frame height.
464
+ * @param {number} max - The maximum frame height the application should
465
+ * receive.
466
+ * @returns {void}
455
  */
467
  */
456
-function _setMaximumReceiverVideoQuality({ getState }, next, action) {
457
-    const { conference, preferredReceiverVideoQuality }
458
-        = getState()['features/base/conference'];
459
-
468
+function _setReceiverVideoConstraint(conference, preferred, max) {
460
     if (conference) {
469
     if (conference) {
461
-        if (typeof preferredReceiverVideoQuality === 'undefined'
462
-            || preferredReceiverVideoQuality > action.maxReceiverVideoQuality) {
463
-            conference.setReceiverVideoConstraint(
464
-                action.maxReceiverVideoQuality);
465
-        }
470
+        conference.setReceiverVideoConstraint(Math.min(preferred, max));
466
     }
471
     }
467
-
468
-    return next(action);
469
-}
470
-
471
-/**
472
- * Sets the preferred receive video quality and will turn off audio only mode if
473
- * enabled.
474
- *
475
- * @param {Store} store - The redux store in which the specified {@code action}
476
- * is being dispatched.
477
- * @param {Dispatch} next - The redux {@code dispatch} function to dispatch the
478
- * specified {@code action} to the specified {@code store}.
479
- * @param {Action} action - The redux action
480
- * {@code SET_PREFERRED_RECEIVER_VIDEO_QUALITY} which is being dispatched in the
481
- * specified {@code store}.
482
- * @private
483
- * @returns {Object} The value returned by {@code next(action)}.
484
- */
485
-function _setPreferredReceiverVideoQuality(
486
-        { dispatch, getState },
487
-        next,
488
-        action) {
489
-    const {
490
-        audioOnly,
491
-        conference,
492
-        maxReceiverVideoQuality
493
-    } = getState()['features/base/conference'];
494
-
495
-    if (conference) {
496
-        const { preferredReceiverVideoQuality } = action;
497
-        const targetQuality = typeof maxReceiverVideoQuality === 'undefined'
498
-            ? preferredReceiverVideoQuality
499
-            : Math.min(maxReceiverVideoQuality, preferredReceiverVideoQuality);
500
-
501
-        conference.setReceiverVideoConstraint(targetQuality);
502
-        audioOnly && dispatch(toggleAudioOnly());
503
-    }
504
-
505
-    return next(action);
506
 }
472
 }
507
 
473
 
508
 /**
474
 /**
592
  * @returns {Object} The value returned by {@code next(action)}.
558
  * @returns {Object} The value returned by {@code next(action)}.
593
  */
559
  */
594
 function _syncReceiveVideoQuality({ getState }, next, action) {
560
 function _syncReceiveVideoQuality({ getState }, next, action) {
595
-    const state = getState()['features/base/conference'];
561
+    const {
562
+        conference,
563
+        maxReceiverVideoQuality,
564
+        preferredReceiverVideoQuality
565
+    } = getState()['features/base/conference'];
596
 
566
 
597
-    state.conference.setReceiverVideoConstraint(
598
-        state.preferredReceiverVideoQuality);
567
+    _setReceiverVideoConstraint(
568
+        conference,
569
+        preferredReceiverVideoQuality,
570
+        maxReceiverVideoQuality);
599
 
571
 
600
     return next(action);
572
     return next(action);
601
 }
573
 }

+ 61
- 76
react/features/base/conference/reducer.js Целия файл

27
 import { VIDEO_QUALITY_LEVELS } from './constants';
27
 import { VIDEO_QUALITY_LEVELS } from './constants';
28
 import { isRoomValid } from './functions';
28
 import { isRoomValid } from './functions';
29
 
29
 
30
+const DEFAULT_STATE = {
31
+    joining: undefined,
32
+    maxReceiverVideoQuality: VIDEO_QUALITY_LEVELS.HIGH,
33
+    preferredReceiverVideoQuality: VIDEO_QUALITY_LEVELS.HIGH
34
+};
35
+
30
 /**
36
 /**
31
  * Listen for actions that contain the conference object, so that it can be
37
  * Listen for actions that contain the conference object, so that it can be
32
  * stored for use by other action creators.
38
  * stored for use by other action creators.
33
  */
39
  */
34
-ReducerRegistry.register('features/base/conference', (state = {}, action) => {
35
-    switch (action.type) {
36
-    case AUTH_STATUS_CHANGED:
37
-        return _authStatusChanged(state, action);
40
+ReducerRegistry.register(
41
+    'features/base/conference',
42
+    (state = DEFAULT_STATE, action) => {
43
+        switch (action.type) {
44
+        case AUTH_STATUS_CHANGED:
45
+            return _authStatusChanged(state, action);
38
 
46
 
39
-    case CONFERENCE_FAILED:
40
-        return _conferenceFailed(state, action);
47
+        case CONFERENCE_FAILED:
48
+            return _conferenceFailed(state, action);
41
 
49
 
42
-    case CONFERENCE_JOINED:
43
-        return _conferenceJoined(state, action);
50
+        case CONFERENCE_JOINED:
51
+            return _conferenceJoined(state, action);
44
 
52
 
45
-    case CONFERENCE_LEFT:
46
-    case CONFERENCE_WILL_LEAVE:
47
-        return _conferenceLeftOrWillLeave(state, action);
53
+        case CONFERENCE_LEFT:
54
+        case CONFERENCE_WILL_LEAVE:
55
+            return _conferenceLeftOrWillLeave(state, action);
48
 
56
 
49
-    case CONFERENCE_WILL_JOIN:
50
-        return _conferenceWillJoin(state, action);
57
+        case CONFERENCE_WILL_JOIN:
58
+            return _conferenceWillJoin(state, action);
51
 
59
 
52
-    case CONNECTION_WILL_CONNECT:
53
-        return set(state, 'authRequired', undefined);
60
+        case CONNECTION_WILL_CONNECT:
61
+            return set(state, 'authRequired', undefined);
54
 
62
 
55
-    case LOCK_STATE_CHANGED:
56
-        return _lockStateChanged(state, action);
63
+        case LOCK_STATE_CHANGED:
64
+            return _lockStateChanged(state, action);
57
 
65
 
58
-    case P2P_STATUS_CHANGED:
59
-        return _p2pStatusChanged(state, action);
66
+        case P2P_STATUS_CHANGED:
67
+            return _p2pStatusChanged(state, action);
60
 
68
 
61
-    case SET_AUDIO_ONLY:
62
-        return _setAudioOnly(state, action);
69
+        case SET_AUDIO_ONLY:
70
+            return _setAudioOnly(state, action);
63
 
71
 
64
-    case SET_DESKTOP_SHARING_ENABLED:
65
-        return _setDesktopSharingEnabled(state, action);
72
+        case SET_DESKTOP_SHARING_ENABLED:
73
+            return _setDesktopSharingEnabled(state, action);
66
 
74
 
67
-    case SET_FOLLOW_ME:
68
-        return set(state, 'followMeEnabled', action.enabled);
75
+        case SET_FOLLOW_ME:
76
+            return set(state, 'followMeEnabled', action.enabled);
69
 
77
 
70
-    case SET_LOCATION_URL:
71
-        return set(state, 'room', undefined);
78
+        case SET_LOCATION_URL:
79
+            return set(state, 'room', undefined);
72
 
80
 
73
-    case SET_MAX_RECEIVER_VIDEO_QUALITY:
74
-        return set(
75
-            state,
76
-            'maxReceiverVideoQuality',
77
-            action.maxReceiverVideoQuality);
81
+        case SET_MAX_RECEIVER_VIDEO_QUALITY:
82
+            return set(
83
+                state,
84
+                'maxReceiverVideoQuality',
85
+                action.maxReceiverVideoQuality);
78
 
86
 
79
-    case SET_PASSWORD:
80
-        return _setPassword(state, action);
87
+        case SET_PASSWORD:
88
+            return _setPassword(state, action);
81
 
89
 
82
-    case SET_PREFERRED_RECEIVER_VIDEO_QUALITY:
83
-        return _setPreferredReceiverVideoQuality(state, action);
90
+        case SET_PREFERRED_RECEIVER_VIDEO_QUALITY:
91
+            return set(
92
+                state,
93
+                'preferredReceiverVideoQuality',
94
+                action.preferredReceiverVideoQuality);
84
 
95
 
85
-    case SET_ROOM:
86
-        return _setRoom(state, action);
96
+        case SET_ROOM:
97
+            return _setRoom(state, action);
87
 
98
 
88
-    case SET_SIP_GATEWAY_ENABLED:
89
-        return _setSIPGatewayEnabled(state, action);
99
+        case SET_SIP_GATEWAY_ENABLED:
100
+            return _setSIPGatewayEnabled(state, action);
90
 
101
 
91
-    case SET_START_MUTED_POLICY:
92
-        return {
93
-            ...state,
94
-            startAudioMutedPolicy: action.startAudioMutedPolicy,
95
-            startVideoMutedPolicy: action.startVideoMutedPolicy
96
-        };
97
-    }
102
+        case SET_START_MUTED_POLICY:
103
+            return {
104
+                ...state,
105
+                startAudioMutedPolicy: action.startAudioMutedPolicy,
106
+                startVideoMutedPolicy: action.startVideoMutedPolicy
107
+            };
108
+        }
98
 
109
 
99
-    return state;
100
-});
110
+        return state;
111
+    });
101
 
112
 
102
 /**
113
 /**
103
  * Reduces a specific Redux action AUTH_STATUS_CHANGED of the feature
114
  * Reduces a specific Redux action AUTH_STATUS_CHANGED of the feature
210
          * @type {boolean}
221
          * @type {boolean}
211
          */
222
          */
212
         locked,
223
         locked,
213
-        passwordRequired: undefined,
214
-
215
-        /**
216
-         * The current resolution restraint on receiving remote video. By
217
-         * default the conference will send the highest level possible.
218
-         *
219
-         * @type number
220
-         */
221
-        preferredReceiverVideoQuality: VIDEO_QUALITY_LEVELS.HIGH
224
+        passwordRequired: undefined
222
     });
225
     });
223
 }
226
 }
224
 
227
 
409
     return state;
412
     return state;
410
 }
413
 }
411
 
414
 
412
-/**
413
- * Reduces a specific Redux action {@code SET_PREFERRED_RECEIVER_VIDEO_QUALITY}
414
- * of the feature base/conference.
415
- *
416
- * @param {Object} state - The Redux state of the feature base/conference.
417
- * @param {Action} action - The Redux action of type
418
- * {@code SET_PREFERRED_RECEIVER_VIDEO_QUALITY} to reduce.
419
- * @private
420
- * @returns {Object} The new state of the feature base/conference after the
421
- * reduction of the specified action.
422
- */
423
-function _setPreferredReceiverVideoQuality(state, action) {
424
-    return set(
425
-        state,
426
-        'preferredReceiverVideoQuality',
427
-        action.preferredReceiverVideoQuality);
428
-}
429
-
430
 /**
415
 /**
431
  * Reduces a specific Redux action SET_ROOM of the feature base/conference.
416
  * Reduces a specific Redux action SET_ROOM of the feature base/conference.
432
  *
417
  *

+ 5
- 9
react/features/conference/middleware.js Целия файл

22
     case SET_REDUCED_UI: {
22
     case SET_REDUCED_UI: {
23
         const { dispatch, getState } = store;
23
         const { dispatch, getState } = store;
24
         const state = getState();
24
         const state = getState();
25
-        const { audioOnly } = state['features/base/conference'];
26
         const { reducedUI } = state['features/base/responsive-ui'];
25
         const { reducedUI } = state['features/base/responsive-ui'];
27
 
26
 
28
         dispatch(setToolboxEnabled(!reducedUI));
27
         dispatch(setToolboxEnabled(!reducedUI));
29
         dispatch(setFilmstripEnabled(!reducedUI));
28
         dispatch(setFilmstripEnabled(!reducedUI));
30
 
29
 
31
-        // XXX: Currently setting the received video quality will disable
32
-        // audio-only mode if engaged, that's why we check for it here.
33
-        audioOnly
34
-            || dispatch(
35
-                setPreferredReceiverVideoQuality(
36
-                    reducedUI
37
-                        ? VIDEO_QUALITY_LEVELS.LOW
38
-                        : VIDEO_QUALITY_LEVELS.HIGH));
30
+        dispatch(
31
+            setPreferredReceiverVideoQuality(
32
+                reducedUI
33
+                    ? VIDEO_QUALITY_LEVELS.LOW
34
+                    : VIDEO_QUALITY_LEVELS.HIGH));
39
 
35
 
40
         break;
36
         break;
41
     }
37
     }

+ 20
- 3
react/features/video-quality/components/VideoQualitySlider.web.js Целия файл

284
     _enableHighDefinition() {
284
     _enableHighDefinition() {
285
         sendAnalytics(createEvent('high'));
285
         sendAnalytics(createEvent('high'));
286
         logger.log('Video quality: high enabled');
286
         logger.log('Video quality: high enabled');
287
-        this.props.dispatch(setPreferredReceiverVideoQuality(HIGH));
287
+        this._setPreferredVideoQuality(HIGH);
288
     }
288
     }
289
 
289
 
290
     /**
290
     /**
297
     _enableLowDefinition() {
297
     _enableLowDefinition() {
298
         sendAnalytics(createEvent('low'));
298
         sendAnalytics(createEvent('low'));
299
         logger.log('Video quality: low enabled');
299
         logger.log('Video quality: low enabled');
300
-        this.props.dispatch(setPreferredReceiverVideoQuality(LOW));
300
+        this._setPreferredVideoQuality(LOW);
301
     }
301
     }
302
 
302
 
303
     /**
303
     /**
310
     _enableStandardDefinition() {
310
     _enableStandardDefinition() {
311
         sendAnalytics(createEvent('standard'));
311
         sendAnalytics(createEvent('standard'));
312
         logger.log('Video quality: standard enabled');
312
         logger.log('Video quality: standard enabled');
313
-        this.props.dispatch(setPreferredReceiverVideoQuality(STANDARD));
313
+        this._setPreferredVideoQuality(STANDARD);
314
     }
314
     }
315
 
315
 
316
     /**
316
     /**
361
 
361
 
362
         onSelect();
362
         onSelect();
363
     }
363
     }
364
+
365
+    /**
366
+     * Helper for changing the preferred maximum video quality to receive and
367
+     * disable audio only.
368
+     *
369
+     * @param {number} qualityLevel - The new maximum video quality. Should be
370
+     * a value enumerated in {@code VIDEO_QUALITY_LEVELS}.
371
+     * @private
372
+     * @returns {void}
373
+     */
374
+    _setPreferredVideoQuality(qualityLevel) {
375
+        this.props.dispatch(setPreferredReceiverVideoQuality(qualityLevel));
376
+
377
+        if (this.props._audioOnly) {
378
+            this.props.dispatch(setAudioOnly(false));
379
+        }
380
+    }
364
 }
381
 }
365
 
382
 
366
 /**
383
 /**

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