Bun's Node compatibility layer will run fluent-ffmpeg. That is the honest answer, and for a lot of apps it is good enough.
I still ended up writing a tiny wrapper around Bun.spawn.
The jobs I actually had were boring: transcode a file, pipe a stream, turn whatever the user uploaded into 16 kHz mono PCM for Whisper. fluent-ffmpeg can do all of that, plus video, filters, and a fluent builder I was not going to use. In a Bun-only service I also did not want "it works through the Node compat layer" as the whole story.
So bun-ffmpeg is intentionally small. Audio only. System ffmpeg / ffprobe. Typed helpers. No bundled binary.
What it looks like
Install ffmpeg yourself (brew install ffmpeg, apt install ffmpeg, or set FFMPEG_PATH in Docker). Then:
bun add bun-ffmpeg
import { audio } from "bun-ffmpeg";
await audio("input.mp3", "output.aac", {
codec: "aac",
bitrate: "192k",
channels: 2,
sampleRate: 44100,
});
The Whisper path is one function. It always emits 16 kHz, mono, pcm_s16le WAV:
import { audioWav } from "bun-ffmpeg";
const wav = await audioWav(
new Uint8Array(await Bun.file("input.mp3").arrayBuffer()),
);
await Bun.write("input.16k.wav", wav);
Streams work the same way: ReadableStream in, file or chunk callbacks out. If the binary is missing you get an error that tells you to install ffmpeg instead of a raw ENOENT.
Why not fluent-ffmpeg
| Need | fluent-ffmpeg | bun-ffmpeg |
|---|---|---|
| Runtime | Node, works on Bun via compat | Bun only (Bun.spawn) |
| Surface | Video, filters, graphs | Audio |
| Binary | Still needs ffmpeg on the machine | Same |
| Shape | Fluent builder | A handful of functions |
If you are muxing video or building filter graphs, keep fluent-ffmpeg. This package is for the case where the runtime is Bun and the media is audio.
Under the hood there is no magic: spawn ffmpeg, pass -i, codec, bitrate, channels, sample rate, and either a path or pipe:0 / pipe:1. The wrapper exists so you do not re-derive those flags in every script.
What it will not do
- Node.js
- Video
- A fluent API
- Shipping ffmpeg inside the npm tarball
v0.3.0 added FFMPEG_PATH / FFPROBE_PATH for containers, and FfmpegNotFoundError when the binary is not there.
Repo: github.com/KenjiGinjo/bun-ffmpeg
npm: bun add bun-ffmpeg
Top comments (0)