ソースを参照

refactor: use createLocalTracks instead of gUM; fix some docs;

master
Radium Zheng 7年前
コミット
e125861b29

+ 1
- 1
react/features/local-recording/controller/RecordingController.js ファイルの表示

@@ -258,7 +258,7 @@ class RecordingController {
258 258
         this._format = newFormat;
259 259
         logger.log(`Recording format switched to ${newFormat}`);
260 260
 
261
-        // will be used next time
261
+        // the new format will be used in the next recording session
262 262
     }
263 263
 
264 264
     /**

+ 3
- 1
react/features/local-recording/middleware.js ファイルの表示

@@ -14,7 +14,6 @@ MiddlewareRegistry.register(({ getState, dispatch }) => next => action => {
14 14
 
15 15
     switch (action.type) {
16 16
     case CONFERENCE_JOINED: {
17
-        // the Conference object is ready
18 17
         const { conference } = getState()['features/base/conference'];
19 18
 
20 19
         recordingController.registerEvents(conference);
@@ -48,5 +47,8 @@ MiddlewareRegistry.register(({ getState, dispatch }) => next => action => {
48 47
         break;
49 48
     }
50 49
 
50
+    // @todo: detect change in features/base/settings micDeviceID
51
+    // @todo: SET_AUDIO_MUTED, when audio is muted
52
+
51 53
     return result;
52 54
 });

+ 14
- 23
react/features/local-recording/recording/OggAdapter.js ファイルの表示

@@ -9,6 +9,9 @@ const logger = require('jitsi-meet-logger').getLogger(__filename);
9 9
  */
