Adds support for bundle.
This commit is contained in:
parent
01811c15fe
commit
20b69ce5ca
|
@ -19,5 +19,6 @@ var config = {
|
||||||
//defaultSipNumber: '20669', //Default SIP number used in call dialog
|
//defaultSipNumber: '20669', //Default SIP number used in call dialog
|
||||||
// channelLastN: -1, // The default value of the channel attribute last-n.
|
// channelLastN: -1, // The default value of the channel attribute last-n.
|
||||||
// useRtcpMux: true,
|
// useRtcpMux: true,
|
||||||
|
// useBundle: true,
|
||||||
enableRecording: false
|
enableRecording: false
|
||||||
};
|
};
|
||||||
|
|
|
@ -72,6 +72,7 @@ function ColibriFocus(connection, bridgejid) {
|
||||||
this.media = ['audio', 'video'];
|
this.media = ['audio', 'video'];
|
||||||
|
|
||||||
this.connection.jingle.sessions[this.sid] = this;
|
this.connection.jingle.sessions[this.sid] = this;
|
||||||
|
this.bundledTransports = {};
|
||||||
this.mychannel = [];
|
this.mychannel = [];
|
||||||
this.channels = [];
|
this.channels = [];
|
||||||
this.remotessrc = {};
|
this.remotessrc = {};
|
||||||
|
@ -296,13 +297,20 @@ ColibriFocus.prototype._makeConference = function () {
|
||||||
|
|
||||||
elem.c(elemName, elemAttrs);
|
elem.c(elemName, elemAttrs);
|
||||||
elem.attrs({ endpoint: self.myMucResource });
|
elem.attrs({ endpoint: self.myMucResource });
|
||||||
|
if (config.useBundle) {
|
||||||
|
elem.attrs({ 'channel-bundle-id': self.myMucResource });
|
||||||
|
}
|
||||||
elem.up();// end of channel/sctpconnection
|
elem.up();// end of channel/sctpconnection
|
||||||
|
|
||||||
for (var j = 0; j < self.peers.length; j++) {
|
for (var j = 0; j < self.peers.length; j++) {
|
||||||
var peer = self.peers[j];
|
var peer = self.peers[j];
|
||||||
|
var peerEndpoint = peer.substr(1 + peer.lastIndexOf('/'));
|
||||||
|
|
||||||
elem.c(elemName, elemAttrs);
|
elem.c(elemName, elemAttrs);
|
||||||
elem.attrs({ endpoint: peer.substr(1 + peer.lastIndexOf('/')) });
|
elem.attrs({ endpoint: peerEndpoint });
|
||||||
|
if (config.useBundle) {
|
||||||
|
elem.attrs({ 'channel-bundle-id': peerEndpoint });
|
||||||
|
}
|
||||||
elem.up(); // end of channel/sctpconnection
|
elem.up(); // end of channel/sctpconnection
|
||||||
}
|
}
|
||||||
elem.up(); // end of content
|
elem.up(); // end of content
|
||||||
|
@ -353,7 +361,7 @@ ColibriFocus.prototype._makeConference = function () {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
// callback when a conference was created
|
// callback when a colibri conference was created
|
||||||
ColibriFocus.prototype.createdConference = function (result) {
|
ColibriFocus.prototype.createdConference = function (result) {
|
||||||
console.log('created a conference on the bridge');
|
console.log('created a conference on the bridge');
|
||||||
var self = this;
|
var self = this;
|
||||||
|
@ -379,6 +387,14 @@ ColibriFocus.prototype.createdConference = function (result) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// save the 'transport' elements from 'channel-bundle'-s
|
||||||
|
var channelBundles = $(result).find('>conference>channel-bundle');
|
||||||
|
for (var i = 0; i < channelBundles.length; i++)
|
||||||
|
{
|
||||||
|
var endpointId = $(channelBundles[i]).attr('id');
|
||||||
|
this.bundledTransports[endpointId] = $(channelBundles[i]).find('>transport[xmlns="urn:xmpp:jingle:transports:ice-udp:1"]');
|
||||||
|
}
|
||||||
|
|
||||||
console.log('remote channels', this.channels);
|
console.log('remote channels', this.channels);
|
||||||
|
|
||||||
// Notify that the focus has created the conference on the bridge
|
// Notify that the focus has created the conference on the bridge
|
||||||
|
@ -390,6 +406,11 @@ ColibriFocus.prototype.createdConference = function (result) {
|
||||||
's=-\r\n' +
|
's=-\r\n' +
|
||||||
't=0 0\r\n' +
|
't=0 0\r\n' +
|
||||||
/* Audio */
|
/* Audio */
|
||||||
|
(config.useBundle
|
||||||
|
? ('a=group:BUNDLE audio video' +
|
||||||
|
(config.openSctp ? ' data' : '') +
|
||||||
|
'\r\n')
|
||||||
|
: '') +
|
||||||
'm=audio 1 RTP/SAVPF 111 103 104 0 8 106 105 13 126\r\n' +
|
'm=audio 1 RTP/SAVPF 111 103 104 0 8 106 105 13 126\r\n' +
|
||||||
'c=IN IP4 0.0.0.0\r\n' +
|
'c=IN IP4 0.0.0.0\r\n' +
|
||||||
'a=rtcp:1 IN IP4 0.0.0.0\r\n' +
|
'a=rtcp:1 IN IP4 0.0.0.0\r\n' +
|
||||||
|
@ -490,7 +511,13 @@ ColibriFocus.prototype.createdConference = function (result) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: should take code from .fromJingle
|
// FIXME: should take code from .fromJingle
|
||||||
tmp = $(this.mychannel[channel]).find('>transport[xmlns="urn:xmpp:jingle:transports:ice-udp:1"]');
|
var channelBundleId = $(this.mychannel[channel]).attr('channel-bundle-id');
|
||||||
|
if (typeof channelBundleId != 'undefined') {
|
||||||
|
tmp = this.bundledTransports[channelBundleId];
|
||||||
|
} else {
|
||||||
|
tmp = $(this.mychannel[channel]).find('>transport[xmlns="urn:xmpp:jingle:transports:ice-udp:1"]');
|
||||||
|
}
|
||||||
|
|
||||||
if (tmp.length) {
|
if (tmp.length) {
|
||||||
bridgeSDP.media[channel] += 'a=ice-ufrag:' + tmp.attr('ufrag') + '\r\n';
|
bridgeSDP.media[channel] += 'a=ice-ufrag:' + tmp.attr('ufrag') + '\r\n';
|
||||||
bridgeSDP.media[channel] += 'a=ice-pwd:' + tmp.attr('pwd') + '\r\n';
|
bridgeSDP.media[channel] += 'a=ice-pwd:' + tmp.attr('pwd') + '\r\n';
|
||||||
|
@ -514,7 +541,7 @@ ColibriFocus.prototype.createdConference = function (result) {
|
||||||
function (answer) {
|
function (answer) {
|
||||||
self.peerconnection.setLocalDescription(answer,
|
self.peerconnection.setLocalDescription(answer,
|
||||||
function () {
|
function () {
|
||||||
console.log('setLocalDescription succeded.');
|
console.log('setLocalDescription succeeded.');
|
||||||
// make sure our presence is updated
|
// make sure our presence is updated
|
||||||
$(document).trigger('setLocalDescription.jingle', [self.sid]);
|
$(document).trigger('setLocalDescription.jingle', [self.sid]);
|
||||||
var elem = $iq({to: self.bridgejid, type: 'get'});
|
var elem = $iq({to: self.bridgejid, type: 'get'});
|
||||||
|
@ -570,7 +597,7 @@ ColibriFocus.prototype.createdConference = function (result) {
|
||||||
},
|
},
|
||||||
function (error) {
|
function (error) {
|
||||||
console.error(
|
console.error(
|
||||||
"ERROR setLocalDescription succeded",
|
"ERROR sending colibri message",
|
||||||
error, elem);
|
error, elem);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -616,7 +643,9 @@ ColibriFocus.prototype.initiate = function (peer, isInitiator) {
|
||||||
var localSDP = new SDP(this.peerconnection.localDescription.sdp);
|
var localSDP = new SDP(this.peerconnection.localDescription.sdp);
|
||||||
// throw away stuff we don't want
|
// throw away stuff we don't want
|
||||||
// not needed with static offer
|
// not needed with static offer
|
||||||
sdp.removeSessionLines('a=group:');
|
if (!config.useBundle) {
|
||||||
|
sdp.removeSessionLines('a=group:');
|
||||||
|
}
|
||||||
sdp.removeSessionLines('a=msid-semantic:'); // FIXME: not mapped over jingle anyway...
|
sdp.removeSessionLines('a=msid-semantic:'); // FIXME: not mapped over jingle anyway...
|
||||||
for (var i = 0; i < sdp.media.length; i++) {
|
for (var i = 0; i < sdp.media.length; i++) {
|
||||||
if (!config.useRtcpMux){
|
if (!config.useRtcpMux){
|
||||||
|
@ -670,7 +699,14 @@ ColibriFocus.prototype.initiate = function (peer, isInitiator) {
|
||||||
sdp.media[j] += 'a=ssrc:' + '3735928559' + ' ' + 'mslabel:mixedmslabel' + '\r\n';
|
sdp.media[j] += 'a=ssrc:' + '3735928559' + ' ' + 'mslabel:mixedmslabel' + '\r\n';
|
||||||
}
|
}
|
||||||
|
|
||||||
tmp = chan.find('>transport[xmlns="urn:xmpp:jingle:transports:ice-udp:1"]');
|
// In the case of bundle, we add each candidate to all m= lines/jingle contents,
|
||||||
|
// just as chrome does
|
||||||
|
if (config.useBundle){
|
||||||
|
tmp = this.bundledTransports[chan.attr('channel-bundle-id')];
|
||||||
|
} else {
|
||||||
|
tmp = chan.find('>transport[xmlns="urn:xmpp:jingle:transports:ice-udp:1"]');
|
||||||
|
}
|
||||||
|
|
||||||
if (tmp.length) {
|
if (tmp.length) {
|
||||||
if (tmp.attr('ufrag'))
|
if (tmp.attr('ufrag'))
|
||||||
sdp.media[j] += 'a=ice-ufrag:' + tmp.attr('ufrag') + '\r\n';
|
sdp.media[j] += 'a=ice-ufrag:' + tmp.attr('ufrag') + '\r\n';
|
||||||
|
@ -757,12 +793,17 @@ ColibriFocus.prototype.addNewParticipant = function (peer) {
|
||||||
localSDP.media.forEach(function (media, channel) {
|
localSDP.media.forEach(function (media, channel) {
|
||||||
var name = SDPUtil.parse_mid(SDPUtil.find_line(media, 'a=mid:'));
|
var name = SDPUtil.parse_mid(SDPUtil.find_line(media, 'a=mid:'));
|
||||||
var elemName;
|
var elemName;
|
||||||
|
var endpointId = peer.substr(1 + peer.lastIndexOf('/'));
|
||||||
var elemAttrs
|
var elemAttrs
|
||||||
= {
|
= {
|
||||||
initiator: 'true',
|
initiator: 'true',
|
||||||
expire: self.channelExpire,
|
expire: self.channelExpire,
|
||||||
endpoint: peer.substr(1 + peer.lastIndexOf('/'))
|
endpoint: endpointId
|
||||||
};
|
};
|
||||||
|
if (config.useBundle) {
|
||||||
|
elemAttrs['channel-bundle-id'] = endpointId;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if ('data' == name)
|
if ('data' == name)
|
||||||
{
|
{
|
||||||
|
@ -785,7 +826,8 @@ ColibriFocus.prototype.addNewParticipant = function (peer) {
|
||||||
this.connection.sendIQ(elem,
|
this.connection.sendIQ(elem,
|
||||||
function (result) {
|
function (result) {
|
||||||
var contents = $(result).find('>conference>content').get();
|
var contents = $(result).find('>conference>content').get();
|
||||||
for (var i = 0; i < contents.length; i++) {
|
var i;
|
||||||
|
for (i = 0; i < contents.length; i++) {
|
||||||
var channelXml = $(contents[i]).find('>channel');
|
var channelXml = $(contents[i]).find('>channel');
|
||||||
if (channelXml.length)
|
if (channelXml.length)
|
||||||
{
|
{
|
||||||
|
@ -797,6 +839,12 @@ ColibriFocus.prototype.addNewParticipant = function (peer) {
|
||||||
}
|
}
|
||||||
self.channels[index][i] = tmp[0];
|
self.channels[index][i] = tmp[0];
|
||||||
}
|
}
|
||||||
|
var channelBundles = $(result).find('>conference>channel-bundle');
|
||||||
|
for (i = 0; i < channelBundles.length; i++)
|
||||||
|
{
|
||||||
|
var endpointId = $(channelBundles[i]).attr('id');
|
||||||
|
self.bundledTransports[endpointId] = $(channelBundles[i]).find('>transport[xmlns="urn:xmpp:jingle:transports:ice-udp:1"]');
|
||||||
|
}
|
||||||
self.initiate(peer, true);
|
self.initiate(peer, true);
|
||||||
},
|
},
|
||||||
function (error) {
|
function (error) {
|
||||||
|
@ -1023,6 +1071,12 @@ ColibriFocus.prototype.addIceCandidate = function (session, elem) {
|
||||||
$(elem).each(function () {
|
$(elem).each(function () {
|
||||||
var name = $(this).attr('name');
|
var name = $(this).attr('name');
|
||||||
|
|
||||||
|
// If we are using bundle, audio/video/data channel will have the same candidates, so only send them for
|
||||||
|
// the audio channel.
|
||||||
|
if (config.useBundle && name !== 'audio') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var channel = name == 'audio' ? 0 : 1; // FIXME: search mlineindex in localdesc
|
var channel = name == 'audio' ? 0 : 1; // FIXME: search mlineindex in localdesc
|
||||||
if (name != 'audio' && name != 'video')
|
if (name != 'audio' && name != 'video')
|
||||||
channel = 2; // name == 'data'
|
channel = 2; // name == 'data'
|
||||||
|
|
Loading…
Reference in New Issue