|
@@ -44,6 +44,9 @@ function JitsiConference(options) {
|
44
|
44
|
this.somebodySupportsDTMF = false;
|
45
|
45
|
this.authEnabled = false;
|
46
|
46
|
this.authIdentity;
|
|
47
|
+ this.startAudioMuted = false;
|
|
48
|
+ this.startVideoMuted = false;
|
|
49
|
+ this.tracks = [];
|
47
|
50
|
}
|
48
|
51
|
|
49
|
52
|
/**
|
|
@@ -250,6 +253,16 @@ JitsiConference.prototype.setDisplayName = function(name) {
|
250
|
253
|
JitsiConference.prototype.addTrack = function (track) {
|
251
|
254
|
this.room.addStream(track.getOriginalStream(), function () {
|
252
|
255
|
this.rtc.addLocalStream(track);
|
|
256
|
+ if (this.startAudioMuted && track.isAudioTrack()) {
|
|
257
|
+ track.mute();
|
|
258
|
+ }
|
|
259
|
+ if (this.startVideoMuted && track.isVideoTrack()) {
|
|
260
|
+ track.mute();
|
|
261
|
+ }
|
|
262
|
+ if (track.startMuted) {
|
|
263
|
+ track.mute();
|
|
264
|
+ }
|
|
265
|
+ this.tracks.push(track);
|
253
|
266
|
var muteHandler = this._fireMuteChangeEvent.bind(this, track);
|
254
|
267
|
var stopHandler = this.removeTrack.bind(this, track);
|
255
|
268
|
var audioLevelHandler = this._fireAudioLevelChangeEvent.bind(this);
|
|
@@ -291,6 +304,10 @@ JitsiConference.prototype._fireMuteChangeEvent = function (track) {
|
291
|
304
|
* @param track the JitsiLocalTrack object.
|
292
|
305
|
*/
|
293
|
306
|
JitsiConference.prototype.removeTrack = function (track) {
|
|
307
|
+ var pos = this.tracks.indexOf(track);
|
|
308
|
+ if (pos > -1) {
|
|
309
|
+ this.tracks.splice(pos, 1);
|
|
310
|
+ }
|
294
|
311
|
if(!this.room){
|
295
|
312
|
if(this.rtc)
|
296
|
313
|
this.rtc.removeLocalStream(track);
|
|
@@ -411,12 +428,13 @@ JitsiConference.prototype.muteParticipant = function (id) {
|
411
|
428
|
this.room.muteParticipant(participant.getJid(), true);
|
412
|
429
|
};
|
413
|
430
|
|
414
|
|
-JitsiConference.prototype.onMemberJoined = function (jid, nick) {
|
|
431
|
+JitsiConference.prototype.onMemberJoined = function (jid, nick, role) {
|
415
|
432
|
var id = Strophe.getResourceFromJid(jid);
|
416
|
433
|
if (id === 'focus' || this.myUserId() === id) {
|
417
|
434
|
return;
|
418
|
435
|
}
|
419
|
436
|
var participant = new JitsiParticipant(jid, this, nick);
|
|
437
|
+ participant._role = role;
|
420
|
438
|
this.participants[id] = participant;
|
421
|
439
|
this.eventEmitter.emit(JitsiConferenceEvents.USER_JOINED, id, participant);
|
422
|
440
|
this.xmpp.connection.disco.info(
|
|
@@ -650,6 +668,41 @@ JitsiConference.prototype.getConnectionState = function () {
|
650
|
668
|
return null;
|
651
|
669
|
}
|
652
|
670
|
|
|
671
|
+/**
|
|
672
|
+ * Make all new participants mute their audio/video on join.
|
|
673
|
+ * @param {boolean} audioMuted if audio should be muted.
|
|
674
|
+ * @param {boolean} videoMuted if video should be muted.
|
|
675
|
+ */
|
|
676
|
+JitsiConference.prototype.setStartMuted = function (audioMuted, videoMuted) {
|
|
677
|
+ if (!this.isModerator()) {
|
|
678
|
+ return;
|
|
679
|
+ }
|
|
680
|
+
|
|
681
|
+ this.room.removeFromPresence("startmuted");
|
|
682
|
+ this.room.addToPresence("startmuted", {
|
|
683
|
+ attributes: {
|
|
684
|
+ audio: audioMuted,
|
|
685
|
+ video: videoMuted,
|
|
686
|
+ xmlns: 'http://jitsi.org/jitmeet/start-muted'
|
|
687
|
+ }
|
|
688
|
+ });
|
|
689
|
+ this.room.sendPresence();
|
|
690
|
+};
|
|
691
|
+
|
|
692
|
+/**
|
|
693
|
+ * Check if audio is muted on join.
|
|
694
|
+ */
|
|
695
|
+JitsiConference.prototype.isStartAudioMuted = function () {
|
|
696
|
+ return this.startAudioMuted;
|
|
697
|
+};
|
|
698
|
+
|
|
699
|
+/**
|
|
700
|
+ * Check if video is muted on join.
|
|
701
|
+ */
|
|
702
|
+JitsiConference.prototype.isStartVideoMuted = function () {
|
|
703
|
+ return this.startVideoMuted;
|
|
704
|
+};
|
|
705
|
+
|
653
|
706
|
/**
|
654
|
707
|
* Setups the listeners needed for the conference.
|
655
|
708
|
* @param conference the conference
|
|
@@ -691,6 +744,9 @@ function setupListeners(conference) {
|
691
|
744
|
conference.room.addListener(XMPPEvents.AUTHENTICATION_REQUIRED, function () {
|
692
|
745
|
conference.eventEmitter.emit(JitsiConferenceEvents.CONFERENCE_FAILED, JitsiConferenceErrors.AUTHENTICATION_REQUIRED);
|
693
|
746
|
});
|
|
747
|
+ conference.room.addListener(XMPPEvents.BRIDGE_DOWN, function () {
|
|
748
|
+ conference.eventEmitter.emit(JitsiConferenceEvents.CONFERENCE_FAILED, JitsiConferenceErrors.VIDEOBRIDGE_NOT_AVAILABLE);
|
|
749
|
+ });
|
694
|
750
|
// FIXME
|
695
|
751
|
// conference.room.addListener(XMPPEvents.MUC_JOINED, function () {
|
696
|
752
|
// conference.eventEmitter.emit(JitsiConferenceEvents.CONFERENCE_LEFT);
|
|
@@ -762,6 +818,70 @@ function setupListeners(conference) {
|
762
|
818
|
conference.eventEmitter.emit(JitsiConferenceErrors.PASSWORD_REQUIRED);
|
763
|
819
|
});
|
764
|
820
|
|
|
821
|
+ conference.xmpp.addListener(XMPPEvents.START_MUTED_FROM_FOCUS, function (audioMuted, videoMuted) {
|
|
822
|
+ conference.startAudioMuted = audioMuted;
|
|
823
|
+ conference.startVideoMuted = videoMuted;
|
|
824
|
+
|
|
825
|
+ // mute existing local tracks because this is initial mute from Jicofo
|
|
826
|
+ conference.tracks.forEach(function (track) {
|
|
827
|
+ if (conference.startAudioMuted && track.isAudioTrack()) {
|
|
828
|
+ track.mute();
|
|
829
|
+ }
|
|
830
|
+ if (conference.startVideoMuted && track.isVideoTrack()) {
|
|
831
|
+ track.mute();
|
|
832
|
+ }
|
|
833
|
+ });
|
|
834
|
+
|
|
835
|
+ var initiallyMuted = audioMuted || videoMuted;
|
|
836
|
+
|
|
837
|
+ conference.eventEmitter.emit(
|
|
838
|
+ JitsiConferenceEvents.START_MUTED,
|
|
839
|
+ conference.startAudioMuted,
|
|
840
|
+ conference.startVideoMuted,
|
|
841
|
+ initiallyMuted
|
|
842
|
+ );
|
|
843
|
+ });
|
|
844
|
+
|
|
845
|
+ conference.room.addPresenceListener("startmuted", function (data, from) {
|
|
846
|
+ var isModerator = false;
|
|
847
|
+ if (conference.myUserId() === from && conference.isModerator()) {
|
|
848
|
+ isModerator = true;
|
|
849
|
+ } else {
|
|
850
|
+ var participant = conference.getParticipantById(from);
|
|
851
|
+ if (participant && participant.isModerator()) {
|
|
852
|
+ isModerator = true;
|
|
853
|
+ }
|
|
854
|
+ }
|
|
855
|
+
|
|
856
|
+ if (!isModerator) {
|
|
857
|
+ return;
|
|
858
|
+ }
|
|
859
|
+
|
|
860
|
+ var startAudioMuted = data.attributes.audio === 'true';
|
|
861
|
+ var startVideoMuted = data.attributes.video === 'true';
|
|
862
|
+
|
|
863
|
+ var updated = false;
|
|
864
|
+
|
|
865
|
+ if (startAudioMuted !== conference.startAudioMuted) {
|
|
866
|
+ conference.startAudioMuted = startAudioMuted;
|
|
867
|
+ updated = true;
|
|
868
|
+ }
|
|
869
|
+
|
|
870
|
+ if (startVideoMuted !== conference.startVideoMuted) {
|
|
871
|
+ conference.startVideoMuted = startVideoMuted;
|
|
872
|
+ updated = true;
|
|
873
|
+ }
|
|
874
|
+
|
|
875
|
+ if (updated) {
|
|
876
|
+ conference.eventEmitter.emit(
|
|
877
|
+ JitsiConferenceEvents.START_MUTED,
|
|
878
|
+ conference.startAudioMuted,
|
|
879
|
+ conference.startVideoMuted,
|
|
880
|
+ false
|
|
881
|
+ );
|
|
882
|
+ }
|
|
883
|
+ });
|
|
884
|
+
|
765
|
885
|
if(conference.statistics) {
|
766
|
886
|
//FIXME: Maybe remove event should not be associated with the conference.
|
767
|
887
|
conference.statistics.addAudioLevelListener(function (ssrc, level) {
|