Moves SSRC owner signaling from MUC presence to Jingle.

pull/311/head 561
paweldomas 10 years ago
parent d74a356a40
commit a1b0677442
  1. 2
      index.html
  2. 41576
      libs/app.bundle.js
  3. 11
      modules/RTC/MediaStream.js
  4. 14
      modules/RTC/RTC.js
  5. 18
      modules/UI/UI.js
  6. 7
      modules/UI/videolayout/VideoLayout.js
  7. 132
      modules/xmpp/JingleSession.js
  8. 15
      modules/xmpp/SDP.js
  9. 11
      modules/xmpp/SDPDiffer.js
  10. 69
      modules/xmpp/strophe.emuc.js
  11. 4
      modules/xmpp/xmpp.js
  12. 1
      service/xmpp/XMPPEvents.js

@ -22,7 +22,7 @@
<script src="libs/popover.js?v=1"></script><!-- bootstrap tooltip lib --> <script src="libs/popover.js?v=1"></script><!-- bootstrap tooltip lib -->
<script src="libs/toastr.js?v=1"></script><!-- notifications lib --> <script src="libs/toastr.js?v=1"></script><!-- notifications lib -->
<script src="interface_config.js?v=5"></script> <script src="interface_config.js?v=5"></script>
<script src="libs/app.bundle.js?v=99"></script> <script src="libs/app.bundle.js?v=100"></script>
<script src="analytics.js?v=1"></script><!-- google analytics plugin --> <script src="analytics.js?v=1"></script><!-- google analytics plugin -->
<link rel="stylesheet" href="css/font.css?v=7"/> <link rel="stylesheet" href="css/font.css?v=7"/>
<link rel="stylesheet" href="css/toastr.css?v=1"> <link rel="stylesheet" href="css/toastr.css?v=1">

File diff suppressed because it is too large Load Diff

@ -28,10 +28,10 @@ function MediaStream(data, sid, ssrc, browser, eventEmitter) {
this.sid = sid; this.sid = sid;
this.stream = data.stream; this.stream = data.stream;
this.peerjid = data.peerjid; this.peerjid = data.peerjid;
this.videoType = data.videoType;
this.ssrc = ssrc; this.ssrc = ssrc;
this.type = (this.stream.getVideoTracks().length > 0)? this.type = (this.stream.getVideoTracks().length > 0)?
MediaStreamType.VIDEO_TYPE : MediaStreamType.AUDIO_TYPE; MediaStreamType.VIDEO_TYPE : MediaStreamType.AUDIO_TYPE;
this.videoType = null;
this.muted = false; this.muted = false;
this.eventEmitter = eventEmitter; this.eventEmitter = eventEmitter;
} }
@ -48,13 +48,4 @@ MediaStream.prototype.setMute = function (value)
this.muted = value; this.muted = value;
}; };
MediaStream.prototype.setVideoType = function (value) {
if(this.videoType === value)
return;
this.videoType = value;
this.eventEmitter.emit(StreamEventType.EVENT_TYPE_REMOTE_CHANGED,
this.peerjid);
};
module.exports = MediaStream; module.exports = MediaStream;

@ -148,20 +148,6 @@ var RTC = {
function (stream, isUsingScreenStream, callback) { function (stream, isUsingScreenStream, callback) {
self.changeLocalVideo(stream, isUsingScreenStream, callback); self.changeLocalVideo(stream, isUsingScreenStream, callback);
}, DesktopSharingEventTypes.NEW_STREAM_CREATED); }, DesktopSharingEventTypes.NEW_STREAM_CREATED);
APP.xmpp.addListener(XMPPEvents.STREAMS_CHANGED, function (jid, changedStreams) {
for(var i = 0; i < changedStreams.length; i++) {
var type = changedStreams[i].type;
if (type != "audio") {
var peerStreams = self.remoteStreams[jid];
if(!peerStreams)
continue;
var videoStream = peerStreams[MediaStreamType.VIDEO_TYPE];
if(!videoStream)
continue;
videoStream.setVideoType(changedStreams[i].type);
}
}
});
APP.xmpp.addListener(XMPPEvents.CALL_INCOMING, function(event) { APP.xmpp.addListener(XMPPEvents.CALL_INCOMING, function(event) {
DataChannels.init(event.peerconnection, eventEmitter); DataChannels.init(event.peerconnection, eventEmitter);
}); });

