Skip to Content

Methods

project.load(clips, options?)

await project.load(clips: Clip[], options?: LoadOptions): Promise<void[]>

Load clip descriptors into the project. Validates the timeline and reads media metadata.

Load options

OptionTypeDefaultDescription
skipFileChecksbooleaninherited from constructorOverride file existence checks for this load call
skipExtensionsCheckbooleaninherited from constructorOverride extension/type validation for this load call

Per-call options take precedence over the constructor-level setting.

SIMPLEFFMPEG.getDuration(clips)

Calculate total visual timeline duration from a clips array.

  • Handles duration shorthand
  • Handles auto-sequencing shorthand
  • Subtracts transition overlap
  • Pure function (no file I/O)
const clips = [ { type: "video", url: "./a.mp4", duration: 5 }, { type: "video", url: "./b.mp4", duration: 10, transition: { type: "fade", duration: 0.5 }, }, ]; SIMPLEFFMPEG.getDuration(clips); // 14.5

Useful when computing text timing and background music boundaries before load().

SIMPLEFFMPEG.probe(filePath)

Probe media with ffprobe and return normalized metadata for video/audio/image files.

const info = await SIMPLEFFMPEG.probe("./video.mp4"); // { // duration: 30.5, // seconds // width: 1920, // pixels // height: 1080, // pixels // hasVideo: true, // hasAudio: true, // rotation: 0, // mobile rotation metadata // videoCodec: "h264", // audioCodec: "aac", // format: "mov,mp4,m4a,3gp,3g2,mj2", // fps: 30, // size: 15728640, // bytes // bitrate: 4125000, // bits/sec // sampleRate: 48000, // Hz // channels: 2 // stereo // }

Fields that do not apply to a file type are null (for example, video fields on audio-only files).

Throws MediaNotFoundError when the file cannot be found or probed.

SIMPLEFFMPEG.snapshot(filePath, options)

Capture one frame from a video and write it as an image.

await SIMPLEFFMPEG.snapshot("./video.mp4", { outputPath: "./frame.png", time: 5, });

Snapshot options

OptionTypeDefaultDescription
outputPathstring-Required output image path (extension sets format)
timenumber0Timestamp in seconds
widthnumber-Output width (keeps aspect ratio if height omitted)
heightnumber-Output height (keeps aspect ratio if width omitted)
qualitynumber2JPEG quality 1-31, lower is better (.jpg/.jpeg only)

Supported formats: .jpg, .jpeg, .png, .webp, .bmp, .tiff.

SIMPLEFFMPEG.extractKeyframes(filePath, options)

Extract representative frames using either:

  • scene-change mode (default; FFmpeg scene detection)
  • interval mode (fixed time spacing)

If outputDir is set, returns string[] paths. If outputDir is omitted, returns in-memory Buffer[].

Each call with outputDir creates a unique simpleffmpeg-keyframes-XXXXXX subdirectory inside it, so repeat and concurrent calls against the same outputDir are fully isolated. Always use the returned paths — do not assume frames live directly at ${outputDir}/frame-0001.jpg.

const frames = await SIMPLEFFMPEG.extractKeyframes("./video.mp4", { mode: "scene-change", sceneThreshold: 0.4, maxFrames: 8, format: "jpeg", }); const paths = await SIMPLEFFMPEG.extractKeyframes("./video.mp4", { mode: "interval", intervalSeconds: 5, outputDir: "./frames/", format: "png", });

Keyframe options

OptionTypeDefaultDescription
modestring'scene-change''scene-change' or 'interval'
sceneThresholdnumber0.3Sensitivity 0-1 (lower = more frames), scene mode only
intervalSecondsnumber5Interval seconds, interval mode only
maxFramesnumber-Maximum number of frames
formatstring'jpeg''jpeg' or 'png'
qualitynumber-JPEG quality 1-31, lower is better
widthnumber-Output width
heightnumber-Output height
outputDirstring-Write files to disk (in a unique subdirectory per call) and return string[]
tempDirstringos.tmpdir()Temp directory for buffer mode

Throws FFmpegError if extraction fails.

project.export(options?)

await project.export(options?: ExportOptions): Promise<string>

Build and execute the FFmpeg command to render final output.

Export options

OptionTypeDefaultDescription
outputPathstring'./output.mp4'Output path
videoCodecstring'libx264'Video codec (libx264, libx265, libvpx-vp9, prores_ks, hardware codecs)
crfnumber23Quality level (0-51, lower is better)
presetstring'medium'Encoding preset (ultrafast .. veryslow)
videoBitratestring-Target bitrate (overrides CRF)
audioCodecstring'aac'Audio codec (aac, libmp3lame, libopus, flac, copy)
audioBitratestring'192k'Audio bitrate
audioSampleRatenumber48000Audio sample rate
hwaccelstring'none'Hardware acceleration (auto, videotoolbox, nvenc, vaapi, qsv)
outputWidthnumber-Scale output width
outputHeightnumber-Scale output height
outputResolutionstring-Resolution preset ('720p', '1080p', '4k')
audioOnlybooleanfalseAudio-only export
twoPassbooleanfalseTwo-pass encoding
metadataobject-Embed metadata
thumbnailobject-Generate thumbnail
verbosebooleanfalseVerbose logging
saveCommandstring-Save generated FFmpeg command
onProgressfunction-Progress callback
onLogfunction-FFmpeg log callback
signalAbortSignal-Cancellation signal
watermarkobject-Watermark overlay config
compensateTransitionsbooleantrueCompensate text/subtitle timings for transition overlap

project.preview(options?)

await project.preview(options?: ExportOptions): Promise<{ command: string; filterComplex: string; totalDuration: number; }>

Returns the resolved command details without executing FFmpeg.

Validation and schema methods

SIMPLEFFMPEG.validate(clips, options?)

Validate timeline descriptors before creating a project instance.

const result = SIMPLEFFMPEG.validate(clips, { skipFileChecks: true, skipExtensionsCheck: true, width: 1920, height: 1080, strictKenBurns: false, });

SIMPLEFFMPEG.formatValidationResult(result)

Produces human-readable validation output.

SIMPLEFFMPEG.getSchema(options?)

Exports schema text for clip model documentation/tooling.

Last updated on