-
Notifications
You must be signed in to change notification settings - Fork 1
/
captureAudio.js
139 lines (116 loc) · 3.93 KB
/
captureAudio.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
// https://addpipe.com/media-recorder-api-demo-audio/
class CaptureAudio {
constructor() {
// Media recorder API
this.gumStream = null; // Stream from getUserMedia()
this.recorder = null; // MediaRecorder object
this.chunks = []; // Array of chunks audio data from the browser
this.extension = null;
this.blobHandler = null;
this.errorHandler = null;
// true on Chrome, false on Firefox
console.log(
'audio/webm: ' + MediaRecorder.isTypeSupported('audio/webm;codecs=opus')
);
// false on Chrome, true on Firefox
console.log(
'audio/ogg: ' + MediaRecorder.isTypeSupported('audio/ogg;codecs=opus')
);
// Set extension
if (MediaRecorder.isTypeSupported('audio/webm;codecs=opus')) {
this.extension = 'webm';
} else {
this.extension = 'ogg';
}
}
setBlobHandler(blobHandler) {
this.blobHandler = blobHandler;
}
setErrorHandler(errorHandler) {
this.errorHandler = errorHandler;
}
startRecording() {
console.log('recordButton clicked');
/*
Simple constraints object, for more advanced audio features see
https://addpipe.com/blog/audio-constraints-getusermedia/
*/
const constraints = { audio: true };
navigator.mediaDevices
.getUserMedia(constraints)
.then((stream) => {
console.log(
'getUserMedia() success, stream created, initializing MediaRecorder'
);
// Assign to gumStream for later use
this.gumStream = stream;
const options = {
audioBitsPerSecond: 256000,
videoBitsPerSecond: 2500000,
bitsPerSecond: 2628000,
mimeType: 'audio/' + this.extension + ';codecs=opus',
};
console.log(
'Sample rate: 48kHz, MIME: audio/' + this.extension + ';codecs=opus'
);
// Create the MediaRecorder object
this.recorder = new MediaRecorder(stream, options);
// When data became available add it to our array of audio data
this.recorder.ondataavailable = (e) => {
console.log('recorder.ondataavailable: ' + e.data);
console.log(
'recorder.audioBitsPerSecond: ' + this.recorder.audioBitsPerSecond
);
console.log(
'recorder.videoBitsPerSecond: ' + this.recorder.videoBitsPerSecond
);
console.log('recorder.bitsPerSecond: ' + this.recorder.bitsPerSecond);
// Add stream data to chunks
this.chunks.push(e.data);
// If recorder is 'inactive' then recording has finished
if (this.recorder.state === 'inactive') {
console.log('recorder is inactive');
// Convert stream data chunks to a 'webm' audio format as blob
const blob = new Blob(this.chunks, {
type: 'audio/' + this.extension,
bitsPerSecond: 128000,
});
this.chunks = []; // reset chunks
if (this.blobHandler) {
this.blobHandler(blob);
}
}
};
this.recorder.onerror = (e) => {
console.log(e.error);
if (this.errorHandler) {
this.errorHandler(`${e.error}`);
}
};
// Start recording using 1 second chunks
// Chrome and firefox will record one long chunk if not specify the length
this.recorder.start(1000);
})
.catch((err) => {
console.log('Media device error: ');
console.log(err);
if (this.errorHandler) {
this.errorHandler(`${err}`);
}
});
}
stopRecording() {
console.log('stopButton clicked');
// Tell the recorder to stop the recording
if (this.recorder) {
this.recorder.stop();
console.log('STOP RECORDER');
}
// Stop microphone access
if (this.gumStream) {
this.gumStream.getAudioTracks()[0].stop();
console.log('STOP MICROPHONE ACCESS');
}
}
}
export default new CaptureAudio();