diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..3c3629e
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+node_modules
diff --git a/.jshintignore b/.jshintignore
new file mode 100644
index 0000000..3c3629e
--- /dev/null
+++ b/.jshintignore
@@ -0,0 +1 @@
+node_modules
diff --git a/.jshintrc b/.jshintrc
new file mode 100644
index 0000000..006e4c0
--- /dev/null
+++ b/.jshintrc
@@ -0,0 +1,15 @@
+{
+ "asi": false,
+ "expr": true,
+ "loopfunc": true,
+ "curly": false,
+ "evil": true,
+ "white": true,
+ "undef": true,
+ "browser": true,
+ "node": true,
+ "trailing": true,
+ "indent": 4,
+ "latedef": true,
+ "newcap": true
+}
diff --git a/examples/muc.js b/examples/muc.js
index 23ea936..4018a32 100644
--- a/examples/muc.js
+++ b/examples/muc.js
@@ -1,7 +1,8 @@
+/* jshint -W117 */
var BOSH_SERVICE = '/http-bind',
- DOMAIN = window.location.hostname;
+ DOMAIN = window.location.hostname,
CONFERENCEDOMAIN = 'conference.' + DOMAIN,
- ice_config = {iceServers: [{url: 'stun:stun.l.google.com:19302'}]},
+ ice_config = {iceServers: [{url: 'stun:stun.l.google.com:19302'}]},
RTC = null,
RTCPeerConnection = null,
AUTOACCEPT = true,
@@ -45,64 +46,37 @@ function onConnect(status) {
}
}
-function onConnected(event) {
- doJoin();
- setTimeout(function() {
- $(window).bind('hashchange', onHashChange);
- }, 500);
+function onHashChange() {
+ setStatus('hashChange: ' + window.location.hash);
+ if (Object.keys(connection.jingle.sessions).length === 0) {
+ window.location.reload();
+ }
}
-function doJoin() {
- var roomnode = null,
- pres;
- if (location.hash.length > 1) {
- roomnode = location.hash.substr(1).toLowerCase();
- if (roomnode.indexOf('/') != -1) {
- setStatus('invalid location, must not contain "/"');
- connection.disconnect();
- return;
- }
- if (roomnode.indexOf('@') != -1) { // allow #room@host
- roomjid = roomnode;
- }
- } else {
- roomnode = Math.random().toString(36).substr(2, 8);
- location.hash = roomnode;
- }
- if (roomjid == null) {
- roomjid = roomnode + '@' + CONFERENCEDOMAIN;
+function onJoinComplete() {
+ setStatus('onJoinComplete');
+ if (list_members.length < 1) {
+ setStatus('waiting for peer');
+ return;
}
- setStatus('Joining ' + location.hash);
- myroomjid = roomjid + '/' + Strophe.getNodeFromJid(connection.jid);
- list_members = new Array();
- console.log('joining', roomjid);
-
- // muc stuff
- connection.addHandler(onPresence, null, 'presence', null, null, roomjid, {matchBare: true});
- connection.addHandler(onPresenceUnavailable, null, 'presence', 'unavailable', null, roomjid, {matchBare: true});
- connection.addHandler(onPresenceError, null, 'presence', 'error', null, roomjid, {matchBare: true});
-
- pres = $pres({to: myroomjid })
- .c('x', {xmlns: 'http://jabber.org/protocol/muc'});
- connection.send(pres);
-}
-function onHashChange() {
- setStatus('hashChange: ' + window.location.hash);
- if (Object.keys(connection.jingle.sessions).length == 0) {
- window.location.reload();
+ setStatus('initiating call');
+ var i, sess, num;
+ num = MULTIPARTY ? list_members.length : 1;
+ for (i = 0; i < num; i++) {
+ connection.jingle.initiate(list_members[i], myroomjid);
}
}
function onPresence(pres) {
var from = pres.getAttribute('from'),
type = pres.getAttribute('type');
- if (type != null) {
+ if (type !== null) {
return true;
}
if ($(pres).find('>x[xmlns="http://jabber.org/protocol/muc#user"]>status[code="201"]').length) {
// http://xmpp.org/extensions/xep-0045.html#createroom-instant
- var create = $iq({type: 'set', to:roomjid})
+ var create = $iq({type: 'set', to: roomjid})
.c('query', {xmlns: 'http://jabber.org/protocol/muc#owner'})
.c('x', {xmlns: 'jabber:x:data', type: 'submit'});
connection.send(create); // fire away
@@ -117,7 +91,7 @@ function onPresence(pres) {
function onPresenceUnavailable(pres) {
connection.jingle.terminateByJid($(pres).attr('from'));
- if (Object.keys(connection.jingle.sessions).length == 0) {
+ if (Object.keys(connection.jingle.sessions).length === 0) {
setStatus('everyone left');
}
for (var i = 0; i < list_members.length; i++) {
@@ -134,19 +108,39 @@ function onPresenceError(pres) {
return true;
}
-function onJoinComplete() {
- setStatus('onJoinComplete');
- if (list_members.length < 1) {
- setStatus('waiting for peer');
- return;
+function doJoin() {
+ var roomnode = null,
+ pres;
+ if (location.hash.length > 1) {
+ roomnode = location.hash.substr(1).toLowerCase();
+ if (roomnode.indexOf('/') != -1) {
+ setStatus('invalid location, must not contain "/"');
+ connection.disconnect();
+ return;
+ }
+ if (roomnode.indexOf('@') != -1) { // allow #room@host
+ roomjid = roomnode;
+ }
+ } else {
+ roomnode = Math.random().toString(36).substr(2, 8);
+ location.hash = roomnode;
}
-
- setStatus('initiating call');
- var i, sess, num;
- num = MULTIPARTY ? list_members.length : 1;
- for (i = 0; i < num; i++) {
- connection.jingle.initiate(list_members[i], myroomjid);
+ if (roomjid === null) {
+ roomjid = roomnode + '@' + CONFERENCEDOMAIN;
}
+ setStatus('Joining ' + location.hash);
+ myroomjid = roomjid + '/' + Strophe.getNodeFromJid(connection.jid);
+ list_members = [];
+ console.log('joining', roomjid);
+
+ // muc stuff
+ connection.addHandler(onPresence, null, 'presence', null, null, roomjid, {matchBare: true});
+ connection.addHandler(onPresenceUnavailable, null, 'presence', 'unavailable', null, roomjid, {matchBare: true});
+ connection.addHandler(onPresenceError, null, 'presence', 'error', null, roomjid, {matchBare: true});
+
+ pres = $pres({to: myroomjid })
+ .c('x', {xmlns: 'http://jabber.org/protocol/muc'});
+ connection.send(pres);
}
function onMediaReady(event, stream) {
@@ -167,25 +161,25 @@ function onMediaReady(event, stream) {
doConnect();
if (typeof hark === "function") {
- var options = { interval:400 };
+ var options = { interval: 400 };
var speechEvents = hark(stream, options);
- speechEvents.on('speaking', function() {
- console.log('speaking');
+ speechEvents.on('speaking', function () {
+ console.log('speaking');
});
- speechEvents.on('stopped_speaking', function() {
- console.log('stopped_speaking');
+ speechEvents.on('stopped_speaking', function () {
+ console.log('stopped_speaking');
});
- speechEvents.on('volume_change', function(volume, treshold) {
+ speechEvents.on('volume_change', function (volume, treshold) {
//console.log('volume', volume, treshold);
- if (volume < -60) { // vary between -60 and -35
- $('#ownvolume').css('width', 0);
- } else if (volume > -35) {
- $('#ownvolume').css('width', '100%');
- } else {
- $('#ownvolume').css('width', (volume+100)*100/25-160+ '%');
- }
+ if (volume < -60) { // vary between -60 and -35
+ $('#ownvolume').css('width', 0);
+ } else if (volume > -35) {
+ $('#ownvolume').css('width', '100%');
+ } else {
+ $('#ownvolume').css('width', (volume + 100) * 100 / 25 - 160 + '%');
+ }
});
} else {
console.warn('without hark, you are missing quite a nice feature');
@@ -207,87 +201,20 @@ function onCallIncoming(event, sid) {
//connection.jingle.terminate(sid);
}
-function onCallActive(event, videoelem, sid) {
- setStatus('call active ' + sid);
- $(videoelem).appendTo('#largevideocontainer');
- arrangeVideos('#largevideocontainer >');
- connection.jingle.sessions[sid].getStats(1000);
-}
-
-function onCallTerminated(event, sid, reason) {
- setStatus('call terminated ' + sid + (reason ? (': ' + reason) : ''));
- if (Object.keys(connection.jingle.sessions).length == 0) {
- setStatus('all calls terminated');
- }
- $('#largevideocontainer #largevideo_' + sid).remove();
- arrangeVideos('#largevideocontainer >');
-}
-
-function onRemoteStreamAdded(event, data, sid) {
- setStatus('Remote stream for session ' + sid + ' added.');
- if ($('#largevideo_' + sid).length != 0) {
- console.log('ignoring duplicate onRemoteStreamAdded...'); // FF 20
- return;
- }
- // after remote stream has been added, wait for ice to become connected
- // old code for compat with FF22 beta
- var el = $("").attr('id', 'largevideo_' + sid);
- RTC.attachMediaStream(el, data.stream);
- waitForRemoteVideo(el, sid);
- /* does not yet work for remote streams -- https://code.google.com/p/webrtc/issues/detail?id=861
- var options = { interval:500 };
- var speechEvents = hark(data.stream, options);
-
- speechEvents.on('volume_change', function(volume, treshold) {
- console.log('volume for ' + sid, volume, treshold);
- });
- */
-}
-
-function waitForRemoteVideo(selector, sid) {
- sess = connection.jingle.sessions[sid];
- videoTracks = sess.remoteStream.getVideoTracks();
- if (videoTracks.length === 0 || selector[0].currentTime > 0) {
- $(document).trigger('callactive.jingle', [selector, sid]);
- RTC.attachMediaStream(selector, sess.remoteStream); // FIXME: why do i have to do this for FF?
- console.log('waitForremotevideo', sess.peerconnection.iceConnectionState, sess.peerconnection.signalingState);
- } else {
- setTimeout(function() { waitForRemoteVideo(selector, sid); }, 100);
- }
-}
-
-
-function onRemoteStreamRemoved(event, data, sid) {
- setStatus('Remote stream for session ' + sid + ' removed.');
-}
-
-function onIceConnectionStateChanged(event, sid, sess) {
- console.log('ice state for', sid, sess.peerconnection.iceConnectionState);
- console.log('sig state for', sid, sess.peerconnection.signalingState);
- // works like charm, unfortunately only in chrome and FF nightly, not FF22 beta
- /*
- if (sess.peerconnection.signalingState == 'stable' && sess.peerconnection.iceConnectionState == 'connected') {
- var el = $("").attr('id', 'largevideo_' + sid);
- $(document).trigger('callactive.jingle', [el, sid]);
- RTC.attachMediaStream(el, sess.remoteStream); // moving this before the trigger doesn't work in FF?!
- }
- */
-}
-
function arrangeVideos(selector) {
var floor = Math.floor,
elements = $(selector),
howMany = elements.length,
availableWidth = $(selector).parent().innerWidth(),
availableHeight = $(selector).parent().innerHeight(),
- usedWidth = 0;
+ usedWidth = 0,
aspectRatio = 4 / 3;
if (availableHeight < availableWidth / aspectRatio) {
availableWidth = availableHeight * aspectRatio;
}
elements.height(availableHeight);
- elements.each(function(index) {
+ elements.each(function (index) {
$(elements[index]).removeAttr('style');
});
@@ -321,7 +248,7 @@ function arrangeVideos(selector) {
$(elements[3]).css('right', ($(selector).parent().innerWidth() - availableWidth) / 2);
break;
}
- elements.each(function(index) {
+ elements.each(function (index) {
$(elements[index]).css({
position: 'absolute',
width: usedWidth,
@@ -331,38 +258,112 @@ function arrangeVideos(selector) {
});
}
+
+function onCallActive(event, videoelem, sid) {
+ setStatus('call active ' + sid);
+ $(videoelem).appendTo('#largevideocontainer');
+ arrangeVideos('#largevideocontainer >');
+ connection.jingle.sessions[sid].getStats(1000);
+}
+
+function onCallTerminated(event, sid, reason) {
+ setStatus('call terminated ' + sid + (reason ? (': ' + reason) : ''));
+ if (Object.keys(connection.jingle.sessions).length === 0) {
+ setStatus('all calls terminated');
+ }
+ $('#largevideocontainer #largevideo_' + sid).remove();
+ arrangeVideos('#largevideocontainer >');
+}
+
+function waitForRemoteVideo(selector, sid) {
+ sess = connection.jingle.sessions[sid];
+ videoTracks = sess.remoteStream.getVideoTracks();
+ if (videoTracks.length === 0 || selector[0].currentTime > 0) {
+ $(document).trigger('callactive.jingle', [selector, sid]);
+ RTC.attachMediaStream(selector, sess.remoteStream); // FIXME: why do i have to do this for FF?
+ console.log('waitForremotevideo', sess.peerconnection.iceConnectionState, sess.peerconnection.signalingState);
+ } else {
+ setTimeout(function () { waitForRemoteVideo(selector, sid); }, 100);
+ }
+}
+
+function onRemoteStreamAdded(event, data, sid) {
+ setStatus('Remote stream for session ' + sid + ' added.');
+ if ($('#largevideo_' + sid).length !== 0) {
+ console.log('ignoring duplicate onRemoteStreamAdded...'); // FF 20
+ return;
+ }
+ // after remote stream has been added, wait for ice to become connected
+ // old code for compat with FF22 beta
+ var el = $("").attr('id', 'largevideo_' + sid);
+ RTC.attachMediaStream(el, data.stream);
+ waitForRemoteVideo(el, sid);
+ /* does not yet work for remote streams -- https://code.google.com/p/webrtc/issues/detail?id=861
+ var options = { interval:500 };
+ var speechEvents = hark(data.stream, options);
+
+ speechEvents.on('volume_change', function (volume, treshold) {
+ console.log('volume for ' + sid, volume, treshold);
+ });
+ */
+}
+
+function onRemoteStreamRemoved(event, data, sid) {
+ setStatus('Remote stream for session ' + sid + ' removed.');
+}
+
+function onIceConnectionStateChanged(event, sid, sess) {
+ console.log('ice state for', sid, sess.peerconnection.iceConnectionState);
+ console.log('sig state for', sid, sess.peerconnection.signalingState);
+ // works like charm, unfortunately only in chrome and FF nightly, not FF22 beta
+ /*
+ if (sess.peerconnection.signalingState == 'stable' && sess.peerconnection.iceConnectionState == 'connected') {
+ var el = $("").attr('id', 'largevideo_' + sid);
+ $(document).trigger('callactive.jingle', [el, sid]);
+ RTC.attachMediaStream(el, sess.remoteStream); // moving this before the trigger doesn't work in FF?!
+ }
+ */
+}
+
function noStunCandidates(event) {
setStatus('webrtc did not encounter stun candidates, NAT traversal will not work');
console.warn('webrtc did not encounter stun candidates, NAT traversal will not work');
}
-$(window).bind('beforeunload', function() {
+function onConnected(event) {
+ doJoin();
+ setTimeout(function () {
+ $(window).bind('hashchange', onHashChange);
+ }, 500);
+}
+
+$(window).bind('beforeunload', function () {
if (connection && connection.connected) {
// ensure signout
$.ajax({
- type: 'POST',
- url: '/http-bind',
- async: false,
- cache: false,
- contentType: 'application/xml',
- data: "
",
- success: function(data) {
+ type: 'POST',
+ url: '/http-bind',
+ async: false,
+ cache: false,
+ contentType: 'application/xml',
+ data: "",
+ success: function (data) {
console.log('signed out');
console.log(data);
},
- error: function(XMLHttpRequest, textStatus, errorThrown) {
+ error: function (XMLHttpRequest, textStatus, errorThrown) {
console.log('signout error', textStatus + ' (' + errorThrown + ')');
}
});
}
});
-$(document).ready(function() {
+$(document).ready(function () {
RTC = setupRTC();
connection = new Strophe.Connection(BOSH_SERVICE);
if (RAWLOGGING) {
- connection.rawInput = function(data) { console.log('RECV: ' + data); };
- connection.rawOutput = function(data) { console.log('SEND: ' + data); };
+ connection.rawInput = function (data) { console.log('RECV: ' + data); };
+ connection.rawOutput = function (data) { console.log('SEND: ' + data); };
}
connection.jingle.ice_config = ice_config;
if (RTC) {
@@ -380,19 +381,19 @@ $(document).ready(function() {
$(document).bind('remotestreamremoved.jingle', onRemoteStreamRemoved);
$(document).bind('iceconnectionstatechange.jingle', onIceConnectionStateChanged);
$(document).bind('nostuncandidates.jingle', noStunCandidates);
- $(document).bind('ack.jingle', function(event, sid, ack) {
+ $(document).bind('ack.jingle', function (event, sid, ack) {
console.log('got stanza ack for ' + sid, ack);
});
- $(document).bind('error.jingle', function(event, sid, err) {
+ $(document).bind('error.jingle', function (event, sid, err) {
console.log('got stanza error for ' + sid, err);
});
- $(document).bind('packetloss.jingle', function(event, sid, loss) {
+ $(document).bind('packetloss.jingle', function (event, sid, loss) {
console.warn('packetloss', sid, loss);
});
- if (RTC != null) {
+ if (RTC !== null) {
RTCPeerconnection = RTC.peerconnection;
if (RTC.browser == 'firefox') {
- connection.jingle.media_constraints.mandatory['MozDontOfferDataChannel'] = true;
+ connection.jingle.media_constraints.mandatory.MozDontOfferDataChannel = true;
}
//setStatus('please allow access to microphone and camera');
//getUserMediaWithConstraints();
diff --git a/strophe.jingle.adapter.js b/strophe.jingle.adapter.js
index e5dd708..bcbbd96 100644
--- a/strophe.jingle.adapter.js
+++ b/strophe.jingle.adapter.js
@@ -1,24 +1,25 @@
+/* jshint -W117 */
// mozilla chrome compat layer -- very similar to adapter.js
function setupRTC() {
var RTC = null;
- if (navigator.mozGetUserMedia && mozRTCPeerConnection) {
+ if (navigator.mozGetUserMedia) {
console.log('This appears to be Firefox');
- var version = parseInt(navigator.userAgent.match(/Firefox\/([0-9]+)\./)[1]);
+ var version = parseInt(navigator.userAgent.match(/Firefox\/([0-9]+)\./)[1], 10);
if (version >= 22) {
RTC = {
peerconnection: mozRTCPeerConnection,
browser: 'firefox',
getUserMedia: navigator.mozGetUserMedia.bind(navigator),
- attachMediaStream: function(element, stream) {
+ attachMediaStream: function (element, stream) {
element[0].mozSrcObject = stream;
element[0].play();
},
pc_constraints: {}
};
if (!MediaStream.prototype.getVideoTracks)
- MediaStream.prototype.getVideoTracks = function() { return []; };
+ MediaStream.prototype.getVideoTracks = function () { return []; };
if (!MediaStream.prototype.getAudioTracks)
- MediaStream.prototype.getAudioTracks = function() { return []; };
+ MediaStream.prototype.getAudioTracks = function () { return []; };
RTCSessionDescription = mozRTCSessionDescription;
RTCIceCandidate = mozRTCIceCandidate;
}
@@ -28,7 +29,7 @@ function setupRTC() {
peerconnection: webkitRTCPeerConnection,
browser: 'chrome',
getUserMedia: navigator.webkitGetUserMedia.bind(navigator),
- attachMediaStream: function(element, stream) {
+ attachMediaStream: function (element, stream) {
element.attr('src', webkitURL.createObjectURL(stream));
},
// pc_constraints: {} // FIVE-182
@@ -38,15 +39,17 @@ function setupRTC() {
RTC.pc_constraints = {}; // disable DTLS on Android
}
if (!webkitMediaStream.prototype.getVideoTracks) {
- webkitMediaStream.prototype.getVideoTracks = function()
- { return this.videoTracks; };
+ webkitMediaStream.prototype.getVideoTracks = function () {
+ return this.videoTracks;
+ };
}
if (!webkitMediaStream.prototype.getAudioTracks) {
- webkitMediaStream.prototype.getAudioTracks = function()
- { return this.audioTracks; };
+ webkitMediaStream.prototype.getAudioTracks = function () {
+ return this.audioTracks;
+ };
}
}
- if (RTC == null) {
+ if (RTC === null) {
try { console.log('Browser does not appear to be WebRTC-capable'); } catch (e) { }
}
return RTC;
@@ -56,7 +59,7 @@ function getUserMediaWithConstraints(um, resolution, bandwidth, fps) {
var constraints = {audio: false, video: false};
if ($.inArray('video', um) >= 0) {
- constraints.video = {mandatory:{}};// same behaviour as true
+ constraints.video = {mandatory: {}};// same behaviour as true
}
if ($.inArray('audio', um) >= 0) {
constraints.audio = {};// same behaviour as true
@@ -66,77 +69,77 @@ function getUserMediaWithConstraints(um, resolution, bandwidth, fps) {
"mandatory": {
"chromeMediaSource": "screen"
}
- }
+ };
}
if (resolution && !constraints.video) {
- constraints.video = {mandatory:{}};// same behaviour as true
+ constraints.video = {mandatory: {}};// same behaviour as true
}
// see https://code.google.com/p/chromium/issues/detail?id=143631#c9 for list of supported resolutions
switch (resolution) {
- // 16:9 first
- case '1080':
- case 'fullhd':
- constraints.video.mandatory.minWidth = 1920;
- constraints.video.mandatory.minHeight = 1080;
- constraints.video.mandatory.minAspectRatio = 1.77;
- break;
- case '720':
- case 'hd':
- constraints.video.mandatory.minWidth = 1280;
- constraints.video.mandatory.minHeight = 720;
- constraints.video.mandatory.minAspectRatio = 1.77;
- break;
- case '360':
- constraints.video.mandatory.minWidth = 640;
- constraints.video.mandatory.minHeight = 360;
- constraints.video.mandatory.minAspectRatio = 1.77;
- break;
- case '180':
- constraints.video.mandatory.minWidth = 320;
- constraints.video.mandatory.minHeight = 180;
- constraints.video.mandatory.minAspectRatio = 1.77;
- break;
- // 4:3
- case '960':
- constraints.video.mandatory.minWidth = 960;
- constraints.video.mandatory.minHeight = 720;
- break;
- case '640':
- case 'vga':
- constraints.video.mandatory.minWidth = 640;
- constraints.video.mandatory.minHeight = 480;
- break;
- case '320':
+ // 16:9 first
+ case '1080':
+ case 'fullhd':
+ constraints.video.mandatory.minWidth = 1920;
+ constraints.video.mandatory.minHeight = 1080;
+ constraints.video.mandatory.minAspectRatio = 1.77;
+ break;
+ case '720':
+ case 'hd':
+ constraints.video.mandatory.minWidth = 1280;
+ constraints.video.mandatory.minHeight = 720;
+ constraints.video.mandatory.minAspectRatio = 1.77;
+ break;
+ case '360':
+ constraints.video.mandatory.minWidth = 640;
+ constraints.video.mandatory.minHeight = 360;
+ constraints.video.mandatory.minAspectRatio = 1.77;
+ break;
+ case '180':
+ constraints.video.mandatory.minWidth = 320;
+ constraints.video.mandatory.minHeight = 180;
+ constraints.video.mandatory.minAspectRatio = 1.77;
+ break;
+ // 4:3
+ case '960':
+ constraints.video.mandatory.minWidth = 960;
+ constraints.video.mandatory.minHeight = 720;
+ break;
+ case '640':
+ case 'vga':
+ constraints.video.mandatory.minWidth = 640;
+ constraints.video.mandatory.minHeight = 480;
+ break;
+ case '320':
+ constraints.video.mandatory.minWidth = 320;
+ constraints.video.mandatory.minHeight = 240;
+ break;
+ default:
+ if (navigator.userAgent.indexOf('Android') != -1) {
constraints.video.mandatory.minWidth = 320;
constraints.video.mandatory.minHeight = 240;
- break;
- default:
- if (navigator.userAgent.indexOf('Android') != -1) {
- constraints.video.mandatory.minWidth = 320;
- constraints.video.mandatory.minHeight = 240;
- constraints.video.mandatory.maxFrameRate = 15;
- }
- break;
+ constraints.video.mandatory.maxFrameRate = 15;
+ }
+ break;
}
if (bandwidth) { // doesn't work currently, see webrtc issue 1846
- if (!constraints.video) constraints.video = {mandatory:{}};//same behaviour as true
+ if (!constraints.video) constraints.video = {mandatory: {}};//same behaviour as true
constraints.video.optional = [{bandwidth: bandwidth}];
}
if (fps) { // for some cameras it might be necessary to request 30fps
// so they choose 30fps mjpg over 10fps yuy2
- if (!constraints.video) constraints.video = {mandatory:{}};// same behaviour as tru;
- constraints.video.mandatory['minFrameRate'] = fps;
+ if (!constraints.video) constraints.video = {mandatory: {}};// same behaviour as tru;
+ constraints.video.mandatory.minFrameRate = fps;
}
try {
RTC.getUserMedia(constraints,
- function(stream) {
+ function (stream) {
console.log('onUserMediaSuccess');
$(document).trigger('mediaready.jingle', [stream]);
},
- function(error) {
+ function (error) {
console.warn('Failed to get access to local media. Error ', error);
$(document).trigger('mediafailure.jingle');
});
diff --git a/strophe.jingle.js b/strophe.jingle.js
index 1a81166..95fc94f 100644
--- a/strophe.jingle.js
+++ b/strophe.jingle.js
@@ -1,17 +1,20 @@
+/* jshint -W117 */
Strophe.addConnectionPlugin('jingle', {
connection: null,
sessions: {},
jid2session: {},
ice_config: {iceServers: []},
pc_constraints: {},
- media_constraints: {'mandatory': {
- 'OfferToReceiveAudio': true,
- 'OfferToReceiveVideo': true }
+ media_constraints: {
+ mandatory: {
+ 'OfferToReceiveAudio': true,
+ 'OfferToReceiveVideo': true
+ }
// MozDontOfferDataChannel: true when this is firefox
},
localStream: null,
- init: function(conn) {
+ init: function (conn) {
this.connection = conn;
if (this.connection.disco) {
// http://xmpp.org/extensions/xep-0167.html#support
@@ -31,7 +34,7 @@ Strophe.addConnectionPlugin('jingle', {
}
this.connection.addHandler(this.onJingle.bind(this), 'urn:xmpp:jingle:1', 'iq', 'set', null, null);
},
- onJingle: function(iq) {
+ onJingle: function (iq) {
var sid = $(iq).find('jingle').attr('sid');
var action = $(iq).find('jingle').attr('action');
// send ack first
@@ -42,7 +45,7 @@ Strophe.addConnectionPlugin('jingle', {
console.log('on jingle ' + action);
var sess = this.sessions[sid];
if ('session-initiate' != action) {
- if (sess == null) {
+ if (sess === null) {
ack.type = 'error';
ack.c('error', {type: 'cancel'})
.c('item-not-found', {xmlns: 'urn:ietf:params:xml:ns:xmpp-stanzas'}).up()
@@ -61,12 +64,12 @@ Strophe.addConnectionPlugin('jingle', {
this.connection.send(ack);
return true;
}
- } else if (sess != null) {
+ } else if (sess !== null) {
// existing session with same session id
// this might be out-of-order if the sess.peerjid is the same as from
ack.type = 'error';
ack.c('error', {type: 'cancel'})
- .c('service-unavailable', {xmlns: 'urn:ietf:params:xml:ns:xmpp-stanzas'}).up()
+ .c('service-unavailable', {xmlns: 'urn:ietf:params:xml:ns:xmpp-stanzas'}).up();
console.warn('duplicate session id', sid);
return true;
}
@@ -100,10 +103,10 @@ Strophe.addConnectionPlugin('jingle', {
case 'session-terminate':
console.log('terminating...');
sess.terminate();
- this.terminate(sess.sid);
+ this.terminate(sess.sid);
if ($(iq).find('>jingle>reason').length) {
$(document).trigger('callterminated.jingle', [
- sess.sid,
+ sess.sid,
$(iq).find('>jingle>reason>:first')[0].tagName,
$(iq).find('>jingle>reason>text').text()
]);
@@ -115,13 +118,14 @@ Strophe.addConnectionPlugin('jingle', {
sess.addIceCandidate($(iq).find('>jingle>content'));
break;
case 'session-info':
+ var affected;
if ($(iq).find('>jingle>ringing[xmlns="urn:xmpp:jingle:apps:rtp:info:1"]').length) {
$(document).trigger('ringing.jingle', [sess.sid]);
} else if ($(iq).find('>jingle>mute[xmlns="urn:xmpp:jingle:apps:rtp:info:1"]').length) {
- var affected = $(iq).find('>jingle>mute[xmlns="urn:xmpp:jingle:apps:rtp:info:1"]').attr('name');
+ affected = $(iq).find('>jingle>mute[xmlns="urn:xmpp:jingle:apps:rtp:info:1"]').attr('name');
$(document).trigger('mute.jingle', [sess.sid, affected]);
} else if ($(iq).find('>jingle>unmute[xmlns="urn:xmpp:jingle:apps:rtp:info:1"]').length) {
- var affected = $(iq).find('>jingle>unmute[xmlns="urn:xmpp:jingle:apps:rtp:info:1"]').attr('name');
+ affected = $(iq).find('>jingle>unmute[xmlns="urn:xmpp:jingle:apps:rtp:info:1"]').attr('name');
$(document).trigger('unmute.jingle', [sess.sid, affected]);
}
break;
@@ -131,7 +135,7 @@ Strophe.addConnectionPlugin('jingle', {
}
return true;
},
- initiate: function(peerjid, myjid) { // initiate a new jinglesession to peerjid
+ initiate: function (peerjid, myjid) { // initiate a new jinglesession to peerjid
var sess = new JingleSession(myjid,
Math.random().toString(36).substr(2, 12), // random string
this.connection);
@@ -147,26 +151,26 @@ Strophe.addConnectionPlugin('jingle', {
sess.sendOffer();
return sess;
},
- terminate: function(sid, reason, text) { // terminate by sessionid (or all sessions)
- if (sid == null) {
+ terminate: function (sid, reason, text) { // terminate by sessionid (or all sessions)
+ if (sid === null) {
for (sid in this.sessions) {
- if(this.sessions[sid].state != 'ended'){
- this.sessions[sid].sendTerminate(reason||(!this.sessions[sid].active())?'cancel':null, text);
+ if (this.sessions[sid].state != 'ended') {
+ this.sessions[sid].sendTerminate(reason || (!this.sessions[sid].active()) ? 'cancel' : null, text);
this.sessions[sid].terminate();
}
delete this.jid2session[this.sessions[sid].peerjid];
delete this.sessions[sid];
}
} else if (this.sessions.hasOwnProperty(sid)) {
- if(this.sessions[sid].state != 'ended'){
- this.sessions[sid].sendTerminate(reason||(!this.sessions[sid].active())?'cancel':null, text);
+ if (this.sessions[sid].state != 'ended') {
+ this.sessions[sid].sendTerminate(reason || (!this.sessions[sid].active()) ? 'cancel' : null, text);
this.sessions[sid].terminate();
}
delete this.jid2session[this.sessions[sid].peerjid];
delete this.sessions[sid];
}
},
- terminateByJid: function(jid) {
+ terminateByJid: function (jid) {
if (this.jid2session.hasOwnProperty(jid)) {
var sess = this.jid2session[jid];
if (sess) {
@@ -178,7 +182,7 @@ Strophe.addConnectionPlugin('jingle', {
}
}
},
- getStunAndTurnCredentials: function() {
+ getStunAndTurnCredentials: function () {
// get stun and turn configuration from server via xep-0215
// uses time-limited credentials as described in
// http://tools.ietf.org/html/draft-uberti-behave-turn-rest-00
@@ -193,9 +197,9 @@ Strophe.addConnectionPlugin('jingle', {
this.connection.sendIQ(
$iq({type: 'get', to: this.connection.domain})
.c('services', {xmlns: 'urn:xmpp:extdisco:1'}).c('service', {host: 'turn.' + this.connection.domain}),
- function(res) {
+ function (res) {
var iceservers = [];
- $(res).find('>services>service').each(function(idx, el) {
+ $(res).find('>services>service').each(function (idx, el) {
el = $(el);
var dict = {};
switch (el.attr('type')) {
@@ -209,7 +213,7 @@ Strophe.addConnectionPlugin('jingle', {
case 'turn':
dict.url = 'turn:';
if (el.attr('username')) { // https://code.google.com/p/webrtc/issues/detail?id=1508
- if (navigator.userAgent.match(/Chrom(e|ium)\/([0-9]+)\./) && parseInt(navigator.userAgent.match(/Chrom(e|ium)\/([0-9]+)\./)[2]) < 28) {
+ if (navigator.userAgent.match(/Chrom(e|ium)\/([0-9]+)\./) && parseInt(navigator.userAgent.match(/Chrom(e|ium)\/([0-9]+)\./)[2], 10) < 28) {
dict.url += el.attr('username') + '@';
} else {
dict.username = el.attr('username'); // only works in M28
@@ -231,7 +235,7 @@ Strophe.addConnectionPlugin('jingle', {
});
this.ice_config.iceServers = iceservers;
},
- function(err) {
+ function (err) {
console.warn('getting turn credentials failed', err);
console.warn('is mod_turncredentials or similar installed?');
}
diff --git a/strophe.jingle.sdp.js b/strophe.jingle.sdp.js
index a49f485..b3f2f97 100644
--- a/strophe.jingle.sdp.js
+++ b/strophe.jingle.sdp.js
@@ -1,3 +1,4 @@
+/* jshint -W117 */
// SDP STUFF
function SDP(sdp) {
this.media = sdp.split('\r\nm=');
@@ -12,7 +13,7 @@ function SDP(sdp) {
}
// remove iSAC and CN from SDP
-SDP.prototype.mangle = function() {
+SDP.prototype.mangle = function () {
var i, j, mline, lines, rtpmap, newdesc;
for (i = 0; i < this.media.length; i++) {
lines = this.media[i].split('\r\n');
@@ -40,7 +41,7 @@ SDP.prototype.mangle = function() {
};
// add content's to a jingle element
-SDP.prototype.toJingle = function(elem, thecreator) {
+SDP.prototype.toJingle = function (elem, thecreator) {
var i, j, k, mline, ssrc, rtpmap, tmp, line, lines;
var ob = this;
// new bundle plan
@@ -48,7 +49,7 @@ SDP.prototype.toJingle = function(elem, thecreator) {
lines = SDPUtil.find_lines(this.session, 'a=group:');
for (i = 0; i < lines.length; i++) {
tmp = lines[i].split(' ');
- elem.c('group', {xmlns:'urn:ietf:rfc:5888', type:tmp.shift().substr(8)});
+ elem.c('group', {xmlns: 'urn:ietf:rfc:5888', type: tmp.shift().substr(8)});
for (j = 0; j < tmp.length; j++) {
elem.c('content', {name: tmp[j]}).up();
}
@@ -80,7 +81,7 @@ SDP.prototype.toJingle = function(elem, thecreator) {
// old BUNDLE plan, to be removed
if (bundle.indexOf(mid) != -1) {
- elem.c('bundle', {xmlns:'http://estos.de/ns/bundle'}).up();
+ elem.c('bundle', {xmlns: 'http://estos.de/ns/bundle'}).up();
bundle.splice(bundle.indexOf(mid), 1);
}
}
@@ -107,7 +108,7 @@ SDP.prototype.toJingle = function(elem, thecreator) {
}
if (SDPUtil.find_line(this.media[i], 'a=crypto:', this.session)) {
elem.c('encryption', {required: 1});
- $.each(SDPUtil.find_lines(this.media[i], 'a=crypto:', this.session), function(idx, line) {
+ $.each(SDPUtil.find_lines(this.media[i], 'a=crypto:', this.session), function (idx, line) {
elem.c('crypto', SDPUtil.parse_crypto(line)).up();
});
elem.up(); // end of encryption
@@ -117,9 +118,9 @@ SDP.prototype.toJingle = function(elem, thecreator) {
// new style mapping
elem.c('source', { ssrc: ssrc, xmlns: 'urn:xmpp:jingle:apps:rtp:ssma:0' });
// FIXME: group by ssrc and support multiple different ssrcs
- $.each(SDPUtil.find_lines(this.media[i], 'a=ssrc:'), function(idx, line) {
- var idx = line.indexOf(' ');
- var kv = line.substr(idx+1);
+ $.each(SDPUtil.find_lines(this.media[i], 'a=ssrc:'), function (idx, line) {
+ idx = line.indexOf(' ');
+ var kv = line.substr(idx + 1);
elem.c('parameter');
if (kv.indexOf(':') == -1) {
elem.attrs({ name: kv });
@@ -157,12 +158,16 @@ SDP.prototype.toJingle = function(elem, thecreator) {
switch (tmp.direction) {
case 'sendonly':
elem.attrs({senders: 'responder'});
+ break;
case 'recvonly':
elem.attrs({senders: 'initiator'});
+ break;
case 'sendrecv':
elem.attrs({senders: 'both'});
+ break;
case 'inactive':
elem.attrs({senders: 'none'});
+ break;
}
}
// TODO: handle params
@@ -174,7 +179,7 @@ SDP.prototype.toJingle = function(elem, thecreator) {
elem.c('transport', {xmlns: 'urn:xmpp:jingle:transports:ice-udp:1'});
// XEP-0320
- $.each(SDPUtil.find_lines(this.media[i], 'a=fingerprint:', this.session), function(idx, line) {
+ $.each(SDPUtil.find_lines(this.media[i], 'a=fingerprint:', this.session), function (idx, line) {
tmp = SDPUtil.parse_fingerprint(line);
tmp.xmlns = 'urn:xmpp:tmp:jingle:apps:dtls:0';
// tmp.xmlns = 'urn:xmpp:jingle:apps:dtls:0'; -- FIXME: update receivers first
@@ -220,10 +225,10 @@ SDP.prototype.toJingle = function(elem, thecreator) {
return elem;
};
-SDP.prototype.RtcpFbToJingle = function(sdp, elem, payloadtype) { // XEP-0293
- lines = SDPUtil.find_lines(sdp, 'a=rtcp-fb:' + payloadtype);
+SDP.prototype.RtcpFbToJingle = function (sdp, elem, payloadtype) { // XEP-0293
+ var lines = SDPUtil.find_lines(sdp, 'a=rtcp-fb:' + payloadtype);
for (var i = 0; i < lines.length; i++) {
- tmp = SDPUtil.parse_rtcpfb(lines[i]);
+ var tmp = SDPUtil.parse_rtcpfb(lines[i]);
if (tmp.type == 'trr-int') {
elem.c('rtcp-fb-trr-int', {xmlns: 'urn:xmpp:jingle:apps:rtp:rtcp-fb:0', value: tmp.params[0]});
elem.up();
@@ -237,9 +242,9 @@ SDP.prototype.RtcpFbToJingle = function(sdp, elem, payloadtype) { // XEP-0293
}
};
-SDP.prototype.RtcpFbFromJingle = function(elem, payloadtype) { // XEP-0293
+SDP.prototype.RtcpFbFromJingle = function (elem, payloadtype) { // XEP-0293
var media = '';
- tmp = elem.find('>rtcp-fb-trr-int[xmlns="urn:xmpp:jingle:apps:rtp:rtcp-fb:0"]');
+ var tmp = elem.find('>rtcp-fb-trr-int[xmlns="urn:xmpp:jingle:apps:rtp:rtcp-fb:0"]');
if (tmp.length) {
media += 'a=rtcp-fb:' + '*' + ' ' + 'trr-int' + ' ';
if (tmp.attr('value')) {
@@ -250,7 +255,7 @@ SDP.prototype.RtcpFbFromJingle = function(elem, payloadtype) { // XEP-0293
media += '\r\n';
}
tmp = elem.find('>rtcp-fb[xmlns="urn:xmpp:jingle:apps:rtp:rtcp-fb:0"]');
- tmp.each(function() {
+ tmp.each(function () {
media += 'a=rtcp-fb:' + payloadtype + ' ' + $(this).attr('type');
if ($(this).attr('subtype')) {
media += ' ' + $(this).attr('subtype');
@@ -261,7 +266,7 @@ SDP.prototype.RtcpFbFromJingle = function(elem, payloadtype) { // XEP-0293
};
// construct an SDP from a jingle stanza
-SDP.prototype.fromJingle = function(jingle) {
+SDP.prototype.fromJingle = function (jingle) {
var obj = this;
this.raw = 'v=0\r\n' +
'o=- ' + '1923518516' + ' 2 IN IP4 0.0.0.0\r\n' +// FIXME
@@ -269,22 +274,22 @@ SDP.prototype.fromJingle = function(jingle) {
't=0 0\r\n';
// http://tools.ietf.org/html/draft-ietf-mmusic-sdp-bundle-negotiation-04#section-8
if ($(jingle).find('>group[xmlns="urn:ietf:rfc:5888"]').length) {
- $(jingle).find('>group[xmlns="urn:ietf:rfc:5888"]').each(function(idx, group) {
- var contents = $(group).find('>content').map(function(idx, content) {
- return $(content).attr('name');
+ $(jingle).find('>group[xmlns="urn:ietf:rfc:5888"]').each(function (idx, group) {
+ var contents = $(group).find('>content').map(function (idx, content) {
+ return $(content).attr('name');
}).get();
- if ($(group).attr('type') != null && contents.length > 0) {
+ if ($(group).attr('type') !== null && contents.length > 0) {
obj.raw += 'a=group:' + $(group).attr('type') + ' ' + contents.join(' ') + '\r\n';
}
});
} else {
// for backward compability, to be removed soon
// assume all contents are in the same bundle group, can be improved upon later
- var bundle = $(jingle).find('>content').filter(function(idx, content) {
+ var bundle = $(jingle).find('>content').filter(function (idx, content) {
//elem.c('bundle', {xmlns:'http://estos.de/ns/bundle'});
return $(content).find('>bundle').length > 0;
- }).map(function(idx, content) {
- return $(content).attr('name');
+ }).map(function (idx, content) {
+ return $(content).attr('name');
}).get();
if (bundle.length) {
this.raw += 'a=group:BUNDLE ' + bundle.join(' ') + '\r\n';
@@ -292,8 +297,8 @@ SDP.prototype.fromJingle = function(jingle) {
}
this.session = this.raw;
- jingle.find('>content').each(function() {
- var m = obj.jingle2media($(this));
+ jingle.find('>content').each(function () {
+ var m = obj.jingle2media($(this));
obj.media.push(m);
});
@@ -309,7 +314,7 @@ SDP.prototype.fromJingle = function(jingle) {
};
// translate a jingle content element into an an SDP media part
-SDP.prototype.jingle2media = function(content) {
+SDP.prototype.jingle2media = function (content) {
var media = '',
desc = content.find('description'),
ssrc = desc.attr('ssrc'),
@@ -320,14 +325,14 @@ SDP.prototype.jingle2media = function(content) {
tmp.port = '1';
if (content.attr('senders') == 'rejected') {
// estos hack to reject an m-line.
- tmp.port = '0';
+ tmp.port = '0';
}
if (content.find('>transport>fingerprint').length || desc.find('encryption').length) {
tmp.proto = 'RTP/SAVPF';
} else {
tmp.proto = 'RTP/AVPF';
}
- tmp.fmt = desc.find('payload-type').map(function() { return $(this).attr('id'); }).get();
+ tmp.fmt = desc.find('payload-type').map(function () { return $(this).attr('id'); }).get();
media += SDPUtil.build_mline(tmp) + '\r\n';
media += 'c=IN IP4 0.0.0.0\r\n';
media += 'a=rtcp:1 IN IP4 0.0.0.0\r\n';
@@ -339,7 +344,7 @@ SDP.prototype.jingle2media = function(content) {
if (tmp.attr('pwd')) {
media += SDPUtil.build_icepwd(tmp.attr('pwd')) + '\r\n';
}
- tmp.find('>fingerprint').each(function() {
+ tmp.find('>fingerprint').each(function () {
// FIXME: check namespace at some point
media += 'a=fingerprint:' + $(this).attr('hash');
media += ' ' + $(this).text();
@@ -360,7 +365,6 @@ SDP.prototype.jingle2media = function(content) {
media += 'a=inactive\r\n';
break;
case 'both':
- default:
media += 'a=sendrecv\r\n';
break;
}
@@ -374,7 +378,7 @@ SDP.prototype.jingle2media = function(content) {
}
if (desc.find('encryption').length) {
- desc.find('encryption>crypto').each(function() {
+ desc.find('encryption>crypto').each(function () {
media += 'a=crypto:' + $(this).attr('tag');
media += ' ' + $(this).attr('crypto-suite');
media += ' ' + $(this).attr('key-params');
@@ -384,11 +388,11 @@ SDP.prototype.jingle2media = function(content) {
media += '\r\n';
});
}
- desc.find('payload-type').each(function() {
+ desc.find('payload-type').each(function () {
media += SDPUtil.build_rtpmap(this) + '\r\n';
if ($(this).find('>parameter').length) {
media += 'a=fmtp:' + $(this).attr('id') + ' ';
- media += $(this).find('parameter').map(function() { return ($(this).attr('name') ? ($(this).attr('name') + '=') : '') + $(this).attr('value'); }).get().join(';');
+ media += $(this).find('parameter').map(function () { return ($(this).attr('name') ? ($(this).attr('name') + '=') : '') + $(this).attr('value'); }).get().join(';');
media += '\r\n';
}
// xep-0293
@@ -400,18 +404,18 @@ SDP.prototype.jingle2media = function(content) {
// xep-0294
tmp = desc.find('>rtp-hdrext[xmlns="urn:xmpp:jingle:apps:rtp:rtp-hdrext:0"]');
- tmp.each(function() {
+ tmp.each(function () {
media += 'a=extmap:' + $(this).attr('id') + ' ' + $(this).attr('uri') + '\r\n';
});
- content.find('>transport[xmlns="urn:xmpp:jingle:transports:ice-udp:1"]>candidate').each(function() {
+ content.find('>transport[xmlns="urn:xmpp:jingle:transports:ice-udp:1"]>candidate').each(function () {
media += SDPUtil.candidateFromJingle(this);
});
tmp = content.find('description>source[xmlns="urn:xmpp:jingle:apps:rtp:ssma:0"]');
- tmp.each(function() {
+ tmp.each(function () {
var ssrc = $(this).attr('ssrc');
- $(this).find('>parameter').each(function() {
+ $(this).find('>parameter').each(function () {
media += 'a=ssrc:' + ssrc + ' ' + $(this).attr('name');
if ($(this).attr('value') && $(this).attr('value').length)
media += ':' + $(this).attr('value');
@@ -419,7 +423,7 @@ SDP.prototype.jingle2media = function(content) {
});
});
- if (tmp.length == 0) {
+ if (tmp.length === 0) {
// fallback to proprietary mapping of a=ssrc lines
tmp = content.find('description>ssrc[xmlns="http://estos.de/ns/ssrc"]');
if (tmp.length) {
@@ -433,48 +437,48 @@ SDP.prototype.jingle2media = function(content) {
};
SDPUtil = {
- iceparams: function(mediadesc, sessiondesc) {
+ iceparams: function (mediadesc, sessiondesc) {
var data = null;
if (SDPUtil.find_line(mediadesc, 'a=ice-ufrag:', sessiondesc) &&
SDPUtil.find_line(mediadesc, 'a=ice-pwd:', sessiondesc)) {
data = {
ufrag: SDPUtil.parse_iceufrag(SDPUtil.find_line(mediadesc, 'a=ice-ufrag:', sessiondesc)),
pwd: SDPUtil.parse_icepwd(SDPUtil.find_line(mediadesc, 'a=ice-pwd:', sessiondesc))
- }
+ };
}
return data;
},
- parse_iceufrag: function(line) {
+ parse_iceufrag: function (line) {
return line.substring(12);
},
- build_iceufrag: function(frag) {
+ build_iceufrag: function (frag) {
return 'a=ice-ufrag:' + frag;
},
- parse_icepwd: function(line) {
+ parse_icepwd: function (line) {
return line.substring(10);
},
- build_icepwd: function(pwd) {
+ build_icepwd: function (pwd) {
return 'a=ice-pwd:' + pwd;
},
- parse_mid: function(line) {
+ parse_mid: function (line) {
return line.substring(6);
},
- parse_mline: function(line) {
+ parse_mline: function (line) {
var parts = line.substring(2).split(' '),
data = {};
data.media = parts.shift();
data.port = parts.shift();
data.proto = parts.shift();
- if (parts[parts.length - 1] == '') { // trailing whitespace
+ if (parts[parts.length - 1] === '') { // trailing whitespace
parts.pop();
}
data.fmt = parts;
return data;
},
- build_mline: function(mline) {
+ build_mline: function (mline) {
return 'm=' + mline.media + ' ' + mline.port + ' ' + mline.proto + ' ' + mline.fmt.join(' ');
},
- parse_rtpmap: function(line) {
+ parse_rtpmap: function (line) {
var parts = line.substring(9).split(' '),
data = {};
data.id = parts.shift();
@@ -484,14 +488,14 @@ SDPUtil = {
data.channels = parts.length ? parts.shift() : '1';
return data;
},
- build_rtpmap: function(el) {
+ build_rtpmap: function (el) {
var line = 'a=rtpmap:' + $(el).attr('id') + ' ' + $(el).attr('name') + '/' + $(el).attr('clockrate');
if ($(el).attr('channels') && $(el).attr('channels') != '1') {
line += '/' + $(el).attr('channels');
}
return line;
},
- parse_crypto: function(line) {
+ parse_crypto: function (line) {
var parts = line.substring(9).split(' '),
data = {};
data.tag = parts.shift();
@@ -502,7 +506,7 @@ SDPUtil = {
}
return data;
},
- parse_fingerprint: function(line) { // RFC 4572
+ parse_fingerprint: function (line) { // RFC 4572
var parts = line.substring(14).split(' '),
data = {};
data.hash = parts.shift();
@@ -510,7 +514,7 @@ SDPUtil = {
// TODO assert that fingerprint satisfies 2UHEX *(":" 2UHEX) ?
return data;
},
- parse_fmtp: function(line) {
+ parse_fmtp: function (line) {
var parts = line.split(' '),
i, key, value,
data = [];
@@ -531,7 +535,7 @@ SDPUtil = {
}
return data;
},
- parse_icecandidate: function(line) {
+ parse_icecandidate: function (line) {
var candidate = {},
elems = line.split(' ');
candidate.foundation = elems[0].substring(12);
@@ -561,7 +565,7 @@ SDPUtil = {
candidate.id = Math.random().toString(36).substr(2, 10); // not applicable to SDP -- FIXME: should be unique, not just random
return candidate;
},
- build_icecandidate: function(cand) {
+ build_icecandidate: function (cand) {
var line = ['a=candidate:' + cand.foundation, cand.component, cand.protocol, cand.priority, cand.ip, cand.port, 'typ', cand.type].join(' ');
line += ' ';
switch (cand.type) {
@@ -585,7 +589,7 @@ SDPUtil = {
line += cand.hasOwnAttribute('generation') ? cand.generation : '0';
return line;
},
- parse_ssrc: function(desc) {
+ parse_ssrc: function (desc) {
// proprietary mapping of a=ssrc lines
// TODO: see "Jingle RTP Source Description" by Juberti and P. Thatcher on google docs
// and parse according to that
@@ -599,7 +603,7 @@ SDPUtil = {
}
return data;
},
- parse_rtcpfb: function(line) {
+ parse_rtcpfb: function (line) {
var parts = line.substr(10).split(' ');
var data = {};
data.pt = parts.shift();
@@ -607,7 +611,7 @@ SDPUtil = {
data.params = parts;
return data;
},
- parse_extmap: function(line) {
+ parse_extmap: function (line) {
var parts = line.substr(9).split(' ');
var data = {};
data.value = parts.shift();
@@ -621,7 +625,7 @@ SDPUtil = {
data.params = parts;
return data;
},
- find_line: function(haystack, needle, sessionpart) {
+ find_line: function (haystack, needle, sessionpart) {
var lines = haystack.split('\r\n');
for (var i = 0; i < lines.length; i++) {
if (lines[i].substring(0, needle.length) == needle) {
@@ -633,16 +637,16 @@ SDPUtil = {
}
// search session part
lines = sessionpart.split('\r\n');
- for (var i = 0; i < lines.length; i++) {
- if (lines[i].substring(0, needle.length) == needle) {
- return lines[i];
+ for (var j = 0; j < lines.length; j++) {
+ if (lines[j].substring(0, needle.length) == needle) {
+ return lines[j];
}
}
return false;
},
- find_lines: function(haystack, needle, sessionpart) {
+ find_lines: function (haystack, needle, sessionpart) {
var lines = haystack.split('\r\n'),
- needles = new Array();
+ needles = [];
for (var i = 0; i < lines.length; i++) {
if (lines[i].substring(0, needle.length) == needle)
needles.push(lines[i]);
@@ -652,14 +656,14 @@ SDPUtil = {
}
// search session part
lines = sessionpart.split('\r\n');
- for (var i = 0; i < lines.length; i++) {
- if (lines[i].substring(0, needle.length) == needle) {
- needles.push(lines[i]);
+ for (var j = 0; j < lines.length; j++) {
+ if (lines[j].substring(0, needle.length) == needle) {
+ needles.push(lines[j]);
}
}
return needles;
},
- candidateToJingle: function(line) {
+ candidateToJingle: function (line) {
// a=candidate:2979166662 1 udp 2113937151 192.168.2.100 57698 typ host generation 0
//
if (line.substring(0, 12) != 'a=candidate:') {
@@ -704,7 +708,7 @@ SDPUtil = {
candidate.id = Math.random().toString(36).substr(2, 10); // not applicable to SDP -- FIXME: should be unique, not just random
return candidate;
},
- candidateFromJingle: function(cand) {
+ candidateFromJingle: function (cand) {
var line = 'a=candidate:';
line += cand.getAttribute('foundation');
line += ' ';
diff --git a/strophe.jingle.session.js b/strophe.jingle.session.js
index 9e380ef..96790d1 100644
--- a/strophe.jingle.session.js
+++ b/strophe.jingle.session.js
@@ -1,3 +1,4 @@
+/* jshint -W117 */
// Jingle stuff
function JingleSession(me, sid, connection) {
this.me = me;
@@ -33,9 +34,9 @@ function JingleSession(me, sid, connection) {
this.reason = null;
}
-JingleSession.prototype.initiate = function(peerjid, isInitiator) {
+JingleSession.prototype.initiate = function (peerjid, isInitiator) {
var obj = this;
- if (this.state != null) {
+ if (this.state !== null) {
console.error('attempt to initiate on session ' + this.sid +
'in state ' + this.state);
return;
@@ -59,22 +60,22 @@ JingleSession.prototype.initiate = function(peerjid, isInitiator) {
this.hadstuncandidate = false;
this.hadturncandidate = false;
this.lasticecandidate = false;
- this.peerconnection.onicecandidate = function(event) {
+ this.peerconnection.onicecandidate = function (event) {
obj.sendIceCandidate(event.candidate);
};
- this.peerconnection.onaddstream = function(event) {
+ this.peerconnection.onaddstream = function (event) {
obj.remoteStream = event.stream;
$(document).trigger('remotestreamadded.jingle', [event, obj.sid]);
};
- this.peerconnection.onremovestream = function(event) {
+ this.peerconnection.onremovestream = function (event) {
obj.remoteStream = null;
$(document).trigger('remotestreamremoved.jingle', [event, obj.sid]);
};
- this.peerconnection.onsignalingstatechange = function(event) {
+ this.peerconnection.onsignalingstatechange = function (event) {
if (!(obj && obj.peerconnection)) return;
console.log('signallingstate ', obj.peerconnection.signalingState, event);
};
- this.peerconnection.oniceconnectionstatechange = function(event) {
+ this.peerconnection.oniceconnectionstatechange = function (event) {
if (!(obj && obj.peerconnection)) return;
console.log('iceconnectionstatechange', obj.peerconnection.iceConnectionState, event);
switch (obj.peerconnection.iceConnectionState) {
@@ -87,14 +88,14 @@ JingleSession.prototype.initiate = function(peerjid, isInitiator) {
}
$(document).trigger('iceconnectionstatechange.jingle', [obj.sid, obj]);
};
- if (this.localStream != null) {
+ if (this.localStream !== null) {
this.peerconnection.addStream(this.localStream);
} else {
console.warn('attempting to initate a jingle session without a local stream');
}
};
-JingleSession.prototype.accept = function() {
+JingleSession.prototype.accept = function () {
var ob = this;
this.state = 'active';
@@ -124,19 +125,19 @@ JingleSession.prototype.accept = function() {
sid: this.sid });
prsdp.toJingle(accept, this.initiator == this.me ? 'initiator' : 'responder');
this.connection.sendIQ(accept,
- function() {
+ function () {
var ack = {};
ack.source = 'answer';
$(document).trigger('ack.jingle', [ob.sid, ack]);
- },
- function(stanza) {
+ },
+ function (stanza) {
var error = ($(stanza).find('error').length) ? {
code: $(stanza).find('error').attr('code'),
reason: $(stanza).find('error :first')[0].tagName,
}:{};
error.source = 'answer';
$(document).trigger('error.jingle', [ob.sid, error]);
- },
+ },
10000);
var sdp = this.peerconnection.localDescription.sdp;
@@ -144,30 +145,32 @@ JingleSession.prototype.accept = function() {
// FIXME: change any inactive to sendrecv or whatever they were originally
sdp = sdp.replace('a=inactive', 'a=sendrecv');
}
- this.peerconnection.setLocalDescription(new RTCSessionDescription({type: 'answer', sdp: sdp}),
- function() {
+ this.peerconnection.setLocalDescription(new RTCSessionDescription({type: 'answer', sdp: sdp}),
+ function () {
console.log('setLocalDescription success');
- }, function(e) {
+ },
+ function (e) {
console.error('setLocalDescription failed', e);
- });
+ }
+ );
};
-JingleSession.prototype.terminate = function(reason) {
+JingleSession.prototype.terminate = function (reason) {
this.state = 'ended';
this.reason = reason;
this.peerconnection.close();
- if (this.statsinterval != null) {
+ if (this.statsinterval !== null) {
window.clearInterval(this.statsinterval);
this.statsinterval = null;
}
};
-JingleSession.prototype.active = function() {
+JingleSession.prototype.active = function () {
return this.state == 'active';
};
-JingleSession.prototype.sendIceCandidate = function(candidate) {
- var ob = this;
+JingleSession.prototype.sendIceCandidate = function (candidate) {
+ var ob = this;
if (candidate && !this.lasticecandidate) {
var ice = SDPUtil.iceparams(this.localSDP.media[candidate.sdpMLineIndex], this.localSDP.session),
jcand = SDPUtil.candidateToJingle(candidate.candidate);
@@ -186,10 +189,10 @@ JingleSession.prototype.sendIceCandidate = function(candidate) {
if (this.usetrickle) {
if (this.usedrip) {
- if (this.drip_container.length == 0) {
+ if (this.drip_container.length === 0) {
// start 10ms callout
- window.setTimeout(function() {
- if (ob.drip_container.length == 0) return;
+ window.setTimeout(function () {
+ if (ob.drip_container.length === 0) return;
var allcands = ob.drip_container;
ob.drip_container = [];
var cand = $iq({to: ob.peerjid, type: 'set'})
@@ -198,7 +201,7 @@ JingleSession.prototype.sendIceCandidate = function(candidate) {
initiator: ob.initiator,
sid: ob.sid});
for (var mid = 0; mid < ob.localSDP.media.length; mid++) {
- var cands = allcands.filter(function(el) { return el.sdpMLineIndex == mid; });
+ var cands = allcands.filter(function (el) { return el.sdpMLineIndex == mid; });
if (cands.length > 0) {
var ice = SDPUtil.iceparams(ob.localSDP.media[mid], ob.localSDP.session);
ice.xmlns = 'urn:xmpp:jingle:transports:ice-udp:1';
@@ -224,12 +227,12 @@ JingleSession.prototype.sendIceCandidate = function(candidate) {
// might merge last-candidate notification into this, but it is called alot later. See webrtc issue #2340
//console.log('was this the last candidate', ob.lasticecandidate);
ob.connection.sendIQ(cand,
- function() {
+ function () {
var ack = {};
ack.source = 'transportinfo';
$(document).trigger('ack.jingle', [ob.sid, ack]);
},
- function(stanza) {
+ function (stanza) {
var error = ($(stanza).find('error').length) ? {
code: $(stanza).find('error').attr('code'),
reason: $(stanza).find('error :first')[0].tagName,
@@ -265,13 +268,13 @@ JingleSession.prototype.sendIceCandidate = function(candidate) {
cand.up();
}
this.connection.sendIQ(cand,
- function() {
- var ack = {};
- ack.source = 'transportinfo';
- $(document).trigger('ack.jingle', [ob.sid, ack]);
- },
- function(stanza) {
- console.error('transport info error');
+ function () {
+ var ack = {};
+ ack.source = 'transportinfo';
+ $(document).trigger('ack.jingle', [ob.sid, ack]);
+ },
+ function (stanza) {
+ console.error('transport info error');
var error = ($(stanza).find('error').length) ? {
code: $(stanza).find('error').attr('code'),
reason: $(stanza).find('error :first')[0].tagName,
@@ -294,13 +297,13 @@ JingleSession.prototype.sendIceCandidate = function(candidate) {
this.localSDP = new SDP(this.peerconnection.localDescription.sdp);
this.localSDP.toJingle(init, this.initiator == this.me ? 'initiator' : 'responder');
this.connection.sendIQ(init,
- function() {
+ function () {
console.log('session initiate ack');
- var ack = {};
- ack.source = 'offer';
- $(document).trigger('ack.jingle', [ob.sid, ack]);
+ var ack = {};
+ ack.source = 'offer';
+ $(document).trigger('ack.jingle', [ob.sid, ack]);
},
- function(stanza) {
+ function (stanza) {
ob.state = 'error';
ob.peerconnection.close();
var error = ($(stanza).find('error').length) ? {
@@ -322,20 +325,20 @@ JingleSession.prototype.sendIceCandidate = function(candidate) {
}
};
-JingleSession.prototype.sendOffer = function() {
+JingleSession.prototype.sendOffer = function () {
console.log('sendOffer...');
var ob = this;
- this.peerconnection.createOffer(function(sdp) {
+ this.peerconnection.createOffer(function (sdp) {
ob.createdOffer(sdp);
},
- function(e) {
+ function (e) {
console.error('createOffer failed', e);
},
this.media_constraints
);
};
-JingleSession.prototype.createdOffer = function(sdp) {
+JingleSession.prototype.createdOffer = function (sdp) {
console.log('createdOffer', sdp);
var ob = this;
this.localSDP = new SDP(sdp.sdp);
@@ -349,12 +352,12 @@ JingleSession.prototype.createdOffer = function(sdp) {
sid: this.sid});
this.localSDP.toJingle(init, this.initiator == this.me ? 'initiator' : 'responder');
this.connection.sendIQ(init,
- function() {
+ function () {
var ack = {};
ack.source = 'offer';
$(document).trigger('ack.jingle', [ob.sid, ack]);
},
- function(stanza) {
+ function (stanza) {
ob.state = 'error';
ob.peerconnection.close();
var error = ($(stanza).find('error').length) ? {
@@ -367,11 +370,13 @@ JingleSession.prototype.createdOffer = function(sdp) {
10000);
}
sdp.sdp = this.localSDP.raw;
- this.peerconnection.setLocalDescription(sdp, function() {
+ this.peerconnection.setLocalDescription(sdp, function () {
console.log('setLocalDescription success');
- }, function(e) {
+ },
+ function (e) {
console.error('setLocalDescription failed', e);
- });
+ }
+ );
var cands = SDPUtil.find_lines(this.localSDP.raw, 'a=candidate:');
for (var i = 0; i < cands.length; i++) {
var cand = SDPUtil.parse_icecandidate(cands[i]);
@@ -383,11 +388,11 @@ JingleSession.prototype.createdOffer = function(sdp) {
}
};
-JingleSession.prototype.setRemoteDescription = function(elem, desctype) {
+JingleSession.prototype.setRemoteDescription = function (elem, desctype) {
console.log('setting remote description... ', desctype);
this.remoteSDP = new SDP('');
this.remoteSDP.fromJingle(elem);
- 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);
if (this.peerconnection.remoteDescription.type == 'pranswer') {
var pranswer = new SDP(this.peerconnection.remoteDescription.sdp);
@@ -416,14 +421,17 @@ JingleSession.prototype.setRemoteDescription = function(elem, desctype) {
}
var remotedesc = new RTCSessionDescription({type: desctype, sdp: this.remoteSDP.raw});
- this.peerconnection.setRemoteDescription(remotedesc, function() {
- console.log('setRemoteDescription success');
- }, function(e){
- console.error('setRemoteDescription error', e);
- });
+ this.peerconnection.setRemoteDescription(remotedesc,
+ function () {
+ console.log('setRemoteDescription success');
+ },
+ function (e) {
+ console.error('setRemoteDescription error', e);
+ }
+ );
};
-JingleSession.prototype.addIceCandidate = function(elem) {
+JingleSession.prototype.addIceCandidate = function (elem) {
var obj = this;
if (this.peerconnection.signalingState == 'closed') {
return;
@@ -448,10 +456,10 @@ JingleSession.prototype.addIceCandidate = function(elem) {
this.remoteSDP = new SDP(cobbled);
}
// then add things like ice and dtls from remote candidate
- elem.each(function() {
+ elem.each(function () {
for (var i = 0; i < obj.remoteSDP.media.length; i++) {
if (SDPUtil.find_line(obj.remoteSDP.media[i], 'a=mid:' + $(this).attr('name')) ||
- obj.remoteSDP.media[i].indexOf('m=' + $(this).attr('name')) == 0) {
+ obj.remoteSDP.media[i].indexOf('m=' + $(this).attr('name')) === 0) {
if (!SDPUtil.find_line(obj.remoteSDP.media[i], 'a=ice-ufrag:')) {
var tmp = $(this).find('transport');
obj.remoteSDP.media[i] += 'a=ice-ufrag:' + tmp.attr('ufrag') + '\r\n';
@@ -473,7 +481,7 @@ JingleSession.prototype.addIceCandidate = function(elem) {
// we need a complete SDP with ice-ufrag/ice-pwd in all parts
// this makes the assumption that the PRANSWER is constructed such that the ice-ufrag is in all mediaparts
// but it could be in the session part as well. since the code above constructs this sdp this can't happen however
- var iscomplete = this.remoteSDP.media.filter(function(mediapart) {
+ var iscomplete = this.remoteSDP.media.filter(function (mediapart) {
return SDPUtil.find_line(mediapart, 'a=ice-ufrag:');
}).length == this.remoteSDP.media.length;
@@ -489,13 +497,13 @@ JingleSession.prototype.addIceCandidate = function(elem) {
}
}
// operate on each content element
- elem.each(function() {
+ elem.each(function () {
// would love to deactivate this, but firefox still requires it
var idx = -1;
var i;
for (i = 0; i < obj.remoteSDP.media.length; i++) {
if (SDPUtil.find_line(obj.remoteSDP.media[i], 'a=mid:' + $(this).attr('name')) ||
- obj.remoteSDP.media[i].indexOf('m=' + $(this).attr('name')) == 0) {
+ obj.remoteSDP.media[i].indexOf('m=' + $(this).attr('name')) === 0) {
idx = i;
break;
}
@@ -503,7 +511,7 @@ JingleSession.prototype.addIceCandidate = function(elem) {
if (idx == -1) { // fall back to localdescription
for (i = 0; i < obj.localSDP.media.length; i++) {
if (SDPUtil.find_line(obj.localSDP.media[i], 'a=mid:' + $(this).attr('name')) ||
- obj.localSDP.media[i].indexOf('m=' + $(this).attr('name')) == 0) {
+ obj.localSDP.media[i].indexOf('m=' + $(this).attr('name')) === 0) {
idx = i;
break;
}
@@ -511,43 +519,42 @@ JingleSession.prototype.addIceCandidate = function(elem) {
}
var name = $(this).attr('name');
// TODO: check ice-pwd and ice-ufrag?
- $(this).find('transport>candidate').each(function() {
+ $(this).find('transport>candidate').each(function () {
var line, candidate;
line = SDPUtil.candidateFromJingle(this);
candidate = new RTCIceCandidate({sdpMLineIndex: idx,
sdpMid: name,
candidate: line});
- console.log(candidate);
try {
- obj.peerconnection.addIceCandidate(candidate);
+ obj.peerconnection.addIceCandidate(candidate);
} catch (e) {
- console.error('addIceCandidate failed', e.toString(), line);
+ console.error('addIceCandidate failed', e.toString(), line);
}
- });
+ });
});
};
-JingleSession.prototype.sendAnswer = function(provisional) {
+JingleSession.prototype.sendAnswer = function (provisional) {
console.log('createAnswer', provisional);
var ob = this;
this.peerconnection.createAnswer(
- function(sdp) {
+ function (sdp) {
ob.createdAnswer(sdp, provisional);
},
- function(e) {
+ function (e) {
console.error('createAnswer failed', e);
},
this.media_constraints
);
};
-JingleSession.prototype.createdAnswer = function(sdp, provisional) {
+JingleSession.prototype.createdAnswer = function (sdp, provisional) {
console.log('createAnswer callback');
console.log(sdp);
var ob = this;
this.localSDP = new SDP(sdp.sdp);
//this.localSDP.mangle();
- this.usepranswer = provisional == true;
+ this.usepranswer = provisional === true;
if (this.usetrickle) {
if (!this.usepranswer) {
var accept = $iq({to: this.peerjid,
@@ -559,12 +566,12 @@ JingleSession.prototype.createdAnswer = function(sdp, provisional) {
sid: this.sid });
this.localSDP.toJingle(accept, this.initiator == this.me ? 'initiator' : 'responder');
this.connection.sendIQ(accept,
- function() {
+ function () {
var ack = {};
ack.source = 'answer';
$(document).trigger('ack.jingle', [ob.sid, ack]);
},
- function(stanza) {
+ function (stanza) {
var error = ($(stanza).find('error').length) ? {
code: $(stanza).find('error').attr('code'),
reason: $(stanza).find('error :first')[0].tagName,
@@ -575,21 +582,24 @@ JingleSession.prototype.createdAnswer = function(sdp, provisional) {
10000);
} else {
sdp.type = 'pranswer';
- for (i = 0; i < this.localSDP.media.length; i++) {
+ for (var i = 0; i < this.localSDP.media.length; i++) {
this.localSDP.media[i] = this.localSDP.media[i].replace('a=sendrecv\r\n', 'a=inactive\r\n');
}
this.localSDP.raw = this.localSDP.session + '\r\n' + this.localSDP.media.join('');
}
}
sdp.sdp = this.localSDP.raw;
- this.peerconnection.setLocalDescription(sdp, function() {
+ this.peerconnection.setLocalDescription(sdp,
+ function () {
console.log('setLocalDescription success');
- }, function(e) {
+ },
+ function (e) {
console.error('setLocalDescription failed', e);
- });
+ }
+ );
var cands = SDPUtil.find_lines(this.localSDP.raw, 'a=candidate:');
- for (var i = 0; i < cands.length; i++) {
- var cand = SDPUtil.parse_icecandidate(cands[i]);
+ for (var j = 0; j < cands.length; j++) {
+ var cand = SDPUtil.parse_icecandidate(cands[j]);
if (cand.type == 'srflx') {
this.hadstuncandidate = true;
} else if (cand.type == 'relay') {
@@ -598,7 +608,7 @@ JingleSession.prototype.createdAnswer = function(sdp, provisional) {
}
};
-JingleSession.prototype.sendTerminate = function(reason, text) {
+JingleSession.prototype.sendTerminate = function (reason, text) {
var obj = this,
term = $iq({to: this.peerjid,
type: 'set'})
@@ -609,11 +619,12 @@ JingleSession.prototype.sendTerminate = function(reason, text) {
.c('reason')
.c(reason || 'success');
- if(text)
+ if (text) {
term.up().c('text').t(text);
+ }
this.connection.sendIQ(term,
- function() {
+ function () {
obj.peerconnection.close();
obj.peerconnection = null;
obj.terminate();
@@ -621,7 +632,7 @@ JingleSession.prototype.sendTerminate = function(reason, text) {
ack.source = 'terminate';
$(document).trigger('ack.jingle', [ob.sid, ack]);
},
- function(stanza) {
+ function (stanza) {
var error = ($(stanza).find('error').length) ? {
code: $(stanza).find('error').attr('code'),
reason: $(stanza).find('error :first')[0].tagName,
@@ -629,13 +640,13 @@ JingleSession.prototype.sendTerminate = function(reason, text) {
$(document).trigger('ack.jingle', [ob.sid, error]);
},
10000);
- if (this.statsinterval != null) {
+ if (this.statsinterval !== null) {
window.clearInterval(this.statsinterval);
this.statsinterval = null;
}
};
-JingleSession.prototype.sendMute = function(muted, content) {
+JingleSession.prototype.sendMute = function (muted, content) {
var info = $iq({to: this.peerjid,
type: 'set'})
.c('jingle', {xmlns: 'urn:xmpp:jingle:1',
@@ -650,7 +661,7 @@ JingleSession.prototype.sendMute = function(muted, content) {
this.connection.send(info);
};
-JingleSession.prototype.sendRinging = function() {
+JingleSession.prototype.sendRinging = function () {
var info = $iq({to: this.peerjid,
type: 'set'})
.c('jingle', {xmlns: 'urn:xmpp:jingle:1',
@@ -661,17 +672,17 @@ JingleSession.prototype.sendRinging = function() {
this.connection.send(info);
};
-JingleSession.prototype.getStats = function(interval) {
+JingleSession.prototype.getStats = function (interval) {
var ob = this;
var recv = {audio: 0, video: 0};
- var lost = {audio: 0, video: 0}
+ var lost = {audio: 0, video: 0};
var lastrecv = {audio: 0, video: 0};
var lastlost = {audio: 0, video: 0};
var loss = {audio: 0, video: 0};
var delta = {audio: 0, video: 0};
- this.statsinterval = window.setInterval(function() {
+ this.statsinterval = window.setInterval(function () {
if (ob && ob.peerconnection && ob.peerconnection.getStats) {
- ob.peerconnection.getStats(function(stats) {
+ ob.peerconnection.getStats(function (stats) {
var results = stats.result();
// TODO: there are so much statistics you can get from this..
for (var i = 0; i < results.length; ++i) {
@@ -679,8 +690,8 @@ JingleSession.prototype.getStats = function(interval) {
var packetsrecv = results[i].stat('packetsReceived');
var packetslost = results[i].stat('packetsLost');
if (packetsrecv && packetslost) {
- packetsrecv = parseInt(packetsrecv);
- packetslost = parseInt(packetslost);
+ packetsrecv = parseInt(packetsrecv, 10);
+ packetslost = parseInt(packetslost, 10);
if (results[i].stat('googFrameRateReceived')) {
lastlost.video = lost.video;
@@ -693,13 +704,13 @@ JingleSession.prototype.getStats = function(interval) {
recv.audio = packetsrecv;
lost.audio = packetslost;
}
- }
+ }
}
}
delta.audio = recv.audio - lastrecv.audio;
delta.video = recv.video - lastrecv.video;
- loss.audio = (delta.audio > 0) ? Math.ceil(100*(lost.audio - lastlost.audio)/delta.audio) : 0;
- loss.video = (delta.video > 0) ? Math.ceil(100*(lost.video - lastlost.video)/delta.video) : 0;
+ loss.audio = (delta.audio > 0) ? Math.ceil(100 * (lost.audio - lastlost.audio) / delta.audio) : 0;
+ loss.video = (delta.video > 0) ? Math.ceil(100 * (lost.video - lastlost.video) / delta.video) : 0;
$(document).trigger('packetloss.jingle', [ob.sid, loss]);
});
}