afmpeg¶
A pure-Go FFmpeg binding that runs on a virtual / in-memory filesystem. No CGO,
no host FFmpeg install, no temp files: FFmpeg is embedded as a WebAssembly module and
executed via wazero (a zero-dependency, pure-Go WASM runtime),
with its I/O bridged to an afero.Fs — so inputs and
outputs can live entirely in memory (or any afero backend), and the whole thing
cross-compiles to a single static binary.
Status: released
afmpeg runs real FFmpeg over a virtual filesystem today: the
vfs bridge, the runtime
(New/Run/Probe/Close), the Command builder (JobSpec()/RunJob for the
ffmpeg-wasi engine), and WithModuleURL module
fetching. Pair it with a released
ffmpeg-wasi module to transcode
entirely in memory. See the latest afmpeg release;
design rationale is in the specs under Development (start with
0001).
Why it exists¶
It was extracted from a need in keryx: keryx renders short reels by shelling out to the ffmpeg binary, which needs real files on disk — so it can't render an in-memory project (a remote cloned into RAM, no local checkout). Every existing Go option was rejected: purego bindings are immature and still need host libav; CGO bindings break a clean static cross-compile; and the existing wazero/WASM binding lacks the filters and codecs real workflows need. afmpeg is the "wazero + WASM done right" synthesis — a maintained FFmpeg-WASM build with the codecs/filters we need, a first-class afero virtual-filesystem I/O layer, and a clean Go API. Until afmpeg is usable, keryx renders local-filesystem-only; afmpeg reaching usable status is what lifts that lock-out.
How it works¶
Three layers — the middle one is the novel engineering:
- Embedded FFmpeg-WASM module — FFmpeg + x264 compiled to
wasm32-wasi, configured to only the codecs/filters needed; shipped as a separate artifact, not embedded. - The afero ↔ wazero vfs bridge (the heart) — routes the guest ffmpeg's WASI
filesystem syscalls to a
sys.FSbacked by the caller'safero.Fs, so reads and writes hit an in-memory filesystem with no host disk touched. - The Go API — compile the module once into a reusable
Runtime, thenRunan ffmpeg invocation over a suppliedafero.Fs; a general command builder layers on top.
See the architecture explainer for the full flow, and the roadmap for how the specs decompose the build.
Where to go next¶
- Tutorials — learn afmpeg by doing.
- How-to guides — solve a specific task.
- Explanation — the architecture and the why.
- Reference — the Go API and engine artifacts.
- Development — specs and contributor docs.
The Go API reference lives on pkg.go.dev.