UNPKG

ffcreator-chuanbota

Version:

FFCreator is a lightweight and flexible short video production library

146 lines (133 loc) 3.69 kB
'use strict'; /** * FFmpegUtil - Auxiliary utils functions related to ffmpeg * * ####Example: * * FFmpegUtil.concatOpts(this.inputOptions, ["-framerate", fps]); * * @object */ const siz = require('siz'); const isArray = require('lodash/isArray'); const forEach = require('lodash/forEach'); const ffmpeg = require('fluent-ffmpeg'); const FFmpegUtil = { /** * Return fluent-ffmpeg class instance * * @return {ffmpeg} fluent-ffmpeg * @public */ getFFmpeg() { return ffmpeg; }, /** * Set the installation path of the current server ffmpeg. * If not set, the ffmpeg command of command will be found by default. * * @param {string} path - installation path of the current server ffmpeg * @public */ setFFmpegPath(path) { ffmpeg.setFfmpegPath(path); }, /** * Set the installation path of the current server ffprobe. * If not set, the ffprobe command of command will be found by default. * Environment variable FFPROBE_PATH is used in ffmpeg-probe. * * @param {string} path - installation path of the current server ffprobe * @public */ setFFprobePath(path) { process.env.FFPROBE_PATH = path; ffmpeg.setFfprobePath(path); }, /** * Set a water mark for swpan stdin * * @param {number} highWaterMark - a water mark for swpan stdin * @public */ setHighWaterMark({ command, highWaterMark }) { highWaterMark = siz(highWaterMark); command.ffmpegProc.stdin._writableState.highWaterMark = highWaterMark; command.ffmpegProc.stdin._readableState.highWaterMark = highWaterMark; }, /** * Create a ffmpeg command instance * @public */ createCommand(conf = {}) { const { threads = 1 } = conf; const command = ffmpeg(); if (threads > 1) command.addOptions([`-threads ${threads}`]); return command; }, /** * Set a cover thumbnail for the video * @public */ addCoverImage({ video, output, cover }) { return new Promise((resolve, reject) => { const command = this.createCommand(); command.addInput(video); command.addInput(cover); command.output(output); command.outputOptions( '-map 0 -map 1 -c copy -c:v:1 png -disposition:v:1 attached_pic'.split(' '), ); //command.on('start', commandLine => console.log(commandLine)); command.on('end', () => { resolve(); this.destroy(command); }); command.on('error', (error, stdout, stderr) => { reject([error, stdout, stderr]); this.destroy(command); }); command.run(); }); }, /** * Take a Clip from the video * @public */ interceptVideo({ video, ss, to, output }) { return new Promise((resolve, reject) => { const command = this.createCommand(); command.addInput(video); command.addInputOption('-ss', ss); command.addInputOption('-to', to); command.output(output); command.outputOptions('-vcodec copy -acodec copy'.split(' ')); //command.on('start', commandLine => console.log(commandLine)); command.on('end', () => { resolve(); this.destroy(command); }); command.on('error', (error, stdout, stderr) => { reject([error, stdout, stderr]); this.destroy(command); }); command.run(); }); }, concatOpts(opts, arr) { if (isArray(arr)) { forEach(arr, o => opts.push(o)); } else { opts.push(arr); } }, destroy(command) { try { command.removeAllListeners(); command.kill(); command._inputs.length = 0; command._currentInput = null; } catch (e) {} }, }; module.exports = FFmpegUtil;