10 10
 export class OggAdapter extends RecordingAdapter {
11 11
 
12
+    /**
13
+     * Instance of MediaRecorder.
14
+     */
12 15
     _mediaRecorder = null;
13 16
 
14 17
     /**
@@ -21,29 +24,17 @@ export class OggAdapter extends RecordingAdapter {
21 24
 
22 25
         if (this._mediaRecorder === null) {
23 26
             p = new Promise((resolve, error) => {
24
-                navigator.getUserMedia(
25
-
26
-                    // constraints, only audio needed
27
-                    {
28
-                        audioBitsPerSecond: 44100, // 44 kbps
29
-                        audio: true,
30
-                        mimeType: 'application/ogg'
31
-                    },
32
-
33
-                    // success callback
34
-                    stream => {
35
-                        this._mediaRecorder = new MediaRecorder(stream);
36
-                        this._mediaRecorder.ondataavailable
37
-                            = e => this._saveMediaData(e.data);
38
-                        resolve();
39
-                    },
40
-
41
-                    // Error callback
42
-                    err => {
43
-                        logger.error(`Error calling getUserMedia(): ${err}`);
44
-                        error();
45
-                    }
46
-                );
27
+                this._getAudioStream(0)
28
+                .then(stream => {
29
+                    this._mediaRecorder = new MediaRecorder(stream);
30
+                    this._mediaRecorder.ondataavailable
31
+                        = e => this._saveMediaData(e.data);
32
+                    resolve();
33
+                })
34
+                .catch(err => {
35
+                    logger.error(`Error calling getUserMedia(): ${err}`);
36
+                    error();
37
+                });
47 38
             });
48 39
         } else {
49 40
             p = new Promise(resolve => {

+ 30
- 1
react/features/local-recording/recording/RecordingAdapter.js ファイルの表示

@@ -1,5 +1,7 @@
1
+import JitsiMeetJS from '../../base/lib-jitsi-meet';
2
+
1 3
 /**
2
- * Common interface for recording mechanisms
4
+ * Base class for recording backends.
3 5
  */
4 6
 export class RecordingAdapter {
5 7
 
@@ -38,4 +40,31 @@ export class RecordingAdapter {
38 40
     download() {
39 41
         throw new Error('Not implemented');
40 42
     }
43
+
44
+    /**
45
+     * Helper method for getting an audio MediaStream. Use this instead of
46
+     * calling browser APIs directly.
47
+     *
48
+     * @protected
49
+     * @param {number} micDeviceId - The ID of the current audio device.
50
+     * @returns {Promise}
51
+     */
52
+    _getAudioStream(micDeviceId) {
53
+        return JitsiMeetJS.createLocalTracks({
54
+            devices: [ 'audio' ],
55
+            micDeviceId
56
+        }).then(result => {
57
+            if (result.length !== 1) {
58
+                throw new Error('Unexpected number of streams '
59
+                    + 'from createLocalTracks.');
60
+            }
61
+            const mediaStream = result[0].stream;
62
+
63
+            if (mediaStream === undefined) {
64
+                throw new Error('Failed to get MediaStream.');
65
+            }
66
+
67
+            return mediaStream;
68
+        });
69
+    }
41 70
 }

+ 22
- 34
react/features/local-recording/recording/WavAdapter.js ファイルの表示

@@ -40,40 +40,28 @@ export class WavAdapter extends RecordingAdapter {
40 40
         }
41 41
 
42 42
         const p = new Promise((resolve, reject) => {
43
-            navigator.getUserMedia(
44
-
45
-                // constraints - only audio needed for this app
46
-                {
47
-                    audioBitsPerSecond: WAV_SAMPLE_RATE * WAV_BITS_PER_SAMPLE,
48
-                    audio: true,
49
-                    mimeType: 'application/ogg' // useless?
50
-                },
51
-
52
-                // Success callback
53
-                stream => {
54
-                    this._audioContext = new AudioContext();
55
-                    this._audioSource
56
-                     = this._audioContext.createMediaStreamSource(stream);
57
-                    this._audioProcessingNode
58
-                      = this._audioContext.createScriptProcessor(4096, 1, 1);
59
-                    this._audioProcessingNode.onaudioprocess = e => {
60
-                        const channelLeft = e.inputBuffer.getChannelData(0);
61
-
62
-                        // https://developer.mozilla.org/en-US/docs/
63
-                        // Web/API/AudioBuffer/getChannelData
64
-                        // the returned value is an Float32Array
65
-                        this._saveWavPCM(channelLeft);
66
-                    };
67
-                    this._isInitialized = true;
68
-                    resolve();
69
-                },
70
-
71
-                // Error callback
72
-                err => {
73
-                    logger.error(`Error calling getUserMedia(): ${err}`);
74
-                    reject();
75
-                }
76
-            );
43
+            this._getAudioStream(0)
44
+            .then(stream => {
45
+                this._audioContext = new AudioContext();
46
+                this._audioSource
47
+                    = this._audioContext.createMediaStreamSource(stream);
48
+                this._audioProcessingNode
49
+                    = this._audioContext.createScriptProcessor(4096, 1, 1);
50
+                this._audioProcessingNode.onaudioprocess = e => {
51
+                    const channelLeft = e.inputBuffer.getChannelData(0);
52
+
53
+                    // https://developer.mozilla.org/en-US/docs/
54
+                    // Web/API/AudioBuffer/getChannelData
55
+                    // the returned value is an Float32Array
56
+                    this._saveWavPCM(channelLeft);
57
+                };
58
+                this._isInitialized = true;
59
+                resolve();
60
+            })
61
+            .catch(err => {
62
+                logger.error(`Error calling getUserMedia(): ${err}`);
63
+                reject();
64
+            });
77 65
         });
78 66
 
79 67
         return p;

+ 25
- 37
react/features/local-recording/recording/flac/FlacAdapter.js ファイルの表示

@@ -12,7 +12,7 @@ import {
12 12
 const logger = require('jitsi-meet-logger').getLogger(__filename);
13 13
 
14 14
 /**
15
- * Recording adapter that uses libflac in the background
15
+ * Recording adapter that uses libflac.js in the background.
16 16
  */
17 17
 export class FlacAdapter extends RecordingAdapter {
18 18
 
@@ -43,7 +43,7 @@ export class FlacAdapter extends RecordingAdapter {
43 43
                 // try load the minified version first
44 44
                 this._encoder = new Worker('/libs/flacEncodeWorker.min.js');
45 45
             } catch (exception1) {
46
-                // if failed, try un minified version
46
+                // if failed, try unminified version
47 47
                 try {
48 48
                     this._encoder = new Worker('/libs/flacEncodeWorker.js');
49 49
                 } catch (exception2) {
@@ -83,41 +83,29 @@ export class FlacAdapter extends RecordingAdapter {
83 83
         });
84 84
 
85 85
         const callbackInitAudioContext = (resolve, reject) => {
86
-            navigator.getUserMedia(
87
-
88
-                // constraints - only audio needed for this app
89
-                {
90
-                    audioBitsPerSecond: 44100, // 44 kbps
91
-                    audio: true,
92
-                    mimeType: 'application/ogg' // useless?
93
-                },
94
-
95
-                // Success callback
96
-                stream => {
97
-                    this._audioContext = new AudioContext();
98
-                    this._audioSource
99
-                     = this._audioContext.createMediaStreamSource(stream);
100
-                    this._audioProcessingNode
101
-                      = this._audioContext.createScriptProcessor(4096, 1, 1);
102
-                    this._audioProcessingNode.onaudioprocess = e => {
103
-                        // delegate to the WebWorker to do the encoding
104
-                        const channelLeft = e.inputBuffer.getChannelData(0);
105
-
106
-                        this._encoder.postMessage({
107
-                            command: MAIN_THREAD_NEW_DATA_ARRIVED,
108
-                            buf: channelLeft
109
-                        });
110
-                    };
111
-                    logger.debug('AudioContext is set up.');
112
-                    resolve();
113
-                },
114
-
115
-                // Error callback
116
-                err => {
117
-                    logger.error(`Error calling getUserMedia(): ${err}`);
118
-                    reject();
119
-                }
120
-            );
86
+            this._getAudioStream(0)
87
+            .then(stream => {
88
+                this._audioContext = new AudioContext();
89
+                this._audioSource
90
+                    = this._audioContext.createMediaStreamSource(stream);
91
+                this._audioProcessingNode
92
+                    = this._audioContext.createScriptProcessor(4096, 1, 1);
93
+                this._audioProcessingNode.onaudioprocess = e => {
94
+                    // delegate to the WebWorker to do the encoding
95
+                    const channelLeft = e.inputBuffer.getChannelData(0);
96
+
97
+                    this._encoder.postMessage({
98
+                        command: MAIN_THREAD_NEW_DATA_ARRIVED,
99
+                        buf: channelLeft
100
+                    });
101
+                };
102
+                logger.debug('AudioContext is set up.');
103
+                resolve();
104
+            })
105
+            .catch(err => {
106
+                logger.error(`Error calling getUserMedia(): ${err}`);
107
+                reject();
108
+            });
121 109
         };
122 110
 
123 111
         // FIXME: because Promise constructor immediately executes the executor

+ 11
- 17
react/features/local-recording/recording/flac/flacEncodeWorker.js ファイルの表示

@@ -26,39 +26,33 @@ importScripts('/libs/libflac3-1.3.2.min.js');
26 26
 declare var Flac: Object;
27 27
 
28 28
 const FLAC_ERRORS = {
29
-    // The encoder is in the normal OK state and
30
-    // samples can be processed.
29
+    // The encoder is in the normal OK state and samples can be processed.
31 30
     0: 'FLAC__STREAM_ENCODER_OK',
32 31
 
33
-    // The encoder is in the
34
-    // uninitialized state one of the FLAC__stream_encoder_init_*() functions
35
-    // must be called before samples can be processed.
32
+    // The encoder is in the uninitialized state one of the
33
+    // FLAC__stream_encoder_init_*() functions must be called before samples can
34
+    // be processed.
36 35
     1: 'FLAC__STREAM_ENCODER_UNINITIALIZED',
37 36
 
38 37
     // An error occurred in the underlying Ogg layer.
39 38
     2: 'FLAC__STREAM_ENCODER_OGG_ERROR',
40 39
 
41
-    // An error occurred in the
42
-    // underlying verify stream decoder; check
40
+    // An error occurred in the underlying verify stream decoder; check
43 41
     // FLAC__stream_encoder_get_verify_decoder_state().
44 42
     3: 'FLAC__STREAM_ENCODER_VERIFY_DECODER_ERROR',
45 43
 
46
-    // The verify decoder detected a mismatch between the
47
-    // original audio signal and the decoded audio signal.
48
-
44
+    // The verify decoder detected a mismatch between the original audio signal
45
+    // and the decoded audio signal.
49 46
     4: 'FLAC__STREAM_ENCODER_VERIFY_MISMATCH_IN_AUDIO_DATA',
50 47
 
51
-    // One of the callbacks returned
52
-    // a fatal error.
48
+    // One of the callbacks returned a fatal error.
53 49
     5: 'FLAC__STREAM_ENCODER_CLIENT_ERROR',
54 50
 
55
-    // An I/O error occurred while
56
-    // opening/reading/writing a file. Check errno.
57
-
51
+    // An I/O error occurred while opening/reading/writing a file. Check errno.
58 52
     6: 'FLAC__STREAM_ENCODER_IO_ERROR',
59 53
 
60
-    // An error occurred while writing
61
-    // the stream; usually, the write_callback returned an error.
54
+    // An error occurred while writing the stream; usually, the write_callback
55
+    // returned an error.
62 56
     7: 'FLAC__STREAM_ENCODER_FRAMING_ERROR',
63 57
 
64 58
     // Memory allocation failed.

+ 0
- 4
react/features/local-recording/reducer.js ファイルの表示

@@ -9,11 +9,7 @@ import {
9 9
 } from './actionTypes';
10 10
 import { recordingController } from './controller';
11 11
 
12
-const logger = require('jitsi-meet-logger').getLogger(__filename);
13
-
14 12
 ReducerRegistry.register('features/local-recording', (state = {}, action) => {
15
-    logger.debug(`Redux state (features/local-recording):\n ${
16
-        JSON.stringify(state)}`);
17 13
     switch (action.type) {
18 14
     case LOCAL_RECORDING_ENGAGED: {
19 15
         return {

読み込み中…
キャンセル
保存