@ -249,24 +249,6 @@ function registerListeners() {
APP.xmpp.addListener(XMPPEvents.USER_ID_CHANGED, function (from, id) { APP.xmpp.addListener(XMPPEvents.USER_ID_CHANGED, function (from, id) {
Avatar.setUserAvatar(from, id); Avatar.setUserAvatar(from, id);
}); });
APP.xmpp.addListener(XMPPEvents.STREAMS_CHANGED, function (jid, changedStreams) {
for(stream in changedStreams)
{
// might need to update the direction if participant just went from sendrecv to recvonly
if (stream.type === 'video' || stream.type === 'screen') {
var el = $('#participant_' + Strophe.getResourceFromJid(jid) + '>' + APP.RTC.getVideoElementName());
switch (stream.direction) {
case 'sendrecv':
el.show();
break;
case 'recvonly':
el.hide();
break;
}
}
}
});
APP.xmpp.addListener(XMPPEvents.DISPLAY_NAME_CHANGED, onDisplayNameChanged); APP.xmpp.addListener(XMPPEvents.DISPLAY_NAME_CHANGED, onDisplayNameChanged);
APP.xmpp.addListener(XMPPEvents.MUC_JOINED, onMucJoined); APP.xmpp.addListener(XMPPEvents.MUC_JOINED, onMucJoined);
APP.xmpp.addListener(XMPPEvents.LOCAL_ROLE_CHANGED, onLocalRoleChanged); APP.xmpp.addListener(XMPPEvents.LOCAL_ROLE_CHANGED, onLocalRoleChanged);

@ -532,6 +532,13 @@ var VideoLayout = (function (my) {
} else { } else {
VideoLayout.ensurePeerContainerExists(jid); VideoLayout.ensurePeerContainerExists(jid);
remoteVideos[Strophe.getResourceFromJid(jid)].showVideoIndicator(value); remoteVideos[Strophe.getResourceFromJid(jid)].showVideoIndicator(value);
var el = $('#participant_' + Strophe.getResourceFromJid(jid)
+ '>' + APP.RTC.getVideoElementName());
if (!value)
el.show();
else
el.hide();
} }
}; };

