|
@@ -8,7 +8,7 @@ var AdapterJS = require("./adapter.screenshare");
|
8
|
8
|
var SDPUtil = require("../xmpp/SDPUtil");
|
9
|
9
|
var EventEmitter = require("events");
|
10
|
10
|
var screenObtainer = require("./ScreenObtainer");
|
11
|
|
-var JitsiMeetJSError = require("../../JitsiMeetJSErrors");
|
|
11
|
+var JitsiTrackErrors = require("../../JitsiTrackErrors");
|
12
|
12
|
|
13
|
13
|
var eventEmitter = new EventEmitter();
|
14
|
14
|
|
|
@@ -335,7 +335,7 @@ function obtainDevices(options) {
|
335
|
335
|
function (error) {
|
336
|
336
|
logger.error(
|
337
|
337
|
"failed to obtain " + device + " stream - stop", error);
|
338
|
|
- options.errorCallback(JitsiMeetJSError.parseError(error));
|
|
338
|
+ options.errorCallback(JitsiTrackErrors.parseError(error));
|
339
|
339
|
});
|
340
|
340
|
}
|
341
|
341
|
|
|
@@ -396,10 +396,17 @@ function handleLocalStream(streams, resolution) {
|
396
|
396
|
//Options parameter is to pass config options. Currently uses only "useIPv6".
|
397
|
397
|
var RTCUtils = {
|
398
|
398
|
init: function (options) {
|
399
|
|
- var self = this;
|
400
|
|
- if (RTCBrowserType.isFirefox()) {
|
401
|
|
- var FFversion = RTCBrowserType.getFirefoxVersion();
|
402
|
|
- if (FFversion >= 40) {
|
|
399
|
+ return new Promise(function(resolve, reject) {
|
|
400
|
+ if (RTCBrowserType.isFirefox()) {
|
|
401
|
+ var FFversion = RTCBrowserType.getFirefoxVersion();
|
|
402
|
+ if (FFversion < 40) {
|
|
403
|
+ logger.error(
|
|
404
|
+ "Firefox version too old: " + FFversion +
|
|
405
|
+ ". Required >= 40.");
|
|
406
|
+ reject(new Error("Firefox version too old: " + FFversion +
|
|
407
|
+ ". Required >= 40."));
|
|
408
|
+ return;
|
|
409
|
+ }
|
403
|
410
|
this.peerconnection = mozRTCPeerConnection;
|
404
|
411
|
this.getUserMedia = wrapGetUserMedia(navigator.mozGetUserMedia.bind(navigator));
|
405
|
412
|
this.enumerateDevices = wrapEnumerateDevices(
|
|
@@ -441,128 +448,124 @@ var RTCUtils = {
|
441
|
448
|
};
|
442
|
449
|
RTCSessionDescription = mozRTCSessionDescription;
|
443
|
450
|
RTCIceCandidate = mozRTCIceCandidate;
|
444
|
|
- } else {
|
445
|
|
- logger.error(
|
446
|
|
- "Firefox version too old: " + FFversion + ". Required >= 40.");
|
447
|
|
- window.location.href = 'unsupported_browser.html';
|
448
|
|
- return;
|
449
|
|
- }
|
450
|
|
-
|
451
|
|
- } else if (RTCBrowserType.isChrome() || RTCBrowserType.isOpera()) {
|
452
|
|
- this.peerconnection = webkitRTCPeerConnection;
|
453
|
|
- var getUserMedia = navigator.webkitGetUserMedia.bind(navigator);
|
454
|
|
- if (navigator.mediaDevices) {
|
455
|
|
- this.getUserMedia = wrapGetUserMedia(getUserMedia);
|
456
|
|
- this.enumerateDevices = wrapEnumerateDevices(
|
457
|
|
- navigator.mediaDevices.enumerateDevices.bind(navigator.mediaDevices)
|
458
|
|
- );
|
459
|
|
- } else {
|
460
|
|
- this.getUserMedia = getUserMedia;
|
461
|
|
- this.enumerateDevices = enumerateDevicesThroughMediaStreamTrack;
|
462
|
|
- }
|
463
|
|
- this.attachMediaStream = function (element, stream) {
|
464
|
|
- element.attr('src', webkitURL.createObjectURL(stream));
|
465
|
|
- };
|
466
|
|
- this.getStreamID = function (stream) {
|
467
|
|
- // streams from FF endpoints have the characters '{' and '}'
|
468
|
|
- // that make jQuery choke.
|
469
|
|
- return SDPUtil.filter_special_chars(stream.id);
|
470
|
|
- };
|
471
|
|
- this.getVideoSrc = function (element) {
|
472
|
|
- if (!element)
|
473
|
|
- return null;
|
474
|
|
- return element.getAttribute("src");
|
475
|
|
- };
|
476
|
|
- this.setVideoSrc = function (element, src) {
|
477
|
|
- if (element)
|
478
|
|
- element.setAttribute("src", src);
|
479
|
|
- };
|
480
|
|
- // DTLS should now be enabled by default but..
|
481
|
|
- this.pc_constraints = {'optional': [
|
482
|
|
- {'DtlsSrtpKeyAgreement': 'true'}
|
483
|
|
- ]};
|
484
|
|
- if (options.useIPv6) {
|
485
|
|
- // https://code.google.com/p/webrtc/issues/detail?id=2828
|
486
|
|
- this.pc_constraints.optional.push({googIPv6: true});
|
487
|
|
- }
|
488
|
|
- if (RTCBrowserType.isAndroid()) {
|
489
|
|
- this.pc_constraints = {}; // disable DTLS on Android
|
490
|
|
- }
|
491
|
|
- if (!webkitMediaStream.prototype.getVideoTracks) {
|
492
|
|
- webkitMediaStream.prototype.getVideoTracks = function () {
|
493
|
|
- return this.videoTracks;
|
|
451
|
+ } else if (RTCBrowserType.isChrome() || RTCBrowserType.isOpera()) {
|
|
452
|
+ this.peerconnection = webkitRTCPeerConnection;
|
|
453
|
+ var getUserMedia = navigator.webkitGetUserMedia.bind(navigator);
|
|
454
|
+ if (navigator.mediaDevices) {
|
|
455
|
+ this.getUserMedia = wrapGetUserMedia(getUserMedia);
|
|
456
|
+ this.enumerateDevices = wrapEnumerateDevices(
|
|
457
|
+ navigator.mediaDevices.enumerateDevices.bind(navigator.mediaDevices)
|
|
458
|
+ );
|
|
459
|
+ } else {
|
|
460
|
+ this.getUserMedia = getUserMedia;
|
|
461
|
+ this.enumerateDevices = enumerateDevicesThroughMediaStreamTrack;
|
|
462
|
+ }
|
|
463
|
+ this.attachMediaStream = function (element, stream) {
|
|
464
|
+ element.attr('src', webkitURL.createObjectURL(stream));
|
494
|
465
|
};
|
495
|
|
- }
|
496
|
|
- if (!webkitMediaStream.prototype.getAudioTracks) {
|
497
|
|
- webkitMediaStream.prototype.getAudioTracks = function () {
|
498
|
|
- return this.audioTracks;
|
|
466
|
+ this.getStreamID = function (stream) {
|
|
467
|
+ // streams from FF endpoints have the characters '{' and '}'
|
|
468
|
+ // that make jQuery choke.
|
|
469
|
+ return SDPUtil.filter_special_chars(stream.id);
|
499
|
470
|
};
|
|
471
|
+ this.getVideoSrc = function (element) {
|
|
472
|
+ if (!element)
|
|
473
|
+ return null;
|
|
474
|
+ return element.getAttribute("src");
|
|
475
|
+ };
|
|
476
|
+ this.setVideoSrc = function (element, src) {
|
|
477
|
+ if (element)
|
|
478
|
+ element.setAttribute("src", src);
|
|
479
|
+ };
|
|
480
|
+ // DTLS should now be enabled by default but..
|
|
481
|
+ this.pc_constraints = {'optional': [
|
|
482
|
+ {'DtlsSrtpKeyAgreement': 'true'}
|
|
483
|
+ ]};
|
|
484
|
+ if (options.useIPv6) {
|
|
485
|
+ // https://code.google.com/p/webrtc/issues/detail?id=2828
|
|
486
|
+ this.pc_constraints.optional.push({googIPv6: true});
|
|
487
|
+ }
|
|
488
|
+ if (RTCBrowserType.isAndroid()) {
|
|
489
|
+ this.pc_constraints = {}; // disable DTLS on Android
|
|
490
|
+ }
|
|
491
|
+ if (!webkitMediaStream.prototype.getVideoTracks) {
|
|
492
|
+ webkitMediaStream.prototype.getVideoTracks = function () {
|
|
493
|
+ return this.videoTracks;
|
|
494
|
+ };
|
|
495
|
+ }
|
|
496
|
+ if (!webkitMediaStream.prototype.getAudioTracks) {
|
|
497
|
+ webkitMediaStream.prototype.getAudioTracks = function () {
|
|
498
|
+ return this.audioTracks;
|
|
499
|
+ };
|
|
500
|
+ }
|
500
|
501
|
}
|
501
|
|
- }
|
502
|
|
- // Detect IE/Safari
|
503
|
|
- else if (RTCBrowserType.isTemasysPluginUsed()) {
|
|
502
|
+ // Detect IE/Safari
|
|
503
|
+ else if (RTCBrowserType.isTemasysPluginUsed()) {
|
504
|
504
|
|
505
|
|
- //AdapterJS.WebRTCPlugin.setLogLevel(
|
506
|
|
- // AdapterJS.WebRTCPlugin.PLUGIN_LOG_LEVELS.VERBOSE);
|
|
505
|
+ //AdapterJS.WebRTCPlugin.setLogLevel(
|
|
506
|
+ // AdapterJS.WebRTCPlugin.PLUGIN_LOG_LEVELS.VERBOSE);
|
507
|
507
|
|
508
|
|
- AdapterJS.webRTCReady(function (isPlugin) {
|
|
508
|
+ AdapterJS.webRTCReady(function (isPlugin) {
|
509
|
509
|
|
510
|
|
- self.peerconnection = RTCPeerConnection;
|
511
|
|
- self.getUserMedia = window.getUserMedia;
|
512
|
|
- self.enumerateDevices = enumerateDevicesThroughMediaStreamTrack;
|
513
|
|
- self.attachMediaStream = function (elSel, stream) {
|
|
510
|
+ self.peerconnection = RTCPeerConnection;
|
|
511
|
+ self.getUserMedia = window.getUserMedia;
|
|
512
|
+ self.enumerateDevices = enumerateDevicesThroughMediaStreamTrack;
|
|
513
|
+ self.attachMediaStream = function (elSel, stream) {
|
514
|
514
|
|
515
|
|
- if (stream.id === "dummyAudio" || stream.id === "dummyVideo") {
|
516
|
|
- return;
|
517
|
|
- }
|
|
515
|
+ if (stream.id === "dummyAudio" || stream.id === "dummyVideo") {
|
|
516
|
+ return;
|
|
517
|
+ }
|
518
|
518
|
|
519
|
|
- attachMediaStream(elSel[0], stream);
|
520
|
|
- };
|
521
|
|
- self.getStreamID = function (stream) {
|
522
|
|
- var id = SDPUtil.filter_special_chars(stream.label);
|
523
|
|
- return id;
|
524
|
|
- };
|
525
|
|
- self.getVideoSrc = function (element) {
|
526
|
|
- if (!element) {
|
527
|
|
- logger.warn("Attempt to get video SRC of null element");
|
|
519
|
+ attachMediaStream(elSel[0], stream);
|
|
520
|
+ };
|
|
521
|
+ self.getStreamID = function (stream) {
|
|
522
|
+ var id = SDPUtil.filter_special_chars(stream.label);
|
|
523
|
+ return id;
|
|
524
|
+ };
|
|
525
|
+ self.getVideoSrc = function (element) {
|
|
526
|
+ if (!element) {
|
|
527
|
+ logger.warn("Attempt to get video SRC of null element");
|
|
528
|
+ return null;
|
|
529
|
+ }
|
|
530
|
+ var children = element.children;
|
|
531
|
+ for (var i = 0; i !== children.length; ++i) {
|
|
532
|
+ if (children[i].name === 'streamId') {
|
|
533
|
+ return children[i].value;
|
|
534
|
+ }
|
|
535
|
+ }
|
|
536
|
+ //logger.info(element.id + " SRC: " + src);
|
528
|
537
|
return null;
|
529
|
|
- }
|
530
|
|
- var children = element.children;
|
531
|
|
- for (var i = 0; i !== children.length; ++i) {
|
532
|
|
- if (children[i].name === 'streamId') {
|
533
|
|
- return children[i].value;
|
|
538
|
+ };
|
|
539
|
+ self.setVideoSrc = function (element, src) {
|
|
540
|
+ //logger.info("Set video src: ", element, src);
|
|
541
|
+ if (!src) {
|
|
542
|
+ logger.warn("Not attaching video stream, 'src' is null");
|
|
543
|
+ return;
|
534
|
544
|
}
|
535
|
|
- }
|
536
|
|
- //logger.info(element.id + " SRC: " + src);
|
537
|
|
- return null;
|
538
|
|
- };
|
539
|
|
- self.setVideoSrc = function (element, src) {
|
540
|
|
- //logger.info("Set video src: ", element, src);
|
541
|
|
- if (!src) {
|
542
|
|
- logger.warn("Not attaching video stream, 'src' is null");
|
543
|
|
- return;
|
544
|
|
- }
|
545
|
|
- AdapterJS.WebRTCPlugin.WaitForPluginReady();
|
546
|
|
- var stream = AdapterJS.WebRTCPlugin.plugin
|
547
|
|
- .getStreamWithId(AdapterJS.WebRTCPlugin.pageId, src);
|
548
|
|
- attachMediaStream(element, stream);
|
549
|
|
- };
|
|
545
|
+ AdapterJS.WebRTCPlugin.WaitForPluginReady();
|
|
546
|
+ var stream = AdapterJS.WebRTCPlugin.plugin
|
|
547
|
+ .getStreamWithId(AdapterJS.WebRTCPlugin.pageId, src);
|
|
548
|
+ attachMediaStream(element, stream);
|
|
549
|
+ };
|
|
550
|
+
|
|
551
|
+ onReady(options, self.getUserMediaWithConstraints);
|
|
552
|
+ resolve();
|
|
553
|
+ });
|
|
554
|
+ } else {
|
|
555
|
+ try {
|
|
556
|
+ logger.error('Browser does not appear to be WebRTC-capable');
|
|
557
|
+ } catch (e) {
|
|
558
|
+ }
|
|
559
|
+ reject('Browser does not appear to be WebRTC-capable');
|
|
560
|
+ return;
|
|
561
|
+ }
|
550
|
562
|
|
|
563
|
+ // Call onReady() if Temasys plugin is not used
|
|
564
|
+ if (!RTCBrowserType.isTemasysPluginUsed()) {
|
551
|
565
|
onReady(options, self.getUserMediaWithConstraints);
|
552
|
|
- });
|
553
|
|
- } else {
|
554
|
|
- try {
|
555
|
|
- logger.error('Browser does not appear to be WebRTC-capable');
|
556
|
|
- } catch (e) {
|
|
566
|
+ resolve();
|
557
|
567
|
}
|
558
|
|
- return;
|
559
|
|
- }
|
560
|
|
-
|
561
|
|
- // Call onReady() if Temasys plugin is not used
|
562
|
|
- if (!RTCBrowserType.isTemasysPluginUsed()) {
|
563
|
|
- onReady(options, self.getUserMediaWithConstraints);
|
564
|
|
- }
|
565
|
|
-
|
|
568
|
+ }.bind(this));
|
566
|
569
|
},
|
567
|
570
|
/**
|
568
|
571
|
* @param {string[]} um required user media types
|
|
@@ -674,14 +677,14 @@ var RTCUtils = {
|
674
|
677
|
desktopStream: desktopStream});
|
675
|
678
|
}, function (error) {
|
676
|
679
|
reject(
|
677
|
|
- JitsiMeetJSError.parseError(error));
|
|
680
|
+ JitsiTrackErrors.parseError(error));
|
678
|
681
|
});
|
679
|
682
|
} else {
|
680
|
683
|
successCallback({audioVideo: stream});
|
681
|
684
|
}
|
682
|
685
|
},
|
683
|
686
|
function (error) {
|
684
|
|
- reject(JitsiMeetJSError.parseError(error));
|
|
687
|
+ reject(JitsiTrackErrors.parseError(error));
|
685
|
688
|
},
|
686
|
689
|
options);
|
687
|
690
|
} else if (hasDesktop) {
|
|
@@ -690,7 +693,7 @@ var RTCUtils = {
|
690
|
693
|
successCallback({desktopStream: stream});
|
691
|
694
|
}, function (error) {
|
692
|
695
|
reject(
|
693
|
|
- JitsiMeetJSError.parseError(error));
|
|
696
|
+ JitsiTrackErrors.parseError(error));
|
694
|
697
|
});
|
695
|
698
|
}
|
696
|
699
|
}
|