|
@@ -42,20 +42,33 @@ var isAudioOutputDeviceChangeAvailable =
|
42
|
42
|
|
43
|
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
|
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
|
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
|
73
|
// TODO: currently no browser supports 'devicechange' event even in nightly
|
61
|
74
|
// builds so no feature/browser detection is used at all. However in future this
|
|
@@ -386,6 +399,9 @@ function onReady (options, GUM) {
|
386
|
399
|
eventEmitter.emit(RTCEvents.RTC_READY, true);
|
387
|
400
|
screenObtainer.init(options, GUM);
|
388
|
401
|
|
|
402
|
+ // Initialize rawEnumerateDevicesWithCallback
|
|
403
|
+ initRawEnumerateDevicesWithCallback();
|
|
404
|
+
|
389
|
405
|
if (RTCUtils.isDeviceListAvailable() && rawEnumerateDevicesWithCallback) {
|
390
|
406
|
rawEnumerateDevicesWithCallback(function (devices) {
|
391
|
407
|
currentlyAvailableMediaDevices = devices.splice(0);
|
|
@@ -1055,17 +1071,51 @@ var RTCUtils = {
|
1055
|
1071
|
isRTCReady: function () {
|
1056
|
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
|
1077
|
var isEnumerateDevicesAvailable
|
1064
|
1078
|
= navigator.mediaDevices && navigator.mediaDevices.enumerateDevices;
|
1065
|
1079
|
if (isEnumerateDevicesAvailable) {
|
1066
|
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
|
1121
|
* Returns true if changing the input (camera / microphone) or output
|