@ -48,6 +48,8 @@ function JingleSession(me, sid, connection, service, eventEmitter) {
this.wait = true; this.wait = true;
this.localStreamsSSRC = null; this.localStreamsSSRC = null;
this.ssrcOwners = {};
this.ssrcVideoTypes = {};
this.eventEmitter = eventEmitter; this.eventEmitter = eventEmitter;
/** /**
@ -189,6 +191,10 @@ function onIceConnectionStateChange(sid, session) {
} }
} }
JingleSession.prototype.getVideoType = function () {
return APP.desktopsharing.isUsingScreenStream() ? 'screen' : 'camera';
};
JingleSession.prototype.accept = function () { JingleSession.prototype.accept = function () {
this.state = 'active'; this.state = 'active';
@ -216,7 +222,12 @@ JingleSession.prototype.accept = function () {
initiator: this.initiator, initiator: this.initiator,
responder: this.responder, responder: this.responder,
sid: this.sid }); sid: this.sid });
prsdp.toJingle(accept, this.initiator == this.me ? 'initiator' : 'responder', this.localStreamsSSRC); // FIXME why do we generate session-accept in 3 different places ?
prsdp.toJingle(
accept,
this.initiator == this.me ? 'initiator' : 'responder',
this.localStreamsSSRC,
self.getVideoType());
var sdp = this.peerconnection.localDescription.sdp; var sdp = this.peerconnection.localDescription.sdp;
while (SDPUtil.find_line(sdp, 'a=inactive')) { while (SDPUtil.find_line(sdp, 'a=inactive')) {
// FIXME: change any inactive to sendrecv or whatever they were originally // FIXME: change any inactive to sendrecv or whatever they were originally
@ -303,6 +314,7 @@ JingleSession.prototype.sendIceCandidate = function (candidate) {
//console.log('sendIceCandidate: last candidate.'); //console.log('sendIceCandidate: last candidate.');
if (!this.usetrickle) { if (!this.usetrickle) {
//console.log('should send full offer now...'); //console.log('should send full offer now...');
//FIXME why do we generate session-accept in 3 different places ?
var init = $iq({to: this.peerjid, var init = $iq({to: this.peerjid,
type: 'set'}) type: 'set'})
.c('jingle', {xmlns: 'urn:xmpp:jingle:1', .c('jingle', {xmlns: 'urn:xmpp:jingle:1',
@ -314,7 +326,11 @@ JingleSession.prototype.sendIceCandidate = function (candidate) {
var sendJingle = function (ssrc) { var sendJingle = function (ssrc) {
if(!ssrc) if(!ssrc)
ssrc = {}; ssrc = {};
self.localSDP.toJingle(init, self.initiator == self.me ? 'initiator' : 'responder', ssrc); self.localSDP.toJingle(
init,
self.initiator == self.me ? 'initiator' : 'responder',
ssrc,
self.getVideoType());
self.connection.sendIQ(init, self.connection.sendIQ(init,
function () { function () {
//console.log('session initiate ack'); //console.log('session initiate ack');
@ -414,6 +430,7 @@ JingleSession.prototype.sendOffer = function () {
); );
}; };
// FIXME createdOffer is never used in jitsi-meet
JingleSession.prototype.createdOffer = function (sdp) { JingleSession.prototype.createdOffer = function (sdp) {
//console.log('createdOffer', sdp); //console.log('createdOffer', sdp);
var self = this; var self = this;
@ -426,7 +443,11 @@ JingleSession.prototype.createdOffer = function (sdp) {
action: 'session-initiate', action: 'session-initiate',
initiator: this.initiator, initiator: this.initiator,
sid: this.sid}); sid: this.sid});
self.localSDP.toJingle(init, this.initiator == this.me ? 'initiator' : 'responder', this.localStreamsSSRC); self.localSDP.toJingle(
init,
this.initiator == this.me ? 'initiator' : 'responder',
this.localStreamsSSRC,
self.getVideoType());
self.connection.sendIQ(init, self.connection.sendIQ(init,
function () { function () {
var ack = {}; var ack = {};
@ -471,10 +492,35 @@ JingleSession.prototype.createdOffer = function (sdp) {
} }
}; };
JingleSession.prototype.readSsrcInfo = function (contents) {
var self = this;
$(contents).each(function (idx, content) {
var name = $(content).attr('name');
var mediaType = this.getAttribute('name');
var ssrcs = $(content).find('description>source[xmlns="urn:xmpp:jingle:apps:rtp:ssma:0"]');
ssrcs.each(function () {
var ssrc = this.getAttribute('ssrc');
$(this).find('>ssrc-info[xmlns="http://jitsi.org/jitmeet"]').each(
function () {
var owner = this.getAttribute('owner');
var videoType = this.getAttribute('video-type');
self.ssrcOwners[ssrc] = owner;
self.ssrcVideoTypes[ssrc] = videoType;
}
);
});
});
};
JingleSession.prototype.getSsrcOwner = function (ssrc) {
return this.ssrcOwners[ssrc];
};
JingleSession.prototype.setRemoteDescription = function (elem, desctype) { JingleSession.prototype.setRemoteDescription = function (elem, desctype) {
//console.log('setting remote description... ', desctype); //console.log('setting remote description... ', desctype);
this.remoteSDP = new SDP(''); this.remoteSDP = new SDP('');
this.remoteSDP.fromJingle(elem); this.remoteSDP.fromJingle(elem);
this.readSsrcInfo($(elem).find(">content"));
if (this.peerconnection.remoteDescription !== null) { if (this.peerconnection.remoteDescription !== null) {
console.log('setRemoteDescription when remote description is not null, should be pranswer', this.peerconnection.remoteDescription); console.log('setRemoteDescription when remote description is not null, should be pranswer', this.peerconnection.remoteDescription);
if (this.peerconnection.remoteDescription.type == 'pranswer') { if (this.peerconnection.remoteDescription.type == 'pranswer') {
@ -655,7 +701,7 @@ JingleSession.prototype.createdAnswer = function (sdp, provisional) {
} }
var self = this; var self = this;
var sendJingle = function (ssrcs) { var sendJingle = function (ssrcs) {
// FIXME why do we generate session-accept in 3 different places ?
var accept = $iq({to: self.peerjid, var accept = $iq({to: self.peerjid,
type: 'set'}) type: 'set'})
.c('jingle', {xmlns: 'urn:xmpp:jingle:1', .c('jingle', {xmlns: 'urn:xmpp:jingle:1',
@ -663,7 +709,11 @@ JingleSession.prototype.createdAnswer = function (sdp, provisional) {
initiator: self.initiator, initiator: self.initiator,
responder: self.responder, responder: self.responder,
sid: self.sid }); sid: self.sid });
self.localSDP.toJingle(accept, self.initiator == self.me ? 'initiator' : 'responder', ssrcs); self.localSDP.toJingle(
accept,
self.initiator == self.me ? 'initiator' : 'responder',
ssrcs,
self.getVideoType());
self.connection.sendIQ(accept, self.connection.sendIQ(accept,
function () { function () {
var ack = {}; var ack = {};
@ -762,6 +812,9 @@ JingleSession.prototype.addSource = function (elem, fromJid) {
console.log('addssrc', new Date().getTime()); console.log('addssrc', new Date().getTime());
console.log('ice', this.peerconnection.iceConnectionState); console.log('ice', this.peerconnection.iceConnectionState);
this.readSsrcInfo(elem);
var sdp = new SDP(this.peerconnection.remoteDescription.sdp); var sdp = new SDP(this.peerconnection.remoteDescription.sdp);
var mySdp = new SDP(this.peerconnection.localDescription.sdp); var mySdp = new SDP(this.peerconnection.localDescription.sdp);
@ -1085,7 +1138,7 @@ JingleSession.prototype.notifyMySSRCUpdate = function (old_sdp, new_sdp) {
sid: this.sid sid: this.sid
} }
); );
var added = sdpDiffer.toJingle(add); var added = sdpDiffer.toJingle(add, this.getVideoType());
if (added) { if (added) {
this.connection.sendIQ(add, this.connection.sendIQ(add,
function (res) { function (res) {
@ -1245,7 +1298,7 @@ JingleSession.onJingleFatalError = function (session, error)
} }
JingleSession.prototype.setLocalDescription = function () { JingleSession.prototype.setLocalDescription = function () {
// put our ssrcs into presence so other clients can identify our stream var self = this;
var newssrcs = []; var newssrcs = [];
var session = transform.parse(this.peerconnection.localDescription.sdp); var session = transform.parse(this.peerconnection.localDescription.sdp);
session.media.forEach(function (media) { session.media.forEach(function (media) {
@ -1258,17 +1311,15 @@ JingleSession.prototype.setLocalDescription = function () {
} }
newssrcs.push({ newssrcs.push({
'ssrc': ssrc.id, 'ssrc': ssrc.id,
'type': media.type, 'type': media.type
'direction': media.direction
}); });
}); });
} }
else if(this.localStreamsSSRC && this.localStreamsSSRC[media.type]) else if(self.localStreamsSSRC && self.localStreamsSSRC[media.type])
{ {
newssrcs.push({ newssrcs.push({
'ssrc': this.localStreamsSSRC[media.type], 'ssrc': self.localStreamsSSRC[media.type],
'type': media.type, 'type': media.type
'direction': media.direction
}); });
} }
@ -1276,20 +1327,16 @@ JingleSession.prototype.setLocalDescription = function () {
console.log('new ssrcs', newssrcs); console.log('new ssrcs', newssrcs);
// Have to clear presence map to get rid of removed streams // Bind us as local SSRCs owner
this.connection.emuc.clearPresenceMedia();
if (newssrcs.length > 0) { if (newssrcs.length > 0) {
for (var i = 1; i <= newssrcs.length; i ++) { for (var i = 1; i <= newssrcs.length; i ++) {
// Change video type to screen var ssrc = newssrcs[i-1].ssrc;
if (newssrcs[i-1].type === 'video' && APP.desktopsharing.isUsingScreenStream()) { var myJid = self.connection.emuc.myroomjid;
newssrcs[i-1].type = 'screen'; self.ssrcOwners[ssrc] = myJid;
if (newssrcs[i-1].type === 'video'){
self.ssrcVideoTypes[ssrc] = self.getVideoType();
} }
this.connection.emuc.addMediaToPresence(i,
newssrcs[i-1].type, newssrcs[i-1].ssrc, newssrcs[i-1].direction);
} }
this.connection.emuc.sendPresence();
} }
} }
@ -1331,7 +1378,6 @@ function sendKeyframe(pc) {
JingleSession.prototype.remoteStreamAdded = function (data, times) { JingleSession.prototype.remoteStreamAdded = function (data, times) {
var self = this; var self = this;
var thessrc; var thessrc;
var ssrc2jid = this.connection.emuc.ssrc2jid;
var streamId = APP.RTC.getStreamID(data.stream); var streamId = APP.RTC.getStreamID(data.stream);
// look up an associated JID for a stream id // look up an associated JID for a stream id
@ -1354,40 +1400,14 @@ JingleSession.prototype.remoteStreamAdded = function (data, times) {
if (ssrclines.length) { if (ssrclines.length) {
thessrc = ssrclines[0].substring(7).split(' ')[0]; thessrc = ssrclines[0].substring(7).split(' ')[0];
// We signal our streams (through Jingle to the focus) before we set if (!self.ssrcOwners[thessrc]) {
// our presence (through which peers associate remote streams to console.error("No SSRC owner known for: " + thessrc);
// jids). So, it might arrive that a remote stream is added but
// ssrc2jid is not yet updated and thus data.peerjid cannot be
// successfully set. Here we wait for up to a second for the
// presence to arrive.
if (!ssrc2jid[thessrc]) {
if (typeof times === 'undefined')
{
times = 0;
}
if (times > 10)
{
console.warning('Waiting for jid timed out', thessrc);
}
else
{
setTimeout(function(d) {
return function() {
self.remoteStreamAdded(d, times++);
}
}(data), 250);
}
return; return;
} }
data.peerjid = self.ssrcOwners[thessrc];
// ok to overwrite the one from focus? might save work in colibri.js data.videoType = self.ssrcVideoTypes[thessrc]
console.log('associated jid', ssrc2jid[thessrc], thessrc); console.log('associated jid', self.ssrcOwners[thessrc],
if (ssrc2jid[thessrc]) { thessrc, data.videoType);
data.peerjid = ssrc2jid[thessrc];
}
} }
} }

@ -125,7 +125,7 @@ SDP.prototype.removeMediaLines = function(mediaindex, prefix) {
} }
// add content's to a jingle element // add content's to a jingle element
SDP.prototype.toJingle = function (elem, thecreator, ssrcs) { SDP.prototype.toJingle = function (elem, thecreator, ssrcs, videoType) {
// console.log("SSRC" + ssrcs["audio"] + " - " + ssrcs["video"]); // console.log("SSRC" + ssrcs["audio"] + " - " + ssrcs["video"]);
var i, j, k, mline, ssrc, rtpmap, tmp, line, lines; var i, j, k, mline, ssrc, rtpmap, tmp, line, lines;
var self = this; var self = this;
@ -227,7 +227,6 @@ SDP.prototype.toJingle = function (elem, thecreator, ssrcs) {
} }
elem.up(); elem.up();
}); });
elem.up();
} }
else else
{ {
@ -257,11 +256,17 @@ SDP.prototype.toJingle = function (elem, thecreator, ssrcs) {
elem.c('parameter'); elem.c('parameter');
elem.attrs({name: "label", value:msid}); elem.attrs({name: "label", value:msid});
elem.up(); elem.up();
elem.up();
} }
} }
// Video type
if (videoType && mline.media == "video") {
elem.c('ssrc-info',
{
xmlns: 'http://jitsi.org/jitmeet',
'video-type': videoType
}).up();
}
elem.up();
// XEP-0339 handle ssrc-group attributes // XEP-0339 handle ssrc-group attributes
var ssrc_group_lines = SDPUtil.find_lines(this.media[i], 'a=ssrc-group:'); var ssrc_group_lines = SDPUtil.find_lines(this.media[i], 'a=ssrc-group:');

@ -106,7 +106,7 @@ SDPDiffer.prototype.getNewMedia = function() {
* @param toJid destination Jid * @param toJid destination Jid
* @param isAdd indicates if this is remove or add operation. * @param isAdd indicates if this is remove or add operation.
*/ */
SDPDiffer.prototype.toJingle = function(modify) { SDPDiffer.prototype.toJingle = function(modify, videoType) {
var sdpMediaSsrcs = this.getNewMedia(); var sdpMediaSsrcs = this.getNewMedia();
var self = this; var self = this;
@ -141,6 +141,15 @@ SDPDiffer.prototype.toJingle = function(modify) {
} }
modify.up(); // end of parameter modify.up(); // end of parameter
}); });
// indicate video type
if (videoType && media.mid == 'video') {
modify.c('ssrc-info',
{
xmlns: 'http://jitsi.org/jitmeet',
'video-type': videoType
})
.up();
}
modify.up(); // end of source modify.up(); // end of source
}); });

