Permalink
Browse files

Merge pull request #209 from njoyard/small-api-cleanup

Small api cleanup
  • Loading branch information...
2 parents 3c35b0c + 0f1c99d commit b0b8371f109f85b2744cc42d9d5e0c629cc6ad09 @bencevans bencevans committed Mar 1, 2014
Showing with 503 additions and 362 deletions.
  1. +39 −3 README.md
  2. +4 −8 lib/capabilities.js
  3. +2 −7 lib/extensions.js
  4. +42 −19 lib/fluent-ffmpeg.js
  5. +113 −134 lib/metadata.js
  6. +210 −178 lib/processor.js
  7. +76 −8 test/args.test.js
  8. +2 −2 test/extensions.test.js
  9. +15 −3 test/processor.test.js
View
@@ -117,7 +117,7 @@ new FFmpeg({ source: '/path/to/video.avi' })
.withVideoBitrate('650k')
// Specify a constant video bitrate
- .withVideoBitrate('650k', FFmpeg.CONSTANT_BITRATE)
+ .withVideoBitrate('650k', true)
/** Video size **/
@@ -196,12 +196,28 @@ new FFmpeg({ source: '/path/to/video.avi' })
// Set output format
.toFormat('webm')
+ /** Custom filters **/
+
+ // Add custom audio filters
+ .withAudioFilter('equalizer=f=1000:width_type=h:width=200:g=-10')
+ .withAudioFilter('pan=1:c0=0.9*c0+0.1*c1')
+
+ // Add custom video filters
+ .withVideoFilter('size=iw*1.5:ih/2')
+ .withVideoFilter('drawtext=\'fontfile=FreeSans.ttf:text=Hello\'')
/** Miscellaneous options **/
// Use strict experimental flag (needed for some codecs)
.withStrictExperimental()
+ // Add custom input option (will be added before the input
+ // on ffmpeg command line)
+ .addInputOption('-f', 'avi')
+
+ // Add several input options at once
+ .addInputOptions(['-f avi', '-ss 2:30'])
+
// Add custom option
.addOption('-crf', '23')
@@ -249,6 +265,7 @@ var command = new FFmpeg({ source: '/path/to/video.avi' })
// - 'targetSize': the current size of the target file
// in kilobytes
// - 'timemark': the timestamp of the current frame
+ // in seconds
// - 'percent': an estimation of the progress
console.log('Processing: ' + progress.percent + '% done');
@@ -314,7 +331,26 @@ new FFmpeg({ source: '/path/to/video.avi' })
### Using presets
-Presets are located in fluent-ffmpeg `lib/presets` directory. To use a preset, call the `usingPreset` method on a command.
+#### Preset functions
+
+You can define a preset as a function that takes an `FfmpegCommand` as an argument and calls method on it, and then pass it to `usePreset`.
+
+```js
+function myPreset(command) {
+ command
+ .withAudioCodec('libmp3lame')
+ .withVideoCodec('libx264')
+ .withSize('320x240');
+}
+
+new Ffmpeg({ source: '/path/to/video.avi' })
+ .usingPreset(myPreset)
+ .saveToFile('/path/to/converted.mp4');
+```
+
+#### Preset modules
+
+Preset modules are located in fluent-ffmpeg `lib/presets` directory. To use a preset, call the `usingPreset` method on a command.
```js
new FFmpeg({ source: '/path/to/video.avi' })
@@ -333,7 +369,7 @@ exports.load = function(command) {
};
```
-fluent-ffmpeg comes with the following presets preinstalled:
+fluent-ffmpeg comes with the following preset modules preinstalled:
* `divx`
* `flashvideo`
* `podcast`
View
@@ -1,5 +1,5 @@
-var exec = require('child_process').exec,
- Registry = require('./registry');
+var exec = require('child_process').exec,
+ Registry = require('./registry');
var avCodecRegexp = /^ ([D ])([E ])([VAS])([S ])([D ])([T ]) ([^ ]+) +(.*)$/;
var ffCodecRegexp = /^ ([D\.])([E\.])([VAS])([I\.])([L\.])([S\.]) ([^ ]+) +(.*)$/;
@@ -17,9 +17,7 @@ exports = module.exports = function capabilities(command) {
command.prototype.getAvailableCodecs = function(callback) {
var codecs = Registry.instance.get('capabilityCodecs');
if (!codecs) {
- var command = [this.ffmpegPath, '-codecs'];
-
- exec(command.join(' '), function(err, stdout, stderr) {
+ this._spawnFfmpeg(['-codecs'], { captureStdout: true }, function(err, stdout) {
if (err) {
return callback(err);
}
@@ -95,9 +93,7 @@ exports = module.exports = function capabilities(command) {
command.prototype.getAvailableFormats = function(callback) {
var formats = Registry.instance.get('capabilityFormats');
if (!formats) {
- var command = [this.ffmpegPath, '-formats'];
-
- exec(command.join(' '), function(err, stdout, stderr) {
+ this._spawnFfmpeg(['-formats'], { captureStdout: true }, function (err, stdout) {
if (err) {
return callback(err);
}
View
@@ -39,19 +39,14 @@ exports = module.exports = function Extensions(command) {
};
command.prototype.ffmpegTimemarkToSeconds = function(timemark) {
-
// In case ffmpeg outputs the timemark as float
if(timemark.indexOf(':') === -1 && timemark.indexOf('.') >= 0)
- return parseInt(timemark)
+ return parseFloat(timemark)
var parts = timemark.split(':');
- var secs = 0;
-
- // split sec/msec part
- var secParts = parts.pop().split('.');
// add seconds
- secs += parseInt(secParts[0], 10);
+ var secs = parseFloat(parts.pop());
if (parts.length) {
// add minutes
View
@@ -56,7 +56,7 @@ function FfmpegCommand(args) {
_isStreamable: true,
_updateFlvMetadata: false,
_useConstantVideoBitrate: false,
- _nice: { level: priority },
+ _niceness: priority,
keepPixelAspect: false,
inputfile: srcfile,
inputstream: srcstream,
@@ -66,6 +66,7 @@ function FfmpegCommand(args) {
video: {},
audio: {},
additional: [],
+ inputOptions: [],
otherInputs: [],
informInputAudioCodec: null,
informInputVideoCodec: null,
@@ -74,15 +75,19 @@ function FfmpegCommand(args) {
// public chaining methods
FfmpegCommand.prototype.usingPreset = function(preset) {
- // require preset (since require() works like a singleton, multiple calls generate no overhead)
- try {
- var module = require('./presets/' + preset);
- if (typeof module.load === 'function') {
- module.load(this);
+ if (typeof preset === 'function') {
+ preset(this);
+ } else {
+ // require preset (since require() works like a singleton, multiple calls generate no overhead)
+ try {
+ var module = require('./presets/' + preset);
+ if (typeof module.load === 'function') {
+ module.load(this);
+ }
+ return this;
+ } catch (err) {
+ throw new Error('preset ' + preset + ' could not be loaded');
}
- return this;
- } catch (err) {
- throw new Error('preset ' + preset + ' could not be loaded');
}
return this;
};
@@ -94,11 +99,11 @@ function FfmpegCommand(args) {
this.options.audio.skip = true;
return this;
};
- FfmpegCommand.prototype.withVideoBitrate = function(vbitrate, type) {
+ FfmpegCommand.prototype.withVideoBitrate = function(vbitrate, constant) {
if (typeof vbitrate === 'string' && vbitrate.indexOf('k') > 0) {
vbitrate = vbitrate.replace('k', '');
}
- if (type && type === exports.CONSTANT_BITRATE) {
+ if (constant) {
this.options._useConstantVideoBitrate = true;
}
this.options.video.bitrate = parseInt(vbitrate, 10);
@@ -145,6 +150,11 @@ function FfmpegCommand(args) {
this.options.video.codec = codec;
return this;
};
+ FfmpegCommand.prototype.withVideoFilter = function(filter) {
+ this.options.video.filters = this.options.video.filters || [];
+ this.options.video.filters.push(filter);
+ return this;
+ };
FfmpegCommand.prototype.loop = function(duration) {
this.options.video.loop = true;
if (duration) {
@@ -179,6 +189,11 @@ function FfmpegCommand(args) {
this.options.audio.quality = parseInt(quality, 10);
return this;
};
+ FfmpegCommand.prototype.withAudioFilter = function(filter) {
+ this.options.audio.filters = this.options.audio.filters || [];
+ this.options.audio.filters.push(filter);
+ return this;
+ };
FfmpegCommand.prototype.setStartTime = function(timestamp) {
this.options.starttime = timestamp;
return this;
@@ -191,22 +206,31 @@ function FfmpegCommand(args) {
this.options.otherInputs.push(inputFile);
return this;
};
- FfmpegCommand.prototype.addOptions = function(optionArray) {
+ FfmpegCommand.prototype.addInputOptions = function(optionsArray) {
+ return this.addOptions(optionsArray, true);
+ };
+ FfmpegCommand.prototype.addOptions = function(optionArray, forInput) {
+ var target = forInput ? this.options.inputOptions : this.options.additional;
+
if (typeof optionArray.length !== undefined) {
var self = this;
optionArray.forEach(function(el) {
if (el.indexOf(' ') > 0) {
var values = el.split(' ');
- self.options.additional.push(values[0], values[1]);
+ target.push(values[0], values[1]);
} else {
- self.options.additional.push(el);
+ target.push(el);
}
});
}
return this;
};
- FfmpegCommand.prototype.addOption = function(option, value) {
- this.options.additional.push(option, value);
+ FfmpegCommand.prototype.addInputOption = function(option, value) {
+ return this.addOption(option, value, true);
+ };
+ FfmpegCommand.prototype.addOption = function(option, value, forInput) {
+ var target = forInput ? this.options.inputOptions : this.options.additional;
+ target.push(option, value);
return this;
};
FfmpegCommand.prototype.mergeAdd = function(path){
@@ -239,7 +263,7 @@ function FfmpegCommand(args) {
level = 0;
}
- this.options._nice.level = level;
+ this.options._niceness = level;
if (this.ffmpegProc) {
this._renice(this.ffmpegProc, level);
@@ -342,5 +366,4 @@ exports = module.exports = function(args) {
exports.Metadata = metaDataLib;
exports.Calculate = require('./calculate');
-exports.CONSTANT_BITRATE = 1;
-exports.VARIABLE_BITRATE = 2;
+exports.CONSTANT_BITRATE = true;
Oops, something went wrong.

0 comments on commit b0b8371

Please sign in to comment.