Browse Source

Make 'isDeviceListAvailable' a Promise

On Safari/IE we have to wait until the WebRTC stack is
initialized in case the plugin is being installed for
the first time.
dev1
paweldomas 9 years ago
parent
commit
a34e4255e4
3 changed files with 72 additions and 18 deletions
  1. 3
    1
      JitsiMediaDevices.js
  2. 3
    1
      JitsiMeetJS.js
  3. 66
    16
      modules/RTC/RTCUtils.js

+ 3
- 1
JitsiMediaDevices.js View File

46
     },
46
     },
47
     /**
47
     /**
48
      * Checks if its possible to enumerate available cameras/micropones.
48
      * Checks if its possible to enumerate available cameras/micropones.
49
-     * @returns {boolean} true if available, false otherwise.
49
+     * @returns {Promise<boolean>} a Promise which will be resolved only once
50
+     * the WebRTC stack is ready, either with true if the device listing is
51
+     * available available or with false otherwise.
50
      */
52
      */
51
     isDeviceListAvailable: function () {
53
     isDeviceListAvailable: function () {
52
         return RTC.isDeviceListAvailable();
54
         return RTC.isDeviceListAvailable();

+ 3
- 1
JitsiMeetJS.js View File

208
     },
208
     },
209
     /**
209
     /**
210
      * Checks if its possible to enumerate available cameras/micropones.
210
      * Checks if its possible to enumerate available cameras/micropones.
211
-     * @returns {boolean} true if available, false otherwise.
211
+     * @returns {Promise<boolean>} a Promise which will be resolved only once
212
+     * the WebRTC stack is ready, either with true if the device listing is
213
+     * available available or with false otherwise.
212
      * @deprecated use JitsiMeetJS.mediaDevices.isDeviceListAvailable instead
214
      * @deprecated use JitsiMeetJS.mediaDevices.isDeviceListAvailable instead
213
      */
215
      */