@ -21,7 +21,6 @@ module.exports = function(XMPP, eventEmitter) {
isOwner: false, isOwner: false,
role: null, role: null,
focusMucJid: null, focusMucJid: null,
ssrc2jid: {},
init: function (conn) { init: function (conn) {
this.connection = conn; this.connection = conn;
}, },
@ -280,14 +279,6 @@ module.exports = function(XMPP, eventEmitter) {
return true; return true;
} }
var self = this;
// Remove old ssrcs coming from the jid
Object.keys(this.ssrc2jid).forEach(function (ssrc) {
if (self.ssrc2jid[ssrc] == from) {
delete self.ssrc2jid[ssrc];
}
});
// Status code 110 indicates that this notification is "self-presence". // Status code 110 indicates that this notification is "self-presence".
if (!$(pres).find('>x[xmlns="http://jabber.org/protocol/muc#user"]>status[code="110"]').length) { if (!$(pres).find('>x[xmlns="http://jabber.org/protocol/muc#user"]>status[code="110"]').length) {
delete this.members[from]; delete this.members[from];
@ -514,26 +505,6 @@ module.exports = function(XMPP, eventEmitter) {
.c('current').t(this.presMap['prezicurrent']).up().up(); .c('current').t(this.presMap['prezicurrent']).up().up();
} }
if (this.presMap['medians']) {
pres.c('media', {xmlns: this.presMap['medians']});
var sourceNumber = 0;
Object.keys(this.presMap).forEach(function (key) {
if (key.indexOf('source') >= 0) {
sourceNumber++;
}
});
if (sourceNumber > 0)
for (var i = 1; i <= sourceNumber / 3; i++) {
pres.c('source',
{type: this.presMap['source' + i + '_type'],
ssrc: this.presMap['source' + i + '_ssrc'],
direction: this.presMap['source' + i + '_direction']
|| 'sendrecv' }
).up();
}
pres.up();
}
if(this.presMap["startMuted"] !== undefined) if(this.presMap["startMuted"] !== undefined)
{ {
pres.c("startmuted", {audio: this.presMap["startMuted"].audio, pres.c("startmuted", {audio: this.presMap["startMuted"].audio,
@ -548,25 +519,9 @@ module.exports = function(XMPP, eventEmitter) {
addDisplayNameToPresence: function (displayName) { addDisplayNameToPresence: function (displayName) {
this.presMap['displayName'] = displayName; this.presMap['displayName'] = displayName;
}, },
addMediaToPresence: function (sourceNumber, mtype, ssrcs, direction) {
if (!this.presMap['medians'])
this.presMap['medians'] = 'http://estos.de/ns/mjs';
this.presMap['source' + sourceNumber + '_type'] = mtype;
this.presMap['source' + sourceNumber + '_ssrc'] = ssrcs;
this.presMap['source' + sourceNumber + '_direction'] = direction;
},
addDevicesToPresence: function (devices) { addDevicesToPresence: function (devices) {
this.presMap['devices'] = devices; this.presMap['devices'] = devices;
}, },
clearPresenceMedia: function () {
var self = this;
Object.keys(this.presMap).forEach(function (key) {
if (key.indexOf('source') != -1) {
delete self.presMap[key];
}
});
},
addPreziToPresence: function (url, currentSlide) { addPreziToPresence: function (url, currentSlide) {
this.presMap['prezins'] = 'http://jitsi.org/jitmeet/prezi'; this.presMap['prezins'] = 'http://jitsi.org/jitmeet/prezi';
this.presMap['preziurl'] = url; this.presMap['preziurl'] = url;
@ -650,30 +605,6 @@ module.exports = function(XMPP, eventEmitter) {
if(memeber.isFocus) if(memeber.isFocus)
return; return;
var self = this;
// Remove old ssrcs coming from the jid
Object.keys(this.ssrc2jid).forEach(function (ssrc) {
if (self.ssrc2jid[ssrc] == from) {
delete self.ssrc2jid[ssrc];
}
});
var changedStreams = [];
$(pres).find('>media[xmlns="http://estos.de/ns/mjs"]>source').each(function (idx, ssrc) {
//console.log(jid, 'assoc ssrc', ssrc.getAttribute('type'), ssrc.getAttribute('ssrc'));
var ssrcV = ssrc.getAttribute('ssrc');
self.ssrc2jid[ssrcV] = from;
var type = ssrc.getAttribute('type');
var direction = ssrc.getAttribute('direction');
changedStreams.push({type: type, direction: direction});
});
eventEmitter.emit(XMPPEvents.STREAMS_CHANGED, from, changedStreams);
var displayName = !config.displayJids var displayName = !config.displayJids
? memeber.displayName : Strophe.getResourceFromJid(from); ? memeber.displayName : Strophe.getResourceFromJid(from);

@ -594,9 +594,9 @@ var XMPP = {
return connection.emuc.members; return connection.emuc.members;
}, },
getJidFromSSRC: function (ssrc) { getJidFromSSRC: function (ssrc) {
if(!connection) if (!this.isConferenceInProgress())
return null; return null;
return connection.emuc.ssrc2jid[ssrc]; return connection.jingle.activecall.getSsrcOwner(ssrc);
}, },
getMUCJoined: function () { getMUCJoined: function () {
return connection.emuc.joined; return connection.emuc.joined;

@ -7,7 +7,6 @@ var XMPPEvents = {
KICKED: "xmpp.kicked", KICKED: "xmpp.kicked",
BRIDGE_DOWN: "xmpp.bridge_down", BRIDGE_DOWN: "xmpp.bridge_down",
USER_ID_CHANGED: "xmpp.user_id_changed", USER_ID_CHANGED: "xmpp.user_id_changed",
STREAMS_CHANGED: "xmpp.streams_changed",
// We joined the MUC // We joined the MUC
MUC_JOINED: "xmpp.muc_joined", MUC_JOINED: "xmpp.muc_joined",
// A member joined the MUC // A member joined the MUC

Loading…
Cancel
Save