Skip to content

Commit

Permalink
Merge pull request #209 from njoyard/small-api-cleanup
Browse files Browse the repository at this point in the history
Small api cleanup
  • Loading branch information
bencevans committed Mar 1, 2014
2 parents 3c35b0c + 0f1c99d commit b0b8371
Show file tree
Hide file tree
Showing 9 changed files with 503 additions and 362 deletions.
42 changes: 39 additions & 3 deletions README.md
Expand Up @@ -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 **/
Expand Down Expand Up @@ -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')

Expand Down Expand Up @@ -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');
Expand Down Expand Up @@ -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' })
Expand All @@ -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`
Expand Down
12 changes: 4 additions & 8 deletions lib/capabilities.js
@@ -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\.]) ([^ ]+) +(.*)$/;
Expand All @@ -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);
}
Expand Down Expand Up @@ -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);
}
Expand Down
9 changes: 2 additions & 7 deletions lib/extensions.js
Expand Up @@ -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
Expand Down
61 changes: 42 additions & 19 deletions lib/fluent-ffmpeg.js
Expand Up @@ -56,7 +56,7 @@ function FfmpegCommand(args) {
_isStreamable: true,
_updateFlvMetadata: false,
_useConstantVideoBitrate: false,
_nice: { level: priority },
_niceness: priority,
keepPixelAspect: false,
inputfile: srcfile,
inputstream: srcstream,
Expand All @@ -66,6 +66,7 @@ function FfmpegCommand(args) {
video: {},
audio: {},
additional: [],
inputOptions: [],
otherInputs: [],
informInputAudioCodec: null,
informInputVideoCodec: null,
Expand All @@ -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;
};
Expand All @@ -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);
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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;
Expand All @@ -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){
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;

0 comments on commit b0b8371

Please sign in to comment.