UNPKG

@itslanguage/recorder

Version:

JavaScript Recorder based on MediaRecorder from ITSLanguage.

119 lines (103 loc) 3.23 kB
import { createAmplitude } from './amplitude'; /** * This class defines the Amplitude plugin. */ class AmplitudePlugin { /** * Constructor method. * * @param {object} options - Options to pass to the plugin. * @param {boolean} options.immediateStart - Immediately start emitting the * `amplitudelevels` events, or wait for the recorder to start. * @param {boolean} options.stopAfterRecording - Stop emitting the events after the * recorder stops recording. */ constructor({ immediateStart = false, stopAfterRecording = true }) { this.immediateStart = immediateStart; this.stopAfterRecording = stopAfterRecording; this.animationFrameStarted = false; this.animationFrame = null; this.amplitudeNode = null; this.recorder = null; this.startDispatching = this.startDispatching.bind(this); this.recordingStopped = this.recordingStopped.bind(this); this.dispatchLevelsAnimationLoop = this.dispatchLevelsAnimationLoop.bind( this, ); } /** * This is the loop, based on `requestAnimationFrame`, that will run to query * and emit Amplitude information. * * @fires AmplitudePlugin#amplitudlevels - Fires an event on the recorder with * the Amplitude levels computed from the audio source. */ dispatchLevelsAnimationLoop() { // Get the levels from the Amplitude object; const levels = this.amplitudeNode.getCurrentLevels(); // Create an event object to dispatch to the recorder; const event = new Event('amplitudelevels'); event.data = { ...levels }; // Dispatch the data! this.recorder.dispatchEvent(event); // Request the next frame to run; this.animationFrame = requestAnimationFrame( this.dispatchLevelsAnimationLoop, ); } /** * Start the loop, only if it is not already running. */ startDispatching() { if (!this.animationFrameStarted) { this.animationFrame = requestAnimationFrame( this.dispatchLevelsAnimationLoop, ); this.animationFrameStarted = true; } } /** * Stop and reset the loop. */ stopDispatching() { cancelAnimationFrame(this.animationFrame); this.animationFrameStarted = false; } /** * Handler for the recorder, this gets executed as soon as the recorder stops * recording. Based on the options it will stop the loop that emits the * Amplitude levels. */ recordingStopped() { if (this.stopAfterRecording) { this.stopDispatching(); } } /** * Start the plugin. */ startPlugin() { this.amplitudeNode = createAmplitude(this.recorder.stream); if (this.immediateStart) { this.startDispatching(); } this.recorder.addEventListener('dataavailable', () => { this.startDispatching(); if (this.recorder.state === 'inactive') { this.recordingStopped(); } }); } /** * This function gets called from itslanguage recorder side. It will pass * the recorder to it so we can use it. * * @param {MediaRecorder} recorder - Recorder for which this plugin needs to be * active on. */ applyPlugin(recorder) { this.recorder = recorder; this.startPlugin(); } } export default AmplitudePlugin;