FFmpeg class
The @ffmpeg/ffmpeg-compatible class — construction, load, events, the virtual filesystem, exec, and terminate — each documented separately.
A drop-in-shaped replacement for @ffmpeg/ffmpeg v0.12, so an existing ffmpeg.wasm
snippet runs with minimal edits. Source: src/js/ffmpeg.js.
const ff = new FFmpeg();
ff.on('log', ({ message }) => console.log(message));
await ff.load();
await ff.writeFile('input.mp4', data);
const frame = await ff.exec(['-i', 'input.mp4', '-vf', 'scale=1280:720']);
Construction
new FFmpeg()
Constructs an instance. ff.loaded is false until load() resolves. Multiple instances
are independent wrappers but share the same underlying WASM module once loaded.
load
Signature
await ff.load(opts?)
Parameters
| Param | Type | Description |
|---|---|---|
opts.wasmPath | string | Optional override for the module’s .js path. |
Behavior
Loads the module (WebGPU build when navigator.gpu exists, else CPU). Idempotent.
Events
on
ff.on('log', ({ type, message }) => {}); // type: 'stdout' | 'stderr'
ff.on('progress', ({ progress }) => {}); // parsed from "time=" in stderr
Registers a handler for 'log' or 'progress'.
off
ff.off('log', handler);
Removes a previously registered handler.
Event payloads
| Event | Payload | Notes |
|---|---|---|
log | { type, message } | type is 'stdout' or 'stderr'. |
progress | { progress } | Fires when a time= token appears in stderr. |
Virtual filesystem
These map directly onto Emscripten’s FS. All five throw call load() first until the module is
loaded.
writeFile
await ff.writeFile(path, data)
Writes data to path. data may be a Uint8Array or anything with an arrayBuffer() method
(a Blob/File), which is read into a Uint8Array first. Returns nothing.
await ff.writeFile('/input.mp4', new Uint8Array(bytes));
await ff.writeFile('/input.mp4', blob);
readFile
const data = await ff.readFile(path)
Returns a Uint8Array of the file at path.
deleteFile
await ff.deleteFile(path)
Unlinks path (FS.unlink). Returns nothing.
createDir
await ff.createDir(path)
Creates a directory (FS.mkdir). Returns nothing.
listDir
const entries = await ff.listDir(path)
Returns a string[] of entry names in the directory, including '.' and '..'.
exec
Reads the -i input from the virtual filesystem and dispatches it through the wasmpeg
pipeline.
Signature
await ff.exec(args, opts?)
Parameters
| Param | Type | Description |
|---|---|---|
args | string[] | FFmpeg-style argument array. The first -i value is the input path, read from the virtual filesystem. |
opts.timeout | number | Accepted for @ffmpeg/ffmpeg compatibility; currently has no effect. |
Returns
The same thing the dispatcher returns: RGBA pixels for a
filter op, or a Decoder for a decode-only command.
Throws if no -i input is given.
Example
const frame = await ff.exec(['-i', 'input.mp4', '-vf', 'scale=1280:720']);
exec() runs the decode + filter pipeline only. It does not mux to an output
file — await ff.exec(['-i','in.mp4','out.webm']); ff.readFile('out.webm') will not
produce out.webm. For media output use the pixels/decoder it returns, or
gpu.createEncoder. The full supported/unsupported
surface is the command reference.terminate
ff.terminate();
Clears event handlers and marks the instance unloaded (ff.loaded === false). Does not
tear down the shared WASM module.
Migrating from @ffmpeg/ffmpeg
The load / on / writeFile / readFile / exec surface matches, so most snippets
port unchanged. The one behavioral difference to rework: ffmpeg.wasm’s exec() writes
output files you read back; wasmpeg’s exec() returns frames/decoders directly and does
not write output containers. Replace any exec(); readFile('out.*') pattern with code
that consumes the return value.