|
|
@@ -40,7 +40,10 @@ function ColibriFocus(connection, bridgejid) {
|
|
40
|
40
|
this.peers = [];
|
|
41
|
41
|
this.confid = null;
|
|
42
|
42
|
|
|
43
|
|
- this.peerconnection = null;
|
|
|
43
|
+ this.peerconnection
|
|
|
44
|
+ = new TraceablePeerConnection(
|
|
|
45
|
+ this.connection.jingle.ice_config,
|
|
|
46
|
+ this.connection.jingle.pc_constraints);
|
|
44
|
47
|
|
|
45
|
48
|
// media types of the conference
|
|
46
|
49
|
this.media = ['audio', 'video'];
|
|
|
@@ -51,13 +54,6 @@ function ColibriFocus(connection, bridgejid) {
|
|
51
|
54
|
this.channels = [];
|
|
52
|
55
|
this.remotessrc = {};
|
|
53
|
56
|
|
|
54
|
|
- // ssrc lines to be added on next update
|
|
55
|
|
- this.addssrc = [];
|
|
56
|
|
- // ssrc lines to be removed on next update
|
|
57
|
|
- this.removessrc = [];
|
|
58
|
|
- // pending mute/unmute video op that modify local description
|
|
59
|
|
- this.pendingop = null;
|
|
60
|
|
-
|
|
61
|
57
|
// container for candidates from the focus
|
|
62
|
58
|
// gathered before confid is known
|
|
63
|
59
|
this.drip_container = [];
|
|
|
@@ -81,7 +77,6 @@ ColibriFocus.prototype.makeConference = function (peers) {
|
|
81
|
77
|
self.channels.push([]);
|
|
82
|
78
|
});
|
|
83
|
79
|
|
|
84
|
|
- this.peerconnection = new TraceablePeerConnection(this.connection.jingle.ice_config, this.connection.jingle.pc_constraints);
|
|
85
|
80
|
this.peerconnection.addStream(this.connection.jingle.localStream);
|
|
86
|
81
|
this.peerconnection.oniceconnectionstatechange = function (event) {
|
|
87
|
82
|
console.warn('ice connection state changed to', self.peerconnection.iceConnectionState);
|
|
|
@@ -651,9 +646,11 @@ ColibriFocus.prototype.setRemoteDescription = function (session, elem, desctype)
|
|
651
|
646
|
// ACT 4: add new a=ssrc lines to local remotedescription
|
|
652
|
647
|
for (channel = 0; channel < this.channels[participant].length; channel++) {
|
|
653
|
648
|
//if (channel == 0) continue; FIXME: does not work as intended
|
|
654
|
|
- if (!this.addssrc[channel]) this.addssrc[channel] = '';
|
|
655
|
649
|
if (SDPUtil.find_lines(remoteSDP.media[channel], 'a=ssrc:').length) {
|
|
656
|
|
- this.addssrc[channel] += SDPUtil.find_lines(remoteSDP.media[channel], 'a=ssrc:').join('\r\n') + '\r\n';
|
|
|
650
|
+ this.peerconnection.enqueueAddSsrc(
|
|
|
651
|
+ channel,
|
|
|
652
|
+ SDPUtil.find_lines(remoteSDP.media[channel], 'a=ssrc:').join('\r\n') + '\r\n'
|
|
|
653
|
+ );
|
|
657
|
654
|
}
|
|
658
|
655
|
}
|
|
659
|
656
|
this.modifySources();
|
|
|
@@ -764,8 +761,7 @@ ColibriFocus.prototype.terminate = function (session, reason) {
|
|
764
|
761
|
}
|
|
765
|
762
|
var ssrcs = this.remotessrc[session.peerjid];
|
|
766
|
763
|
for (var i = 0; i < ssrcs.length; i++) {
|
|
767
|
|
- if (!this.removessrc[i]) this.removessrc[i] = '';
|
|
768
|
|
- this.removessrc[i] += ssrcs[i];
|
|
|
764
|
+ this.peerconnection.enqueueRemoveSsrc(i, ssrcs[i]);
|
|
769
|
765
|
}
|
|
770
|
766
|
// remove from this.peers
|
|
771
|
767
|
this.peers.splice(participant, 1);
|
|
|
@@ -796,7 +792,7 @@ ColibriFocus.prototype.terminate = function (session, reason) {
|
|
796
|
792
|
for (var j = 0; j < ssrcs.length; j++) {
|
|
797
|
793
|
sdp.media[j] = 'a=mid:' + contents[j] + '\r\n';
|
|
798
|
794
|
sdp.media[j] += ssrcs[j];
|
|
799
|
|
- this.removessrc[j] += ssrcs[j];
|
|
|
795
|
+ this.peerconnection.enqueueRemoveSsrc(j, ssrcs[j]);
|
|
800
|
796
|
}
|
|
801
|
797
|
this.sendSSRCUpdate(sdp, session.peerjid, false);
|
|
802
|
798
|
|
|
|
@@ -806,126 +802,14 @@ ColibriFocus.prototype.terminate = function (session, reason) {
|
|
806
|
802
|
|
|
807
|
803
|
ColibriFocus.prototype.modifySources = function () {
|
|
808
|
804
|
var self = this;
|
|
809
|
|
- if (this.peerconnection.signalingState == 'closed') return;
|
|
810
|
|
- if (!(this.addssrc.length || this.removessrc.length || this.pendingop !== null)) return;
|
|
811
|
|
-
|
|
812
|
|
- // FIXME: this is a big hack
|
|
813
|
|
- // https://code.google.com/p/webrtc/issues/detail?id=2688
|
|
814
|
|
- if (!(this.peerconnection.signalingState == 'stable' && this.peerconnection.iceConnectionState == 'connected')) {
|
|
815
|
|
- console.warn('modifySources not yet', this.peerconnection.signalingState, this.peerconnection.iceConnectionState);
|
|
816
|
|
- window.setTimeout(function () { self.modifySources(); }, 250);
|
|
817
|
|
- this.wait = true;
|
|
818
|
|
- return;
|
|
819
|
|
- }
|
|
820
|
|
- if (this.wait) {
|
|
821
|
|
- window.setTimeout(function () { self.modifySources(); }, 2500);
|
|
822
|
|
- this.wait = false;
|
|
823
|
|
- return;
|
|
824
|
|
- }
|
|
825
|
|
- var sdp = new SDP(this.peerconnection.remoteDescription.sdp);
|
|
826
|
|
-
|
|
827
|
|
- // add sources
|
|
828
|
|
- this.addssrc.forEach(function (lines, idx) {
|
|
829
|
|
- sdp.media[idx] += lines;
|
|
|
805
|
+ this.peerconnection.modifySources(function(){
|
|
|
806
|
+ $(document).trigger('setLocalDescription.jingle', [self.sid]);
|
|
830
|
807
|
});
|
|
831
|
|
- this.addssrc = [];
|
|
832
|
|
-
|
|
833
|
|
- // remove sources
|
|
834
|
|
- this.removessrc.forEach(function (lines, idx) {
|
|
835
|
|
- lines = lines.split('\r\n');
|
|
836
|
|
- lines.pop(); // remove empty last element;
|
|
837
|
|
- lines.forEach(function (line) {
|
|
838
|
|
- sdp.media[idx] = sdp.media[idx].replace(line + '\r\n', '');
|
|
839
|
|
- });
|
|
840
|
|
- });
|
|
841
|
|
- this.removessrc = [];
|
|
842
|
|
-
|
|
843
|
|
- sdp.raw = sdp.session + sdp.media.join('');
|
|
844
|
|
- this.peerconnection.setRemoteDescription(
|
|
845
|
|
- new RTCSessionDescription({type: 'offer', sdp: sdp.raw }),
|
|
846
|
|
- function () {
|
|
847
|
|
- console.log('setModifiedRemoteDescription ok');
|
|
848
|
|
- self.peerconnection.createAnswer(
|
|
849
|
|
- function (modifiedAnswer) {
|
|
850
|
|
- console.log('modifiedAnswer created');
|
|
851
|
|
-
|
|
852
|
|
- // change video direction, see https://github.com/jitsi/jitmeet/issues/41
|
|
853
|
|
- if (self.pendingop !== null) {
|
|
854
|
|
- var sdp = new SDP(modifiedAnswer.sdp);
|
|
855
|
|
- if (sdp.media.length > 1) {
|
|
856
|
|
- switch(self.pendingop) {
|
|
857
|
|
- case 'mute':
|
|
858
|
|
- sdp.media[1] = sdp.media[1].replace('a=sendrecv', 'a=recvonly');
|
|
859
|
|
- break;
|
|
860
|
|
- case 'unmute':
|
|
861
|
|
- sdp.media[1] = sdp.media[1].replace('a=recvonly', 'a=sendrecv');
|
|
862
|
|
- break;
|
|
863
|
|
- }
|
|
864
|
|
- sdp.raw = sdp.session + sdp.media.join('');
|
|
865
|
|
- modifiedAnswer.sdp = sdp.raw;
|
|
866
|
|
- }
|
|
867
|
|
- self.pendingop = null;
|
|
868
|
|
- }
|
|
869
|
|
-
|
|
870
|
|
- // FIXME: pushing down an answer while ice connection state
|
|
871
|
|
- // is still checking is bad...
|
|
872
|
|
- //console.log(self.peerconnection.iceConnectionState);
|
|
873
|
|
-
|
|
874
|
|
- // trying to work around another chrome bug
|
|
875
|
|
- //modifiedAnswer.sdp = modifiedAnswer.sdp.replace(/a=setup:active/g, 'a=setup:actpass');
|
|
876
|
|
- self.peerconnection.setLocalDescription(modifiedAnswer,
|
|
877
|
|
- function () {
|
|
878
|
|
- console.log('setModifiedLocalDescription ok');
|
|
879
|
|
- $(document).trigger('setLocalDescription.jingle', [self.sid]);
|
|
880
|
|
- },
|
|
881
|
|
- function (error) {
|
|
882
|
|
- console.log('setModifiedLocalDescription failed', error);
|
|
883
|
|
- }
|
|
884
|
|
- );
|
|
885
|
|
- },
|
|
886
|
|
- function (error) {
|
|
887
|
|
- console.log('createModifiedAnswer failed', error);
|
|
888
|
|
- }
|
|
889
|
|
- );
|
|
890
|
|
- },
|
|
891
|
|
- function (error) {
|
|
892
|
|
- console.log('setModifiedRemoteDescription failed', error);
|
|
893
|
|
- }
|
|
894
|
|
- );
|
|
895
|
|
- /*
|
|
896
|
|
- * now that we have a passive focus, this way is bad again! :-)
|
|
897
|
|
- this.peerconnection.createOffer(
|
|
898
|
|
- function (modifiedOffer) {
|
|
899
|
|
- console.log('created (un)modified offer');
|
|
900
|
|
- self.peerconnection.setLocalDescription(modifiedOffer,
|
|
901
|
|
- function () {
|
|
902
|
|
- console.log('setModifiedLocalDescription ok');
|
|
903
|
|
- self.peerconnection.setRemoteDescription(
|
|
904
|
|
- new RTCSessionDescription({type: 'answer', sdp: sdp.raw }),
|
|
905
|
|
- function () {
|
|
906
|
|
- console.log('setModifiedRemoteDescription ok');
|
|
907
|
|
- },
|
|
908
|
|
- function (error) {
|
|
909
|
|
- console.log('setModifiedRemoteDescription failed');
|
|
910
|
|
- }
|
|
911
|
|
- );
|
|
912
|
|
- $(document).trigger('setLocalDescription.jingle', [self.sid]);
|
|
913
|
|
- },
|
|
914
|
|
- function (error) {
|
|
915
|
|
- console.log('setModifiedLocalDescription failed');
|
|
916
|
|
- }
|
|
917
|
|
- );
|
|
918
|
|
- },
|
|
919
|
|
- function (error) {
|
|
920
|
|
- console.log('creating (un)modified offerfailed');
|
|
921
|
|
- }
|
|
922
|
|
- );
|
|
923
|
|
- */
|
|
924
|
808
|
};
|
|
925
|
809
|
|
|
926
|
810
|
ColibriFocus.prototype.hardMuteVideo = function (muted) {
|
|
927
|
|
- this.pendingop = muted ? 'mute' : 'unmute';
|
|
928
|
|
- this.modifySources();
|
|
|
811
|
+
|
|
|
812
|
+ this.peerconnection.hardMuteVideo(muted);
|
|
929
|
813
|
|
|
930
|
814
|
this.connection.jingle.localStream.getVideoTracks().forEach(function (track) {
|
|
931
|
815
|
track.enabled = !muted;
|