瀏覽代碼

some improvements for USER_JOINED/USER_LEFT events

master
isymchych 10 年之前
父節點
當前提交
843bad3c87
共有 3 個檔案被更改,包括 123 行新增33 行删除
  1. 6
    2
      JitsiConference.js
  2. 4
    4
      doc/API.md
  3. 113
    27
      lib-jitsi-meet.js

+ 6
- 2
JitsiConference.js 查看文件

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

+ 4
- 4
doc/API.md 查看文件

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```.
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
     We support the following events:
66
     We support the following events:
67
     1. conference
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
         - TRACK_MUTE_CHANGED - JitsiTrack was muted or unmuted. (parameters - JitsiTrack)
70
         - TRACK_MUTE_CHANGED - JitsiTrack was muted or unmuted. (parameters - JitsiTrack)
71
         - ACTIVE_SPEAKER_CHANGED - the active speaker is changed. (parameters - id(string))
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
         - MESSAGE_RECEIVED - new text message received. (parameters - id(string), text(string))
74
         - MESSAGE_RECEIVED - new text message received. (parameters - id(string), text(string))
75
         - DISPLAY_NAME_CHANGED - user has changed his display name. (parameters - id(string), displayName(string))
75
         - DISPLAY_NAME_CHANGED - user has changed his display name. (parameters - id(string), displayName(string))
76
         - LAST_N_ENDPOINTS_CHANGED - last n set was changed (parameters - array of ids of users)
76
         - LAST_N_ENDPOINTS_CHANGED - last n set was changed (parameters - array of ids of users)

+ 113
- 27
lib-jitsi-meet.js 查看文件

8
 var RTCEvents = require("./service/RTC/RTCEvents");
8
 var RTCEvents = require("./service/RTC/RTCEvents");
9
 var EventEmitter = require("events");
9
 var EventEmitter = require("events");
10
 var JitsiConferenceEvents = require("./JitsiConferenceEvents");
10
 var JitsiConferenceEvents = require("./JitsiConferenceEvents");
11
+var JitsiConferenceErrors = require("./JitsiConferenceErrors");
11
 var JitsiParticipant = require("./JitsiParticipant");
12
 var JitsiParticipant = require("./JitsiParticipant");
12
 var Statistics = require("./modules/statistics/statistics");
13
 var Statistics = require("./modules/statistics/statistics");
13
 var JitsiDTMFManager = require('./modules/DTMF/JitsiDTMFManager');
14
 var JitsiDTMFManager = require('./modules/DTMF/JitsiDTMFManager');
246
     return this.room.isModerator();
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
  * Elects the participant with the given id to be the selected participant or the speaker.
281
  * Elects the participant with the given id to be the selected participant or the speaker.
251
  * @param id the identifier of the participant
282
  * @param id the identifier of the participant
287
 
318
 
288
 JitsiConference.prototype.onMemberJoined = function (jid, email, nick) {
319
 JitsiConference.prototype.onMemberJoined = function (jid, email, nick) {
289
     var id = Strophe.getResourceFromJid(jid);
320
     var id = Strophe.getResourceFromJid(jid);
321
+    if (id === 'focus') {
322
+       return;
323
+    }
290
     var participant = new JitsiParticipant(id, this, nick);
324
     var participant = new JitsiParticipant(id, this, nick);
291
-    this.eventEmitter.emit(JitsiConferenceEvents.USER_JOINED, id);
292
     this.participants[id] = participant;
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
         jid, "node", function(iq) {
328
         jid, "node", function(iq) {
295
             participant._supportsDTMF = $(iq).find(
329
             participant._supportsDTMF = $(iq).find(
296
                 '>query>feature[var="urn:xmpp:jingle:dtmf:0"]').length > 0;
330
                 '>query>feature[var="urn:xmpp:jingle:dtmf:0"]').length > 0;
301
 
335
 
302
 JitsiConference.prototype.onMemberLeft = function (jid) {
336
 JitsiConference.prototype.onMemberLeft = function (jid) {
303
     var id = Strophe.getResourceFromJid(jid);
337
     var id = Strophe.getResourceFromJid(jid);
338
+    var participant = this.participants[id];
304
     delete this.participants[id];
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
 JitsiConference.prototype.onUserRoleChanged = function (jid, role) {
343
 JitsiConference.prototype.onUserRoleChanged = function (jid, role) {
398
 
433
 
399
 JitsiConference.prototype.sendTones = function (tones, duration, pause) {
434
 JitsiConference.prototype.sendTones = function (tones, duration, pause) {
400
     if (!this.dtmfManager) {
435
     if (!this.dtmfManager) {
401
-        var connection = this.connection.xmpp.connection.jingle.activecall.peerconnection;
436
+        var connection = this.xmpp.connection.jingle.activecall.peerconnection;
402
         if (!connection) {
437
         if (!connection) {
403
             logger.warn("cannot sendTones: no conneciton");
438
             logger.warn("cannot sendTones: no conneciton");
404
             return;
439
             return;
482
             conference.eventEmitter.emit(JitsiConferenceEvents.LAST_N_ENDPOINTS_CHANGED,
517
             conference.eventEmitter.emit(JitsiConferenceEvents.LAST_N_ENDPOINTS_CHANGED,
483
                 lastNEndpoints, endpointsEnteringLastN);
518
                 lastNEndpoints, endpointsEnteringLastN);
484
         });
519
         });
520
+    conference.xmpp.addListener(XMPPEvents.PASSWORD_REQUIRED, function () {
521
+        conference.eventEmitter.emit(JitsiConferenceErrors.PASSWORD_REQUIRED);
522
+    });
485
 
523
 
486
     if(conference.statistics) {
524
     if(conference.statistics) {
487
         //FIXME: Maybe remove event should not be associated with the conference.
525
         //FIXME: Maybe remove event should not be associated with the conference.
508
 module.exports = JitsiConference;
546
 module.exports = JitsiConference;
509
 
547
 
510
 }).call(this,"/JitsiConference.js")
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
  * Enumeration with the errors for the conference.
551
  * Enumeration with the errors for the conference.
514
  * @type {{string: string}}
552
  * @type {{string: string}}
518
      * Indicates that a password is required in order to join the conference.
556
      * Indicates that a password is required in order to join the conference.
519
      */
557
      */
520
     PASSWORD_REQUIRED: "conference.passwordRequired",
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
      * Indicates that a connection error occurred when trying to join a
564
      * Indicates that a connection error occurred when trying to join a
523
      * conference.
565
      * conference.
2333
     // this later can be a problem with some of the tests
2375
     // this later can be a problem with some of the tests
2334
     if(RTCBrowserType.isFirefox() && options.firefox_fake_device)
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
         constraints.fake = true;
2381
         constraints.fake = true;
2338
     }
2382
     }
2339
 
2383
 
2486
 }
2530
 }
2487
 
2531
 
2488
 function obtainDevices(options) {
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
     var device = options.devices.splice(0, 1);
2537
     var device = options.devices.splice(0, 1);
2494
     options.deviceGUM[device](function (stream) {
2538
     options.deviceGUM[device](function (stream) {
2539
+            options.streams = options.streams || {};
2495
             options.streams[device] = stream;
2540
             options.streams[device] = stream;
2496
             obtainDevices(options);
2541
             obtainDevices(options);
2497
         },
2542
         },
5535
         this.eventEmitter.emit(StatisticsEvents.STOP);
5580
         this.eventEmitter.emit(StatisticsEvents.STOP);
5536
         this.rtpStats = null;
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
 Statistics.LOCAL_JID = require("../../service/statistics/constants").LOCAL_JID;
5602
 Statistics.LOCAL_JID = require("../../service/statistics/constants").LOCAL_JID;
5541
 
5603
 
6509
     this.addingStreams = false;
6571
     this.addingStreams = false;
6510
 
6572
 
6511
     this.wait = true;
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
     this.ssrcOwners = {};
6579
     this.ssrcOwners = {};
6514
     this.ssrcVideoTypes = {};
6580
     this.ssrcVideoTypes = {};
6515
 
6581
 
6725
     // FIXME why do we generate session-accept in 3 different places ?
6791
     // FIXME why do we generate session-accept in 3 different places ?
6726
     prsdp.toJingle(
6792
     prsdp.toJingle(
6727
         accept,
6793
         accept,
6728
-        this.initiator == this.me ? 'initiator' : 'responder',
6729
-        this.localStreamsSSRC);
6794
+        this.initiator == this.me ? 'initiator' : 'responder');
6730
     var sdp = this.peerconnection.localDescription.sdp;
6795
     var sdp = this.peerconnection.localDescription.sdp;
6731
     while (SDPUtil.find_line(sdp, 'a=inactive')) {
6796
     while (SDPUtil.find_line(sdp, 'a=inactive')) {
6732
         // FIXME: change any inactive to sendrecv or whatever they were originally
6797
         // FIXME: change any inactive to sendrecv or whatever they were originally
6953
                 sid: this.sid});
7018
                 sid: this.sid});
6954
         self.localSDP.toJingle(
7019
         self.localSDP.toJingle(
6955
             init,
7020
             init,
6956
-            this.initiator == this.me ? 'initiator' : 'responder',
6957
-            this.localStreamsSSRC);
7021
+            this.initiator == this.me ? 'initiator' : 'responder');
6958
 
7022
 
6959
         SSRCReplacement.processSessionInit(init);
7023
         SSRCReplacement.processSessionInit(init);
6960
 
7024
 
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
 JingleSessionPC.prototype.getSsrcOwner = function (ssrc) {
7096
 JingleSessionPC.prototype.getSsrcOwner = function (ssrc) {
7024
     return this.ssrcOwners[ssrc];
7097
     return this.ssrcOwners[ssrc];
7025
 };
7098
 };
7975
                     'ssrc': ssrc.id,
8048
                     'ssrc': ssrc.id,
7976
                     'type': media.type
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
 }
8579
 }
8512
 
8580
 
8513
 // add content's to a jingle element
8581
 // add content's to a jingle element
8514
-SDP.prototype.toJingle = function (elem, thecreator, ssrcs) {
8582
+SDP.prototype.toJingle = function (elem, thecreator) {
8515
 //    logger.log("SSRC" + ssrcs["audio"] + " - " + ssrcs["video"]);
8583
 //    logger.log("SSRC" + ssrcs["audio"] + " - " + ssrcs["video"]);
8516
     var self = this;
8584
     var self = this;
8517
     var i, j, k, mline, ssrc, rtpmap, tmp, lines;
8585
     var i, j, k, mline, ssrc, rtpmap, tmp, lines;
8539
         if (SDPUtil.find_line(this.media[i], 'a=ssrc:')) {
8607
         if (SDPUtil.find_line(this.media[i], 'a=ssrc:')) {
8540
             ssrc = SDPUtil.find_line(this.media[i], 'a=ssrc:').substring(7).split(' ')[0]; // take the first
8608
             ssrc = SDPUtil.find_line(this.media[i], 'a=ssrc:').substring(7).split(' ')[0]; // take the first
8541
         } else {
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
         elem.c('content', {creator: thecreator, name: mline.media});
8613
         elem.c('content', {creator: thecreator, name: mline.media});
10154
                 value: this.xmppService.options.hosts.bridge
10218
                 value: this.xmppService.options.hosts.bridge
10155
             }).up();
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
     // Tell the focus we have Jigasi configured
10228
     // Tell the focus we have Jigasi configured
10158
     if (this.xmppService.options.hosts.call_control !== undefined) {
10229
     if (this.xmppService.options.hosts.call_control !== undefined) {
10159
         elem.c(
10230
         elem.c(
11445
     this.connection.disconnect();
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
 module.exports = XMPP;
11535
 module.exports = XMPP;
11450
 
11536
 

Loading…
取消
儲存