Quellcode durchsuchen

Fixes audio / video mutes

j8
hristoterezov vor 9 Jahren
Ursprung
Commit
29a85b797a

+ 4
- 593
app.js Datei anzeigen

@@ -15,35 +15,15 @@ window.toastr = require("toastr");
15 15
 
16 16
 import URLProcessor from "./modules/config/URLProcessor";
17 17
 import RoomnameGenerator from './modules/util/RoomnameGenerator';
18
-import CQEvents from './service/connectionquality/CQEvents';
19
-import UIEvents from './service/UI/UIEvents';
20
-import DSEvents from './service/desktopsharing/DesktopSharingEventTypes';
21 18
 
22 19
 import UI from "./modules/UI/UI";
23 20
 import statistics from "./modules/statistics/statistics";
24 21
 import settings from "./modules/settings/Settings";
22
+import UIEvents from './service/UI/UIEvents';
25 23
 
26
-import {openConnection} from './modules/connection';
27
-import AuthHandler from './modules/AuthHandler';
28
-
29
-import createRoomLocker from './modules/RoomLocker';
30
-
31
-const ConnectionEvents = JitsiMeetJS.events.connection;
32
-const ConnectionErrors = JitsiMeetJS.errors.connection;
33
-
34
-const ConferenceEvents = JitsiMeetJS.events.conference;
35
-const ConferenceErrors = JitsiMeetJS.errors.conference;
24
+import conference from './conference';
36 25
 
37
-let localVideo, localAudio;
38 26
 
39
-const Commands = {
40
-    CONNECTION_QUALITY: "stats",
41
-    EMAIL: "email",
42
-    VIDEO_TYPE: "videoType",
43
-    ETHERPAD: "etherpad",
44
-    PREZI: "prezi",
45
-    STOP_PREZI: "stop-prezi"
46
-};
47 27
 
