Fixes issues with starting the streams after the conference has been joined.

This commit is contained in:
hristoterezov 2015-10-15 16:24:51 -05:00
parent fe1067b8a3
commit 055765fd80
7 changed files with 144 additions and 30 deletions

View File

@ -1,3 +1,13 @@
//var options = {
// hosts: {
// domain: "prod-us-east-1-app-xmpp1.internal.meet.hipchat.ninja",
// focus: "focus.prod-us-east-1-app-xmpp1.internal.meet.hipchat.ninja",
// muc: "conference.prod-us-east-1-app-xmpp1.internal.meet.hipchat.ninja", // FIXME: use XEP-0030
// },
// bosh: "https://xmpp1-meet.hipchat.me/http-bind", // FIXME: use xep-0156 for that
// clientNode: "http://prod-us-east-1-app-xmpp1.internal.meet.hipchat.ninja/jitsimeet" // The name of client node advertised in XEP-0115 'c' stanza
//};
var options = {
hosts: {
domain: 'hristo.jitsi.net',
@ -5,8 +15,8 @@ var options = {
bridge: 'jitsi-videobridge.hristo.jitsi.net', // FIXME: use XEP-0030
},
bosh: '//hristo.jitsi.net/http-bind', // FIXME: use xep-0156 for that
clientNode: 'http://jitsi.org/jitsimeet' // The name of client node advertised in XEP-0115 'c' stanza
};
clientNode: 'http://jitsi.org/jitsimeet', // The name of client node advertised in XEP-0115 'c' stanza
}
var confOptions = {
openSctp: true
@ -22,6 +32,10 @@ function onLocalTracks(tracks)
console.log(tracks);
tracks[0].attach($("#localAudio"));
tracks[1].attach($("#localVideo"));
for(var i = 0; i < localTracks.length; i++)
{
localTracks[i].start();
}
}
/**
@ -46,10 +60,8 @@ function onRemoteTrack(track) {
* That function is executed when the conference is joined
*/
function onConferenceJoined () {
for(var i = 0; i < localTracks.length; i++)
{
localTracks[i].start();
}
console.log("conference joined!");
room.createLocalTracks().then(onLocalTracks);
}
function onUserLeft(id) {
@ -64,8 +76,7 @@ function onUserLeft(id) {
* That function is called when connection is established successfully
*/
function onConnectionSuccess(){
room = connection.initJitsiConference("conference1", confOptions);
room.createLocalTracks().then(onLocalTracks);
room = connection.initJitsiConference("conference2", confOptions);
room.on(JitsiMeetJS.events.conference.TRACK_ADDED, onRemoteTrack);
room.on(JitsiMeetJS.events.conference.TRACK_REMOVED, function () {
console.debug("track removed!!!");

View File

@ -12,6 +12,6 @@
</head>
<body>
<video id="localVideo" autoplay="true"></video>
<audio id="localAudio" autoplay="true"></audio>
<!--<audio id="localAudio" autoplay="true" muted="true"></audio>-->
</body>
</html>

View File

@ -26,6 +26,7 @@ function JitsiConference(options) {
this.rtc = new RTC(this.room, options);
setupListeners(this);
this.participants = {};
this.lastActiveSpeaker = null;
}
/**
@ -220,7 +221,11 @@ function setupListeners(conference) {
// conference.eventEmitter.emit(JitsiConferenceEvents.CONFERENCE_LEFT);
// });
conference.rtc.addListener(RTCEvents.DOMINANTSPEAKER_CHANGED, function (id) {
conference.eventEmitter.emit(JitsiConferenceEvents.ACTIVE_SPEAKER_CHANGED, id);
if(conference.lastActiveSpeaker !== id && conference.room
&& conference.room.myroomjid !== id) {
conference.lastActiveSpeaker = id;
conference.eventEmitter.emit(JitsiConferenceEvents.ACTIVE_SPEAKER_CHANGED, id);
}
});
conference.rtc.addListener(RTCEvents.LASTN_CHANGED, function (oldValue, newValue) {
@ -845,6 +850,7 @@ function JitsiLocalTrack(RTC, stream, eventEmitter, videoType, isGUMStream)
this.videoType = videoType;
this.isGUMStream = true;
this.dontFireRemoveEvent = false;
this.isStarted = false;
var self = this;
if(isGUMStream === false)
this.isGUMStream = isGUMStream;
@ -947,6 +953,7 @@ JitsiLocalTrack.prototype.stop = function () {
* NOTE: Works for local tracks only.
*/
JitsiLocalTrack.prototype.start = function() {
this.isStarted = true;
this.rtc.room.addStream(this.stream, function () {});
}
@ -1220,7 +1227,6 @@ var DesktopSharingEventTypes
var MediaStreamType = require("../../service/RTC/MediaStreamTypes");
var StreamEventTypes = require("../../service/RTC/StreamEventTypes.js");
var RTCEvents = require("../../service/RTC/RTCEvents.js");
var XMPPEvents = require("../../service/xmpp/XMPPEvents");
var desktopsharing = require("../desktopsharing/desktopsharing");
function getMediaStreamUsage()
@ -1279,7 +1285,6 @@ function RTC(room, options) {
if(self.remoteStreams[from])
self.remoteStreams[from][JitsiTrack.AUDIO].setMute(values.value == "true");
});
}
/**
@ -1298,7 +1303,11 @@ RTC.prototype.obtainAudioAndVideoPermissions = function (options, dontCreateJits
RTC.prototype.onIncommingCall = function(event) {
if(this.options.config.openSctp)
this.dataChannels = new DataChannels(event.peerconnection, this.eventEmitter);
this.room.addLocalStreams(this.localStreams);
for(var i = 0; i < this.localStreams.length; i++)
if(this.localStreams[i].isStarted)
{
this.localStreams[i].start();
}
}
RTC.prototype.selectedEndpoint = function (id) {
@ -1565,7 +1574,7 @@ RTC.prototype.setDeviceAvailability = function (devices) {
module.exports = RTC;
},{"../../service/RTC/MediaStreamTypes":70,"../../service/RTC/RTCEvents.js":71,"../../service/RTC/StreamEventTypes.js":73,"../../service/desktopsharing/DesktopSharingEventTypes":75,"../../service/xmpp/XMPPEvents":76,"../desktopsharing/desktopsharing":17,"./DataChannels":9,"./JitsiLocalTrack.js":10,"./JitsiRemoteTrack.js":11,"./JitsiTrack":12,"./RTCBrowserType":14,"./RTCUtils.js":15,"events":77}],14:[function(require,module,exports){
},{"../../service/RTC/MediaStreamTypes":70,"../../service/RTC/RTCEvents.js":71,"../../service/RTC/StreamEventTypes.js":73,"../../service/desktopsharing/DesktopSharingEventTypes":75,"../desktopsharing/desktopsharing":17,"./DataChannels":9,"./JitsiLocalTrack.js":10,"./JitsiRemoteTrack.js":11,"./JitsiTrack":12,"./RTCBrowserType":14,"./RTCUtils.js":15,"events":77}],14:[function(require,module,exports){
var currentBrowser;
@ -4903,6 +4912,7 @@ function JingleSessionPC(me, sid, connection, service) {
this.removessrc = [];
this.pendingop = null;
this.switchstreams = false;
this.addingStreams = false;
this.wait = true;
this.localStreamsSSRC = null;
@ -4915,6 +4925,7 @@ function JingleSessionPC(me, sid, connection, service) {
* by the application logic.
*/
this.videoMuteByUser = false;
this.modifySourcesQueue = async.queue(this._modifySources.bind(this), 1);
// We start with the queue paused. We resume it when the signaling state is
// stable and the ice connection state is connected.
@ -5024,6 +5035,8 @@ JingleSessionPC.prototype.addLocalStreams = function (localStreams) {
var self = this;
// add any local and relayed stream
localStreams.forEach(function(stream) {
if(!stream.isStarted())
return;
self.peerconnection.addStream(stream.getOriginalStream());
});
}
@ -5831,7 +5844,8 @@ JingleSessionPC.prototype._modifySources = function (successCallback, queueCallb
var self = this;
if (this.peerconnection.signalingState == 'closed') return;
if (!(this.addssrc.length || this.removessrc.length || this.pendingop !== null || this.switchstreams)){
if (!(this.addssrc.length || this.removessrc.length || this.pendingop !== null
|| this.switchstreams || this.addingStreams)){
// There is nothing to do since scheduled job might have been executed by another succeeding call
this.setLocalDescription();
if(successCallback){
@ -5841,8 +5855,9 @@ JingleSessionPC.prototype._modifySources = function (successCallback, queueCallb
return;
}
// Reset switch streams flag
// Reset switch streams flags
this.switchstreams = false;
this.addingStreams = false;
var sdp = new SDP(this.peerconnection.remoteDescription.sdp);
@ -5991,6 +6006,7 @@ JingleSessionPC.prototype.addStream = function (stream, callback) {
return;
}
this.addingStreams = true;
this.modifySourcesQueue.push(function() {
console.log('modify sources done');
@ -6393,6 +6409,7 @@ var RTCBrowserType = require('../RTC/RTCBrowserType');
*/
var isEnabled = !RTCBrowserType.isFirefox();
/**
* Stored SSRC of local video stream.
*/
@ -6403,7 +6420,7 @@ var localVideoSSRC;
* This is in order to tell Chrome what SSRC should be used in RTCP requests
* instead of 1.
*/
var localRecvOnlySSRC;
var localRecvOnlySSRC, localRecvOnlyMSID, localRecvOnlyMSLabel, localRecvOnlyLabel;
/**
* cname for <tt>localRecvOnlySSRC</tt>
@ -6475,6 +6492,22 @@ var storeLocalVideoSSRC = function (jingleIq) {
});
};
function rangeRandomHex(min, max)
{
return Math.floor(Math.random() * (max - min) + min).toString(16);
}
var random4digitsHex = rangeRandomHex.bind(null, 4096, 65535);
var random8digitsHex = rangeRandomHex.bind(null, 268435456, 4294967295);
var random12digitsHex = rangeRandomHex.bind(null, 17592186044416, 281474976710655);
function generateLabel() {
//4294967295 - ffffffff
//65535 - ffff
//281474976710655 - ffffffffffff
return random8digitsHex() + "-" + random4digitsHex() + "-" + random4digitsHex() + "-" + random4digitsHex() + "-" + random12digitsHex();
}
/**
* Generates new SSRC for local video recvonly stream.
* FIXME what about eventual SSRC collision ?
@ -6485,7 +6518,12 @@ function generateRecvonlySSRC() {
Math.random().toString(10).substring(2, 11);
localRecvOnlyCName =
Math.random().toString(36).substring(2);
console.info(
localRecvOnlyMSLabel = generateLabel();
localRecvOnlyLabel = generateLabel();
localRecvOnlyMSID = localRecvOnlyMSLabel + " " + localRecvOnlyLabel;
console.info(
"Generated local recvonly SSRC: " + localRecvOnlySSRC +
", cname: " + localRecvOnlyCName);
}
@ -6556,12 +6594,19 @@ var LocalSSRCReplacement = {
if (!localRecvOnlySSRC) {
generateRecvonlySSRC();
}
localVideoSSRC = localRecvOnlySSRC;
console.info('No SSRC in video recvonly stream' +
' - adding SSRC: ' + localRecvOnlySSRC);
sdp.media[1] += 'a=ssrc:' + localRecvOnlySSRC +
' cname:' + localRecvOnlyCName + '\r\n';
' cname:' + localRecvOnlyCName + '\r\n' +
'a=ssrc:' + localRecvOnlySSRC +
' msid:' + localRecvOnlyMSID + '\r\n' +
'a=ssrc:' + localRecvOnlySSRC +
' mslabel:' + localRecvOnlyMSLabel + '\r\n' +
'a=ssrc:' + localRecvOnlySSRC +
' label:' + localRecvOnlyLabel + '\r\n';
localDescription.sdp = sdp.session + sdp.media.join('');
}
@ -7799,6 +7844,7 @@ function TraceablePeerConnection(ice_config, constraints, session) {
// override as desired
this.trace = function (what, info) {
console.debug(what + " - " + info);
/*console.warn('WTRACE', what, info);
if (info && RTCBrowserType.isIExplorer()) {
if (info.length > 1024) {

View File

@ -14,6 +14,7 @@ function JitsiLocalTrack(RTC, stream, eventEmitter, videoType, isGUMStream)
this.videoType = videoType;
this.isGUMStream = true;
this.dontFireRemoveEvent = false;
this.isStarted = false;
var self = this;
if(isGUMStream === false)
this.isGUMStream = isGUMStream;
@ -116,6 +117,7 @@ JitsiLocalTrack.prototype.stop = function () {
* NOTE: Works for local tracks only.
*/
JitsiLocalTrack.prototype.start = function() {
this.isStarted = true;
this.rtc.room.addStream(this.stream, function () {});
}

View File

@ -11,7 +11,6 @@ var DesktopSharingEventTypes
var MediaStreamType = require("../../service/RTC/MediaStreamTypes");
var StreamEventTypes = require("../../service/RTC/StreamEventTypes.js");
var RTCEvents = require("../../service/RTC/RTCEvents.js");
var XMPPEvents = require("../../service/xmpp/XMPPEvents");
var desktopsharing = require("../desktopsharing/desktopsharing");
function getMediaStreamUsage()
@ -70,7 +69,6 @@ function RTC(room, options) {
if(self.remoteStreams[from])
self.remoteStreams[from][JitsiTrack.AUDIO].setMute(values.value == "true");
});
}
/**
@ -89,7 +87,11 @@ RTC.prototype.obtainAudioAndVideoPermissions = function (options, dontCreateJits
RTC.prototype.onIncommingCall = function(event) {
if(this.options.config.openSctp)
this.dataChannels = new DataChannels(event.peerconnection, this.eventEmitter);
this.room.addLocalStreams(this.localStreams);
for(var i = 0; i < this.localStreams.length; i++)
if(this.localStreams[i].isStarted)
{
this.localStreams[i].start();
}
}
RTC.prototype.selectedEndpoint = function (id) {

View File

@ -37,6 +37,7 @@ function JingleSessionPC(me, sid, connection, service) {
this.removessrc = [];
this.pendingop = null;
this.switchstreams = false;
this.addingStreams = false;
this.wait = true;
this.localStreamsSSRC = null;
@ -49,6 +50,7 @@ function JingleSessionPC(me, sid, connection, service) {
* by the application logic.
*/
this.videoMuteByUser = false;
this.modifySourcesQueue = async.queue(this._modifySources.bind(this), 1);
// We start with the queue paused. We resume it when the signaling state is
// stable and the ice connection state is connected.
@ -158,6 +160,8 @@ JingleSessionPC.prototype.addLocalStreams = function (localStreams) {
var self = this;
// add any local and relayed stream
localStreams.forEach(function(stream) {
if(!stream.isStarted())
return;
self.peerconnection.addStream(stream.getOriginalStream());
});
}
@ -965,7 +969,8 @@ JingleSessionPC.prototype._modifySources = function (successCallback, queueCallb
var self = this;
if (this.peerconnection.signalingState == 'closed') return;
if (!(this.addssrc.length || this.removessrc.length || this.pendingop !== null || this.switchstreams)){
if (!(this.addssrc.length || this.removessrc.length || this.pendingop !== null
|| this.switchstreams || this.addingStreams)){
// There is nothing to do since scheduled job might have been executed by another succeeding call
this.setLocalDescription();
if(successCallback){
@ -975,8 +980,9 @@ JingleSessionPC.prototype._modifySources = function (successCallback, queueCallb
return;
}
// Reset switch streams flag
// Reset switch streams flags
this.switchstreams = false;
this.addingStreams = false;
var sdp = new SDP(this.peerconnection.remoteDescription.sdp);
@ -1125,6 +1131,7 @@ JingleSessionPC.prototype.addStream = function (stream, callback) {
return;
}
this.addingStreams = true;
this.modifySourcesQueue.push(function() {
console.log('modify sources done');

View File

@ -41,17 +41,18 @@ var RTCBrowserType = require('../RTC/RTCBrowserType');
*/
var isEnabled = !RTCBrowserType.isFirefox();
/**
* Stored SSRC of local video stream.
*/
var localVideoSSRC;
/**
* SSRC used for recvonly video stream when we have no local camera.
* SSRC, msid, mslabel, label used for recvonly video stream when we have no local camera.
* This is in order to tell Chrome what SSRC should be used in RTCP requests
* instead of 1.
*/
var localRecvOnlySSRC;
var localRecvOnlySSRC, localRecvOnlyMSID, localRecvOnlyMSLabel, localRecvOnlyLabel;
/**
* cname for <tt>localRecvOnlySSRC</tt>
@ -124,16 +125,54 @@ var storeLocalVideoSSRC = function (jingleIq) {
};
/**
* Generates new SSRC for local video recvonly stream.
* Generates random hex number within the range [min, max]
* @param max the maximum value for the generated number
* @param min the minimum value for the generated number
* @returns random hex number
*/
function rangeRandomHex(min, max)
{
return Math.floor(Math.random() * (max - min) + min).toString(16);
}
/**
* Generates hex number with length 4
*/
var random4digitsHex = rangeRandomHex.bind(null, 4096, 65535);
/**
* Generates hex number with length 8
*/
var random8digitsHex = rangeRandomHex.bind(null, 268435456, 4294967295);
/**
* Generates hex number with length 12
*/
var random12digitsHex = rangeRandomHex.bind(null, 17592186044416, 281474976710655);
/**
* Generates new label/mslabel attribute
* @returns {string} label/mslabel attribute
*/
function generateLabel() {
return random8digitsHex() + "-" + random4digitsHex() + "-" + random4digitsHex() + "-" + random4digitsHex() + "-" + random12digitsHex();
}
/**
* Generates new SSRC, CNAME, mslabel, label and msid for local video recvonly stream.
* FIXME what about eventual SSRC collision ?
*/
function generateRecvonlySSRC() {
//
localRecvOnlySSRC =
Math.random().toString(10).substring(2, 11);
localRecvOnlyCName =
Math.random().toString(36).substring(2);
console.info(
localRecvOnlyMSLabel = generateLabel();
localRecvOnlyLabel = generateLabel();
localRecvOnlyMSID = localRecvOnlyMSLabel + " " + localRecvOnlyLabel;
console.info(
"Generated local recvonly SSRC: " + localRecvOnlySSRC +
", cname: " + localRecvOnlyCName);
}
@ -204,12 +243,19 @@ var LocalSSRCReplacement = {
if (!localRecvOnlySSRC) {
generateRecvonlySSRC();
}
localVideoSSRC = localRecvOnlySSRC;
console.info('No SSRC in video recvonly stream' +
' - adding SSRC: ' + localRecvOnlySSRC);
sdp.media[1] += 'a=ssrc:' + localRecvOnlySSRC +
' cname:' + localRecvOnlyCName + '\r\n';
' cname:' + localRecvOnlyCName + '\r\n' +
'a=ssrc:' + localRecvOnlySSRC +
' msid:' + localRecvOnlyMSID + '\r\n' +
'a=ssrc:' + localRecvOnlySSRC +
' mslabel:' + localRecvOnlyMSLabel + '\r\n' +
'a=ssrc:' + localRecvOnlySSRC +
' label:' + localRecvOnlyLabel + '\r\n';
localDescription.sdp = sdp.session + sdp.media.join('');
}