|
@@ -295,12 +295,21 @@ function getConstraints(um, options) {
|
295
|
295
|
return constraints;
|
296
|
296
|
}
|
297
|
297
|
|
298
|
|
-function setAvailableDevices(um, available) {
|
|
298
|
+/**
|
|
299
|
+ * Sets the availbale devices based on the options we requested and the
|
|
300
|
+ * streams we received.
|
|
301
|
+ * @param um the options we requested to getUserMedia.
|
|
302
|
+ * @param stream the stream we received from calling getUserMedia.
|
|
303
|
+ */
|
|
304
|
+function setAvailableDevices(um, stream) {
|
|
305
|
+ var audioTracksReceived = stream && !!stream.getAudioTracks().length;
|
|
306
|
+ var videoTracksReceived = stream && !!stream.getVideoTracks().length;
|
|
307
|
+
|
299
|
308
|
if (um.indexOf("video") != -1) {
|
300
|
|
- devices.video = available;
|
|
309
|
+ devices.video = videoTracksReceived;
|
301
|
310
|
}
|
302
|
311
|
if (um.indexOf("audio") != -1) {
|
303
|
|
- devices.audio = available;
|
|
312
|
+ devices.audio = audioTracksReceived;
|
304
|
313
|
}
|
305
|
314
|
|
306
|
315
|
eventEmitter.emit(RTCEvents.AVAILABLE_DEVICES_CHANGED, devices);
|
|
@@ -361,8 +370,8 @@ function pollForAvailableMediaDevices() {
|
361
|
370
|
* @param {MediaDeviceInfo[]} devices - list of media devices.
|
362
|
371
|
* @emits RTCEvents.DEVICE_LIST_CHANGED
|
363
|
372
|
*/
|
364
|
|
-function onMediaDevicesListChanged(devices) {
|
365
|
|
- currentlyAvailableMediaDevices = devices.slice(0);
|
|
373
|
+function onMediaDevicesListChanged(devicesReceived) {
|
|
374
|
+ currentlyAvailableMediaDevices = devicesReceived.slice(0);
|
366
|
375
|
logger.info('list of media devices has changed:', currentlyAvailableMediaDevices);
|
367
|
376
|
|
368
|
377
|
var videoInputDevices = currentlyAvailableMediaDevices.filter(function (d) {
|
|
@@ -382,15 +391,15 @@ function onMediaDevicesListChanged(devices) {
|
382
|
391
|
|
383
|
392
|
if (videoInputDevices.length &&
|
384
|
393
|
videoInputDevices.length === videoInputDevicesWithEmptyLabels.length) {
|
385
|
|
- setAvailableDevices(['video'], false);
|
|
394
|
+ devices.video = false;
|
386
|
395
|
}
|
387
|
396
|
|
388
|
397
|
if (audioInputDevices.length &&
|
389
|
398
|
audioInputDevices.length === audioInputDevicesWithEmptyLabels.length) {
|
390
|
|
- setAvailableDevices(['audio'], false);
|
|
399
|
+ devices.audio = false;
|
391
|
400
|
}
|
392
|
401
|
|
393
|
|
- eventEmitter.emit(RTCEvents.DEVICE_LIST_CHANGED, devices);
|
|
402
|
+ eventEmitter.emit(RTCEvents.DEVICE_LIST_CHANGED, devicesReceived);
|
394
|
403
|
}
|
395
|
404
|
|
396
|
405
|
// In case of IE we continue from 'onReady' callback
|
|
@@ -905,11 +914,11 @@ var RTCUtils = {
|
905
|
914
|
this.getUserMedia(constraints,
|
906
|
915
|
function (stream) {
|
907
|
916
|
logger.log('onUserMediaSuccess');
|
908
|
|
- setAvailableDevices(um, true);
|
|
917
|
+ setAvailableDevices(um, stream);
|
909
|
918
|
success_callback(stream);
|
910
|
919
|
},
|
911
|
920
|
function (error) {
|
912
|
|
- setAvailableDevices(um, false);
|
|
921
|
+ setAvailableDevices(um, undefined);
|
913
|
922
|
logger.warn('Failed to get access to local media. Error ',
|
914
|
923
|
error, constraints);
|
915
|
924
|
|
|
@@ -1027,11 +1036,35 @@ var RTCUtils = {
|
1027
|
1036
|
devices.push("video");
|
1028
|
1037
|
}
|
1029
|
1038
|
|
1030
|
|
- reject(new JitsiTrackError(
|
1031
|
|
- { name: "UnknownError" },
|
1032
|
|
- getConstraints(options.devices, options),
|
1033
|
|
- devices)
|
1034
|
|
- );
|
|
1039
|
+ // we are missing one of the media we requested
|
|
1040
|
+ // in order to get the actual error that caused
|
|
1041
|
+ // this missing media we will call one more time
|
|
1042
|
+ // getUserMedia so we can obtain the actual
|
|
1043
|
+ // error (Example usecases are requesting
|
|
1044
|
+ // audio and video and video device is missing
|
|
1045
|
+ // or device is denied to be used and chrome is
|
|
1046
|
+ // set to not ask for permissions)
|
|
1047
|
+ self.getUserMediaWithConstraints(
|
|
1048
|
+ devices,
|
|
1049
|
+ function (stream) {
|
|
1050
|
+ // we already failed to obtain this
|
|
1051
|
+ // media, so we are not supposed in any
|
|
1052
|
+ // way to receive success for this call
|
|
1053
|
+ // any way we will throw an error to be
|
|
1054
|
+ // sure the promise will finish
|
|
1055
|
+ reject(new JitsiTrackError(
|
|
1056
|
+ { name: "UnknownError" },
|
|
1057
|
+ getConstraints(
|
|
1058
|
+ options.devices, options),
|
|
1059
|
+ devices)
|
|
1060
|
+ );
|
|
1061
|
+ },
|
|
1062
|
+ function (error) {
|
|
1063
|
+ // rejects with real error for not
|
|
1064
|
+ // obtaining the media
|
|
1065
|
+ reject(error);
|
|
1066
|
+ },options);
|
|
1067
|
+
|
1035
|
1068
|
return;
|
1036
|
1069
|
}
|
1037
|
1070
|
if(hasDesktop) {
|