audiobookshelf/server/libs/fluentFfmpeg/options/output.js

163 lines
3.8 KiB
JavaScript

/*jshint node:true*/
'use strict';
var utils = require('../utils');
/*
*! Output-related methods
*/
module.exports = function(proto) {
/**
* Add output
*
* @method FfmpegCommand#output
* @category Output
* @aliases addOutput
*
* @param {String|Writable} target target file path or writable stream
* @param {Object} [pipeopts={}] pipe options (only applies to streams)
* @return FfmpegCommand
*/
proto.addOutput =
proto.output = function(target, pipeopts) {
var isFile = false;
if (!target && this._currentOutput) {
// No target is only allowed when called from constructor
throw new Error('Invalid output');
}
if (target && typeof target !== 'string') {
if (!('writable' in target) || !(target.writable)) {
throw new Error('Invalid output');
}
} else if (typeof target === 'string') {
var protocol = target.match(/^([a-z]{2,}):/i);
isFile = !protocol || protocol[0] === 'file';
}
if (target && !('target' in this._currentOutput)) {
// For backwards compatibility, set target for first output
this._currentOutput.target = target;
this._currentOutput.isFile = isFile;
this._currentOutput.pipeopts = pipeopts || {};
} else {
if (target && typeof target !== 'string') {
var hasOutputStream = this._outputs.some(function(output) {
return typeof output.target !== 'string';
});
if (hasOutputStream) {
throw new Error('Only one output stream is supported');
}
}
this._outputs.push(this._currentOutput = {
target: target,
isFile: isFile,
flags: {},
pipeopts: pipeopts || {}
});
var self = this;
['audio', 'audioFilters', 'video', 'videoFilters', 'sizeFilters', 'options'].forEach(function(key) {
self._currentOutput[key] = utils.args();
});
if (!target) {
// Call from constructor: remove target key
delete this._currentOutput.target;
}
}
return this;
};
/**
* Specify output seek time
*
* @method FfmpegCommand#seek
* @category Input
* @aliases seekOutput
*
* @param {String|Number} seek seek time in seconds or as a '[hh:[mm:]]ss[.xxx]' string
* @return FfmpegCommand
*/
proto.seekOutput =
proto.seek = function(seek) {
this._currentOutput.options('-ss', seek);
return this;
};
/**
* Set output duration
*
* @method FfmpegCommand#duration
* @category Output
* @aliases withDuration,setDuration
*
* @param {String|Number} duration duration in seconds or as a '[[hh:]mm:]ss[.xxx]' string
* @return FfmpegCommand
*/
proto.withDuration =
proto.setDuration =
proto.duration = function(duration) {
this._currentOutput.options('-t', duration);
return this;
};
/**
* Set output format
*
* @method FfmpegCommand#format
* @category Output
* @aliases toFormat,withOutputFormat,outputFormat
*
* @param {String} format output format name
* @return FfmpegCommand
*/
proto.toFormat =
proto.withOutputFormat =
proto.outputFormat =
proto.format = function(format) {
this._currentOutput.options('-f', format);
return this;
};
/**
* Add stream mapping to output
*
* @method FfmpegCommand#map
* @category Output
*
* @param {String} spec stream specification string, with optional square brackets
* @return FfmpegCommand
*/
proto.map = function(spec) {
this._currentOutput.options('-map', spec.replace(utils.streamRegexp, '[$1]'));
return this;
};
/**
* Run flvtool2/flvmeta on output
*
* @method FfmpegCommand#flvmeta
* @category Output
* @aliases updateFlvMetadata
*
* @return FfmpegCommand
*/
proto.updateFlvMetadata =
proto.flvmeta = function() {
this._currentOutput.flags.flvmeta = true;
return this;
};
};