214
     isDeviceListAvailable: function () {
216
     isDeviceListAvailable: function () {

+ 66
- 16
modules/RTC/RTCUtils.js View File

42
 
42
 
43
 var currentlyAvailableMediaDevices;
43
 var currentlyAvailableMediaDevices;
44
 
44
 
45
-var rawEnumerateDevicesWithCallback = navigator.mediaDevices
46
-    && navigator.mediaDevices.enumerateDevices
45
+var rawEnumerateDevicesWithCallback = undefined;
46
+/**
47
+ * "rawEnumerateDevicesWithCallback" will be initialized only after WebRTC is
48
+ * ready. Otherwise it is too early to assume that the devices listing is not
49
+ * supported.
50
+ */
51
+function initRawEnumerateDevicesWithCallback() {
52
+    rawEnumerateDevicesWithCallback = navigator.mediaDevices
53
+        && navigator.mediaDevices.enumerateDevices
47
         ? function(callback) {
54
         ? function(callback) {
48
-            navigator.mediaDevices.enumerateDevices().then(callback, function () {
49
-                callback([]);
55
+            navigator.mediaDevices.enumerateDevices().then(
56
+                callback, function () {
57
+                    callback([]);
50
             });
58
             });
51
         }
59
         }
60
+        // Safari:
61
+        // "ReferenceError: Can't find variable: MediaStreamTrack"
62
+        // when Temasys plugin is not installed yet, have to delay this call
63
+        // until WebRTC is ready.
52
         : (MediaStreamTrack && MediaStreamTrack.getSources)
64
         : (MediaStreamTrack && MediaStreamTrack.getSources)
53
-            ? function (callback) {
54
-                MediaStreamTrack.getSources(function (sources) {
55
-                    callback(sources.map(convertMediaStreamTrackSource));
56
-                });
57
-            }
58
-            : undefined;
65
+        ? function (callback) {
66
+            MediaStreamTrack.getSources(function (sources) {
67
+                callback(sources.map(convertMediaStreamTrackSource));
68
+            });
69
+        }
70
+        : undefined;
71
+}
59
 
72
 
60
 // TODO: currently no browser supports 'devicechange' event even in nightly
73
 // TODO: currently no browser supports 'devicechange' event even in nightly
61
 // builds so no feature/browser detection is used at all. However in future this
74
 // builds so no feature/browser detection is used at all. However in future this
386
     eventEmitter.emit(RTCEvents.RTC_READY, true);
399
     eventEmitter.emit(RTCEvents.RTC_READY, true);
387
     screenObtainer.init(options, GUM);
400
     screenObtainer.init(options, GUM);
388
 
401
 
402
+    // Initialize rawEnumerateDevicesWithCallback
403
+    initRawEnumerateDevicesWithCallback();
404
+
389
     if (RTCUtils.isDeviceListAvailable() && rawEnumerateDevicesWithCallback) {
405
     if (RTCUtils.isDeviceListAvailable() && rawEnumerateDevicesWithCallback) {
390
         rawEnumerateDevicesWithCallback(function (devices) {
406
         rawEnumerateDevicesWithCallback(function (devices) {
391
             currentlyAvailableMediaDevices = devices.splice(0);
407
             currentlyAvailableMediaDevices = devices.splice(0);
1055
     isRTCReady: function () {
1071
     isRTCReady: function () {
1056
         return rtcReady;
1072
         return rtcReady;
1057
     },
1073
     },
1058
-    /**
1059
-     * Checks if its possible to enumerate available cameras/micropones.
1060
-     * @returns {boolean} true if available, false otherwise.
1061
-     */
1062
-    isDeviceListAvailable: function () {
1074
+    _isDeviceListAvailable: function () {
1075
+        if (!rtcReady)
1076
+            throw new Error("WebRTC not ready yet");
1063
         var isEnumerateDevicesAvailable
1077
         var isEnumerateDevicesAvailable
1064
             = navigator.mediaDevices && navigator.mediaDevices.enumerateDevices;
1078
             = navigator.mediaDevices && navigator.mediaDevices.enumerateDevices;
1065
         if (isEnumerateDevicesAvailable) {
1079
         if (isEnumerateDevicesAvailable) {
1066
             return true;
1080
             return true;
1067
         }
1081
         }
1068
-        return (MediaStreamTrack && MediaStreamTrack.getSources)? true : false;
1082
+        return (typeof MediaStreamTrack !== "undefined" &&
1083
+            MediaStreamTrack.getSources)? true : false;
1084
+    },
1085
+    /**
1086
+     * Returns a promise which can be used to make sure that the WebRTC stack
1087
+     * has been initialized.
1088
+     *
1089
+     * @returns {Promise} which is resolved only if the WebRTC stack is ready.
1090
+     * Note that currently we do not detect stack initialization failure and
1091
+     * the promise is never rejected(unless unexpected error occurs).
1092
+     */
1093
+    onRTCReady: function() {
1094
+        if (rtcReady) {
1095
+            return Promise.resolve();
1096
+        } else {
1097
+            return new Promise(function (resolve) {
1098
+                var listener = function () {
1099
+                    eventEmitter.removeListener(RTCEvents.RTC_READY, listener);
1100
+                    resolve();
1101
+                };
1102
+                eventEmitter.addListener(RTCEvents.RTC_READY, listener);
1103
+                // We have no failed event, so... it either resolves or nothing
1104
+                // happens
1105
+            });
1106
+        }
1107
+    },
1108
+    /**
1109
+     * Checks if its possible to enumerate available cameras/microphones.
1110
+     *
1111
+     * @returns {Promise<boolean>} a Promise which will be resolved only once
1112
+     * the WebRTC stack is ready, either with true if the device listing is
1113
+     * available available or with false otherwise.
1114
+     */
1115
+    isDeviceListAvailable: function () {
1116
+        return this.onRTCReady().then(function() {
1117
+            return this._isDeviceListAvailable();
1118
+        }.bind(this));
1069
     },
1119
     },
1070
     /**
1120
     /**
1071
      * Returns true if changing the input (camera / microphone) or output
1121
      * Returns true if changing the input (camera / microphone) or output

Loading…
Cancel
Save