Pārlūkot izejas kodu

some improvements for USER_JOINED/USER_LEFT events

master
isymchych 10 gadus atpakaļ
vecāks
revīzija
843bad3c87
3 mainītis faili ar 123 papildinājumiem un 33 dzēšanām
  1. 6
    2
      JitsiConference.js
  2. 4
    4
      doc/API.md
  3. 113
    27
      lib-jitsi-meet.js

+ 6
- 2
JitsiConference.js Parādīt failu

@@ -283,9 +283,12 @@ JitsiConference.prototype.getParticipantById = function(id) {
283 283
 
284 284
 JitsiConference.prototype.onMemberJoined = function (jid, email, nick) {
285 285
     var id = Strophe.getResourceFromJid(jid);
286
+    if (id === 'focus') {
287
+       return;
288
+    }
286 289
     var participant = new JitsiParticipant(id, this, nick);
287
-    this.eventEmitter.emit(JitsiConferenceEvents.USER_JOINED, id);
288 290
     this.participants[id] = participant;
291
+    this.eventEmitter.emit(JitsiConferenceEvents.USER_JOINED, id, participant);
289 292
     this.xmpp.connection.disco.info(
290 293
         jid, "node", function(iq) {
291 294
             participant._supportsDTMF = $(iq).find(
@@ -297,8 +300,9 @@ JitsiConference.prototype.onMemberJoined = function (jid, email, nick) {
297 300
 
298 301
 JitsiConference.prototype.onMemberLeft = function (jid) {
299 302
     var id = Strophe.getResourceFromJid(jid);
303
+    var participant = this.participants[id];
300 304
     delete this.participants[id];
301
-    this.eventEmitter.emit(JitsiConferenceEvents.USER_LEFT, id);
305
+    this.eventEmitter.emit(JitsiConferenceEvents.USER_LEFT, id, participant);
302 306
 };
303 307
 
304 308
 JitsiConference.prototype.onUserRoleChanged = function (jid, role) {

+ 4
- 4
doc/API.md Parādīt failu

@@ -65,12 +65,12 @@ JitsiMeetJS.setLogLevel(JitsiMeetJS.logLevels.ERROR);
65 65
     For example if you want to use the conference event that is fired when somebody leave conference you can use the following code - ```JitsiMeetJS.events.conference.USER_LEFT```.
66 66
     We support the following events:
67 67
     1. conference
68
-        - TRACK_ADDED - remote stream received. (parameters - JitsiTrack)
69
-        - TRACK_REMOVED - remote stream removed. (parameters - JitsiTrack)
68
+        - TRACK_ADDED - stream received. (parameters - JitsiTrack)
69
+        - TRACK_REMOVED - stream removed. (parameters - JitsiTrack)
70 70
         - TRACK_MUTE_CHANGED - JitsiTrack was muted or unmuted. (parameters - JitsiTrack)
71 71
         - ACTIVE_SPEAKER_CHANGED - the active speaker is changed. (parameters - id(string))
72
-        - USER_JOINED - new user joined a conference. (parameters - id(string))
73
-        - USER_LEFT - a participant left conference. (parameters - id(string))
72
+        - USER_JOINED - new user joined a conference. (parameters - id(string), user(JitsiParticipant))
73
+        - USER_LEFT - a participant left conference. (parameters - id(string), user(JitsiParticipant))
74 74
         - MESSAGE_RECEIVED - new text message received. (parameters - id(string), text(string))
75 75
         - DISPLAY_NAME_CHANGED - user has changed his display name. (parameters - id(string), displayName(string))
76 76
         - LAST_N_ENDPOINTS_CHANGED - last n set was changed (parameters - array of ids of users)

+ 113
- 27
lib-jitsi-meet.js Parādīt failu

@@ -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
 

Notiek ielāde…
Atcelt
Saglabāt