UNPKG

@e10in/videojs-record

Version:

A video.js plugin for recording audio/video/image files.

182 lines (156 loc) 5.18 kB
/** * @file ffmpegjs-plugin.js * @since 3.8.0 */ import videojs from 'video.js'; const ConvertEngine = videojs.getComponent('ConvertEngine'); /** * Converter engine using the ffmpeg.js library. * * Deprecated. Use the ffmpeg.wasm plugin instead. * * @class * @augments videojs.ConvertEngine */ class FFmpegjsEngine extends ConvertEngine { /** * Creates an instance of this class. * * @param {Player} player * The `Player` that this class should be attached to. * * @param {Object} [options] * The key/value store of player options. */ constructor(player, options) { super(player, options); /** * Enables console logging for debugging purposes. * * @type {boolean} */ this.debug = false; /** * Path to worker script `ffmpeg-worker-mp4.js` (H.264 & AAC & MP3 encoders) * or `ffmpeg-worker-webm.js` (VP8 & Opus encoders). * * @type {string} */ this.convertWorkerURL = 'ffmpeg-worker-mp4.js'; /** * Mime-type for output. * * @type {string} */ this.outputType = null; /** * Additional configuration options for the ffmpeg.js library. * * @type {object} */ this.pluginLibraryOptions = {}; } /** * Setup recording engine. * * @param {Object} mediaType - Object describing the media type of this * engine. * @param {Boolean} debug - Indicating whether or not debug messages should * be printed in the console. */ setup(mediaType, debug) { this.mediaType = mediaType; this.debug = debug; this.stdout = this.stderr = ''; // set output mime type if (this.pluginLibraryOptions.outputType === undefined) { throw new Error('no outputType specified!'); } this.outputType = this.pluginLibraryOptions.outputType; // setup worker this.engine = new Worker(this.convertWorkerURL); this.engine.onmessage = this.onWorkerMessage.bind(this); } /** * Invoked when recording is stopped and resulting stream is available. * * @param {blob} data - Reference to the recorded `Blob` that needs to be * converted. */ convert(data) { // save timestamp this.timestamp = new Date(); this.timestamp.setTime(data.lastModified); // load and convert blob this.loadBlob(data).then((buffer) => { // specify input let opts = ['-i', data.name]; // add ffmpeg options opts = opts.concat(this.convertOptions); // use a temporary name opts.push('output_' + this.timestamp.getTime()); // start conversion this.engine.postMessage({ type: 'run', MEMFS: [{name: data.name, data: buffer}], arguments: opts }); }); } /** * Received a message from the worker. * * @param {Object} event - Event containing converted data. * @private */ onWorkerMessage(event) { let msg = event.data; switch (msg.type) { // worker loaded and ready to accept commands case 'ready': break; // worker started job case 'run': // notify listeners this.player().trigger('startConvert'); break; // job finished with some result case 'done': // converted data let buf; try { buf = msg.data.MEMFS[0].data; } catch (e) { this.player().trigger('error', this.stderr); } // store in blob let result = new Blob(buf, {type: this.outputType}); // inject date and name into blob this.addFileInfo(result, this.timestamp); // store result this.player().convertedData = result; // notify listeners this.player().trigger('finishConvert'); break; // FFmpeg printed to stdout case 'stdout': this.stdout += msg.data + '\n'; break; // FFmpeg printed to stderr case 'stderr': this.stderr += msg.data + "\n"; break; // FFmpeg exited case 'exit': break; // FFmpeg terminated abnormally (e.g. out of memory, wasm error) case 'abort': case 'error': this.player().trigger('error', msg.data); break; } } } // expose plugin videojs.FFmpegjsEngine = FFmpegjsEngine; export default FFmpegjsEngine;