|
|
@@ -8,6 +8,7 @@ var XMPPEvents = require("./service/xmpp/XMPPEvents");
|
|
8
|
8
|
var RTCEvents = require("./service/RTC/RTCEvents");
|
|
9
|
9
|
var EventEmitter = require("events");
|
|
10
|
10
|
var JitsiConferenceEvents = require("./JitsiConferenceEvents");
|
|
|
11
|
+var JitsiConferenceErrors = require("./JitsiConferenceErrors");
|
|
11
|
12
|
var JitsiParticipant = require("./JitsiParticipant");
|
|
12
|
13
|
var Statistics = require("./modules/statistics/statistics");
|
|
13
|
14
|
var JitsiDTMFManager = require('./modules/DTMF/JitsiDTMFManager');
|
|
|
@@ -246,6 +247,36 @@ JitsiConference.prototype.isModerator = function () {
|
|
246
|
247
|
return this.room.isModerator();
|
|
247
|
248
|
};
|
|
248
|
249
|
|
|
|
250
|
+/**
|
|
|
251
|
+ * Set password for the room.
|
|
|
252
|
+ * @param {string} password new password for the room.
|
|
|
253
|
+ * @returns {Promise}
|
|
|
254
|
+ */
|
|
|
255
|
+JitsiConference.prototype.lock = function (password) {
|
|
|
256
|
+ if (!this.isModerator()) {
|
|
|
257
|
+ return Promise.reject();
|
|
|
258
|
+ }
|
|
|
259
|
+
|
|
|
260
|
+ var conference = this;
|
|
|
261
|
+ return new Promise(function (resolve, reject) {
|
|
|
262
|
+ conference.xmpp.lockRoom(password, function () {
|
|
|
263
|
+ resolve();
|
|
|
264
|
+ }, function (err) {
|
|
|
265
|
+ reject(err);
|
|
|
266
|
+ }, function () {
|
|
|
267
|
+ reject(JitsiConferenceErrors.PASSWORD_REQUIRED);
|
|
|
268
|
+ });
|
|
|
269
|
+ });
|
|
|
270
|
+};
|
|
|
271
|
+
|
|
|
272
|
+/**
|
|
|
273
|
+ * Remove password from the room.
|
|
|
274
|
+ * @returns {Promise}
|
|
|
275
|
+ */
|
|
|
276
|
+JitsiConference.prototype.unlock = function () {
|
|
|
277
|
+ return this.lock(undefined);
|
|
|
278
|
+};
|
|
|
279
|
+
|
|
249
|
280
|
/**
|
|
250
|
281
|
* Elects the participant with the given id to be the selected participant or the speaker.
|
|
251
|
282
|
* @param id the identifier of the participant
|
|
|
@@ -287,10 +318,13 @@ JitsiConference.prototype.getParticipantById = function(id) {
|
|
287
|
318
|
|
|
288
|
319
|
JitsiConference.prototype.onMemberJoined = function (jid, email, nick) {
|
|
289
|
320
|
var id = Strophe.getResourceFromJid(jid);
|
|
|
321
|
+ if (id === 'focus') {
|
|
|
322
|
+ return;
|
|
|
323
|
+ }
|
|
290
|
324
|
var participant = new JitsiParticipant(id, this, nick);
|
|
291
|
|
- this.eventEmitter.emit(JitsiConferenceEvents.USER_JOINED, id);
|
|
292
|
325
|
this.participants[id] = participant;
|
|
293
|
|
- this.connection.xmpp.connection.disco.info(
|
|
|
326
|
+ this.eventEmitter.emit(JitsiConferenceEvents.USER_JOINED, id, participant);
|
|
|
327
|
+ this.xmpp.connection.disco.info(
|
|
294
|
328
|
jid, "node", function(iq) {
|
|
295
|
329
|
participant._supportsDTMF = $(iq).find(
|
|
296
|
330
|
'>query>feature[var="urn:xmpp:jingle:dtmf:0"]').length > 0;
|
|
|
@@ -301,8 +335,9 @@ JitsiConference.prototype.onMemberJoined = function (jid, email, nick) {
|
|
301
|
335
|
|
|
302
|
336
|
JitsiConference.prototype.onMemberLeft = function (jid) {
|
|
303
|
337
|
var id = Strophe.getResourceFromJid(jid);
|
|
|
338
|
+ var participant = this.participants[id];
|
|
304
|
339
|
delete this.participants[id];
|
|
305
|
|
- this.eventEmitter.emit(JitsiConferenceEvents.USER_LEFT, id);
|
|
|
340
|
+ this.eventEmitter.emit(JitsiConferenceEvents.USER_LEFT, id, participant);
|
|
306
|
341
|
};
|
|
307
|
342
|
|
|
308
|
343
|
JitsiConference.prototype.onUserRoleChanged = function (jid, role) {
|
|
|
@@ -398,7 +433,7 @@ JitsiConference.prototype.myUserId = function () {
|
|
398
|
433
|
|
|
399
|
434
|
JitsiConference.prototype.sendTones = function (tones, duration, pause) {
|
|
400
|
435
|
if (!this.dtmfManager) {
|
|
401
|
|
- var connection = this.connection.xmpp.connection.jingle.activecall.peerconnection;
|
|
|
436
|
+ var connection = this.xmpp.connection.jingle.activecall.peerconnection;
|
|
402
|
437
|
if (!connection) {
|
|
403
|
438
|
logger.warn("cannot sendTones: no conneciton");
|
|
404
|
439
|
return;
|
|
|
@@ -482,6 +517,9 @@ function setupListeners(conference) {
|
|
482
|
517
|
conference.eventEmitter.emit(JitsiConferenceEvents.LAST_N_ENDPOINTS_CHANGED,
|
|
483
|
518
|
lastNEndpoints, endpointsEnteringLastN);
|
|
484
|
519
|
});
|
|
|
520
|
+ conference.xmpp.addListener(XMPPEvents.PASSWORD_REQUIRED, function () {
|
|
|
521
|
+ conference.eventEmitter.emit(JitsiConferenceErrors.PASSWORD_REQUIRED);
|
|
|
522
|
+ });
|
|
485
|
523
|
|
|
486
|
524
|
if(conference.statistics) {
|
|
487
|
525
|
//FIXME: Maybe remove event should not be associated with the conference.
|
|
|
@@ -508,7 +546,7 @@ function setupListeners(conference) {
|
|
508
|
546
|
module.exports = JitsiConference;
|
|
509
|
547
|
|
|
510
|
548
|
}).call(this,"/JitsiConference.js")
|
|
511
|
|
-},{"./JitsiConferenceEvents":3,"./JitsiParticipant":8,"./JitsiTrackEvents":10,"./modules/DTMF/JitsiDTMFManager":11,"./modules/RTC/RTC":16,"./modules/statistics/statistics":24,"./service/RTC/RTCEvents":79,"./service/xmpp/XMPPEvents":85,"events":43,"jitsi-meet-logger":47}],2:[function(require,module,exports){
|
|
|
549
|
+},{"./JitsiConferenceErrors":2,"./JitsiConferenceEvents":3,"./JitsiParticipant":8,"./JitsiTrackEvents":10,"./modules/DTMF/JitsiDTMFManager":11,"./modules/RTC/RTC":16,"./modules/statistics/statistics":24,"./service/RTC/RTCEvents":79,"./service/xmpp/XMPPEvents":85,"events":43,"jitsi-meet-logger":47}],2:[function(require,module,exports){
|
|
512
|
550
|
/**
|
|
513
|
551
|
* Enumeration with the errors for the conference.
|
|
514
|
552
|
* @type {{string: string}}
|
|
|
@@ -518,6 +556,10 @@ var JitsiConferenceErrors = {
|
|
518
|
556
|
* Indicates that a password is required in order to join the conference.
|
|
519
|
557
|
*/
|
|
520
|
558
|
PASSWORD_REQUIRED: "conference.passwordRequired",
|
|
|
559
|
+ /**
|
|
|
560
|
+ * Indicates that password cannot be set for this conference.
|
|
|
561
|
+ */
|
|
|
562
|
+ PASSWORD_NOT_SUPPORTED: "conference.passwordNotSupported",
|
|
521
|
563
|
/**
|
|
522
|
564
|
* Indicates that a connection error occurred when trying to join a
|
|
523
|
565
|
* conference.
|
|
|
@@ -2333,7 +2375,9 @@ function getConstraints(um, options) {
|
|
2333
|
2375
|
// this later can be a problem with some of the tests
|
|
2334
|
2376
|
if(RTCBrowserType.isFirefox() && options.firefox_fake_device)
|
|
2335
|
2377
|
{
|
|
2336
|
|
- constraints.audio = true;
|
|
|
2378
|
+ // seems to be fixed now, removing this experimental fix, as having
|
|
|
2379
|
+ // multiple audio tracks brake the tests
|
|
|
2380
|
+ //constraints.audio = true;
|
|
2337
|
2381
|
constraints.fake = true;
|
|
2338
|
2382
|
}
|
|
2339
|
2383
|
|
|
|
@@ -2486,12 +2530,13 @@ function enumerateDevicesThroughMediaStreamTrack (callback) {
|
|
2486
|
2530
|
}
|
|
2487
|
2531
|
|
|
2488
|
2532
|
function obtainDevices(options) {
|
|
2489
|
|
- if (!options.devices || options.devices.length === 0) {
|
|
2490
|
|
- return options.successCallback(options.streams);
|
|
|
2533
|
+ if(!options.devices || options.devices.length === 0) {
|
|
|
2534
|
+ return options.successCallback(options.streams || {});
|
|
2491
|
2535
|
}
|
|
2492
|
2536
|
|
|
2493
|
2537
|
var device = options.devices.splice(0, 1);
|
|
2494
|
2538
|
options.deviceGUM[device](function (stream) {
|
|
|
2539
|
+ options.streams = options.streams || {};
|
|
2495
|
2540
|
options.streams[device] = stream;
|
|
2496
|
2541
|
obtainDevices(options);
|
|
2497
|
2542
|
},
|
|
|
@@ -5535,7 +5580,24 @@ Statistics.prototype.stopRemote = function () {
|
|
5535
|
5580
|
this.eventEmitter.emit(StatisticsEvents.STOP);
|
|
5536
|
5581
|
this.rtpStats = null;
|
|
5537
|
5582
|
}
|
|
5538
|
|
-}
|
|
|
5583
|
+};
|
|
|
5584
|
+
|
|
|
5585
|
+/**
|
|
|
5586
|
+ * Obtains audio level reported in the stats for specified peer.
|
|
|
5587
|
+ * @param peerJid full MUC jid of the user for whom we want to obtain last
|
|
|
5588
|
+ * audio level.
|
|
|
5589
|
+ * @param ssrc the SSRC of audio stream for which we want to obtain audio
|
|
|
5590
|
+ * level.
|
|
|
5591
|
+ * @returns {*} a float form 0 to 1 that represents current audio level or
|
|
|
5592
|
+ * <tt>null</tt> if for any reason the value is not available
|
|
|
5593
|
+ * at this time.
|
|
|
5594
|
+ */
|
|
|
5595
|
+Statistics.prototype.getPeerSSRCAudioLevel = function (peerJid, ssrc) {
|
|
|
5596
|
+
|
|
|
5597
|
+ var peerStats = this.rtpStats.jid2stats[peerJid];
|
|
|
5598
|
+
|
|
|
5599
|
+ return peerStats ? peerStats.ssrc2AudioLevel[ssrc] : null;
|
|
|
5600
|
+};
|
|
5539
|
5601
|
|
|
5540
|
5602
|
Statistics.LOCAL_JID = require("../../service/statistics/constants").LOCAL_JID;
|
|
5541
|
5603
|
|
|
|
@@ -6509,7 +6571,11 @@ function JingleSessionPC(me, sid, connection, service) {
|
|
6509
|
6571
|
this.addingStreams = false;
|
|
6510
|
6572
|
|
|
6511
|
6573
|
this.wait = true;
|
|
6512
|
|
- this.localStreamsSSRC = null;
|
|
|
6574
|
+ /**
|
|
|
6575
|
+ * A map that stores SSRCs of local streams
|
|
|
6576
|
+ * @type {{}} maps media type('audio' or 'video') to SSRC number
|
|
|
6577
|
+ */
|
|
|
6578
|
+ this.localStreamsSSRC = {};
|
|
6513
|
6579
|
this.ssrcOwners = {};
|
|
6514
|
6580
|
this.ssrcVideoTypes = {};
|
|
6515
|
6581
|
|
|
|
@@ -6725,8 +6791,7 @@ JingleSessionPC.prototype.accept = function () {
|
|
6725
|
6791
|
// FIXME why do we generate session-accept in 3 different places ?
|
|
6726
|
6792
|
prsdp.toJingle(
|
|
6727
|
6793
|
accept,
|
|
6728
|
|
- this.initiator == this.me ? 'initiator' : 'responder',
|
|
6729
|
|
- this.localStreamsSSRC);
|
|
|
6794
|
+ this.initiator == this.me ? 'initiator' : 'responder');
|
|
6730
|
6795
|
var sdp = this.peerconnection.localDescription.sdp;
|
|
6731
|
6796
|
while (SDPUtil.find_line(sdp, 'a=inactive')) {
|
|
6732
|
6797
|
// FIXME: change any inactive to sendrecv or whatever they were originally
|
|
|
@@ -6953,8 +7018,7 @@ JingleSessionPC.prototype.createdOffer = function (sdp) {
|
|
6953
|
7018
|
sid: this.sid});
|
|
6954
|
7019
|
self.localSDP.toJingle(
|
|
6955
|
7020
|
init,
|
|
6956
|
|
- this.initiator == this.me ? 'initiator' : 'responder',
|
|
6957
|
|
- this.localStreamsSSRC);
|
|
|
7021
|
+ this.initiator == this.me ? 'initiator' : 'responder');
|
|
6958
|
7022
|
|
|
6959
|
7023
|
SSRCReplacement.processSessionInit(init);
|
|
6960
|
7024
|
|
|
|
@@ -7020,6 +7084,15 @@ JingleSessionPC.prototype.readSsrcInfo = function (contents) {
|
|
7020
|
7084
|
});
|
|
7021
|
7085
|
};
|
|
7022
|
7086
|
|
|
|
7087
|
+/**
|
|
|
7088
|
+ * Returns the SSRC of local audio stream.
|
|
|
7089
|
+ * @param mediaType 'audio' or 'video' media type
|
|
|
7090
|
+ * @returns {*} the SSRC number of local audio or video stream.
|
|
|
7091
|
+ */
|
|
|
7092
|
+JingleSessionPC.prototype.getLocalSSRC = function (mediaType) {
|
|
|
7093
|
+ return this.localStreamsSSRC[mediaType];
|
|
|
7094
|
+};
|
|
|
7095
|
+
|
|
7023
|
7096
|
JingleSessionPC.prototype.getSsrcOwner = function (ssrc) {
|
|
7024
|
7097
|
return this.ssrcOwners[ssrc];
|
|
7025
|
7098
|
};
|
|
|
@@ -7975,13 +8048,8 @@ JingleSessionPC.prototype.setLocalDescription = function () {
|
|
7975
|
8048
|
'ssrc': ssrc.id,
|
|
7976
|
8049
|
'type': media.type
|
|
7977
|
8050
|
});
|
|
7978
|
|
- });
|
|
7979
|
|
- }
|
|
7980
|
|
- else if(self.localStreamsSSRC && self.localStreamsSSRC[media.type])
|
|
7981
|
|
- {
|
|
7982
|
|
- newssrcs.push({
|
|
7983
|
|
- 'ssrc': self.localStreamsSSRC[media.type],
|
|
7984
|
|
- 'type': media.type
|
|
|
8051
|
+ // FIXME allows for only one SSRC per media type
|
|
|
8052
|
+ self.localStreamsSSRC[media.type] = ssrc.id;
|
|
7985
|
8053
|
});
|
|
7986
|
8054
|
}
|
|
7987
|
8055
|
|
|
|
@@ -8511,7 +8579,7 @@ SDP.prototype.removeMediaLines = function(mediaindex, prefix) {
|
|
8511
|
8579
|
}
|
|
8512
|
8580
|
|
|
8513
|
8581
|
// add content's to a jingle element
|
|
8514
|
|
-SDP.prototype.toJingle = function (elem, thecreator, ssrcs) {
|
|
|
8582
|
+SDP.prototype.toJingle = function (elem, thecreator) {
|
|
8515
|
8583
|
// logger.log("SSRC" + ssrcs["audio"] + " - " + ssrcs["video"]);
|
|
8516
|
8584
|
var self = this;
|
|
8517
|
8585
|
var i, j, k, mline, ssrc, rtpmap, tmp, lines;
|
|
|
@@ -8539,11 +8607,7 @@ SDP.prototype.toJingle = function (elem, thecreator, ssrcs) {
|
|
8539
|
8607
|
if (SDPUtil.find_line(this.media[i], 'a=ssrc:')) {
|
|
8540
|
8608
|
ssrc = SDPUtil.find_line(this.media[i], 'a=ssrc:').substring(7).split(' ')[0]; // take the first
|
|
8541
|
8609
|
} else {
|
|
8542
|
|
- if(ssrcs && ssrcs[mline.media]) {
|
|
8543
|
|
- ssrc = ssrcs[mline.media];
|
|
8544
|
|
- } else {
|
|
8545
|
|
- ssrc = false;
|
|
8546
|
|
- }
|
|
|
8610
|
+ ssrc = false;
|
|
8547
|
8611
|
}
|
|
8548
|
8612
|
|
|
8549
|
8613
|
elem.c('content', {creator: thecreator, name: mline.media});
|
|
|
@@ -10154,6 +10218,13 @@ Moderator.prototype.createConferenceIq = function () {
|
|
10154
|
10218
|
value: this.xmppService.options.hosts.bridge
|
|
10155
|
10219
|
}).up();
|
|
10156
|
10220
|
}
|
|
|
10221
|
+ if (this.xmppService.options.enforcedBridge !== undefined) {
|
|
|
10222
|
+ elem.c(
|
|
|
10223
|
+ 'property', {
|
|
|
10224
|
+ name: 'enforcedBridge',
|
|
|
10225
|
+ value: this.xmppService.options.enforcedBridge
|
|
|
10226
|
+ }).up();
|
|
|
10227
|
+ }
|
|
10157
|
10228
|
// Tell the focus we have Jigasi configured
|
|
10158
|
10229
|
if (this.xmppService.options.hosts.call_control !== undefined) {
|
|
10159
|
10230
|
elem.c(
|
|
|
@@ -11445,6 +11516,21 @@ XMPP.prototype.disconnect = function () {
|
|
11445
|
11516
|
this.connection.disconnect();
|
|
11446
|
11517
|
};
|
|
11447
|
11518
|
|
|
|
11519
|
+/**
|
|
|
11520
|
+ * Gets the SSRC of local media stream.
|
|
|
11521
|
+ * @param mediaType the media type that tells whether we want to get
|
|
|
11522
|
+ * the SSRC of local audio or video stream.
|
|
|
11523
|
+ * @returns {*} the SSRC number for local media stream or <tt>null</tt> if
|
|
|
11524
|
+ * not available.
|
|
|
11525
|
+ */
|
|
|
11526
|
+XMPP.prototype.getLocalSSRC = function (mediaType) {
|
|
|
11527
|
+ if (this.connection.jingle.activecall &&
|
|
|
11528
|
+ this.connection.jingle.activecall.peerconnection) {
|
|
|
11529
|
+ return this.connection.jingle.activecall.getLocalSSRC(mediaType);
|
|
|
11530
|
+ } else {
|
|
|
11531
|
+ return null;
|
|
|
11532
|
+ }
|
|
|
11533
|
+};
|
|
11448
|
11534
|
|
|
11449
|
11535
|
module.exports = XMPP;
|
|
11450
|
11536
|
|