Overview
FFmpeg underlies most media processing, and its reputation for difficulty comes largely from a few concepts that are not obvious from the documentation, particularly stream mapping and the difference between copying and re-encoding. Once those land, a small number of command shapes cover the large majority of real work. This guide covers those patterns and the specific behaviours that produce surprising output.
What You Need
- FFmpeg installed, with the encoders you need compiled in
- A way to inspect files, ffprobe, which ships alongside it
- Test media that is deliberately awkward, not just clean exports
- Awareness of which build you have, since features vary
- Somewhere to record the exact commands you run
- Patience with the argument order, which is positional and matters
Steps
Probe before you process
Inspect the input first: how many streams, which codecs, what resolution and frame rate, what channel layout, and whether rotation metadata is present. Most surprising output comes from an input that was not what you assumed. Making probing a required first step turns mysterious failures into obvious ones.
Learn the difference between copying and re-encoding
Stream copy passes compressed data through untouched, fast, lossless, and only possible when the output container accepts that codec. Re-encoding decodes and compresses again, which is slower and loses quality. Changing container without changing codec should always be a copy. People routinely re-encode by accident and lose quality for no reason.
Be explicit about stream mapping
Without instruction, FFmpeg picks one stream of each type by its own rules, which quietly discards additional audio tracks, subtitles, and data streams. If your input has multiple audio tracks and your output has one, this is why. Specify which streams you want explicitly rather than relying on the defaults.
Order arguments correctly, because position is meaningful
Options before an input apply to that input. Options after apply to the output. The same flag means different things in different positions, and misplacing it is a frequent source of commands that appear to be ignored. When something has no effect, check its position before assuming the flag is wrong.
Handle rotation and odd dimensions deliberately
Phone video frequently carries rotation in metadata rather than in the pixels, so naive processing produces sideways output. Some encoders also require even dimensions and fail on odd ones. Both are extremely common with user-supplied media and both are best handled explicitly in your pipeline.
Log the exact command and toolchain version
Record what you ran and which build ran it, on every job. Behaviour differs between versions and builds, and when output changes character months later this log is the only way to establish what actually changed. It converts an unreproducible report into a reproducible case.
Pro Tips
- Probe every input. Assumptions about user-supplied media are wrong more often than not.
- Copy rather than re-encode whenever the container change is all you need.
- Map streams explicitly. Silent stream dropping is the most common surprise in FFmpeg output.
- Pin the version in a container. Behaviour genuinely differs between builds.
- Test with variable frame rate footage. It is common from phones and screen recorders and breaks naive assumptions.
Knowledge Base
What You'll Learn
FFmpeg is not difficult so much as unforgiving about a few specific concepts. Below: why stream mapping causes so much trouble, and the input characteristics that break naive pipelines.
Why Stream Mapping Causes So Much Trouble
A media file can contain many streams: several video, several audio in different languages or channel layouts, subtitles, chapters, and data. FFmpeg has to decide which of them end up in the output.
Left unspecified, it applies default selection rules, broadly, the best single stream of each type by its own criteria. That is convenient for simple cases and silently destructive for anything else. Multiple audio tracks become one. Subtitle streams disappear. A second video stream used as a thumbnail vanishes.
Nothing warns you, because from FFmpeg's perspective it did what it was designed to do. The symptom appears later as "the localised audio track is missing", frequently after processing has been running in production for weeks.
The discipline is to be explicit about which streams you want in every command that matters, and to verify the output by probing rather than by assuming. In a pipeline handling user-supplied media, mapping should never be left to defaults, because you do not know what the inputs contain.
The Input Characteristics That Break Naive Pipelines
User-supplied media is reliably stranger than test media, and the same few characteristics cause most failures.
Variable frame rate. Phone cameras and screen recorders frequently produce footage with no constant frame rate. Pipelines assuming constancy produce audio drift or timing errors that grow across a long file.
Rotation in metadata. The pixels are stored one way and a flag says to display them rotated. Processing that ignores the flag produces sideways output. Processing that applies it twice produces upside-down output.
Unexpected channel layouts. Audio arriving as mono, as multichannel, or with silent channels breaks assumptions about stream mapping and loudness.
Container and codec mismatch with the extension. A file named .mp4 that is something else entirely is common.
Odd dimensions. Some encoders require even width and height and fail outright.
A fixture set containing all of these, run through your pipeline in tests, catches the overwhelming majority of production failures before they happen.
Where This Fits
This guide covers one specific part of building media applications. The wider picture, why media workloads break ordinary web architecture, and the upload, job, and toolchain patterns that handle them, is in Building Media Applications: A Developer Primer, which frames the discipline as a whole and links out to the detailed guides underneath it, including this one. If you are starting from scratch rather than solving a specific problem, read that first and come back here.
FAQ
Q: When should I copy streams instead of re-encoding?
A: Whenever you are not changing the codec: for example remuxing from one container to another, trimming on keyframe boundaries, or extracting a stream. Copying is fast and lossless. Re-encoding unnecessarily costs time and image quality for no benefit, and it is a very common accidental mistake.
Q: Why did my output lose an audio track or subtitles?
A: Because stream mapping was left to defaults, which select roughly one stream of each type and silently discard the rest. Specify explicitly which streams should appear in the output, and verify by probing the result. In pipelines handling user-supplied media, never rely on default selection.
Q: Why is my processed phone video sideways?
A: Rotation stored in metadata rather than baked into the pixels. Processing that ignores the flag outputs the raw orientation. Processing that applies it twice flips it again. Handle rotation explicitly in your pipeline rather than hoping the defaults do what you expect.
Q: Why does the same command behave differently on another machine?
A: Different FFmpeg version or build. Which encoders are compiled in, which flags exist, and what the defaults are all vary between builds, which is why media toolchains should be pinned in a container and the version recorded on every job.
Translate this page
- Español
- 简体中文
- हिन्दी
- العربية
- Português
- Français
- Deutsch
- 日本語
- Русский
- Bahasa Indonesia
- 한국어
- Italiano
- Türkçe
- Tiếng Việt
- Polski
- Nederlands
Machine translation provided by Google Translate, on Google’s servers. We do not check these translations and they will get technical terms wrong. The English page is the authoritative one. Following a link sends this page’s address to Google. Your browser may also offer to translate this page itself, which keeps the request on your device.