ITSLanguage Recorder Package
Speech technology for language education. 📣
This package exposes a very simple wrapper around a polyfill for the MediaRecorder API. We have two
reasons to use the polyfill:
- The MediaRecorder API is not available in some browser (like safari). With this
polyfill it is.
- The polyfill supports WAVE which is what we need for the backend.
In the future we want to be able to support both the browser default MediaRecorder,
and this polyfill.
Getting started
Install with npm:
npm install @itslanguage/recorder
Example usage, in code:
import { createRecorder, createMediaStream } from '@itslanguage/recorder';
createMediaStream().then(stream => {
const recorder = createRecorder(stream);
let audioChunks = [];
recorder.addEventListener('dataavailable', event => {
audioChunks.push(event.data);
});
recorder.start();
window.setTimeout(() => {
recorder.stop();
audioChunks.forEach(chunk => {
const audioElm = document.createElement('audio');
audioElm.controls = true;
audioElm.src = URL.createObjectURL(chunk);
document.getElementsByTagName('body')[0].appendChild(audioElm);
});
}, 25000);
});
Plugins
The recorder is prepared to be extended with plugins. For example, we have
written a plugin called AmplitudePlugin
that will output (emit) volume
information directly via the recorder. This information can, for example, be
used to create a volume meter to indicate recording to an end user. For more
information on this plugin, check the plugin itself.
Plugins can be used to create an instance of the plugin, and then add it to the
recorder. The recorder will then call the apply
function of the plugin.
This is an example on how one could use the AmplitudePlugin
.
import {
createRecorder,
createMediaStream,
createAmplitudePlugin,
} from '@itslanguage/recorder';
createMediaStream().then(stream => {
const amplitudePlugin = createAmplitudePlugin();
const recorder = createRecorder(stream, [amplitudePlugin]);
recorder.addEventListener('amplitudelevels', event => {
console.log(event.data.volume);
});
recorder.start();
});
API
createRecorder
createRecorder([stream], [plugins], [(mimeType = 'audio/wav')]);
This function is a factory method that just instantiates and returns a
MediaRecorder
object.
Arguments
[stream : MediaStream]
: Pass a MediaStream
object to the constructor
of MediaStream
. This param is not required, even though if you would omit it,
recording would not work obviously (no stream = no data).[plugins: Array]
: Pass plugins to the recorder to initialize.[mimeType: 'audio/wav' : String]
: Override the default mimeType for the
recorder. Whether a mimeType is valid or not can be checked with
MediaRecorder.isTypeSupported()
. Defaults to audio/wav
.
createMediaStream
createMediaStream();
This method will (try to) call navigator.mediaDevices.getUserMedia()
. This will
give you the required (authorized) stream to use with the MediaRecorder
object.
Also, this function will trigger the browser to ask the user for permission to
access the microphone.
It returns a promise and if all good the promise resolve with a MediaStream
object
createAmplitudePlugin
createAmplitudePlugin(
(options = { immediateStart: false, stopAfterRecording: true }),
);
Factory function to create an amplitude plugin. It will accept some options and
if all good it will return an AmplitudePlugin
object that can be passed to the
plugin array for createRecorder
.
The amplitude plugin wil dispatch amplitudelevels
events on the recorder with
information about the volume levels (per input channel if possible).
Arguments
[options: Object]
: Pass an object with options to control how the plugin
behaves.[options.immediateStart: false : Boolean]
: Start dispatching volume levels
when instantiating the plugin. If false (default value) it will start when
the recording is started.[options.stopAfterRecording: true : Boolean]
: Stop dispatching volume levels
when the recorder is stopped, which is the default behaviour.
createBufferPlugin
createBufferPlugin(
(options = {
immediateStart: false,
stopAfterRecording: true,
secondsToBuffer: 30,
eventToDispatch: 'bufferdataavailable',
}),
);
Factory function to create a buffer plugin. It will accept some options and if
all good it will return a BufferPlugin
object that can be passed to the plugin
array for createRecorder
.
The buffer plugin will dispatch buffered audio as audio/wav
blob to the
recorder via the bufferdataavailable
event. When instantiated it will register
a function requestBufferedData
on the recorder. When invoking that function the
configured event will be dispatched with the requested data. See below for the
API of requestBufferedData
.
Arguments
[options: Object]
: Pass an object with options to control how the plugin
behaves.[options.immediateStart: false : Boolean]
: Start buffering audio when
instantiating the plugin. If false (default value) it will start when
the recording is started.[options.stopAfterRecording: true : Boolean]
: Stop buffering audio when the
recorder is stopped, which is the default behaviour.[options.secondsToBuffer: 30: Number]
: Value that controls how many seconds
of audio will always be in the buffer. Defaults to 30 seconds.[options.eventToDispatch: bufferdataavailable: String]
: The event that is
used to dispatch the buffered audio on when requested. Use this option to
override the default value.
requestBufferedData
requestBufferedData((secondsToRead = 3));
This function will be registered on a recorder and allow you to get the buffered
data. When invoked it will make sure the configured event (by default
bufferdataavailable
) will be dispatched.
The function will be registered when audio buffering is started, and will be
deleted once the buffering stops.
Arguments
[secondsToRead: 3: Number]
: Use this param to define how may seconds there
will be read from the buffer. By default there will be gathered 3 seconds of
audio. If the value of secondsToRead
is 0 or equal or larger than the amount
of audio in the buffer the buffer will be returned completely.
Example
import {
createRecorder,
createMediaStream,
createNufferPlugin,
} from '@itslanguage/recorder';
createMediaStream().then(stream => {
const bufferPlugin = createNufferPlugin();
const recorder = createRecorder(stream, [bufferPlugin]);
recorder.addEventListener('bufferdataavailable', event => {
console.log(event.data);
});
recorder.start();
recorder.requestBufferedData();
});
Read more
Read more on the MediaStream Recording API on MDN:
https://developer.mozilla.org/en-US/docs/Web/API/MediaRecorder
Read more on the polyfill we used: https://github.com/ai/audio-recorder-polyfill