Bläddra i källkod

Adds new persistent state for devices user selection.

The state about currently opened devices is filtered and not stored, where we only store when user selects a device preferences.
Also allow changing input devices for Firefox when we are not in a conference.
master
damencho 6 år sedan
förälder
incheckning
740c1eb84f

+ 9
- 1
conference.js Visa fil

@@ -2394,7 +2394,15 @@ export default {
2394 2394
                                             : this.useVideoStream.bind(this);
2395 2395
 
2396 2396
                                     // Use the new stream or null if we failed to obtain it.
2397
-                                    return useStream(tracks.find(track => track.getType() === mediaType) || null);
2397
+                                    return useStream(tracks.find(track => track.getType() === mediaType) || null)
2398
+                                        .then(() => {
2399
+                                            const settings
2400
+                                                = mediaType === 'audio'
2401
+                                                    ? { micDeviceId: newDevices.audioinput }
2402
+                                                    : { cameraDeviceId: newDevices.videoinput };
2403
+
2404
+                                            APP.store.dispatch(updateSettings(settings));
2405
+                                        });
2398 2406
                                 }
2399 2407
 
2400 2408
                                 return Promise.resolve();

+ 2
- 2
modules/devices/mediaDeviceHelper.js Visa fil

@@ -39,7 +39,7 @@ function getNewAudioInputDevice(newDevices, localAudio) {
39 39
     const availableAudioInputDevices = newDevices.filter(
40 40
         d => d.kind === 'audioinput');
41 41
     const settings = APP.store.getState()['features/base/settings'];
42
-    const selectedAudioInputDeviceId = settings.micDeviceId;
42
+    const selectedAudioInputDeviceId = settings.userSelectedMicDeviceId;
43 43
     const selectedAudioInputDevice = availableAudioInputDevices.find(
44 44
         d => d.deviceId === selectedAudioInputDeviceId);
45 45
 
@@ -78,7 +78,7 @@ function getNewVideoInputDevice(newDevices, localVideo) {
78 78
     const availableVideoInputDevices = newDevices.filter(
79 79
         d => d.kind === 'videoinput');
80 80
     const settings = APP.store.getState()['features/base/settings'];
81
-    const selectedVideoInputDeviceId = settings.cameraDeviceId;
81
+    const selectedVideoInputDeviceId = settings.userSelectedCameraDeviceId;
82 82
     const selectedVideoInputDevice = availableVideoInputDevices.find(
83 83
         d => d.deviceId === selectedVideoInputDeviceId);
84 84
 

+ 2
- 2
react/features/base/devices/actions.js Visa fil

@@ -90,10 +90,10 @@ export function configureInitialDevices() {
90 90
 
91 91
         return updateSettingsPromise
92 92
             .then(() => {
93
-                const { audioOutputDeviceId }
93
+                const { userSelectedAudioOutputDeviceId }
94 94
                     = getState()['features/base/settings'];
95 95
 
96
-                return setAudioOutputDeviceId(audioOutputDeviceId, dispatch)
96
+                return setAudioOutputDeviceId(userSelectedAudioOutputDeviceId, dispatch)
97 97
                     .catch(ex => logger.warn(`Failed to set audio output device.
98 98
                         Default audio output device will be used instead ${ex}`));
99 99
             });

+ 18
- 5
react/features/base/devices/functions.js Visa fil

@@ -117,14 +117,27 @@ export function groupDevicesByKind(devices: Object[]): Object {
117 117
  *
118 118
  * @param {string} newId - New audio output device id.
119 119
  * @param {Function} dispatch - The Redux dispatch function.
120
+ * @param {boolean} userSelection - Whether this is a user selection update.
120 121
  * @returns {Promise}
121 122
  */
122 123
 export function setAudioOutputDeviceId(
123 124
         newId: string = 'default',
124
-        dispatch: Function): Promise<*> {
125
+        dispatch: Function,
126
+        userSelection: boolean = false): Promise<*> {
125 127
     return JitsiMeetJS.mediaDevices.setAudioOutputDevice(newId)
126
-        .then(() =>
127
-            dispatch(updateSettings({
128
-                audioOutputDeviceId: newId
129
-            })));
128
+        .then(() => {
129
+            const newSettings = {
130
+                audioOutputDeviceId: newId,
131
+                userSelectedAudioOutputDeviceId: undefined
132
+            };
133
+
134
+            if (userSelection) {
135
+                newSettings.userSelectedAudioOutputDeviceId = newId;
136
+            } else {
137
+                // a flow workaround, I needed to add 'userSelectedAudioOutputDeviceId: undefined'
138
+                delete newSettings.userSelectedAudioOutputDeviceId;
139
+            }
140
+
141
+            return dispatch(updateSettings(newSettings));
142
+        });
130 143
 }

+ 18
- 2
react/features/base/settings/reducer.js Visa fil

@@ -30,7 +30,10 @@ const DEFAULT_STATE = {
30 30
     serverURL: undefined,
31 31
     startAudioOnly: false,
32 32
     startWithAudioMuted: false,
33
-    startWithVideoMuted: false
33
+    startWithVideoMuted: false,
34
+    userSelectedAudioOutputDeviceId: undefined,
35
+    userSelectedCameraDeviceId: undefined,
36
+    userSelectedMicDeviceId: undefined
34 37
 };
35 38
 
36 39
 const STORE_NAME = 'features/base/settings';
@@ -38,7 +41,20 @@ const STORE_NAME = 'features/base/settings';
38 41
 /**
39 42
  * Sets up the persistence of the feature {@code base/settings}.
40 43
  */
41
-PersistenceRegistry.register(STORE_NAME);
44
+const filterSubtree = {};
45
+
46
+// start with the default state
47
+Object.keys(DEFAULT_STATE).forEach(key => {
48
+    filterSubtree[key] = true;
49
+});
50
+
51
+// we want to filter these props, to not be stored as they represent
52
+// what is currently opened/used as devices
53
+filterSubtree.audioOutputDeviceId = false;
54
+filterSubtree.cameraDeviceId = false;
55
+filterSubtree.micDeviceId = false;
56
+
57
+PersistenceRegistry.register(STORE_NAME, filterSubtree);
42 58
 
43 59
 ReducerRegistry.register(STORE_NAME, (state = DEFAULT_STATE, action) => {
44 60
     switch (action.type) {

+ 2
- 2
react/features/base/tracks/functions.js Visa fil

@@ -40,10 +40,10 @@ export function createLocalTracksF(
40 40
         const settings = store.getState()['features/base/settings'];
41 41
 
42 42
         if (typeof cameraDeviceId === 'undefined' || cameraDeviceId === null) {
43
-            cameraDeviceId = settings.cameraDeviceId;
43
+            cameraDeviceId = settings.userSelectedCameraDeviceId;
44 44
         }
45 45
         if (typeof micDeviceId === 'undefined' || micDeviceId === null) {
46
-            micDeviceId = settings.micDeviceId;
46
+            micDeviceId = settings.userSelectedMicDeviceId;
47 47
         }
48 48
     }
49 49
 

+ 6
- 3
react/features/device-selection/actions.js Visa fil

@@ -112,7 +112,8 @@ export function submitDeviceSelectionTab(newState) {
112 112
             && newState.selectedVideoInputId
113 113
                 !== currentState.selectedVideoInputId) {
114 114
             dispatch(updateSettings({
115
-                cameraDeviceId: newState.selectedVideoInputId
115
+                cameraDeviceId: newState.selectedVideoInputId,
116
+                userSelectedCameraDeviceId: newState.selectedVideoInputId
116 117
             }));
117 118
 
118 119
             dispatch(
@@ -123,7 +124,8 @@ export function submitDeviceSelectionTab(newState) {
123 124
                 && newState.selectedAudioInputId
124 125
                   !== currentState.selectedAudioInputId) {
125 126
             dispatch(updateSettings({
126
-                micDeviceId: newState.selectedAudioInputId
127
+                micDeviceId: newState.selectedAudioInputId,
128
+                userSelectedMicDeviceId: newState.selectedAudioInputId
127 129
             }));
128 130
 
129 131
             dispatch(
@@ -137,7 +139,8 @@ export function submitDeviceSelectionTab(newState) {
137 139
 
138 140
             setAudioOutputDeviceId(
139 141
                 newState.selectedAudioOutputId,
140
-                dispatch)
142
+                dispatch,
143
+                true)
141 144
                 .then(() => logger.log('changed audio output device'))
142 145
                 .catch(err => {
143 146
                     logger.warn(

+ 22
- 5
react/features/device-selection/functions.js Visa fil

@@ -26,20 +26,37 @@ import { toState } from '../base/redux';
26 26
 export function getDeviceSelectionDialogProps(stateful: Object | Function) {
27 27
     const state = toState(stateful);
28 28
     const settings = state['features/base/settings'];
29
+    const { conference } = state['features/base/conference'];
30
+    let disableAudioInputChange = !JitsiMeetJS.mediaDevices.isMultipleAudioInputSupported();
31
+    let selectedAudioInputId = settings.micDeviceId;
32
+    let selectedAudioOutputId = getAudioOutputDeviceId();
33
+    let selectedVideoInputId = settings.cameraDeviceId;
34
+
35
+    // audio input change will be a problem only when we are in a
36
+    // conference and this is not supported, when we open device selection on
37
+    // welcome page changing input devices will not be a problem
38
+    // on welcome page we also show only what we have saved as user selected devices
39
+    if (!conference) {
40
+        disableAudioInputChange = false;
41
+        selectedAudioInputId = settings.userSelectedMicDeviceId;
42
+        selectedAudioOutputId = settings.userSelectedAudioOutputDeviceId;
43
+        selectedVideoInputId = settings.userSelectedCameraDeviceId;
44
+    }
29 45
 
46
+    // we fill the device selection dialog with the devices that are currently
47
+    // used or if none are currently used with what we have in settings(user selected)
30 48
     return {
31 49
         availableDevices: state['features/base/devices'].availableDevices,
32
-        disableAudioInputChange:
33
-            !JitsiMeetJS.isMultipleAudioInputSupported(),
50
+        disableAudioInputChange,
34 51
         disableDeviceChange:
35 52
             !JitsiMeetJS.mediaDevices.isDeviceChangeAvailable(),
36 53
         hideAudioInputPreview:
37 54
             !JitsiMeetJS.isCollectingLocalStats(),
38 55
         hideAudioOutputSelect: !JitsiMeetJS.mediaDevices
39 56
                             .isDeviceChangeAvailable('output'),
40
-        selectedAudioInputId: settings.micDeviceId,
41
-        selectedAudioOutputId: getAudioOutputDeviceId(),
42
-        selectedVideoInputId: settings.cameraDeviceId
57
+        selectedAudioInputId,
58
+        selectedAudioOutputId,
59
+        selectedVideoInputId
43 60
     };
44 61
 }
45 62
 

Laddar…
Avbryt
Spara