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

feat(GUM): timeout.

dev1
Hristo Terezov преди 4 години
родител
ревизия
054fbdf45f
променени са 3 файла, в които са добавени 55 реда и са изтрити 29 реда
  1. 2
    0
      JitsiTrackError.js
  2. 6
    0
      JitsiTrackErrors.js
  3. 47
    29
      modules/RTC/RTCUtils.js

+ 2
- 0
JitsiTrackError.js Целия файл

@@ -20,6 +20,8 @@ TRACK_ERROR_TO_MESSAGE_MAP[JitsiTrackErrors.NOT_FOUND]
20 20
     = 'Requested device(s) was/were not found: ';
21 21
 TRACK_ERROR_TO_MESSAGE_MAP[JitsiTrackErrors.CONSTRAINT_FAILED]
22 22
     = 'Constraint could not be satisfied: ';
23
+TRACK_ERROR_TO_MESSAGE_MAP[JitsiTrackErrors.TIMEOUT]
24
+    = 'Could not start media source. Timeout occured!';
23 25
 TRACK_ERROR_TO_MESSAGE_MAP[JitsiTrackErrors.TRACK_IS_DISPOSED]
24 26
     = 'Track has been already disposed';
25 27
 TRACK_ERROR_TO_MESSAGE_MAP[JitsiTrackErrors.TRACK_NO_STREAM_FOUND]

+ 6
- 0
JitsiTrackErrors.js Целия файл

@@ -51,6 +51,12 @@ export const SCREENSHARING_GENERIC_ERROR
51 51
 export const SCREENSHARING_USER_CANCELED
52 52
     = 'gum.screensharing_user_canceled';
53 53
 
54
+
55
+/**
56
+ * Indicates that the timeout passed to the obtainAudioAndVideoPermissions has expired without GUM resolving.
57
+ */
58
+export const TIMEOUT = 'gum.timeout';
59
+
54 60
 /**
55 61
  * An error which indicates that track has been already disposed and cannot
56 62
  * be longer used.

+ 47
- 29
modules/RTC/RTCUtils.js Целия файл

@@ -11,6 +11,7 @@ import { getLogger } from 'jitsi-meet-logger';
11 11
 import clonedeep from 'lodash.clonedeep';
12 12
 
13 13
 import JitsiTrackError from '../../JitsiTrackError';
14
+import * as JitsiTrackErrors from '../../JitsiTrackErrors';
14 15
 import CameraFacingMode from '../../service/RTC/CameraFacingMode';
15 16
 import * as MediaType from '../../service/RTC/MediaType';
16 17
 import RTCEvents from '../../service/RTC/RTCEvents';
@@ -911,27 +912,20 @@ class RTCUtils extends Listenable {
911 912
     * @param {Object} options.frameRate.max - Maximum fps
912 913
     * @param {bool}   options.screenShareAudio - Used by electron clients to
913 914
     * enable system audio screen sharing.
915
+    * @param {number} options.timeout - The timeout in ms for GUM.
914 916
     * @returns {Promise} Returns a media stream on success or a JitsiTrackError
915 917
     * on failure.
916 918
     **/
917 919
     getUserMediaWithConstraints(um, options = {}) {
918
-        const constraints = getConstraints(um, options);
920
+        const {
921
+            timeout,
922
+            ...otherOptions
923
+        } = options;
924
+        const constraints = getConstraints(um, otherOptions);
919 925
 
920 926
         logger.info('Get media constraints', JSON.stringify(constraints));
921 927
 
922
-        return new Promise((resolve, reject) => {
923
-            navigator.mediaDevices.getUserMedia(constraints)
924
-            .then(stream => {
925
-                logger.log('onUserMediaSuccess');
926
-                updateGrantedPermissions(um, stream);
927
-                resolve(stream);
928
-            })
929
-            .catch(error => {
930
-                logger.warn(`Failed to get access to local media. ${error} ${JSON.stringify(constraints)}`);
931
-                updateGrantedPermissions(um, undefined);
932
-                reject(new JitsiTrackError(error, constraints, um));
933
-            });
934
-        });
928
+        return this._getUserMedia(um, constraints, timeout);
935 929
     }
936 930
 
937 931
     /**
@@ -940,20 +934,41 @@ class RTCUtils extends Listenable {
940 934
      *
941 935
      * @param {array} umDevices which devices to acquire (e.g. audio, video)
942 936
      * @param {Object} constraints - Stream specifications to use.
937
+     * @param {number} timeout - The timeout in ms for GUM.
943 938
      * @returns {Promise}
944 939
      */
