|
@@ -47,6 +47,11 @@ function JitsiConference(options) {
|
47
|
47
|
this._init(options);
|
48
|
48
|
this.componentsVersions = new ComponentsVersions(this);
|
49
|
49
|
this.participants = {};
|
|
50
|
+ /**
|
|
51
|
+ * Jingle Session instance
|
|
52
|
+ * @type {JingleSessionPC}
|
|
53
|
+ */
|
|
54
|
+ this.jingleSession = null;
|
50
|
55
|
this.lastDominantSpeaker = null;
|
51
|
56
|
this.dtmfManager = null;
|
52
|
57
|
this.somebodySupportsDTMF = false;
|
|
@@ -181,6 +186,11 @@ JitsiConference.prototype.leave = function () {
|
181
|
186
|
// ChatRoom instance.
|
182
|
187
|
this.getParticipants().forEach(
|
183
|
188
|
participant => this.onMemberLeft(participant.getJid()));
|
|
189
|
+ // Close the JingleSession
|
|
190
|
+ if (this.jingleSession) {
|
|
191
|
+ this.jingleSession.close();
|
|
192
|
+ this.jingleSession = null;
|
|
193
|
+ }
|
184
|
194
|
});
|
185
|
195
|
}
|
186
|
196
|
|
|
@@ -517,7 +527,7 @@ JitsiConference.prototype.replaceTrack = function (oldTrack, newTrack) {
|
517
|
527
|
newTrack.ssrcHandler);
|
518
|
528
|
}
|
519
|
529
|
// Now replace the stream at the lower levels
|
520
|
|
- return this.room.replaceStream (oldTrack, newTrack)
|
|
530
|
+ return this._doReplaceTrack(oldTrack, newTrack)
|
521
|
531
|
.then(() => {
|
522
|
532
|
if (oldTrack) {
|
523
|
533
|
this.onTrackRemoved(oldTrack);
|
|
@@ -532,6 +542,25 @@ JitsiConference.prototype.replaceTrack = function (oldTrack, newTrack) {
|
532
|
542
|
});
|
533
|
543
|
};
|
534
|
544
|
|
|
545
|
+/**
|
|
546
|
+ * Replaces the tracks at the lower level by going through the Jingle session
|
|
547
|
+ * and WebRTC peer connection. The method will resolve immediately if there is
|
|
548
|
+ * currently no JingleSession started.
|
|
549
|
+ * @param {JitsiLocalTrack|null} oldTrack the track to be removed during
|
|
550
|
+ * the process or <tt>null</t> if the method should act as "add track"
|
|
551
|
+ * @param {JitsiLocalTrackn|null} newTrack the new track to be added or
|
|
552
|
+ * <tt>null</tt> if the method should act as "remove track"
|
|
553
|
+ * @return {Promise}
|
|
554
|
+ * @private
|
|
555
|
+ */
|
|
556
|
+JitsiConference.prototype._doReplaceTrack = function (oldTrack, newTrack) {
|
|
557
|
+ if (this.jingleSession) {
|
|
558
|
+ return this.jingleSession.replaceStream(oldTrack, newTrack);
|
|
559
|
+ } else {
|
|
560
|
+ return Promise.resolve();
|
|
561
|
+ }
|
|
562
|
+};
|
|
563
|
+
|
535
|
564
|
/**
|
536
|
565
|
* Operations related to creating a new track
|
537
|
566
|
* @param {JitsiLocalTrack} newTrack the new track being created
|
|
@@ -590,6 +619,62 @@ JitsiConference.prototype._setupNewTrack = function (newTrack) {
|
590
|
619
|
this.eventEmitter.emit(JitsiConferenceEvents.TRACK_ADDED, newTrack);
|
591
|
620
|
};
|
592
|
621
|
|
|
622
|
+/**
|
|
623
|
+ * Adds loca WebRTC stream to the conference.
|
|
624
|
+ * @param {MediaStream} stream new stream that will be added.
|
|
625
|
+ * @param {function} callback callback executed after successful stream addition.
|
|
626
|
+ * @param {function(error)} errorCallback callback executed if stream addition fail.
|
|
627
|
+ * @param {object} ssrcInfo object with information about the SSRCs associated with the
|
|
628
|
+ * stream.
|
|
629
|
+ * @param {boolean} [dontModifySources] if true _modifySources won't be called.
|
|
630
|
+ * Used for streams added before the call start.
|
|
631
|
+ */
|
|
632
|
+JitsiConference.prototype.addLocalWebRTCStream
|
|
633
|
+ = function (stream, callback, errorCallback, ssrcInfo, dontModifySources) {
|
|
634
|
+ if(this.jingleSession) {
|
|
635
|
+ this.jingleSession.addStream(
|
|
636
|
+ stream, callback, errorCallback, ssrcInfo, dontModifySources);
|
|
637
|
+ } else {
|
|
638
|
+ // We are done immediately
|
|
639
|
+ logger.warn("Add local MediaStream - no JingleSession started yet");
|
|
640
|
+ callback();
|
|
641
|
+ }
|
|
642
|
+};
|
|
643
|
+
|
|
644
|
+/**
|
|
645
|
+ * Remove local WebRTC media stream.
|
|
646
|
+ * @param {MediaStream} stream the stream that will be removed.
|
|
647
|
+ * @param {function} callback callback executed after successful stream removal.
|
|
648
|
+ * @param {function} errorCallback callback executed if stream removal fail.
|
|
649
|
+ * @param {object} ssrcInfo object with information about the SSRCs associated
|
|
650
|
+ * with the stream.
|
|
651
|
+ */
|
|
652
|
+JitsiConference.prototype.removeLocalWebRTCStream
|
|
653
|
+ = function (stream, callback, errorCallback, ssrcInfo) {
|
|
654
|
+ if(this.jingleSession) {
|
|
655
|
+ this.jingleSession.removeStream(
|
|
656
|
+ stream, callback, errorCallback, ssrcInfo);
|
|
657
|
+ } else {
|
|
658
|
+ // We are done immediately
|
|
659
|
+ logger.warn("Remove local MediaStream - no JingleSession started yet");
|
|
660
|
+ callback();
|
|
661
|
+ }
|
|
662
|
+};
|
|
663
|
+
|
|
664
|
+/**
|
|
665
|
+ * Generate ssrc info object for a stream with the following properties:
|
|
666
|
+ * - ssrcs - Array of the ssrcs associated with the stream.
|
|
667
|
+ * - groups - Array of the groups associated with the stream.
|
|
668
|
+ */
|
|
669
|
+JitsiConference.prototype._generateNewStreamSSRCInfo = function () {
|
|
670
|
+ if(!this.jingleSession) {
|
|
671
|
+ logger.warn("The call haven't been started. " +
|
|
672
|
+ "Cannot generate ssrc info at the moment!");
|
|
673
|
+ return null;
|
|
674
|
+ }
|
|
675
|
+ return this.jingleSession.generateNewStreamSSRCInfo();
|
|
676
|
+};
|
|
677
|
+
|
593
|
678
|
/**
|
594
|
679
|
* Get role of the local user.
|
595
|
680
|
* @returns {string} user role: 'moderator' or 'none'
|
|
@@ -875,7 +960,7 @@ function (jingleSession, jingleOffer, now) {
|
875
|
960
|
}
|
876
|
961
|
|
877
|
962
|
// Accept incoming call
|
878
|
|
- this.room.setJingleSession(jingleSession);
|
|
963
|
+ this.jingleSession = jingleSession;
|
879
|
964
|
this.room.connectionTimes["session.initiate"] = now;
|
880
|
965
|
// Log "session.restart"
|
881
|
966
|
if (this.wasStopped) {
|
|
@@ -927,8 +1012,7 @@ function (jingleSession, jingleOffer, now) {
|
927
|
1012
|
* In order to solve issues like the above one here we have to
|
928
|
1013
|
* generate the ssrc information for the track .
|
929
|
1014
|
*/
|
930
|
|
- localTrack._setSSRC(
|
931
|
|
- this.room.generateNewStreamSSRCInfo());
|
|
1015
|
+ localTrack._setSSRC(this._generateNewStreamSSRCInfo());
|
932
|
1016
|
ssrcInfo = {
|
933
|
1017
|
mtype: localTrack.getType(),
|
934
|
1018
|
type: "addMuted",
|
|
@@ -937,9 +1021,9 @@ function (jingleSession, jingleOffer, now) {
|
937
|
1021
|
};
|
938
|
1022
|
}
|
939
|
1023
|
try {
|
940
|
|
- this.room.addStream(
|
|
1024
|
+ this.addLocalWebRTCStream(
|
941
|
1025
|
localTrack.getOriginalStream(), function () {}, function () {},
|
942
|
|
- ssrcInfo, true);
|
|
1026
|
+ ssrcInfo, true /* don't modify SSRCs */);
|
943
|
1027
|
} catch(e) {
|
944
|
1028
|
GlobalOnErrorHandler.callErrorHandler(e);
|
945
|
1029
|
logger.error(e);
|
|
@@ -986,7 +1070,7 @@ JitsiConference.prototype.onCallEnded
|
986
|
1070
|
this.statistics.stopCallStats();
|
987
|
1071
|
}
|
988
|
1072
|
// Current JingleSession is invalid so set it to null on the room
|
989
|
|
- this.room.setJingleSession(null);
|
|
1073
|
+ this.jingleSession = null;
|
990
|
1074
|
// Let the RTC service do any cleanups
|
991
|
1075
|
this.rtc.onCallEnded();
|
992
|
1076
|
// PeerConnection has been closed which means that SSRCs stored in
|
|
@@ -1160,8 +1244,8 @@ JitsiConference.prototype.getPhonePin = function () {
|
1160
|
1244
|
* for its session.
|
1161
|
1245
|
*/
|
1162
|
1246
|
JitsiConference.prototype.getConnectionState = function () {
|
1163
|
|
- if(this.room)
|
1164
|
|
- return this.room.getConnectionState();
|
|
1247
|
+ if(this.jingleSession)
|
|
1248
|
+ return this.jingleSession.getIceConnectionState();
|
1165
|
1249
|
return null;
|
1166
|
1250
|
};
|
1167
|
1251
|
|