48 28
 function buildRoomName () {
49 29
     let path = window.location.pathname;
@@ -77,66 +57,12 @@ function buildRoomName () {
77 57
     return roomName;
78 58
 }
79 59
 
80
-
81 60
 const APP = {
82 61
     UI,
83 62
     statistics,
84 63
     settings,
85
-
86
-    createLocalTracks (...devices) {
87
-        return JitsiMeetJS.createLocalTracks({
88
-            // copy array to avoid mutations inside library
89
-            devices: devices.slice(0),
90
-            resolution: config.resolution
91
-        }).catch(function (err) {
92
-            console.error('failed to create local tracks', ...devices, err);
93
-            APP.statistics.onGetUserMediaFailed(err);
94
-            return [];
95
-        });
96
-    },
97
-
98 64
     init () {
99
-        let roomName = buildRoomName();
100
-        this.conference = {
101
-            roomName,
102
-            localId: undefined,
103
-            isModerator: false,
104
-            membersCount: 0,
105
-            audioMuted: false,
106
-            videoMuted: false,
107
-            isLocalId (id) {
108
-                return this.localId === id;
109
-            },
110
-            muteAudio (mute) {
111
-                APP.UI.eventEmitter.emit(UIEvents.AUDIO_MUTED, mute);
112
-                APP.statistics.onAudioMute(mute);
113
-            },
114
-            toggleAudioMuted () {
115
-                this.muteAudio(!this.audioMuted);
116
-            },
117
-            muteVideo (mute) {
118
-                APP.UI.eventEmitter.emit(UIEvents.VIDEO_MUTED, mute);
119
-                APP.statistics.onVideoMute(mute);
120
-            },
121
-            toggleVideoMuted () {
122
-                this.muteVideo(!this.videoMuted);
123
-            },
124
-
125
-            // used by torture currently
126
-            isJoined () {
127
-                return APP.conference._room
128
-                    && APP.conference._room.isJoined();
129
-            },
130
-            getConnectionState () {
131
-                return APP.conference._room
132
-                    && APP.conference._room.getConnectionState();
133
-            },
134
-            getMyUserId () {
135
-                return APP.conference._room
136
-                    && APP.conference._room.myUserId();
137
-            }
138
-        };
139
-
65
+        this.conference = conference;
140 66
         this.API = require("./modules/API/API");
141 67
         this.connectionquality =
142 68
             require("./modules/connectionquality/connectionquality");
@@ -149,524 +75,9 @@ const APP = {
149 75
     }
150 76
 };
151 77
 
152
-function initConference(localTracks, connection) {
153
-    let options = {
154
-        openSctp: config.openSctp,
155
-        disableAudioLevels: config.disableAudioLevels
156
-    };
157
-    if(config.enableRecording) {
158
-        options.recordingType = (config.hosts &&
159
-            (typeof config.hosts.jirecon != "undefined"))?
160
-            "jirecon" : "colibri";
161
-    }
162
-    let room = connection.initJitsiConference(APP.conference.roomName, options);
163
-    APP.conference._room = room; // FIXME do not use this
164
-
165
-    const addTrack = (track) => {
166
-        room.addTrack(track);
167
-        if (track.isAudioTrack()) {
168
-            return;
169
-        }
170
-
171
-        room.removeCommand(Commands.VIDEO_TYPE);
172
-        room.sendCommand(Commands.VIDEO_TYPE, {
173
-            value: track.videoType,
174
-            attributes: {
175
-                xmlns: 'http://jitsi.org/jitmeet/video'
176
-            }
177
-        });
178
-    };
179
-
180
-    APP.conference.localId = room.myUserId();
181
-    Object.defineProperty(APP.conference, "membersCount", {
182
-        get: function () {
183
-            return room.getParticipants().length; // FIXME maybe +1?
184
-        }
185
-    });
186
-
187
-    APP.conference.listMembers = function () {
188
-        return room.getParticipants();
189
-    };
190
-    APP.conference.listMembersIds = function () {
191
-        return room.getParticipants().map(p => p.getId());
192
-    };
193
-
194
-    APP.conference.sipGatewayEnabled = () => {
195
-        return room.isSIPCallingSupported();
196
-    };
197
-
198
-    function getDisplayName(id) {
199
-        if (APP.conference.isLocalId(id)) {
200
-            return APP.settings.getDisplayName();
201
-        }
202
-
203
-        let participant = room.getParticipantById(id);
204
-        if (participant && participant.getDisplayName()) {
205
-            return participant.getDisplayName();
206
-        }
207
-    }
208
-
209
-    // add local streams when joined to the conference
210
-    room.on(ConferenceEvents.CONFERENCE_JOINED, function () {
211
-        localTracks.forEach(function (track) {
212
-            if(track.isAudioTrack()) {
213
-                localAudio = track;
214
-            }
215
-            else if (track.isVideoTrack()) {
216
-                localVideo = track;
217
-            }
218
-            addTrack(track);
219
-            APP.UI.addLocalStream(track);
220
-        });
221
-
222
-        APP.UI.updateAuthInfo(room.isAuthEnabled(), room.getAuthLogin());
223
-    });
224
-
225
-
226
-    room.on(ConferenceEvents.USER_JOINED, function (id, user) {
227
-        console.log('USER %s connnected', id, user);
228
-        // FIXME email???
229
-        APP.UI.addUser(id, user.getDisplayName());
230
-    });
231
-    room.on(ConferenceEvents.USER_LEFT, function (id, user) {
232
-        console.log('USER %s LEFT', id, user);
233
-        APP.UI.removeUser(id, user.getDisplayName());
234
-        APP.UI.stopPrezi(id);
235
-    });
236
-
237
-
238
-    room.on(ConferenceEvents.USER_ROLE_CHANGED, function (id, role) {
239
-        if (APP.conference.isLocalId(id)) {
240
-            console.info(`My role changed, new role: ${role}`);
241
-            APP.conference.isModerator = room.isModerator();
242
-            APP.UI.updateLocalRole(room.isModerator());
243
-        } else {
244
-            let user = room.getParticipantById(id);
245
-            if (user) {
246
-                APP.UI.updateUserRole(user);
247
-            }
248
-        }
249
-    });
250
-
251
-
252
-    let roomLocker = createRoomLocker(room);
253
-    APP.UI.addListener(UIEvents.ROOM_LOCK_CLICKED, function () {
254
-        if (room.isModerator()) {
255
-            let promise = roomLocker.isLocked
256
-                ? roomLocker.askToUnlock()
257
-                : roomLocker.askToLock();
258
-            promise.then(function () {
259
-                APP.UI.markRoomLocked(roomLocker.isLocked);
260
-            });
261
-        } else {
262
-            roomLocker.notifyModeratorRequired();
263
-        }
264
-    });
265
-
266
-
267
-    room.on(ConferenceEvents.TRACK_ADDED, function (track) {
268
-        if (track.isLocal()) { // skip local tracks
269
-            return;
270
-        }
271
-        console.log(
272
-            'REMOTE %s TRACK', track.getType(), track.getParticipantId()
273
-        );
274
-        APP.UI.addRemoteStream(track);
275
-    });
276
-    room.on(ConferenceEvents.TRACK_REMOVED, function (track) {
277
-        if (track.isLocal()) { // skip local tracks
278
-            return;
279
-        }
280
-
281
-        console.log(
282
-            'REMOTE %s TRACK REMOVED', track.getType(), track.getParticipantId()
283
-        );
284
-
285
-        // FIXME handle
286
-    });
287
-    room.on(ConferenceEvents.TRACK_MUTE_CHANGED, function (track) {
288
-        // FIXME handle mute
289
-    });
290
-    room.on(ConferenceEvents.TRACK_AUDIO_LEVEL_CHANGED, function (id, lvl) {
291
-        APP.UI.setAudioLevel(id, lvl);
292
-    });
293
-    APP.UI.addListener(UIEvents.AUDIO_MUTED, function (muted) {
294
-        // FIXME mute or unmute
295
-        APP.UI.setAudioMuted(muted);
296
-        APP.conference.audioMuted = muted;
297
-    });
298
-    APP.UI.addListener(UIEvents.VIDEO_MUTED, function (muted) {
299
-        // FIXME mute or unmute
300
-        APP.UI.setVideoMuted(muted);
301
-        APP.conference.videoMuted = muted;
302
-    });
303
-
304
-
305
-    room.on(ConferenceEvents.IN_LAST_N_CHANGED, function (inLastN) {
306
-        if (config.muteLocalVideoIfNotInLastN) {
307
-            // TODO mute or unmute if required
308
-            // mark video on UI
309
-            // APP.UI.markVideoMuted(true/false);
310
-        }
311
-    });
312
-    room.on(ConferenceEvents.LAST_N_ENDPOINTS_CHANGED, function (ids) {
313
-        APP.UI.handleLastNEndpoints(ids);
314
-    });
315
-    room.on(ConferenceEvents.ACTIVE_SPEAKER_CHANGED, function (id) {
316
-        APP.UI.markDominantSpiker(id);
317
-    });
318
-
319
-
320
-    if (!interfaceConfig.filmStripOnly) {
321
-        room.on(ConferenceEvents.CONNECTION_INTERRUPTED, function () {
322
-            APP.UI.markVideoInterrupted(true);
323
-        });
324
-        room.on(ConferenceEvents.CONNECTION_RESTORED, function () {
325
-            APP.UI.markVideoInterrupted(false);
326
-        });
327
-
328
-        APP.UI.addListener(UIEvents.MESSAGE_CREATED, function (message) {
329
-            room.sendTextMessage(message);
330
-        });
331
-        room.on(ConferenceEvents.MESSAGE_RECEIVED, function (id, text, ts) {
332
-            APP.UI.addMessage(id, getDisplayName(id), text, ts);
333
-        });
334
-    }
335
-
336
-    APP.connectionquality.addListener(
337
-        CQEvents.LOCALSTATS_UPDATED,
338
-        function (percent, stats) {
339
-            APP.UI.updateLocalStats(percent, stats);
340
-
341
-            // send local stats to other users
342
-            room.sendCommandOnce(Commands.CONNECTION_QUALITY, {
343
-                children: APP.connectionquality.convertToMUCStats(stats),
344
-                attributes: {
345
-                    xmlns: 'http://jitsi.org/jitmeet/stats'
346
-                }
347
-            });
348
-        }
349
-    );
350
-    APP.connectionquality.addListener(CQEvents.STOP, function () {
351
-        APP.UI.hideStats();
352
-        room.removeCommand(Commands.CONNECTION_QUALITY);
353
-    });
354
-    // listen to remote stats
355
-    room.addCommandListener(
356
-        Commands.CONNECTION_QUALITY,
357
-        function (values, from) {
358
-            APP.connectionquality.updateRemoteStats(from, values);
359
-        }
360
-    );
361
-    APP.connectionquality.addListener(
362
-        CQEvents.REMOTESTATS_UPDATED,
363
-        function (id, percent, stats) {
364
-            APP.UI.updateRemoteStats(id, percent, stats);
365
-        }
366
-    );
367
-
368
-    room.addCommandListener(Commands.ETHERPAD, function ({value}) {
369
-        APP.UI.initEtherpad(value);
370
-    });
371
-
372
-
373
-    room.addCommandListener(Commands.PREZI, function ({value, attributes}) {
374
-        APP.UI.showPrezi(attributes.id, value, attributes.slide);
375
-    });
376
-    room.addCommandListener(Commands.STOP_PREZI, function ({attributes}) {
377
-        APP.UI.stopPrezi(attributes.id);
378
-    });
379
-    APP.UI.addListener(UIEvents.SHARE_PREZI, function (url, slide) {
380
-        console.log('Sharing Prezi %s slide %s', url, slide);
381
-        room.removeCommand(Commands.PREZI);
382
-        room.sendCommand(Commands.PREZI, {
383
-            value: url,
384
-            attributes: {
385
-                id: room.myUserId(),
386
-                slide
387
-            }
388
-        });
389
-    });
390
-    APP.UI.addListener(UIEvents.STOP_SHARING_PREZI, function () {
391
-        room.removeCommand(Commands.PREZI);
392
-        room.sendCommandOnce(Commands.STOP_PREZI, {
393
-            attributes: {
394
-                id: room.myUserId()
395
-            }
396
-        });
397
-    });
398
-
399
-    room.addCommandListener(Commands.VIDEO_TYPE, ({value}, from) => {
400
-        APP.UI.onPeerVideoTypeChanged(from, value);
401
-    });
402
-
403
-
404
-    // share email with other users
405
-    function sendEmail(email) {
406
-        room.sendCommand(Commands.EMAIL, {
407
-            value: email,
408
-            attributes: {
409
-                id: room.myUserId()
410
-            }
411
-        });
412
-    }
413
-
414
-    let email = APP.settings.getEmail();
415
-    email && sendEmail(email);
416
-    APP.UI.addListener(UIEvents.EMAIL_CHANGED, function (email) {
417
-        APP.settings.setEmail(email);
418
-        APP.UI.setUserAvatar(room.myUserId(), email);
419
-        sendEmail(email);
420
-    });
421
-    room.addCommandListener(Commands.EMAIL, function (data) {
422
-        APP.UI.setUserAvatar(data.attributes.id, data.value);
423
-    });
424
-
425
-    let nick = APP.settings.getDisplayName();
426
-    if (config.useNicks && !nick) {
427
-        nick = APP.UI.askForNickname();
428
-        APP.settings.setDisplayName(nick);
429
-    }
430
-
431
-    if (nick) {
432
-        room.setDisplayName(nick);
433
-    }
434
-    room.on(ConferenceEvents.DISPLAY_NAME_CHANGED, function (id, displayName) {
435
-        APP.UI.changeDisplayName(id, displayName);
436
-    });
437
-
438
-    room.on(ConferenceEvents.RECORDING_STATE_CHANGED, (status, error) => {
439
-        if(status == "error") {
440
-            console.error(error);
441
-            return;
442
-        }
443
-        APP.UI.updateRecordingState(status);
444
-    });
445
-
446
-    APP.UI.addListener(UIEvents.NICKNAME_CHANGED, function (nickname) {
447
-        APP.settings.setDisplayName(nickname);
448
-        room.setDisplayName(nickname);
449
-        APP.UI.changeDisplayName(APP.conference.localId, nickname);
450
-    });
451
-
452
-    APP.UI.addListener(
453
-        UIEvents.START_MUTED_CHANGED,
454
-        function (startAudioMuted, startVideoMuted) {
455
-            // FIXME start muted
456
-        }
457
-    );
458
-
459
-    APP.UI.addListener(UIEvents.USER_INVITED, function (roomUrl) {
460
-        APP.UI.inviteParticipants(
461
-            roomUrl,
462
-            APP.conference.roomName,
463
-            roomLocker.password,
464
-            APP.settings.getDisplayName()
465
-        );
466
-    });
467
-
468
-    // call hangup
469
-    APP.UI.addListener(UIEvents.HANGUP, function () {
470
-        APP.UI.requestFeedback().then(function () {
471
-            connection.disconnect();
472
-
473
-            if (config.enableWelcomePage) {
474
-                setTimeout(function() {
475
-                    window.localStorage.welcomePageDisabled = false;
476
-                    window.location.pathname = "/";
477
-                }, 3000);
478
-            }
479
-        }, function (err) {
480
-            console.error(err);
481
-        });
482
-    });
483
-
484
-    // logout
485
-    APP.UI.addListener(UIEvents.LOGOUT, function () {
486
-        // FIXME handle logout
487
-        // APP.xmpp.logout(function (url) {
488
-        //     if (url) {
489
-        //         window.location.href = url;
490
-        //     } else {
491
-        //         hangup();
492
-        //     }
493
-        // });
494
-    });
495
-
496
-    APP.UI.addListener(UIEvents.SIP_DIAL, function (sipNumber) {
497
-        room.dial(sipNumber);
498
-    });
499
-
500
-
501
-    // Starts or stops the recording for the conference.
502
-    APP.UI.addListener(UIEvents.RECORDING_TOGGLE, function (predefinedToken) {
503
-        if (predefinedToken) {
504
-            room.toggleRecording({token: predefinedToken});
505
-            return;
506
-        }
507
-        APP.UI.requestRecordingToken().then((token) => {
508
-            room.toggleRecording({token: token});
509
-        });
510
-
511
-    });
512
-
513
-    APP.UI.addListener(UIEvents.TOPIC_CHANGED, function (topic) {
514
-        // FIXME handle topic change
515
-        // APP.xmpp.setSubject(topic);
516
-        // on SUBJECT_CHANGED UI.setSubject(topic);
517
-    });
518
-
519
-    APP.UI.addListener(UIEvents.USER_KICKED, function (id) {
520
-        room.kickParticipant(id);
521
-    });
522
-
523
-    APP.UI.addListener(UIEvents.REMOTE_AUDIO_MUTED, function (id) {
524
-        room.muteParticipant(id);
525
-    });
526
-
527
-    room.on(ConferenceEvents.KICKED, function () {
528
-        APP.UI.notifyKicked();
529
-        // FIXME close
530
-    });
531
-
532
-    APP.UI.addListener(UIEvents.AUTH_CLICKED, function () {
533
-        AuthHandler.authenticate(room);
534
-    });
535
-
536
-    APP.UI.addListener(UIEvents.SELECTED_ENDPOINT, function (id) {
537
-        room.selectParticipant(id);
538
-    });
539
-
540
-    room.on(ConferenceEvents.DTMF_SUPPORT_CHANGED, function (isDTMFSupported) {
541
-        APP.UI.updateDTMFSupport(isDTMFSupported);
542
-    });
543
-
544
-    APP.UI.addListener(UIEvents.TOGGLE_SCREENSHARING, function () {
545
-        APP.desktopsharing.toggleScreenSharing();
546
-    });
547
-    APP.UI.addListener(DSEvents.SWITCHING_DONE, function (isSharingScreen) {
548
-        APP.UI.updateDesktopSharingButtons(isSharingScreen);
549
-    });
550
-    APP.desktopsharing.addListener(
551
-        DSEvents.NEW_STREAM_CREATED,
552
-        (track, callback) => {
553
-            const localCallback = (newTrack) => {
554
-                if (newTrack.isLocal() && newTrack === localVideo) {
555
-                    if(localVideo.isMuted() &&
556
-                       localVideo.videoType !== track.videoType) {
557
-                        localVideo.mute();
558
-                    }
559
-                    callback();
560
-                    room.off(ConferenceEvents.TRACK_ADDED, localCallback);
561
-                }
562
-            };
563
-
564
-            room.on(ConferenceEvents.TRACK_ADDED, localCallback);
565
-
566
-            localVideo.stop();
567
-            localVideo = track;
568
-            addTrack(track);
569
-            APP.UI.addLocalStream(track);
570
-        }
571
-    );
572
-
573
-    const unload = () => {
574
-        room.leave();
575
-        connection.disconnect();
576
-    };
577
-    $(window).bind('beforeunload', unload );
578
-    $(window).bind('unload', unload );
579
-
580
-    return new Promise(function (resolve, reject) {
581
-        room.on(ConferenceEvents.CONFERENCE_JOINED, handleConferenceJoined);
582
-        room.on(ConferenceEvents.CONFERENCE_FAILED, onConferenceFailed);
583
-
584
-        let password;
585
-        let reconnectTimeout;
586
-
587
-        function unsubscribe() {
588
-            room.off(
589
-                ConferenceEvents.CONFERENCE_JOINED, handleConferenceJoined
590
-            );
591
-            room.off(
592
-                ConferenceEvents.CONFERENCE_FAILED, onConferenceFailed
593
-            );
594
-            if (reconnectTimeout) {
595
-                clearTimeout(reconnectTimeout);
596
-            }
597
-            AuthHandler.closeAuth();
598
-        }
599
-
600
-        function handleConferenceJoined() {
601
-            unsubscribe();
602
-            resolve();
603
-        }
604
-
605
-        function handleConferenceFailed(err) {
606
-            unsubscribe();
607
-            reject(err);
608
-        }
609
-
610
-        function onConferenceFailed(err, msg = '') {
611
-            console.error('CONFERENCE FAILED:', err, msg);
612
-            switch (err) {
613
-                // room is locked by the password
614
-            case ConferenceErrors.PASSWORD_REQUIRED:
615
-                APP.UI.markRoomLocked(true);
616
-                roomLocker.requirePassword().then(function () {
617
-                    room.join(roomLocker.password);
618
-                });
619
-                break;
620
-
621
-            case ConferenceErrors.CONNECTION_ERROR:
622
-                APP.UI.notifyConnectionFailed(msg);
623
-                break;
624
-
625
-                // not enough rights to create conference
626
-            case ConferenceErrors.AUTHENTICATION_REQUIRED:
627
-                // schedule reconnect to check if someone else created the room
628
-                reconnectTimeout = setTimeout(function () {
629
-                    room.join(password);
630
-                }, 5000);
631
-
632
-                // notify user that auth is required
633
-                AuthHandler.requireAuth(APP.conference.roomName);
634
-                break;
635
-
636
-            default:
637
-                handleConferenceFailed(err);
638
-            }
639
-        }
640
-
641
-        room.join(password);
642
-    });
643
-}
644
-
645
-function connect() {
646
-    return openConnection({retry: true}).catch(function (err) {
647
-        if (err === ConnectionErrors.PASSWORD_REQUIRED) {
648
-            APP.UI.notifyTokenAuthFailed();
649
-        } else {
650
-            APP.UI.notifyConnectionFailed(err);
651
-        }
652
-        throw err;
653
-    });
654
-}
655
-
656 78
 function init() {
657 79
     APP.UI.start();
658
-
659
-    JitsiMeetJS.setLogLevel(JitsiMeetJS.logLevels.TRACE);
660
-
661
-    JitsiMeetJS.init(config).then(function () {
662
-        return Promise.all([
663
-            APP.createLocalTracks('audio', 'video'),
664
-            connect()
665
-        ]);
666
-    }).then(function ([tracks, connection]) {
667
-        console.log('initialized with %s local tracks', tracks.length);
668
-        return initConference(tracks, connection);
669
-    }).then(function () {
80
+    APP.conference.init({roomName: buildRoomName()}).then(function () {
670 81
         APP.UI.initConference();
671 82
 
672 83
         APP.UI.addListener(UIEvents.LANG_CHANGED, function (language) {

+ 614
- 0
conference.js Datei anzeigen

@@ -0,0 +1,614 @@
1
+/* global $, APP, JitsiMeetJS, config, interfaceConfig */
2
+import {openConnection} from './connection';
3
+//FIXME:
4
+import createRoomLocker from './modules/UI/authentication/RoomLocker';
5
+//FIXME:
6
+import AuthHandler from './modules/UI/authentication/AuthHandler';
7
+
8
+import CQEvents from './service/connectionquality/CQEvents';
9
+import UIEvents from './service/UI/UIEvents';
10
+import DSEvents from './service/desktopsharing/DesktopSharingEventTypes';
11
+
12
+const ConnectionEvents = JitsiMeetJS.events.connection;
13
+const ConnectionErrors = JitsiMeetJS.errors.connection;
14
+
15
+const ConferenceEvents = JitsiMeetJS.events.conference;
16
+const ConferenceErrors = JitsiMeetJS.errors.conference;
17
+
18
+let room, connection, localTracks, localAudio, localVideo;
19
+let roomLocker = createRoomLocker(room);
20
+
21
+const Commands = {
22
+    CONNECTION_QUALITY: "stats",
23
+    EMAIL: "email",
24
+    VIDEO_TYPE: "videoType",
25
+    ETHERPAD: "etherpad",
26
+    PREZI: "prezi",
27
+    STOP_PREZI: "stop-prezi"
28
+};
29
+
30
+function connect() {
31
+    return openConnection({retry: true}).catch(function (err) {
32
+        if (err === ConnectionErrors.PASSWORD_REQUIRED) {
33
+            APP.UI.notifyTokenAuthFailed();
34
+        } else {
35
+            APP.UI.notifyConnectionFailed(err);
36
+        }
37
+        throw err;
38
+    });
39
+}
40
+
41
+const addTrack = (track) => {
42
+    room.addTrack(track);
43
+    if (track.isAudioTrack()) {
44
+        return;
45
+    }
46
+
47
+    room.removeCommand(Commands.VIDEO_TYPE);
48
+    room.sendCommand(Commands.VIDEO_TYPE, {
49
+        value: track.videoType,
50
+        attributes: {
51
+            xmlns: 'http://jitsi.org/jitmeet/video'
52
+        }
53
+    });
54
+};
55
+
56
+// share email with other users
57
+const sendEmail = (email) => {
58
+    room.sendCommand(Commands.EMAIL, {
59
+        value: email,
60
+        attributes: {
61
+            id: room.myUserId()
62
+        }
63
+    });
64
+};
65
+
66
+
67
+const unload = () => {
68
+    room.leave();
69
+    connection.disconnect();
70
+};
71
+
72
+const getDisplayName = (id) => {
73
+    if (APP.conference.isLocalId(id)) {
74
+        return APP.settings.getDisplayName();
75
+    }
76
+
77
+    let participant = room.getParticipantById(id);
78
+    if (participant && participant.getDisplayName()) {
79
+        return participant.getDisplayName();
80
+    }
81
+};
82
+
83
+class ConferenceConnector {
84
+    constructor(resolve, reject) {
85
+        this._resolve = resolve;
86
+        this._reject = reject;
87
+        this.reconnectTimeout = null;
88
+        room.on(ConferenceEvents.CONFERENCE_JOINED,
89
+            this._handleConferenceJoined.bind(this));
90
+        room.on(ConferenceEvents.CONFERENCE_FAILED,
91
+            this._onConferenceFailed.bind(this));
92
+    }
93
+    _handleConferenceFailed(err) {
94
+        this._unsubscribe();
95
+        this._reject(err);
96
+    }
97
+    _onConferenceFailed(err, msg = '') {
98
+        console.error('CONFERENCE FAILED:', err, msg);
99
+        switch (err) {
100
+            // room is locked by the password
101
+        case ConferenceErrors.PASSWORD_REQUIRED:
102
+            APP.UI.markRoomLocked(true);
103
+            roomLocker.requirePassword().then(function () {
104
+                room.join(roomLocker.password);
105
+            });
106
+            break;
107
+
108
+        case ConferenceErrors.CONNECTION_ERROR:
109
+            APP.UI.notifyConnectionFailed(msg);
110
+            break;
111
+
112
+            // not enough rights to create conference
113
+        case ConferenceErrors.AUTHENTICATION_REQUIRED:
114
+            // schedule reconnect to check if someone else created the room
115
+            this.reconnectTimeout = setTimeout(function () {
116
+                room.join();
117
+            }, 5000);
118
+
119
+            // notify user that auth is required
120
+            AuthHandler.requireAuth(APP.conference.roomName);
121
+            break;
122
+
123
+        default:
124
+            this.handleConferenceFailed(err);
125
+        }
126
+    }
127
+    _unsubscribe() {
128
+        room.off(
129
+            ConferenceEvents.CONFERENCE_JOINED, this._handleConferenceJoined);
130
+        room.off(
131
+            ConferenceEvents.CONFERENCE_FAILED, this._onConferenceFailed);
132
+        if (this.reconnectTimeout !== null) {
133
+            clearTimeout(this.reconnectTimeout);
134
+        }
135
+        AuthHandler.closeAuth();
136
+    }
137
+    _handleConferenceJoined() {
138
+        this._unsubscribe();
139
+        this._resolve();
140
+    }
141
+    connect() {
142
+        room.join();
143
+    }
144
+}
145
+
146
+export default {
147
+    localId: undefined,
148
+    isModerator: false,
149
+    audioMuted: false,
150
+    videoMuted: false,
151
+    init(options) {
152
+        this.roomName = options.roomName;
153
+        JitsiMeetJS.setLogLevel(JitsiMeetJS.logLevels.TRACE);
154
+
155
+        return JitsiMeetJS.init(config).then(() => {
156
+            return Promise.all([
157
+                this.createLocalTracks('audio', 'video'),
158
+                connect()
159
+            ]);
160
+        }).then(([tracks, con]) => {
161
+            console.log('initialized with %s local tracks', tracks.length);
162
+            localTracks = tracks;
163
+            connection = con;
164
+            this._createRoom();
165
+            $(window).bind('beforeunload', unload );
166
+            $(window).bind('unload', unload );
167
+            return new Promise((resolve, reject) => {
168
+                (new ConferenceConnector(resolve, reject)).connect();
169
+            });
170
+        });
171
+    },
172
+    createLocalTracks (...devices) {
173
+        return JitsiMeetJS.createLocalTracks({
174
+            // copy array to avoid mutations inside library
175
+            devices: devices.slice(0),
176
+            resolution: config.resolution
177
+        }).catch(function (err) {
178
+            console.error('failed to create local tracks', ...devices, err);
179
+            APP.statistics.onGetUserMediaFailed(err);
180
+            return [];
181
+        });
182
+    },
183
+    isLocalId (id) {
184
+        return this.localId === id;
185
+    },
186
+    /**
187
+     * Simulates toolbar button click for audio mute. Used by shortcuts and API.
188
+     * @param mute true for mute and false for unmute.
189
+     */
190
+    muteAudio (mute) {
191
+        //FIXME: Maybe we should create method for that in the UI instead of
192
+        //accessing directly eventEmitter????
193
+        APP.UI.eventEmitter.emit(UIEvents.AUDIO_MUTED, mute);
194
+    },
195
+    /**
196
+     * Simulates toolbar button click for audio mute. Used by shortcuts and API.
197
+     */
198
+    toggleAudioMuted () {
199
+        this.muteAudio(!this.audioMuted);
200
+    },
201
+    /**
202
+     * Simulates toolbar button click for video mute. Used by shortcuts and API.
203
+     * @param mute true for mute and false for unmute.
204
+     */
205
+    muteVideo (mute) {
206
+        //FIXME: Maybe we should create method for that in the UI instead of
207
+        //accessing directly eventEmitter????
208
+        APP.UI.eventEmitter.emit(UIEvents.VIDEO_MUTED, mute);
209
+    },
210
+    /**
211
+     * Simulates toolbar button click for video mute. Used by shortcuts and API.
212
+     */
213
+    toggleVideoMuted () {
214
+        this.muteVideo(!this.videoMuted);
215
+    },
216
+    listMembers () {
217
+        return room.getParticipants();
218
+    },
219
+    listMembersIds () {
220
+        return room.getParticipants().map(p => p.getId());
221
+    },
222
+    sipGatewayEnabled () {
223
+        return room.isSIPCallingSupported();
224
+    },
225
+    get membersCount () {
226
+        return room.getParticipants().length; // FIXME maybe +1?
227
+    },
228
+    // used by torture currently
229
+    isJoined () {
230
+        return this._room
231
+            && this._room.isJoined();
232
+    },
233
+    getConnectionState () {
234
+        return this._room
235
+            && this._room.getConnectionState();
236
+    },
237
+    getMyUserId () {
238
+        return this._room
239
+            && this._room.myUserId();
240
+    },
241
+    _createRoom () {
242
+        room = connection.initJitsiConference(APP.conference.roomName,
243
+            this._getConferenceOptions());
244
+        this._room = room; // FIXME do not use this
245
+        this.localId = room.myUserId();
246
+
247
+        let email = APP.settings.getEmail();
248
+        email && sendEmail(email);
249
+
250
+        let nick = APP.settings.getDisplayName();
251
+        (config.useNicks && !nick) && (() => {
252
+            nick = APP.UI.askForNickname();
253
+            APP.settings.setDisplayName(nick);
254
+        })();
255
+        nick && room.setDisplayName(nick);
256
+
257
+        this._setupListeners();
258
+    },
259
+    _getConferenceOptions() {
260
+        let options = {
261
+            openSctp: config.openSctp,
262
+            disableAudioLevels: config.disableAudioLevels
263
+        };
264
+        if(config.enableRecording) {
265
+            options.recordingType = (config.hosts &&
266
+                (typeof config.hosts.jirecon != "undefined"))?
267
+                "jirecon" : "colibri";
268
+        }
269
+        return options;
270
+    },
271
+    _setupListeners () {
272
+        // add local streams when joined to the conference
273
+        room.on(ConferenceEvents.CONFERENCE_JOINED, () => {
274
+            localTracks.forEach((track) => {
275
+                if(track.isAudioTrack()) {
276
+                    localAudio = track;
277
+                }
278
+                else if (track.isVideoTrack()) {
279
+                    localVideo = track;
280
+                }
281
+                addTrack(track);
282
+                APP.UI.addLocalStream(track);
283
+            });
284
+
285
+            APP.UI.updateAuthInfo(room.isAuthEnabled(), room.getAuthLogin());
286
+        });
287
+
288
+
289
+        room.on(ConferenceEvents.USER_JOINED, (id, user) => {
290
+            console.log('USER %s connnected', id, user);
291
+            // FIXME email???
292
+            APP.UI.addUser(id, user.getDisplayName());
293
+        });
294
+        room.on(ConferenceEvents.USER_LEFT, (id, user) => {
295
+            console.log('USER %s LEFT', id, user);
296
+            APP.UI.removeUser(id, user.getDisplayName());
297
+            APP.UI.stopPrezi(id);
298
+        });
299
+
300
+
301
+        room.on(ConferenceEvents.USER_ROLE_CHANGED, (id, role) => {
302
+            if (this.isLocalId(id)) {
303
+                console.info(`My role changed, new role: ${role}`);
304
+                this.isModerator = room.isModerator();
305
+                APP.UI.updateLocalRole(room.isModerator());
306
+            } else {
307
+                let user = room.getParticipantById(id);
308
+                if (user) {
309
+                    APP.UI.updateUserRole(user);
310
+                }
311
+            }
312
+        });
313
+
314
+        room.on(ConferenceEvents.TRACK_ADDED, (track) => {
315
+            if(!track || track.isLocal())
316
+                return;
317
+            APP.UI.addRemoteStream(track);
318
+        });
319
+
320
+        room.on(ConferenceEvents.TRACK_REMOVED, (track) => {
321
+            // FIXME handle
322
+        });
323
+
324
+        room.on(ConferenceEvents.TRACK_MUTE_CHANGED, (track) => {
325
+            if(!track)
326
+                return;
327
+            const handler = (track.getType() === "audio")?
328
+                APP.UI.setAudioMuted : APP.UI.setVideoMuted;
329
+            let id;
330
+            const mute = track.isMuted();
331
+            if(track.isLocal()){
332
+                id = this.localId;
333
+                (track.getType() === "audio")?
334
+                    APP.statistics.onAudioMute(mute) :
335
+                    APP.statistics.onVideoMute(mute);
336
+            } else {
337
+                id = track.getParticipantId();
338
+            }
339
+            handler(id , mute);
340
+        });
341
+        room.on(ConferenceEvents.TRACK_AUDIO_LEVEL_CHANGED, (id, lvl) => {
342
+            if(this.isLocalId(id) && localAudio.isMuted()) {
343
+                lvl = 0;
344
+            }
345
+            APP.UI.setAudioLevel(id, lvl);
346
+        });
347
+
348
+        room.on(ConferenceEvents.IN_LAST_N_CHANGED, (inLastN) => {
349
+            //FIXME
350
+            if (config.muteLocalVideoIfNotInLastN) {
351
+                // TODO mute or unmute if required
352
+                // mark video on UI
353
+                // APP.UI.markVideoMuted(true/false);
354
+            }
355
+        });
356
+        room.on(ConferenceEvents.LAST_N_ENDPOINTS_CHANGED, (ids) => {
357
+            APP.UI.handleLastNEndpoints(ids);
358
+        });
359
+        room.on(ConferenceEvents.ACTIVE_SPEAKER_CHANGED, (id) => {
360
+            APP.UI.markDominantSpiker(id);
361
+        });
362
+
363
+        if (!interfaceConfig.filmStripOnly) {
364
+            room.on(ConferenceEvents.CONNECTION_INTERRUPTED, () => {
365
+                APP.UI.markVideoInterrupted(true);
366
+            });
367
+            room.on(ConferenceEvents.CONNECTION_RESTORED, () => {
368
+                APP.UI.markVideoInterrupted(false);
369
+            });
370
+            room.on(ConferenceEvents.MESSAGE_RECEIVED, (id, text, ts) => {
371
+                APP.UI.addMessage(id, getDisplayName(id), text, ts);
372
+            });
373
+        }
374
+
375
+        room.on(ConferenceEvents.DISPLAY_NAME_CHANGED, (id, displayName) => {
376
+            APP.UI.changeDisplayName(id, displayName);
377
+        });
378
+
379
+        room.on(ConferenceEvents.RECORDING_STATE_CHANGED, (status, error) => {
380
+            if(status == "error") {
381
+                console.error(error);
382
+                return;
383
+            }
384
+            APP.UI.updateRecordingState(status);
385
+        });
386
+
387
+        room.on(ConferenceEvents.KICKED, () => {
388
+            APP.UI.notifyKicked();
389
+            // FIXME close
390
+        });
391
+
392
+        room.on(ConferenceEvents.DTMF_SUPPORT_CHANGED, (isDTMFSupported) => {
393
+            APP.UI.updateDTMFSupport(isDTMFSupported);
394
+        });
395
+
396
+        APP.UI.addListener(UIEvents.ROOM_LOCK_CLICKED, () => {
397
+            if (room.isModerator()) {
398
+                let promise = roomLocker.isLocked
399
+                    ? roomLocker.askToUnlock()
400
+                    : roomLocker.askToLock();
401
+                promise.then(() => {
402
+                    APP.UI.markRoomLocked(roomLocker.isLocked);
403
+                });
404
+            } else {
405
+                roomLocker.notifyModeratorRequired();
406
+            }
407
+        });
408
+
409
+        APP.UI.addListener(UIEvents.AUDIO_MUTED, (muted) => {
410
+            (muted)? localAudio.mute() : localAudio.unmute();
411
+            this.audioMuted = muted;
412
+        });
413
+        APP.UI.addListener(UIEvents.VIDEO_MUTED, (muted) => {
414
+            (muted)? localVideo.mute() : localVideo.unmute();
415
+            this.videoMuted = muted;
416
+        });
417
+
418
+        if (!interfaceConfig.filmStripOnly) {
419
+            APP.UI.addListener(UIEvents.MESSAGE_CREATED, (message) => {
420
+                room.sendTextMessage(message);
421
+            });
422
+        }
423
+
424
+        APP.connectionquality.addListener(
425
+            CQEvents.LOCALSTATS_UPDATED,
426
+            (percent, stats) => {
427
+                APP.UI.updateLocalStats(percent, stats);
428
+
429
+                // send local stats to other users
430
+                room.sendCommandOnce(Commands.CONNECTION_QUALITY, {
431
+                    children: APP.connectionquality.convertToMUCStats(stats),
432
+                    attributes: {
433
+                        xmlns: 'http://jitsi.org/jitmeet/stats'
434
+                    }
435
+                });
436
+            }
437
+        );
438
+
439
+        APP.connectionquality.addListener(CQEvents.STOP, () => {
440
+            APP.UI.hideStats();
441
+            room.removeCommand(Commands.CONNECTION_QUALITY);
442
+        });
443
+
444
+        // listen to remote stats
445
+        room.addCommandListener(Commands.CONNECTION_QUALITY,(values, from) => {
446
+            APP.connectionquality.updateRemoteStats(from, values);
447
+        });
448
+
449
+        APP.connectionquality.addListener(CQEvents.REMOTESTATS_UPDATED,
450
+            (id, percent, stats) => {
451
+                APP.UI.updateRemoteStats(id, percent, stats);
452
+            });
453
+
454
+        room.addCommandListener(Commands.ETHERPAD, ({value}) => {
455
+            APP.UI.initEtherpad(value);
456
+        });
457
+
458
+        room.addCommandListener(Commands.PREZI, ({value, attributes}) => {
459
+            APP.UI.showPrezi(attributes.id, value, attributes.slide);
460
+        });
461
+
462
+        room.addCommandListener(Commands.STOP_PREZI, ({attributes}) => {
463
+            APP.UI.stopPrezi(attributes.id);
464
+        });
465
+
466
+        APP.UI.addListener(UIEvents.SHARE_PREZI, (url, slide) => {
467
+            console.log('Sharing Prezi %s slide %s', url, slide);
468
+            room.removeCommand(Commands.PREZI);
469
+            room.sendCommand(Commands.PREZI, {
470
+                value: url,
471
+                attributes: {
472
+                    id: room.myUserId(),
473
+                    slide
474
+                }
475
+            });
476
+        });
477
+
478
+        APP.UI.addListener(UIEvents.STOP_SHARING_PREZI, () => {
479
+            room.removeCommand(Commands.PREZI);
480
+            room.sendCommandOnce(Commands.STOP_PREZI, {
481
+                attributes: {
482
+                    id: room.myUserId()
483
+                }
484
+            });
485
+        });
486
+
487
+        room.addCommandListener(Commands.VIDEO_TYPE, ({value}, from) => {
488
+            APP.UI.onPeerVideoTypeChanged(from, value);
489
+        });
490
+
491
+        APP.UI.addListener(UIEvents.EMAIL_CHANGED, (email) => {
492
+            APP.settings.setEmail(email);
493
+            APP.UI.setUserAvatar(room.myUserId(), email);
494
+            sendEmail(email);
495
+        });
496
+        room.addCommandListener(Commands.EMAIL, (data) => {
497
+            APP.UI.setUserAvatar(data.attributes.id, data.value);
498
+        });
499
+
500
+        APP.UI.addListener(UIEvents.NICKNAME_CHANGED, (nickname) => {
501
+            APP.settings.setDisplayName(nickname);
502
+            room.setDisplayName(nickname);
503
+            APP.UI.changeDisplayName(APP.conference.localId, nickname);
504
+        });
505
+
506
+        APP.UI.addListener(UIEvents.START_MUTED_CHANGED,
507
+            (startAudioMuted, startVideoMuted) => {
508
+                // FIXME start muted
509
+            }
510
+        );
511
+
512
+        APP.UI.addListener(UIEvents.USER_INVITED, (roomUrl) => {
513
+            APP.UI.inviteParticipants(
514
+                roomUrl,
515
+                APP.conference.roomName,
516
+                roomLocker.password,
517
+                APP.settings.getDisplayName()
518
+            );
519
+        });
520
+
521
+        // call hangup
522
+        APP.UI.addListener(UIEvents.HANGUP, () => {
523
+            APP.UI.requestFeedback().then(() => {
524
+                connection.disconnect();
525
+                config.enableWelcomePage && setTimeout(() => {
526
+                        window.localStorage.welcomePageDisabled = false;
527
+                        window.location.pathname = "/";
528
+                    }, 3000);
529
+            }, (err) => {console.error(err);});
530
+        });
531
+
532
+        // logout
533
+        APP.UI.addListener(UIEvents.LOGOUT, () => {
534
+            // FIXME handle logout
535
+            // APP.xmpp.logout(function (url) {
536
+            //     if (url) {
537
+            //         window.location.href = url;
538
+            //     } else {
539
+            //         hangup();
540
+            //     }
541
+            // });
542
+        });
543
+
544
+        APP.UI.addListener(UIEvents.SIP_DIAL, (sipNumber) => {
545
+            room.dial(sipNumber);
546
+        });
547
+
548
+
549
+        // Starts or stops the recording for the conference.
550
+        APP.UI.addListener(UIEvents.RECORDING_TOGGLE, (predefinedToken) => {
551
+            if (predefinedToken) {
552
+                room.toggleRecording({token: predefinedToken});
553
+                return;
554
+            }
555
+            APP.UI.requestRecordingToken().then((token) => {
556
+                room.toggleRecording({token: token});
557
+            });
558
+
559
+        });
560
+
561
+        APP.UI.addListener(UIEvents.TOPIC_CHANGED, (topic) => {
562
+            // FIXME handle topic change
563
+            // APP.xmpp.setSubject(topic);
564
+            // on SUBJECT_CHANGED UI.setSubject(topic);
565
+        });
566
+
567
+        APP.UI.addListener(UIEvents.USER_KICKED, (id) => {
568
+            room.kickParticipant(id);
569
+        });
570
+
571
+        APP.UI.addListener(UIEvents.REMOTE_AUDIO_MUTED, (id) => {
572
+            room.muteParticipant(id);
573
+        });
574
+
575
+        APP.UI.addListener(UIEvents.AUTH_CLICKED, () => {
576
+            AuthHandler.authenticate(room);
577
+        });
578
+
579
+        APP.UI.addListener(UIEvents.SELECTED_ENDPOINT, (id) => {
580
+            room.selectParticipant(id);
581
+        });
582
+
583
+        APP.UI.addListener(UIEvents.TOGGLE_SCREENSHARING, () => {
584
+            APP.desktopsharing.toggleScreenSharing();
585
+        });
586
+
587
+        APP.UI.addListener(DSEvents.SWITCHING_DONE, (isSharingScreen) => {
588
+            APP.UI.updateDesktopSharingButtons(isSharingScreen);
589
+        });
590
+
591
+        APP.desktopsharing.addListener(DSEvents.NEW_STREAM_CREATED,
592
+            (track, callback) => {
593
+                const localCallback = (newTrack) => {
594
+                    if(!newTrack)
595
+                        return;
596
+                    if (newTrack.isLocal() && newTrack === localVideo) {
597
+                        if(localVideo.isMuted() &&
598
+                           localVideo.videoType !== track.videoType) {
599
+                            localVideo.mute();
600
+                        }
601
+                        callback();
602
+                        room.off(ConferenceEvents.TRACK_ADDED, localCallback);
603
+                    }
604
+                };
605
+
606
+                room.on(ConferenceEvents.TRACK_ADDED, localCallback);
607
+                localVideo.stop();
608
+                localVideo = track;
609
+                addTrack(track);
610
+                APP.UI.addLocalStream(track);
611
+            }
612
+        );
613
+    }
614
+};

modules/connection.js → connection.js Datei anzeigen

@@ -1,6 +1,6 @@
1 1
 /* global APP, JitsiMeetJS, config */
2
-
3
-import LoginDialog from './UI/authentication/LoginDialog';
2
+//FIXME:
3
+import LoginDialog from './modules/UI/authentication/LoginDialog';
4 4
 
5 5
 const ConnectionEvents = JitsiMeetJS.events.connection;
6 6
 const ConnectionErrors = JitsiMeetJS.errors.connection;

+ 1
- 1
index.html Datei anzeigen

@@ -13,7 +13,7 @@
13 13
     <script>console.log("(TIME) index.html loaded:\t", window.performance.now());</script>
14 14
     <script src="config.js?v=15"></script><!-- adapt to your needs, i.e. set hosts and bosh path -->
15 15
     <script src="interface_config.js?v=6"></script>
16
-    <script src="lib-jitsi-meet.js?v=139"></script>
16
+    <script src="libs/lib-jitsi-meet.js?v=139"></script>
17 17
     <script src="libs/app.bundle.min.js?v=139"></script>
18 18
     <!--
19 19
         Link used for inline installation of chrome desktop streaming extension,

+ 6
- 3
libs/lib-jitsi-meet.js Datei anzeigen

@@ -2250,7 +2250,7 @@ RTC.prototype.createRemoteStream = function (data, sid, thessrc) {
2250 2250
     var remoteStream = new JitsiRemoteTrack(this, data, sid, thessrc);
2251 2251
     if(!data.peerjid)
2252 2252
         return;
2253
-    var jid = data.peerjid;
2253
+    var jid = Strophe.getResourceFromJid(data.peerjid);
2254 2254
     if(!this.remoteStreams[jid]) {
2255 2255
         this.remoteStreams[jid] = {};
2256 2256
     }
@@ -2337,8 +2337,11 @@ RTC.prototype.switchVideoStreams = function (newStream) {
2337 2337
 };
2338 2338
 
2339 2339
 RTC.prototype.setAudioLevel = function (jid, audioLevel) {
2340
-    if(this.remoteStreams[jid] && this.remoteStreams[jid][JitsiTrack.AUDIO])
2341
-        this.remoteStreams[jid][JitsiTrack.AUDIO].setAudioLevel(audioLevel);
2340
+    if(!jid)
2341
+        return;
2342
+    var resource = Strophe.getResourceFromJid(jid);
2343
+    if(this.remoteStreams[resource] && this.remoteStreams[resource][JitsiTrack.AUDIO])
2344
+        this.remoteStreams[resource][JitsiTrack.AUDIO].setAudioLevel(audioLevel);
2342 2345
 }
2343 2346
 module.exports = RTC;
2344 2347
 

+ 15
- 7
modules/UI/UI.js Datei anzeigen

@@ -382,7 +382,8 @@ UI.removeUser = function (id, displayName) {
382 382
         displayName,'notify.somebody', 'disconnected', 'notify.disconnected'
383 383
     );
384 384
 
385
-    if (!config.startAudioMuted || config.startAudioMuted > APP.conference.membersCount) {
385
+    if (!config.startAudioMuted
386
+        || config.startAudioMuted > APP.conference.membersCount) {
386 387
         UIUtil.playSoundNotification('userLeft');
387 388
     }
388 389
 
@@ -504,15 +505,22 @@ UI.askForNickname = function () {
504 505
 };
505 506
 
506 507
 /**
507
- * Sets muted audio state for the local participant.
508
+ * Sets muted audio state for participant
508 509
  */
509
-UI.setAudioMuted = function (mute) {
510
-    VideoLayout.showLocalAudioIndicator(mute);
511
-    UIUtil.buttonClick("#toolbar_button_mute", "icon-microphone icon-mic-disabled");
510
+UI.setAudioMuted = function (id, muted) {
511
+    VideoLayout.onAudioMute(id, muted);
512
+    if(APP.conference.isLocalId(id))
513
+        UIUtil.buttonClick("#toolbar_button_mute",
514
+            "icon-microphone icon-mic-disabled");
512 515
 };
513 516
 
514
-UI.setVideoMuted = function (muted) {
515
-    $('#toolbar_button_camera').toggleClass("icon-camera-disabled", muted);
517
+/**
518
+ * Sets muted video state for participant
519
+ */
520
+UI.setVideoMuted = function (id, muted) {
521
+    VideoLayout.onVideoMute(id, muted);
522
+    if(APP.conference.isLocalId(id))
523
+        $('#toolbar_button_camera').toggleClass("icon-camera-disabled", muted);
516 524
 };
517 525
 
518 526
 UI.addListener = function (type, listener) {

modules/AuthHandler.js → modules/UI/authentication/AuthHandler.js Datei anzeigen

@@ -1,9 +1,9 @@
1 1
 /* global JitsiMeetJS, APP */
2 2
 
3
-import LoginDialog from './UI/authentication/LoginDialog';
4
-import UIEvents from '../service/UI/UIEvents';
5
-import UIUtil from './UI/util/UIUtil';
6
-import {openConnection} from './connection';
3
+import LoginDialog from './LoginDialog';
4
+import UIEvents from '../../../service/UI/UIEvents';
5
+import UIUtil from '../util/UIUtil';
6
+import {openConnection} from '../../../connection';
7 7
 
8 8
 const ConferenceEvents = JitsiMeetJS.events.conference;
9 9
 

modules/RoomLocker.js → modules/UI/authentication/RoomLocker.js Datei anzeigen

@@ -1,7 +1,8 @@
1 1
 /* global APP, JitsiMeetJS */
2
-import messageHandler from './UI/util/MessageHandler';
3
-import UIUtil from './UI/util/UIUtil';
4
-import AnalyticsAdapter from './statistics/AnalyticsAdapter';
2
+import messageHandler from '../util/MessageHandler';
3
+import UIUtil from '../util/UIUtil';
4
+//FIXME:
5
+import AnalyticsAdapter from '../../statistics/AnalyticsAdapter';
5 6
 
6 7
 function askForNewPassword () {
7 8
     let passMsg = APP.translation.generateTranslationHTML("dialog.passwordMsg");

+ 2
- 0
modules/UI/videolayout/LargeVideo.js Datei anzeigen

@@ -11,6 +11,8 @@ const RTCBrowserType = require("../../RTC/RTCBrowserType");
11 11
 const avatarSize = interfaceConfig.ACTIVE_SPEAKER_AVATAR_SIZE;
12 12
 
13 13
 function getStreamId(stream) {
14
+    if(!stream)
15
+        return;
14 16
     if (stream.isLocal()) {
15 17
         return APP.conference.localId;
16 18
     } else {

+ 6
- 9
modules/UI/videolayout/LocalVideo.js Datei anzeigen

@@ -7,6 +7,8 @@ import SmallVideo from "./SmallVideo";
7 7
 var LargeVideo = require("./LargeVideo");
8 8
 var RTCBrowserType = require("../../RTC/RTCBrowserType");
9 9
 
10
+const TrackEvents = JitsiMeetJS.events.track;
11
+
10 12
 function LocalVideo(VideoLayout, emitter) {
11 13
     this.videoSpanId = "localVideoContainer";
12 14
     this.container = $("#localVideoContainer").get(0);
@@ -187,18 +189,13 @@ LocalVideo.prototype.changeVideo = function (stream) {
187 189
     // Attach WebRTC stream
188 190
     stream.attach(localVideoSelector);
189 191
 
190
-    // FIXME handle
191
-    return;
192
-
193
-    // Add stream ended handler
194
-    /**APP.RTC.addMediaStreamInactiveHandler(
195
-        stream.getOriginalStream(), function () {
196
-        // We have to re-select after attach when Temasys plugin is used,
197
-        // because <video> element is replaced with <object>
192
+    let endedHandler = () => {
198 193
         localVideo = $('#' + localVideo.id)[0];
199 194
         localVideoContainer.removeChild(localVideo);
200 195
         self.VideoLayout.updateRemovedVideo(self.id);
201
-    });*/
196
+        stream.off(TrackEvents.TRACK_STOPPED, endedHandler);
197
+    };
198
+    stream.on(TrackEvents.TRACK_STOPPED, endedHandler);
202 199
 };
203 200
 
204 201
 LocalVideo.prototype.joined = function (id) {

+ 14
- 29
modules/UI/videolayout/VideoLayout.js Datei anzeigen

@@ -128,7 +128,7 @@ var VideoLayout = {
128 128
         let localAudio = document.getElementById('localAudio');
129 129
         stream.attach($(localAudio));
130 130
 
131
-        return; // FIXME maybe move this into the library?
131
+        //return; // FIXME maybe move this into the library?
132 132
         // Writing volume not allowed in IE
133 133
         if (!RTCBrowserType.isIExplorer()) {
134 134
             localAudio.autoplay = true;
@@ -253,7 +253,6 @@ var VideoLayout = {
253 253
 
254 254
     onRemoteStreamAdded (stream) {
255 255
         let id = stream.getParticipantId();
256
-
257 256
         remoteVideos[id].addRemoteStreamElement(stream);
258 257
     },
259 258
 
@@ -475,14 +474,13 @@ var VideoLayout = {
475 474
     /**
476 475
      * On audio muted event.
477 476
      */
478
-    onAudioMute (jid, isMuted) {
479
-        var resourceJid = Strophe.getResourceFromJid(jid);
480
-        if (resourceJid === APP.xmpp.myResource()) {
477
+    onAudioMute (id, isMuted) {
478
+        if (APP.conference.isLocalId(id)) {
481 479
             localVideoThumbnail.showAudioIndicator(isMuted);
482 480
         } else {
483
-            remoteVideos[resourceJid].showAudioIndicator(isMuted);
484
-            if (APP.xmpp.isModerator()) {
485
-                remoteVideos[resourceJid].updateRemoteVideoMenu(isMuted);
481
+            remoteVideos[id].showAudioIndicator(isMuted);
482
+            if (APP.conference.isModerator) {
483
+                remoteVideos[id].updateRemoteVideoMenu(isMuted);
486 484
             }
487 485
         }
488 486
     },
@@ -490,17 +488,11 @@ var VideoLayout = {
490 488
     /**
491 489
      * On video muted event.
492 490
      */
493
-    onVideoMute (jid, value) {
494
-        if (jid !== APP.xmpp.myJid() &&
495
-            !APP.RTC.muteRemoteVideoStream(jid, value))
496
-            return;
497
-
498
-        if (jid === APP.xmpp.myJid()) {
491
+    onVideoMute (id, value) {
492
+        if (APP.conference.isLocalId(id)) {
499 493
             localVideoThumbnail.showVideoIndicator(value);
500 494
         } else {
501
-            var resource = Strophe.getResourceFromJid(jid);
502
-
503
-            var remoteVideo = remoteVideos[resource];
495
+            var remoteVideo = remoteVideos[id];
504 496
             remoteVideo.showVideoIndicator(value);
505 497
 
506 498
             var el = remoteVideo.selectVideoElement();
@@ -528,11 +520,7 @@ var VideoLayout = {
528 520
      */
529 521
     onDominantSpeakerChanged (id) {
530 522
         // We ignore local user events.
531
-        if (APP.conference.isLocalId(id)) {
532
-            return;
533
-        }
534
-
535
-        if (id === currentDominantSpeaker) {
523
+        if (APP.conference.isLocalId(id) || (id === currentDominantSpeaker)) {
536 524
             return;
537 525
         }
538 526
 
@@ -623,7 +611,7 @@ var VideoLayout = {
623 611
             // video
624 612
             // Detected from avatar tests, where lastN event override
625 613
             // local video pinning
626
-            if(resourceJid == APP.xmpp.myResource())
614
+            if(APP.conference.isLocalId(resourceJid))
627 615
                 return;
628 616
 
629 617
             var isReceived = true;
@@ -633,7 +621,7 @@ var VideoLayout = {
633 621
                 console.log("Remove from last N", resourceJid);
634 622
                 if (remoteVideos[resourceJid])
635 623
                     remoteVideos[resourceJid].showPeerContainer('hide');
636
-                else if (APP.xmpp.myResource() !== resourceJid)
624
+                else if (!APP.conference.isLocalId(resourceJid))
637 625
                     console.error("No remote video for: " + resourceJid);
638 626
                 isReceived = false;
639 627
             } else if (resourceJid &&
@@ -642,7 +630,7 @@ var VideoLayout = {
642 630
                 localLastNSet.indexOf(resourceJid) >= 0) {
643 631
                 if (remoteVideos[resourceJid])
644 632
                     remoteVideos[resourceJid].showPeerContainer('avatar');
645
-                else if (APP.xmpp.myResource() !== resourceJid)
633
+                else if (!APP.conference.isLocalId(resourceJid))
646 634
                     console.error("No remote video for: " + resourceJid);
647 635
                 isReceived = false;
648 636
             }
@@ -701,13 +689,10 @@ var VideoLayout = {
701 689
 
702 690
         if (updateLargeVideo) {
703 691
             var resource;
704
-            var myResource
705
-                = APP.xmpp.myResource();
706
-
707 692
             // Find out which endpoint to show in the large video.
708 693
             for (i = 0; i < lastNEndpoints.length; i++) {
709 694
                 resource = lastNEndpoints[i];
710
-                if (!resource || resource === myResource)
695
+                if (!resource || APP.conference.isLocalId(resource))
711 696
                     continue;
712 697
 
713 698
                 // videoSrcToSsrc needs to be update for this call to succeed.

Laden…
Abbrechen
Speichern