A fluent API to FFMPEG for audio and video manipulation with chainable methods
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
System configuration capabilities including binary path management, capability queries, preset system, and FFmpeg environment setup.
Configure paths to FFmpeg, FFprobe, and related binaries.
/**
* Set FFmpeg binary path
* @param path - Full path to ffmpeg executable
* @returns FfmpegCommand instance
*/
setFfmpegPath(path) // → FfmpegCommand
/**
* Set FFprobe binary path
* @param path - Full path to ffprobe executable
* @returns FfmpegCommand instance
*/
setFfprobePath(path) // → FfmpegCommand
/**
* Set flvtool2/flvmeta binary path
* @param path - Full path to flvtool executable
* @returns FfmpegCommand instance
*/
setFlvtoolPath(path) // → FfmpegCommand
/**
* Static methods for global configuration
*/
FfmpegCommand.setFfmpegPath(path) // → void
FfmpegCommand.setFfprobePath(path) // → void
FfmpegCommand.setFlvtoolPath(path) // → voidUsage Examples:
const ffmpeg = require('fluent-ffmpeg');
// Set paths globally (affects all instances)
ffmpeg.setFfmpegPath('/usr/local/bin/ffmpeg');
ffmpeg.setFfprobePath('/usr/local/bin/ffprobe');
ffmpeg.setFlvtoolPath('/usr/local/bin/flvmeta');
// Set paths per instance
ffmpeg('input.mp4')
.setFfmpegPath('/opt/ffmpeg/bin/ffmpeg')
.setFfprobePath('/opt/ffmpeg/bin/ffprobe')
.save('output.mp4');
// Platform-specific paths
const os = require('os');
const path = require('path');
if (os.platform() === 'win32') {
ffmpeg.setFfmpegPath(path.join(__dirname, 'bin', 'ffmpeg.exe'));
ffmpeg.setFfprobePath(path.join(__dirname, 'bin', 'ffprobe.exe'));
} else {
ffmpeg.setFfmpegPath('/usr/bin/ffmpeg');
ffmpeg.setFfprobePath('/usr/bin/ffprobe');
}
// Custom installation paths
ffmpeg.setFfmpegPath('/Applications/FFmpeg/ffmpeg');
ffmpeg.setFfprobePath('/Applications/FFmpeg/ffprobe');
// Relative paths (not recommended for production)
ffmpeg.setFfmpegPath('./vendor/ffmpeg');Query FFmpeg installation for available codecs, filters, and formats.
/**
* Get available filters
* @param callback - Callback with (err, filters) where filters is object
*/
availableFilters(callback) // → void
// Aliases: getAvailableFilters
/**
* Get available codecs
* @param callback - Callback with (err, codecs) where codecs is object
*/
availableCodecs(callback) // → void
// Aliases: getAvailableCodecs
/**
* Get available encoders
* @param callback - Callback with (err, encoders) where encoders is object
*/
availableEncoders(callback) // → void
// Aliases: getAvailableEncoders
/**
* Get available formats
* @param callback - Callback with (err, formats) where formats is object
*/
availableFormats(callback) // → void
// Aliases: getAvailableFormats
/**
* Static methods for global queries
*/
FfmpegCommand.availableFilters(callback) // → void
FfmpegCommand.availableCodecs(callback) // → void
FfmpegCommand.availableEncoders(callback) // → void
FfmpegCommand.availableFormats(callback) // → voidUsage Examples:
// Check available video codecs
ffmpeg.availableCodecs((err, codecs) => {
if (err) {
console.error('Could not retrieve codecs:', err);
return;
}
console.log('Available codecs:', Object.keys(codecs));
// Check for specific codec
if (codecs.libx264) {
console.log('H.264 encoder available');
console.log('Details:', codecs.libx264);
}
if (codecs.libx265) {
console.log('H.265 encoder available');
}
});
// Check available filters
ffmpeg.availableFilters((err, filters) => {
if (!err) {
console.log('Video filters:', Object.keys(filters).filter(name =>
filters[name].multipleInputs || filters[name].description.includes('video')
));
// Check for specific filter
if (filters.scale) {
console.log('Scale filter available:', filters.scale.description);
}
}
});
// Check available formats
ffmpeg.availableFormats((err, formats) => {
if (!err) {
console.log('Input formats:', Object.keys(formats).filter(name =>
formats[name].canDemux
));
console.log('Output formats:', Object.keys(formats).filter(name =>
formats[name].canMux
));
}
});
// Promise wrapper for capability checks
const getCapabilities = () => {
return Promise.all([
new Promise((resolve, reject) => {
ffmpeg.availableCodecs((err, codecs) => {
if (err) reject(err);
else resolve({ type: 'codecs', data: codecs });
});
}),
new Promise((resolve, reject) => {
ffmpeg.availableFilters((err, filters) => {
if (err) reject(err);
else resolve({ type: 'filters', data: filters });
});
}),
new Promise((resolve, reject) => {
ffmpeg.availableFormats((err, formats) => {
if (err) reject(err);
else resolve({ type: 'formats', data: formats });
});
})
]);
};
// Feature detection
const checkFeatureSupport = async () => {
try {
const capabilities = await getCapabilities();
const codecs = capabilities.find(c => c.type === 'codecs').data;
const filters = capabilities.find(c => c.type === 'filters').data;
return {
h264: !!codecs.libx264,
h265: !!codecs.libx265,
vp9: !!codecs.libvpx_vp9,
scaling: !!filters.scale,
stabilization: !!filters.deshake,
hwAccel: !!codecs.h264_nvenc || !!codecs.h264_qsv
};
} catch (error) {
console.error('Feature detection failed:', error);
return null;
}
};Apply predefined configuration presets for common encoding scenarios.
/**
* Apply preset configuration
* @param preset - Preset name (string) or preset function
* @returns FfmpegCommand instance
*/
preset(preset) // → FfmpegCommand
// Aliases: usingPresetBuilt-in Presets:
'podcast' - Optimized for podcast audio/video (M4V, x264, AAC)'divx' - DivX-compatible encoding'flashvideo' - Flash video formatUsage Examples:
// Use built-in presets
ffmpeg('input.avi')
.preset('podcast')
.save('podcast.m4v');
ffmpeg('input.mp4')
.preset('flashvideo')
.save('flash_video.flv');
// Custom preset function
const myPreset = (command) => {
return command
.videoCodec('libx264')
.audioCodec('aac')
.videoBitrate('2000k')
.audioBitrate('128k')
.size('1920x1080')
.fps(30)
.outputOptions([
'-preset', 'medium',
'-crf', '23',
'-movflags', '+faststart'
]);
};
ffmpeg('input.avi')
.preset(myPreset)
.save('custom_preset.mp4');
// Preset with parameters
const qualityPreset = (quality = 'medium') => {
const presets = {
high: { crf: '18', preset: 'slow', bitrate: '5000k' },
medium: { crf: '23', preset: 'medium', bitrate: '2000k' },
low: { crf: '28', preset: 'fast', bitrate: '1000k' }
};
const config = presets[quality] || presets.medium;
return (command) => {
return command
.videoCodec('libx264')
.videoBitrate(config.bitrate)
.outputOptions([
'-crf', config.crf,
'-preset', config.preset,
'-movflags', '+faststart'
]);
};
};
ffmpeg('input.avi')
.preset(qualityPreset('high'))
.save('high_quality.mp4');Configure custom preset directory for loading preset modules.
/**
* Constructor options for preset configuration
*/
interface FfmpegOptions {
presets?: string; // Preset directory path
preset?: string; // Alias for presets
}Usage Examples:
// Set preset directory in constructor
const command = ffmpeg('input.avi', {
presets: './my-presets' // Look for presets in this directory
});
command.preset('my-custom-preset').save('output.mp4');
// Preset module structure (./my-presets/web-optimized.js)
module.exports = {
load: function(ffmpeg) {
return ffmpeg
.videoCodec('libx264')
.audioCodec('aac')
.videoBitrate('1500k')
.size('1280x720')
.outputOptions([
'-preset', 'medium',
'-crf', '25',
'-movflags', '+faststart',
'-pix_fmt', 'yuv420p'
]);
}
};
// Use the custom preset
ffmpeg('input.mp4', { presets: './my-presets' })
.preset('web-optimized')
.save('web_ready.mp4');Configure logging, process options, and other environment settings.
/**
* Constructor options for environment configuration
*/
interface FfmpegOptions {
logger?: Logger; // Custom logger object
niceness?: number; // Process niceness (-20 to 20)
priority?: number; // Alias for niceness
stdoutLines?: number; // Max stdout lines to keep (default: 100)
timeout?: number; // Processing timeout in seconds
}
/**
* Logger interface
*/
interface Logger {
debug(message: string): void;
info(message: string): void;
warn(message: string): void;
error(message: string): void;
}Usage Examples:
// Custom logger
const logger = {
debug: (msg) => console.log(`[DEBUG] ${msg}`),
info: (msg) => console.log(`[INFO] ${msg}`),
warn: (msg) => console.warn(`[WARN] ${msg}`),
error: (msg) => console.error(`[ERROR] ${msg}`)
};
ffmpeg('input.mp4', {
logger: logger,
niceness: 10, // Lower priority
stdoutLines: 50, // Keep fewer lines in memory
timeout: 300 // 5 minute timeout
})
.save('output.mp4');
// Production configuration
const productionConfig = {
logger: {
debug: () => {}, // Disable debug logging
info: (msg) => console.log(msg),
warn: (msg) => console.warn(`WARNING: ${msg}`),
error: (msg) => console.error(`ERROR: ${msg}`)
},
niceness: 5, // Slightly lower priority
stdoutLines: 20, // Minimal memory usage
timeout: 1800 // 30 minute timeout for long videos
};
ffmpeg('large_video.mkv', productionConfig)
.videoCodec('libx264')
.save('processed.mp4');
// Development configuration with verbose logging
const developmentConfig = {
logger: console, // Use console directly
stdoutLines: 200, // Keep more output for debugging
timeout: 0 // No timeout
};/**
* Binary path specification
*/
type BinaryPath = string; // Absolute or relative path to executable
/**
* Capability query results
*/
interface CodecInfo {
type: string; // 'audio', 'video', 'subtitle'
description: string; // Codec description
canDecode: boolean; // Can decode this format
canEncode: boolean; // Can encode to this format
directRendering?: boolean; // Supports direct rendering
weirdFrameTruncation?: boolean; // Has frame truncation issues
}
interface FilterInfo {
description: string; // Filter description
input: string; // Input type ('audio', 'video', 'none')
multipleInputs: boolean; // Accepts multiple inputs
output: string; // Output type
multipleOutputs: boolean; // Produces multiple outputs
}
interface FormatInfo {
description: string; // Format description
canDemux: boolean; // Can read this format
canMux: boolean; // Can write this format
}
/**
* Preset function signature
*/
type PresetFunction = (command: FfmpegCommand) => FfmpegCommand;
/**
* Process niceness range
*/
type ProcessNiceness = number; // -20 (highest priority) to 20 (lowest priority)
/**
* Timeout specification
*/
type TimeoutSeconds = number; // 0 = no timeout, >0 = timeout in seconds
/**
* Constructor options interface
*/
interface FfmpegOptions {
logger?: Logger; // Custom logger implementation
niceness?: ProcessNiceness; // Process priority
priority?: ProcessNiceness; // Alias for niceness
presets?: string; // Custom preset directory
preset?: string; // Alias for presets
stdoutLines?: number; // Max stdout lines to buffer
timeout?: TimeoutSeconds; // Processing timeout
source?: string | Stream; // Alias for input parameter
}