How FFmpeg Works — Explained with a Diagram (Beginner Friendly)

2026-08-20

Most people's first encounter with ffmpeg is a line like this:

ffmpeg -i input.mp4 output.mkv

And they think: "wow, one command turned mp4 into mkv."

But the biggest lesson from building tools.beer is this: ffmpeg is not a "format converter" — it's a multimedia factory pipeline. Once you see that pipeline, the re-encode vs stream copy puzzle ("why is stream copy fast and re-encode slow?") explains itself — because they travel completely different stretches of that line.

1. The one-line definition

FFmpeg is an open-source multimedia framework. The ffmpeg command is just an "operator console": you give it an input, tell it the output you want, and it assembles a pipeline out of its parts to process the material into a finished file.

The parts that actually do the work are these libraries:

  • libavformat: unboxing and reboxing (demux / mux);
  • libavcodec: decoding and encoding (compressing and decompressing video/audio);
  • libavfilter: processing (crop, volume, watermark, etc.);
  • libswscale / libswresample: image scaling and audio resampling.

You don't need to memorize the library names. Just remember: ffmpeg chains five steps into one line; raw material goes in one end, finished file comes out the other.

2. The analogy: a multimedia factory pipeline

Picture one conversion as a factory processing a batch of goods:

  1. Demux = unbox: receive a shipping box (the container file), open it, and sort the video packets and audio packets.
  2. Decode = decompress: expand the compressed video/audio back into "raw material" (uncompressed frames, raw audio samples).
  3. Filter = process (optional): modify the raw material — crop black bars, adjust volume, add a watermark, scale resolution.
  4. Encode = compress: re-compress the processed raw material into small data streams with the target codec.
  5. Mux = rebox: package the new video and audio streams into the target container, index them, and produce a playable file.
FFmpeg pipeline: source in one end, finished file out the otherStream copy -c copy: skip the middle three, move directlySourcecontainer+codecDemuxunboxsplit streamsDecodedecompressCPU-heavyFilterprocessoptionalEncodecompressCPU-heavyMuxreboxpackageTargetnew containerDecode → encode is the CPU-heavy core: when this is slow, everything is slowBlue = container (unbox/rebox); Red = codec (decompress/compress); Green = optional processStream copy (-c copy) only runs demux → mux, so it's instant and lossless

3. The five stages, one by one

  • Demux: read the container and split the interleaved video, audio, and subtitle packets. Like opening a box and sorting clothes, books, and snacks into piles.
  • Decode: expand each compressed stream back to raw form — video into frames, audio into samples. CPU-intensive.
  • Filter (optional): process the raw material — -vf "crop=..." to cut black bars, -af "volume=2" to raise volume, scale to change resolution. Skip it and the stage is bypassed.
  • Encode: re-compress the raw material with the target codec — video into H.264/H.265, audio into AAC/MP3. Also CPU-intensive, and a lossy codec loses quality here.
  • Mux: package the new video and audio streams into the target container (mp4/mkv/webm), write the index, and produce a playable file.

4. Connecting it back: what stream copy actually skips

Recall re-encode vs stream copy: stream copy (-c copy) is exactly the pipeline with the middle three stages — decode → filter → encode — skipped. After demux, the packets go straight into mux, untouched.

Because the audio/video data is never touched:

  • it's fast (CPU barely participates);
  • it's lossless (not a single byte changed);
  • it can only swap containers or extract streams — it can't change codec or resolution.

Re-encode runs the full pipeline, and the decode → encode core is the heaviest part, so it's slow and may look worse. One diagram explains both — that's the point of this article.

5. Real bugs we hit

These aren't abstract theory — they are things we actually ran into running ffmpeg in the browser and on the desktop at tools.beer.

Bug 1: the browser ffmpeg wouldn't start until we added two HTTP headers. Our web tool uses FFmpeg.wasm (ffmpeg compiled to WebAssembly, running in the browser). It depends on SharedArrayBuffer, which the browser only provides when the page is crossOriginIsolated — and that requires the server to send both Cross-Origin-Opener-Policy: same-origin and Cross-Origin-Embedder-Policy: require-corp. Miss one and crossOriginIsolated is false, so the ffmpeg core throws on load. We spent a long time before pinning it on those two headers.

Bug 2: browser ffmpeg is slower than native — for a physical reason. The decode → encode core is CPU-heavy. On the desktop (we call a native ffmpeg binary via Tauri) it gets multi-core and hardware acceleration; the WebAssembly build in the browser gets neither, so the same pipeline is clearly slower there. That's why our desktop "convert to mp4" (a real libx264 re-encode) takes genuine time, while a pure container swap in the browser finishes in seconds — the latter is essentially stream copy.

Bug 3: ffmpeg isn't just a converter — it may re-encode behind your back. ffmpeg -i in.mp4 out.mkv looks like a plain format swap. But if the target container doesn't support the source codec, ffmpeg automatically triggers a re-encode — often without you noticing, until "why is it slow and blurry now?". Understand the pipeline and you'll see it actually ran the whole line and re-compressed everything.

6. Summary

  • FFmpeg isn't a "format converter" — it's a pipeline: demux → decode → filter → encode → mux;
  • Blue blocks handle the container (unbox/rebox), red blocks handle the codec (decompress/compress), green is optional processing;
  • Decode → encode is the CPU-heavy core — it decides the overall speed;
  • Stream copy (-c copy) skips the middle three stages, so it's fast and lossless — the real reason stream copy is fast from the previous article;
  • The same pipeline runs slower in browser wasm than native, because of the hardware-acceleration gap, not magic.

Further reading

Want to try it now? You can convert MP4 to MP3 right in your browser.

References (authoritative sources)

FFmpeg official site and documentation
Wikipedia: FFmpeg

Written by the tools.beer team, based on real lessons from running FFmpeg.wasm in the browser and native ffmpeg on the desktop. Last updated 2026-08-20.