瀏覽代碼

feat: add config.startAudioOnly

When the 'startAudioOnly' config option is set to true the conference
will start in the audio only mode.
master
paweldomas 7 年之前
父節點
當前提交
6493b09565
共有 3 個文件被更改,包括 63 次插入6 次删除
  1. 29
    5
      conference.js
  2. 1
    0
      config.js
  3. 33
    1
      react/features/base/conference/middleware.js

+ 29
- 5
conference.js 查看文件

@@ -26,6 +26,7 @@ import {
26 26
     conferenceFailed,
27 27
     conferenceJoined,
28 28
     conferenceLeft,
29
+    toggleAudioOnly,
29 30
     EMAIL_COMMAND,
30 31
     lockStateChanged
31 32
 } from './react/features/base/conference';
@@ -459,11 +460,14 @@ export default {
459 460
      * Creates local media tracks and connects to a room. Will show error
460 461
      * dialogs in case accessing the local microphone and/or camera failed. Will
461 462
      * show guidance overlay for users on how to give access to camera and/or
462
-     * microphone,
463
+     * microphone.
463 464
      * @param {string} roomName
464 465
      * @param {object} options
465
-     * @param {boolean} options.startScreenSharing - if <tt>true</tt> should
466
-     * start with screensharing instead of camera video.
466
+     * @param {boolean} options.startAudioOnly=false - if <tt>true</tt> then
467
+     * only audio track will be created and the audio only mode will be turned
468
+     * on.
469
+     * @param {boolean} options.startScreenSharing=false - if <tt>true</tt>
470
+     * should start with screensharing instead of camera video.
467 471
      * @returns {Promise.<JitsiLocalTrack[], JitsiConnection>}
468 472
      */
469 473
     createInitialLocalTracksAndConnect(roomName, options = {}) {
@@ -482,8 +486,18 @@ export default {
482 486
         // First try to retrieve both audio and video.
483 487
         let tryCreateLocalTracks;
484 488
 
489
+        // FIXME there is no video muted indication visible on the remote side,
490
+        // after starting in audio only (there's no video track)
485 491
         // FIXME the logic about trying to go audio only on error is duplicated
486
-        if (options.startScreenSharing) {
492
+        if (options.startAudioOnly) {
493
+            tryCreateLocalTracks
494
+                = createLocalTracks({ devices: ['audio'] }, true)
495
+                    .catch(err => {
496
+                        audioOnlyError = err;
497
+
498
+                        return [];
499
+                    });
500
+        } else if (options.startScreenSharing) {
487 501
             tryCreateLocalTracks = this._createDesktopTrack()
488 502
                 .then(desktopStream => {
489 503
                     return createLocalTracks({ devices: ['audio'] }, true)
@@ -591,6 +605,7 @@ export default {
591 605
                 analytics.init();
592 606
                 return this.createInitialLocalTracksAndConnect(
593 607
                     options.roomName, {
608
+                        startAudioOnly: config.startAudioOnly,
594 609
                         startScreenSharing: config.startScreenSharing
595 610
                     });
596 611
             }).then(([tracks, con]) => {
@@ -649,6 +664,15 @@ export default {
649 664
                     this.updateVideoIconEnabled();
650 665
                 }
651 666
 
667
+                // Enable audio only mode
668
+                if (config.startAudioOnly) {
669
+                    // It is important to have that toggled after video muted
670
+                    // state is adjusted by the code about lack of video tracks
671
+                    // above. That's because audio only will store muted state
672
+                    // on toggle action.
673
+                    APP.store.dispatch(toggleAudioOnly());
674
+                }
675
+
652 676
                 this._initDeviceList();
653 677
 
654 678
                 if (config.iAmRecorder)
@@ -2035,7 +2059,7 @@ export default {
2035 2059
                     JitsiMeetJS.mediaDevices.enumerateDevices(devices => {
2036 2060
                         // Ugly way to synchronize real device IDs with local
2037 2061
                         // storage and settings menu. This is a workaround until
2038
-                        // getConstraints() method will be implemented 
2062
+                        // getConstraints() method will be implemented
2039 2063
                         // in browsers.
2040 2064
                         if (localAudio) {
2041 2065
                             APP.settings.setMicDeviceId(

+ 1
- 0
config.js 查看文件

@@ -72,6 +72,7 @@ var config = { // eslint-disable-line no-unused-vars
72 72
                               // page redirection when call is hangup
73 73
     disableSimulcast: false,
74 74
 //    requireDisplayName: true, // Forces the participants that doesn't have display name to enter it when they enter the room.
75
+    startAudioOnly: false, // Will start the conference in the audio only mode (no video is being received nor sent)
75 76
     startScreenSharing: false, // Will try to start with screensharing instead of camera
76 77
 //    startAudioMuted: 10, // every participant after the Nth will start audio muted
77 78
 //    startVideoMuted: 10, // every participant after the Nth will start video muted

+ 33
- 1
react/features/base/conference/middleware.js 查看文件

@@ -15,7 +15,7 @@ import {
15 15
     _setAudioOnlyVideoMuted,
16 16
     setLastN
17 17
 } from './actions';
18
-import { SET_AUDIO_ONLY, SET_LASTN } from './actionTypes';
18
+import { CONFERENCE_JOINED, SET_AUDIO_ONLY, SET_LASTN } from './actionTypes';
19 19
 import {
20 20
     _addLocalTracksToConference,
21 21
     _handleParticipantError,
@@ -33,6 +33,9 @@ MiddlewareRegistry.register(store => next => action => {
33 33
     case CONNECTION_ESTABLISHED:
34 34
         return _connectionEstablished(store, next, action);
35 35
 
36
+    case CONFERENCE_JOINED:
37
+        return _conferenceJoined(store, next, action);
38
+
36 39
     case PIN_PARTICIPANT:
37 40
         return _pinParticipant(store, next, action);
38 41
 
@@ -76,6 +79,35 @@ function _connectionEstablished(store, next, action) {
76 79
     return result;
77 80
 }
78 81
 
82
+/**
83
+ * Does extra sync up on properties that may need to be updated, after
84
+ * the conference was joined.
85
+ *
86
+ * @param {Store} store - The Redux store in which the specified action is being
87
+ * dispatched.
88
+ * @param {Dispatch} next - The Redux dispatch function to dispatch the
89
+ * specified action to the specified store.
90
+ * @param {Action} action - The Redux action CONFERENCE_JOINED which is being
91
+ * dispatched in the specified store.
92
+ * @private
93
+ * @returns {Object} The new state that is the result of the reduction of the
94
+ * specified action.
95
+ */
96
+function _conferenceJoined(store, next, action) {
97
+    const result = next(action);
98
+    const { audioOnly, conference }
99
+        = store.getState()['features/base/conference'];
100
+
101
+    // FIXME On Web the audio only mode for "start audio only" is toggled before
102
+    // conference is added to the redux store ("on conference joined" action)
103
+    // and the LastN value needs to be synchronized here.
104
+    if (audioOnly && conference.getLastN() !== 0) {
105
+        store.dispatch(setLastN(0));
106
+    }
107
+
108
+    return result;
109
+}
110
+
79 111
 /**
80 112
  * Notifies the feature base/conference that the action PIN_PARTICIPANT is being
81 113
  * dispatched within a specific Redux store. Pins the specified remote

Loading…
取消
儲存