945
-    _newGetUserMediaWithConstraints(umDevices, constraints = {}) {
940
+    _getUserMedia(umDevices, constraints = {}, timeout = 0) {
946 941
         return new Promise((resolve, reject) => {
942
+            let gumTimeout, timeoutExpired = false;
943
+
944
+            if (typeof timeout === 'number' && !isNaN(timeout) && timeout > 0) {
945
+                gumTimeout = setTimeout(() => {
946
+                    timeoutExpired = true;
947
+                    gumTimeout = undefined;
948
+                    reject(new JitsiTrackError(JitsiTrackErrors.TIMEOUT));
949
+                }, timeout);
950
+            }
951
+
947 952
             navigator.mediaDevices.getUserMedia(constraints)
948 953
                 .then(stream => {
949 954
                     logger.log('onUserMediaSuccess');
950 955
                     updateGrantedPermissions(umDevices, stream);
951
-                    resolve(stream);
956
+                    if (!timeoutExpired) {
957
+                        if (typeof gumTimeout !== 'undefined') {
958
+                            clearTimeout(gumTimeout);
959
+                        }
960
+                        resolve(stream);
961
+                    }
952 962
                 })
953 963
                 .catch(error => {
954 964
                     logger.warn(`Failed to get access to local media. ${error} ${JSON.stringify(constraints)}`);
955 965
                     updateGrantedPermissions(umDevices, undefined);
956
-                    reject(new JitsiTrackError(error, constraints, umDevices));
966
+                    if (!timeoutExpired) {
967
+                        if (typeof gumTimeout !== 'undefined') {
968
+                            clearTimeout(gumTimeout);
969
+                        }
970
+                        reject(new JitsiTrackError(error, constraints, umDevices));
971
+                    }
957 972
                 });
958 973
         });
959 974
     }
@@ -961,7 +976,7 @@ class RTCUtils extends Listenable {
961 976
     /**
962 977
      * Acquire a display stream via the screenObtainer. This requires extra
963 978
      * logic compared to use screenObtainer versus normal device capture logic
964
-     * in RTCUtils#_newGetUserMediaWithConstraints.
979
+     * in RTCUtils#_getUserMedia.
965 980
      *
966 981
      * @param {Object} options
967 982
      * @param {string[]} options.desktopSharingSources
@@ -1162,6 +1177,11 @@ class RTCUtils extends Listenable {
1162 1177
     newObtainAudioAndVideoPermissions(options) {
1163 1178
         logger.info('Using the new gUM flow');
1164 1179
 
1180
+        const {
1181
+            timeout,
1182
+            ...otherOptions
1183
+        } = options;
1184
+
1165 1185
         const mediaStreamsMetaData = [];
1166 1186
 
1167 1187
         // Declare private functions to be used in the promise chain below.
@@ -1175,7 +1195,7 @@ class RTCUtils extends Listenable {
1175 1195
          * @returns {Promise}
1176 1196
          */
1177 1197
         const maybeRequestDesktopDevice = function() {
1178
-            const umDevices = options.devices || [];
1198
+            const umDevices = otherOptions.devices || [];
1179 1199
             const isDesktopDeviceRequested
1180 1200
                 = umDevices.indexOf('desktop') !== -1;
1181 1201
 
@@ -1187,7 +1207,7 @@ class RTCUtils extends Listenable {
1187 1207
                 desktopSharingSourceDevice,
1188 1208
                 desktopSharingSources,
1189 1209
                 desktopSharingFrameRate
1190
-            } = options;
1210
+            } = otherOptions;
1191 1211
 
1192 1212
             // Attempt to use a video input device as a screenshare source if
1193 1213
             // the option is defined.
@@ -1211,7 +1231,7 @@ class RTCUtils extends Listenable {
1211 1231
                 // Leverage the helper used by {@link _newGetDesktopMedia} to
1212 1232
                 // get constraints for the desktop stream.
1213 1233
                 const { gumOptions, trackOptions }
1214
-                    = this._parseDesktopSharingOptions(options);
1234
+                    = this._parseDesktopSharingOptions(otherOptions);
1215 1235
 
1216 1236
                 const constraints = {
1217 1237
                     video: {
@@ -1220,8 +1240,7 @@ class RTCUtils extends Listenable {
1220 1240
                     }
1221 1241
                 };
1222 1242
 
1223
-                return this._newGetUserMediaWithConstraints(
1224
-                    requestedDevices, constraints)
1243
+                return this._getUserMedia(requestedDevices, constraints, timeout)
1225 1244
                     .then(stream => {
1226 1245
                         const track = stream && stream.getTracks()[0];
1227 1246
                         const applyConstrainsPromise
@@ -1297,7 +1316,7 @@ class RTCUtils extends Listenable {
1297 1316
          * @returns {Promise}
1298 1317
          */
1299 1318
         const maybeRequestCaptureDevices = function() {
1300
-            const umDevices = options.devices || [ 'audio', 'video' ];
1319
+            const umDevices = otherOptions.devices || [ 'audio', 'video' ];
1301 1320
             const requestedCaptureDevices = umDevices.filter(device => device === 'audio' || device === 'video');
1302 1321
 
1303 1322
             if (!requestedCaptureDevices.length) {
@@ -1305,12 +1324,11 @@ class RTCUtils extends Listenable {
1305 1324
             }
1306 1325
 
1307 1326
             const constraints = newGetConstraints(
1308
-                requestedCaptureDevices, options);
1327
+                requestedCaptureDevices, otherOptions);
1309 1328
 
1310 1329
             logger.info('Got media constraints: ', JSON.stringify(constraints));
1311 1330
 
1312
-            return this._newGetUserMediaWithConstraints(
1313
-                requestedCaptureDevices, constraints);
1331
+            return this._getUserMedia(requestedCaptureDevices, constraints, timeout);
1314 1332
         }.bind(this);
1315 1333
 
1316 1334
         /**
@@ -1335,7 +1353,7 @@ class RTCUtils extends Listenable {
1335 1353
                 mediaStreamsMetaData.push({
1336 1354
                     stream: audioStream,
1337 1355
                     track: audioStream.getAudioTracks()[0],
1338
-                    effects: options.effects
1356
+                    effects: otherOptions.effects
1339 1357
                 });
1340 1358
             }
1341 1359
 
@@ -1348,7 +1366,7 @@ class RTCUtils extends Listenable {
1348 1366
                     stream: videoStream,
1349 1367
                     track: videoStream.getVideoTracks()[0],
1350 1368
                     videoType: VideoType.CAMERA,
1351
-                    effects: options.effects
1369
+                    effects: otherOptions.effects
1352 1370
                 });
1353 1371
             }
1354 1372
         };

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