diff --git a/app.js b/app.js index e64038e88..008f04ae2 100644 --- a/app.js +++ b/app.js @@ -58,11 +58,6 @@ function init() { } function connect(jid, password) { - var localAudio, localVideo; - if (connection && connection.jingle) { - localAudio = connection.jingle.localAudio; - localVideo = connection.jingle.localVideo; - } connection = new Strophe.Connection(document.getElementById('boshURL').value || config.bosh || '/http-bind'); var settings = UI.getSettings(); @@ -86,8 +81,6 @@ function connect(jid, password) { if (!connection.jingle.pc_constraints.optional) connection.jingle.pc_constraints.optional = []; connection.jingle.pc_constraints.optional.push({googIPv6: true}); } - if (localAudio) connection.jingle.localAudio = localAudio; - if (localVideo) connection.jingle.localVideo = localVideo; if(!password) password = document.getElementById('password').value; @@ -127,7 +120,7 @@ function connect(jid, password) { function maybeDoJoin() { if (connection && connection.connected && Strophe.getResourceFromJid(connection.jid) // .connected is true while connecting? - && (connection.jingle.localAudio || connection.jingle.localVideo)) { + && (RTC.localAudio || RTC.localVideo)) { doJoin(); } } @@ -300,7 +293,7 @@ function waitForPresence(data, sid) { if (isVideo && data.peerjid && sess.peerjid === data.peerjid && data.stream.getVideoTracks().length === 0 && - connection.jingle.localVideo.getVideoTracks().length > 0) { + RTC.localVideo.getTracks().length > 0) { // window.setTimeout(function () { sendKeyframe(sess.peerconnection); @@ -621,11 +614,9 @@ function isVideoSrcDesktop(jid) { * contrast to an automatic decision taken by the application logic) */ function setVideoMute(mute, options) { - if (connection && connection.jingle.localVideo) { - var session = activecall; - - if (session) { - session.setVideoMute( + if (connection && RTC.localVideo) { + if (activecall) { + activecall.setVideoMute( mute, function (mute) { var video = $('#video'); @@ -659,12 +650,8 @@ $(document).on('inlastnchanged', function (event, oldValue, newValue) { function toggleVideo() { buttonClick("#video", "icon-camera icon-camera-disabled"); - if (connection && connection.jingle.localVideo) { - var session = activecall; - - if (session) { - setVideoMute(!session.isVideoMute()); - } + if (connection && activecall && RTC.localVideo ) { + setVideoMute(!RTC.localVideo.isMuted()); } } @@ -672,14 +659,14 @@ function toggleVideo() { * Mutes / unmutes audio for the local participant. */ function toggleAudio() { - setAudioMuted(!isAudioMuted()); + setAudioMuted(!RTC.localAudio.isMuted()); } /** * Sets muted audio state for the local participant. */ function setAudioMuted(mute) { - if (!(connection && connection.jingle.localAudio)) { + if (!(connection && RTC.localAudio)) { preMuted = mute; // We still click the button. buttonClick("#mute", "icon-microphone icon-mic-disabled"); @@ -693,7 +680,7 @@ function setAudioMuted(mute) { forceMuted = false; } - if (mute == isAudioMuted()) { + if (mute == RTC.localAudio.isMuted()) { // Nothing to do return; } @@ -701,12 +688,7 @@ function setAudioMuted(mute) { // It is not clear what is the right way to handle multiple tracks. // So at least make sure that they are all muted or all unmuted and // that we send presence just once. - var localAudioTracks = connection.jingle.localAudio.getAudioTracks(); - if (localAudioTracks.length > 0) { - for (var idx = 0; idx < localAudioTracks.length; idx++) { - localAudioTracks[idx].enabled = !mute; - } - } + RTC.localAudio.mute(); // isMuted is the opposite of audioEnabled connection.emuc.addAudioInfoToPresence(mute); connection.emuc.sendPresence(); @@ -715,19 +697,6 @@ function setAudioMuted(mute) { buttonClick("#mute", "icon-microphone icon-mic-disabled"); } -/** - * Checks whether the audio is muted or not. - * @returns {boolean} true if audio is muted and false if not. - */ -function isAudioMuted() -{ - var localAudio = connection.jingle.localAudio; - for (var idx = 0; idx < localAudio.getAudioTracks().length; idx++) { - if(localAudio.getAudioTracks()[idx].enabled === true) - return false; - } - return true; -} $(document).ready(function () { @@ -780,11 +749,11 @@ function disposeConference(onUnload) { if (handler && handler.peerconnection) { // FIXME: probably removing streams is not required and close() should // be enough - if (connection.jingle.localAudio) { - handler.peerconnection.removeStream(connection.jingle.localAudio, onUnload); + if (RTC.localAudio) { + handler.peerconnection.removeStream(RTC.localAudio.getOriginalStream(), onUnload); } - if (connection.jingle.localVideo) { - handler.peerconnection.removeStream(connection.jingle.localVideo, onUnload); + if (RTC.localVideo) { + handler.peerconnection.removeStream(RTC.localVideo.getOriginalStream(), onUnload); } handler.peerconnection.close(); } diff --git a/desktopsharing.js b/desktopsharing.js index e07e1fbc9..804c060f8 100644 --- a/desktopsharing.js +++ b/desktopsharing.js @@ -254,9 +254,9 @@ function streamSwitchDone() { function newStreamCreated(stream) { - var oldStream = connection.jingle.localVideo; + var oldStream = RTC.localVideo.getOriginalStream(); - connection.jingle.localVideo = stream; + RTC.localVideo.stream = stream; UI.changeLocalVideo(stream, !isUsingScreenStream); diff --git a/index.html b/index.html index 517d43819..2585c1018 100644 --- a/index.html +++ b/index.html @@ -15,9 +15,9 @@ - - - + + + @@ -29,22 +29,22 @@ - + - + - + - + - + diff --git a/keyboard_shortcut.js b/keyboard_shortcut.js index e27b1fc45..64be13994 100644 --- a/keyboard_shortcut.js +++ b/keyboard_shortcut.js @@ -19,7 +19,7 @@ var KeyboardShortcut = (function(my) { 84: { character: "T", function: function() { - if(!isAudioMuted()) { + if(!RTC.localAudio.isMuted()) { toggleAudio(); } } @@ -52,7 +52,7 @@ var KeyboardShortcut = (function(my) { window.onkeydown = function(e) { if(!($(":focus").is("input[type=text]") || $(":focus").is("input[type=password]") || $(":focus").is("textarea"))) { if(e.which === "T".charCodeAt(0)) { - if(isAudioMuted()) { + if(RTC.localAudio.isMuted()) { toggleAudio(); } } diff --git a/libs/modules/RTC.bundle.js b/libs/modules/RTC.bundle.js index a2187f745..2887a107d 100644 --- a/libs/modules/RTC.bundle.js +++ b/libs/modules/RTC.bundle.js @@ -243,8 +243,20 @@ function LocalStream(stream, type, eventEmitter) this.stream = stream; this.eventEmitter = eventEmitter; this.type = type; - var self = this; + if(type == "audio") + { + this.getTracks = function () { + return self.stream.getAudioTracks(); + }; + } + else + { + this.getTracks = function () { + return self.stream.getVideoTracks(); + }; + } + this.stream.onended = function() { self.streamEnded(); @@ -262,31 +274,32 @@ LocalStream.prototype.getOriginalStream = function() LocalStream.prototype.isAudioStream = function () { return (this.stream.getAudioTracks() && this.stream.getAudioTracks().length > 0); -} +}; LocalStream.prototype.mute = function() { var ismuted = false; - var tracks = []; - if(this.type = "audio") - { - tracks = this.stream.getAudioTracks(); - } - else - { - tracks = this.stream.getVideoTracks(); - } + var tracks = this.getTracks(); for (var idx = 0; idx < tracks.length; idx++) { ismuted = !tracks[idx].enabled; - tracks[idx].enabled = !tracks[idx].enabled; + tracks[idx].enabled = ismuted; } return ismuted; -} +}; + +LocalStream.prototype.setMute = function(mute) +{ + var tracks = this.getTracks(); + + for (var idx = 0; idx < tracks.length; idx++) { + tracks[idx].enabled = mute; + } +}; LocalStream.prototype.isMuted = function () { var tracks = []; - if(this.type = "audio") + if(this.type == "audio") { tracks = this.stream.getAudioTracks(); } @@ -301,6 +314,12 @@ LocalStream.prototype.isMuted = function () { return true; } +LocalStream.prototype.getId = function () { + return this.stream.getTracks()[0].id; +} + + + module.exports = LocalStream; },{}],3:[function(require,module,exports){ @@ -394,7 +413,10 @@ var RTC = { createLocalStream: function (stream, type) { var localStream = new LocalStream(stream, type, eventEmitter); - this.localStreams.push(localStream); + //in firefox we have only one stream object + if(this.localStreams.length == 0 || + this.localStreams[0].getOriginalStream() != stream) + this.localStreams.push(localStream); if(type == "audio") { this.localAudio = localStream; @@ -484,6 +506,16 @@ var RTC = { return true; } return false; + }, + switchVideoStreams: function (new_stream) { + this.localVideo.stream = new_stream; + + this.localStreams = []; + + //in firefox we have only one stream object + if(this.localAudio.getOriginalStream() != new_stream) + this.localStreams.push(this.localAudio); + this.localStreams.push(this.localVideo); } }; diff --git a/libs/modules/UI.bundle.js b/libs/modules/UI.bundle.js index 532372636..004a75b2b 100644 --- a/libs/modules/UI.bundle.js +++ b/libs/modules/UI.bundle.js @@ -84,7 +84,7 @@ function registerListeners() { if(jid === statistics.LOCAL_JID) { resourceJid = AudioLevels.LOCAL_LEVEL; - if(isAudioMuted()) + if(RTC.localAudio.isMuted()) { audioLevel = 0; } @@ -4591,12 +4591,10 @@ var VideoLayout = (function (my) { }; my.changeLocalStream = function (stream) { - connection.jingle.localAudio = stream; VideoLayout.changeLocalVideo(stream, true); }; my.changeLocalAudio = function(stream) { - connection.jingle.localAudio = stream; RTC.attachMediaStream($('#localAudio'), stream); document.getElementById('localAudio').autoplay = true; document.getElementById('localAudio').volume = 0; @@ -4607,8 +4605,6 @@ var VideoLayout = (function (my) { }; my.changeLocalVideo = function(stream, flipX) { - connection.jingle.localVideo = stream; - var localVideo = document.createElement('video'); localVideo.id = 'localVideo_' + RTC.getStreamID(stream); localVideo.autoplay = true; diff --git a/libs/modules/simulcast.bundle.js b/libs/modules/simulcast.bundle.js index 36c32d2a8..c6aeb7851 100644 --- a/libs/modules/simulcast.bundle.js +++ b/libs/modules/simulcast.bundle.js @@ -369,7 +369,7 @@ SimulcastSender.prototype.getLocalVideoStream = function () { return (this.displayedLocalVideoStream != null) ? this.displayedLocalVideoStream // in case we have no simulcast at all, i.e. we didn't perform the GUM - : connection.jingle.localVideo; + : RTC.localVideo.getOriginalStream(); }; function NativeSimulcastSender() { diff --git a/libs/strophe/strophe.jingle.js b/libs/strophe/strophe.jingle.js index 652358b51..cbc081798 100644 --- a/libs/strophe/strophe.jingle.js +++ b/libs/strophe/strophe.jingle.js @@ -31,9 +31,6 @@ Strophe.addConnectionPlugin('jingle', { } // MozDontOfferDataChannel: true when this is firefox }, - localAudio: null, - localVideo: null, - init: function (conn) { this.connection = conn; if (this.connection.disco) { @@ -108,13 +105,6 @@ Strophe.addConnectionPlugin('jingle', { sess = new JingleSession($(iq).attr('to'), $(iq).find('jingle').attr('sid'), this.connection); // configure session - //in firefox we have only one stream object - if (this.localAudio != this.localVideo) { - sess.localStreams.push(this.localAudio); - } - if (this.localVideo) { - sess.localStreams.push(this.localVideo); - } sess.media_constraints = this.media_constraints; sess.pc_constraints = this.pc_constraints; sess.ice_config = this.ice_config; @@ -195,13 +185,6 @@ Strophe.addConnectionPlugin('jingle', { this.connection); // configure session - //in firefox we have only one stream - if (this.localAudio != this.localVideo) { - sess.localStreams.push(this.localAudio); - } - if (this.localVideo) { - sess.localStreams.push(this.localVideo); - } sess.media_constraints = this.media_constraints; sess.pc_constraints = this.pc_constraints; sess.ice_config = this.ice_config; diff --git a/libs/strophe/strophe.jingle.sdp.js b/libs/strophe/strophe.jingle.sdp.js index 19f73c62f..03dbceb08 100644 --- a/libs/strophe/strophe.jingle.sdp.js +++ b/libs/strophe/strophe.jingle.sdp.js @@ -396,11 +396,11 @@ SDP.prototype.toJingle = function (elem, thecreator, ssrcs) { var msid = null; if(mline.media == "audio") { - msid = connection.jingle.localAudio.getAudioTracks()[0].id; + msid = RTC.localAudio.getId(); } else { - msid = connection.jingle.localVideo.getVideoTracks()[0].id; + msid = RTC.localVideo.getId(); } if(msid != null) { diff --git a/libs/strophe/strophe.jingle.session.js b/libs/strophe/strophe.jingle.session.js index e8d3f683b..140b406fe 100644 --- a/libs/strophe/strophe.jingle.session.js +++ b/libs/strophe/strophe.jingle.session.js @@ -11,7 +11,6 @@ function JingleSession(me, sid, connection) { this.state = null; this.localSDP = null; this.remoteSDP = null; - this.localStreams = []; this.relayedStreams = []; this.remoteStreams = []; this.startTime = null; @@ -103,8 +102,8 @@ JingleSession.prototype.initiate = function (peerjid, isInitiator) { $(document).trigger('iceconnectionstatechange.jingle', [self.sid, self]); }; // add any local and relayed stream - this.localStreams.forEach(function(stream) { - self.peerconnection.addStream(stream); + RTC.localStreams.forEach(function(stream) { + self.peerconnection.addStream(stream.getOriginalStream()); }); this.relayedStreams.forEach(function(stream) { self.peerconnection.addStream(stream); @@ -934,14 +933,7 @@ JingleSession.prototype.switchStreams = function (new_stream, oldStream, success self.peerconnection.addStream(new_stream); } - self.connection.jingle.localVideo = new_stream; - - self.connection.jingle.localStreams = []; - - //in firefox we have only one stream object - if(self.connection.jingle.localAudio != self.connection.jingle.localVideo) - self.connection.jingle.localStreams.push(self.connection.jingle.localAudio); - self.connection.jingle.localStreams.push(self.connection.jingle.localVideo); + RTC.switchVideoStreams(new_stream, oldStream); // Conference is not active if(!oldSdp || !self.peerconnection) { @@ -1031,7 +1023,7 @@ JingleSession.prototype.notifyMySSRCUpdate = function (old_sdp, new_sdp) { * disabled; otherwise, false */ JingleSession.prototype.isVideoMute = function () { - var tracks = connection.jingle.localVideo.getVideoTracks(); + var tracks = RTC.localVideo.getVideoTracks(); var mute = true; for (var i = 0; i < tracks.length; ++i) { @@ -1075,7 +1067,7 @@ JingleSession.prototype.setVideoMute = function (mute, callback, options) { } else if (this.videoMuteByUser) { return; } - if (mute == this.isVideoMute()) + if (mute == RTC.localVideo.isMuted()) { // Even if no change occurs, the specified callback is to be executed. // The specified callback may, optionally, return a successCallback @@ -1086,11 +1078,7 @@ JingleSession.prototype.setVideoMute = function (mute, callback, options) { successCallback(); } } else { - var tracks = connection.jingle.localVideo.getVideoTracks(); - - for (var i = 0; i < tracks.length; ++i) { - tracks[i].enabled = !mute; - } + RTC.localVideo.setMute(!mute); this.hardMuteVideo(mute); @@ -1101,7 +1089,7 @@ JingleSession.prototype.setVideoMute = function (mute, callback, options) { // SDP-based mute by going recvonly/sendrecv // FIXME: should probably black out the screen as well JingleSession.prototype.toggleVideoMute = function (callback) { - setVideoMute(isVideoMute(), callback); + setVideoMute(RTC.localVideo.isMuted(), callback); }; JingleSession.prototype.hardMuteVideo = function (muted) { diff --git a/modules/RTC/LocalStream.js b/modules/RTC/LocalStream.js index 21829fd09..fdcfcfd8e 100644 --- a/modules/RTC/LocalStream.js +++ b/modules/RTC/LocalStream.js @@ -5,8 +5,20 @@ function LocalStream(stream, type, eventEmitter) this.stream = stream; this.eventEmitter = eventEmitter; this.type = type; - var self = this; + if(type == "audio") + { + this.getTracks = function () { + return self.stream.getAudioTracks(); + }; + } + else + { + this.getTracks = function () { + return self.stream.getVideoTracks(); + }; + } + this.stream.onended = function() { self.streamEnded(); @@ -24,31 +36,32 @@ LocalStream.prototype.getOriginalStream = function() LocalStream.prototype.isAudioStream = function () { return (this.stream.getAudioTracks() && this.stream.getAudioTracks().length > 0); -} +}; LocalStream.prototype.mute = function() { var ismuted = false; - var tracks = []; - if(this.type = "audio") - { - tracks = this.stream.getAudioTracks(); - } - else - { - tracks = this.stream.getVideoTracks(); - } + var tracks = this.getTracks(); for (var idx = 0; idx < tracks.length; idx++) { ismuted = !tracks[idx].enabled; - tracks[idx].enabled = !tracks[idx].enabled; + tracks[idx].enabled = ismuted; } return ismuted; -} +}; + +LocalStream.prototype.setMute = function(mute) +{ + var tracks = this.getTracks(); + + for (var idx = 0; idx < tracks.length; idx++) { + tracks[idx].enabled = mute; + } +}; LocalStream.prototype.isMuted = function () { var tracks = []; - if(this.type = "audio") + if(this.type == "audio") { tracks = this.stream.getAudioTracks(); } @@ -63,4 +76,10 @@ LocalStream.prototype.isMuted = function () { return true; } +LocalStream.prototype.getId = function () { + return this.stream.getTracks()[0].id; +} + + + module.exports = LocalStream; diff --git a/modules/RTC/RTC.js b/modules/RTC/RTC.js index 3acc70d73..8553f851c 100644 --- a/modules/RTC/RTC.js +++ b/modules/RTC/RTC.js @@ -27,7 +27,10 @@ var RTC = { createLocalStream: function (stream, type) { var localStream = new LocalStream(stream, type, eventEmitter); - this.localStreams.push(localStream); + //in firefox we have only one stream object + if(this.localStreams.length == 0 || + this.localStreams[0].getOriginalStream() != stream) + this.localStreams.push(localStream); if(type == "audio") { this.localAudio = localStream; @@ -117,6 +120,16 @@ var RTC = { return true; } return false; + }, + switchVideoStreams: function (new_stream) { + this.localVideo.stream = new_stream; + + this.localStreams = []; + + //in firefox we have only one stream object + if(this.localAudio.getOriginalStream() != new_stream) + this.localStreams.push(this.localAudio); + this.localStreams.push(this.localVideo); } }; diff --git a/modules/UI/UI.js b/modules/UI/UI.js index c8edf59d3..cc71af1be 100644 --- a/modules/UI/UI.js +++ b/modules/UI/UI.js @@ -83,7 +83,7 @@ function registerListeners() { if(jid === statistics.LOCAL_JID) { resourceJid = AudioLevels.LOCAL_LEVEL; - if(isAudioMuted()) + if(RTC.localAudio.isMuted()) { audioLevel = 0; } diff --git a/modules/UI/videolayout/VideoLayout.js b/modules/UI/videolayout/VideoLayout.js index 2e8969cf0..0a5984046 100644 --- a/modules/UI/videolayout/VideoLayout.js +++ b/modules/UI/videolayout/VideoLayout.js @@ -414,12 +414,10 @@ var VideoLayout = (function (my) { }; my.changeLocalStream = function (stream) { - connection.jingle.localAudio = stream; VideoLayout.changeLocalVideo(stream, true); }; my.changeLocalAudio = function(stream) { - connection.jingle.localAudio = stream; RTC.attachMediaStream($('#localAudio'), stream); document.getElementById('localAudio').autoplay = true; document.getElementById('localAudio').volume = 0; @@ -430,8 +428,6 @@ var VideoLayout = (function (my) { }; my.changeLocalVideo = function(stream, flipX) { - connection.jingle.localVideo = stream; - var localVideo = document.createElement('video'); localVideo.id = 'localVideo_' + RTC.getStreamID(stream); localVideo.autoplay = true; diff --git a/modules/simulcast/SimulcastSender.js b/modules/simulcast/SimulcastSender.js index 6207d23f4..432db64d3 100644 --- a/modules/simulcast/SimulcastSender.js +++ b/modules/simulcast/SimulcastSender.js @@ -32,7 +32,7 @@ SimulcastSender.prototype.getLocalVideoStream = function () { return (this.displayedLocalVideoStream != null) ? this.displayedLocalVideoStream // in case we have no simulcast at all, i.e. we didn't perform the GUM - : connection.jingle.localVideo; + : RTC.localVideo.getOriginalStream(); }; function NativeSimulcastSender() {