src/audio/media-recorder.js
/*
* Use the Media Stream Recording API for recording and encoding. Ogg Opus
* (audio/ogg) is the prefered output format.
*
* The Media Stream Recording API is W3C standard in the making:
* https://dvcs.w3.org/hg/dap/raw-file/tip/media-stream-capture/RecordingProposal.html
*
* Currently only supported in Firefox. There's a standards author working for
* Microsoft which hints wide adoption in the future.
*
* Encoder only supports 48k/16k mono audio channel.
* http://dxr.mozilla.org/mozilla-central/source/content/media/MediaRecorder.cpp
* https://wiki.mozilla.org/Gecko:MediaRecorder
*
*/
/**
* @private
*/
export default class MediaRecorder {
/**
* MediaRecorder.
*
* @param {MediaStream} mediaStream - The MediaStream to analyze.
*/
constructor(mediaStream) {
const self = this;
this.mediaRecorder = new window.MediaRecorder(mediaStream);
this.mediaRecorder.ondataavailable = function(e) {
self.recordedBlob = new Blob([e.data], {
type: 'audio/ogg'
});
console.log('Recorded audio/ogg Blob size: ' + self.recordedBlob.size);
if (self.callback) {
self.callback(self.recordedBlob);
self.callback = null;
}
};
}
/**
* Start recording audio.
*/
record() {
this.recordedBlob = null;
this.callback = null;
this.mediaRecorder.start();
}
/**
* Is audio recording in progress.
*
* @returns {boolean} True when recording. False otherwise.
*/
isRecording() {
return this.mediaRecorder.state === 'recording';
}
/**
* Stop recording audio.
*/
stop() {
if (this.isRecording()) {
// Calling `stop()` throws a dataavailable event.
this.mediaRecorder.stop();
}
}
/**
* Request encoded audio to be returned through callback.
*
* @param {Function} callback - The callback to use when returning the audio as a blob in Ogg Opus format.
*/
getEncodedAudio(callback) {
if (this.recordedBlob) {
// Data already available, return right away.
callback(this.recordedBlob);
return;
}
// Callback will trigger later when audio is ready.
this.callback = callback;
}
}