FFmpeg verstehen: Das mentale Modell, das dir fehlt
Kopiere FFmpeg-Befehle nicht blind. Lerne das mentale Modell hinter Containern, Codecs, Streams und Filtern, mit praxisnahen Rezepten.

Wir alle kennen das. Du musst ein Video konvertieren, suchst bei Google und findest eine Stack-Overflow-Antwort mit einem Befehl, der aussieht, als hätte jemand wild auf die Tastatur gehauen: ffmpeg -i input.mov -c:v libx264 -preset slow -crf 22 -c:a aac -b:a 128k -movflags +faststart output.mp4. Du führst ihn aus. Er funktioniert. Du hast keinen blassen Schimmer, warum, und beim nächsten Mal, wenn du etwas leicht anderes brauchst, landest du wieder auf Stack Overflow. Ich habe das jahrelang so gemacht, bis ich mich endlich hingesetzt und herausgefunden habe, was FFmpeg eigentlich von mir will.
Die Sache ist die: FFmpeg ist eigentlich gar nicht so kompliziert. Es hat ein durchgängiges mentales Modell, das, sobald man es verstanden hat, fast jeden Befehl lesbar macht. Das Problem ist, dass niemand das Modell erklärt, man bekommt einfach Befehle vorgesetzt. Also lass uns das ändern.
Container vs. Codecs: Das Erste, was du verstehen solltest
Die mit Abstand größte Quelle für Verwirrung bei Videodateien ist der Unterschied zwischen Containern und Codecs. Ein Container ist das Dateiformat, .mp4, .mkv, .webm, .mov. Er ist eine Box, die Dinge enthält. Ein Codec legt fest, wie die eigentlichen Video- und Audiodaten in dieser Box komprimiert werden: H.264, H.265, VP9, AV1, AAC, Opus.
Eine MP4-Datei kann H.264-Video mit AAC-Audio enthalten, oder H.265-Video mit Opus-Audio, oder dutzende andere Kombinationen. Eine MKV-Datei kann praktisch alles enthalten. Wenn jemand „In MP4 konvertieren“ sagt, meint er meist „H.264-Video und AAC-Audio in einen MP4-Container packen“, aber das sind drei separate Entscheidungen.
# See what's actually inside a file
$ ffprobe -hide_banner video.mkv
Input #0, matroska:
Stream #0:0: Video: hevc (Main), 1920x1080, 23.98 fps
Stream #0:1: Audio: opus, 48000 Hz, stereo
Stream #0:2: Subtitle: subrip
# This file is:
# Container: MKV (Matroska)
# Video codec: HEVC (H.265)
# Audio codec: Opus
# Plus a subtitle stream
Verwende ffprobe, bevor du irgendetwas tust. Es zeigt dir genau, womit du es zu tun hast. In der Hälfte der Fälle ist die benötigte „Konvertierung“ nur ein Remuxing, also das Verschieben der gleichen Streams in einen anderen Container ohne Neukodierung. Das geht praktisch sofort.
Die Struktur eines FFmpeg-Befehls
Jeder FFmpeg-Befehl folgt demselben Muster, und wenn du es einmal gesehen hast, kannst du es nicht mehr übersehen:
ffmpeg [global options] [input options] -i input [output options] output
# The KEY insight: options apply to the NEXT file.
# Options before -i apply to the input.
# Options after -i (before the output filename) apply to the output.
# This matters! These two commands are different:
ffmpeg -ss 00:01:00 -i video.mp4 output.mp4 # Seeks BEFORE decoding (fast)
ffmpeg -i video.mp4 -ss 00:01:00 output.mp4 # Seeks AFTER decoding (slow, precise)
Die Reihenfolge ist bei FFmpeg wichtig. Hier stolpern alle. Die Bedeutung einer Option kann sich ändern, je nachdem, ob sie vor oder nach -i steht. Das -ss-Beispiel oben ist der häufigste Fall: Steht es vor -i, springt FFmpeg direkt in der Eingabedatei zur Position (schnell, aber potenziell ungenau). Steht es danach, dekodiert FFmpeg alles bis zu diesem Punkt und beginnt erst dann mit der Ausgabe (langsam, aber frame-genau).
Stream-Auswahl: FFmpeg sagen, was du willst
Videodateien enthalten oft mehrere Streams: Video, Audio, Untertitel, manchmal mehrere Audiospuren in verschiedenen Sprachen. FFmpeg verwendet eine Stream-Spezifizierer-Syntax, mit der du gezielt bestimmte Streams ansprechen kannst:
-c:v— Codec für Video-Streams (v = video)-c:a— Codec für Audio-Streams (a = audio)-c:s— Codec für Untertitel-Streams (s = subtitle)-c copy— alle Streams kopieren, ohne neu zu kodieren-c:v copy -c:a aac— Video unverändert kopieren, Audio in AAC neu kodieren-map 0:a:1— den zweiten Audio-Stream der ersten Eingabe auswählen
Das Flag -c copy ist das wichtigste, das du kennen solltest. Es weist FFmpeg an, die Stream-Daten direkt zu kopieren, ohne sie neu zu kodieren. Das geht praktisch sofort und verlustfrei, denn du verschiebst lediglich Daten von einem Container in einen anderen. Wann immer du den Codec nicht ändern musst, verwende -c copy.
# Remux MKV to MP4 without re-encoding (instant)
ffmpeg -i input.mkv -c copy output.mp4
# Copy video but re-encode audio (fast — only audio is processed)
ffmpeg -i input.mkv -c:v copy -c:a aac -b:a 192k output.mp4
# Extract just the audio stream
ffmpeg -i video.mp4 -vn -c:a copy audio.aac
# -vn means "no video" — drop the video stream entirely
Praxisrezepte, die du wirklich verwenden wirst
Hier sind die Befehle, die ich ständig benutze. Jeder wird erklärt, damit du ihn für deine Zwecke anpassen kannst.
Ein Video für das Web komprimieren
ffmpeg -i raw_video.mov \
-c:v libx264 \
-preset slow \
-crf 23 \
-c:a aac -b:a 128k \
-movflags +faststart \
web_video.mp4
# -c:v libx264 → encode video with H.264
# -preset slow → slower encoding = smaller file (options: ultrafast to veryslow)
# -crf 23 → quality level (18=near lossless, 23=default, 28=low quality)
# -c:a aac → encode audio as AAC
# -b:a 128k → audio bitrate 128 kbps
# -movflags +faststart → move metadata to start of file for streaming
Der CRF-Wert (Constant Rate Factor) ist der wichtigste Qualitätsregler. Niedrigere Werte bedeuten höhere Qualität und größere Dateien. Für die meisten Web-Videos ist CRF 20–25 der Sweet Spot. Ich verwende meist 22 für alles, was gut aussehen muss, und 26 für Hintergrund- oder Zusatzvideos, bei denen die Qualität weniger wichtig ist.
Ein Video ohne Neukodierung zuschneiden
# Extract from 1:30 to 3:45 — no re-encoding, nearly instant
ffmpeg -ss 00:01:30 -to 00:03:45 -i input.mp4 -c copy trimmed.mp4
# If you need frame-accurate cuts (slower):
ffmpeg -i input.mp4 -ss 00:01:30 -to 00:03:45 \
-c:v libx264 -crf 18 -c:a copy trimmed.mp4
Vorschaubilder erzeugen
# Single thumbnail at the 10-second mark
ffmpeg -ss 00:00:10 -i video.mp4 -frames:v 1 thumb.jpg
# One thumbnail every 30 seconds
ffmpeg -i video.mp4 -vf "fps=1/30" thumbs/thumb_%04d.jpg
# Resize to 320px wide, maintain aspect ratio
ffmpeg -ss 00:00:10 -i video.mp4 -frames:v 1 \
-vf "scale=320:-1" thumb_small.jpg
Ein GIF aus einem Videoclip erstellen
# Good quality GIF with palette generation (two-pass)
ffmpeg -ss 00:00:05 -t 3 -i video.mp4 \
-vf "fps=15,scale=480:-1:flags=lanczos,split[s0][s1]; \
[s0]palettegen[p];[s1][p]paletteuse" \
output.gif
# -t 3 → duration: 3 seconds
# fps=15 → 15 frames per second (keep GIFs small)
# scale=480:-1 → resize to 480px wide
# palettegen/use → generate optimal color palette (much better quality)
Filter verstehen: die Stärke von FFmpeg
Filter sind der Punkt, an dem FFmpeg vom „nützlichen Tool“ zum „absurd mächtigen“ wird. Mit den Flags -vf (Videofilter) und -af (Audiofilter) kannst du Verarbeitungsschritte verketten. Filter werden für die sequenzielle Verarbeitung durch Kommas getrennt, für komplexe Filtergraphen durch Semikola.
# Chain multiple filters: resize, then add padding for exact dimensions
ffmpeg -i input.mp4 -vf "scale=1280:720:force_original_aspect_ratio=decrease,\
pad=1280:720:(ow-iw)/2:(oh-ih)/2:black" output.mp4
# Normalize audio volume
ffmpeg -i input.mp4 -af "loudnorm" -c:v copy output.mp4
# Speed up a video 2x (with audio pitch correction)
ffmpeg -i input.mp4 -vf "setpts=0.5*PTS" -af "atempo=2.0" fast.mp4
# Add text overlay
ffmpeg -i input.mp4 \
-vf "drawtext=text='DRAFT':fontsize=72:fontcolor=red:x=10:y=10" \
watermarked.mp4
Das Filtersystem ist so umfangreich, dass es einen eigenen Artikel füllen könnte, aber die zentrale Erkenntnis ist diese: Filter verarbeiten dekodierte Frames. Das bedeutet, dass du -c copy nicht mit Filtern verwenden kannst. Das Video muss dekodiert, gefiltert und neu kodiert werden. Wenn dein Befehl -vf verwendet, plane Zeit für eine vollständige Neukodierung ein.
Hardwarebeschleunigung: Nutze deine GPU
Wenn du regelmäßig Videos kodierst, kann Hardwarebeschleunigung den Prozess um das Fünf- bis Zehnfache beschleunigen. Moderne GPUs haben dedizierte Encoding-Hardware, die FFmpeg nutzen kann.
# NVIDIA GPU (NVENC)
ffmpeg -i input.mp4 -c:v h264_nvenc -preset p4 -crf 23 output.mp4
# Apple Silicon (VideoToolbox)
ffmpeg -i input.mp4 -c:v h264_videotoolbox -b:v 5M output.mp4
# Intel Quick Sync (QSV)
ffmpeg -i input.mp4 -c:v h264_qsv -preset medium output.mp4
# Check what's available on your system:
ffmpeg -encoders 2>/dev/null | grep -E '(nvenc|videotoolbox|qsv|vaapi)'
Eine Warnung vorweg: Hardware-Encoder sind schneller, erzeugen bei gleicher visueller Qualität aber meist etwas größere Dateien als Software-Kodierung (libx264). Für einmalige Transcodes, bei denen die Qualität zählt, ist Software-Kodierung nach wie vor besser. Für Batch-Verarbeitung oder Echtzeit-Streaming ist Hardwarebeschleunigung der klare Gewinner. Ich verwende libx264 für finale Produktions-Encodes und NVENC für alles andere.
Häufige Fehler und wie du sie vermeidest
- Neukodieren, obwohl es nicht nötig ist. Wenn du nur zuschneidest, Audio extrahierst oder den Container wechselst, verwende
-c copy. Es gibt keinen Grund, 20 Minuten für die Neukodierung eines Videos zu verschwenden, von dem du nur 30 Sekunden abschneidest. - Einen zu niedrigen CRF-Wert verwenden. CRF 18 erzeugt riesige Dateien mit Qualitätsverbesserungen, die die meisten Menschen gar nicht sehen können. Beginne bei 23 und gehe nur tiefer, wenn du Artefakte siehst. Für die meisten Web-Inhalte reichen 23–25 völlig aus.
- Vergessen von
-movflags +faststart. Ohne diese Option liegen die MP4-Metadaten am Ende der Datei. Browser können dann erst mit der Wiedergabe beginnen, wenn die gesamte Datei heruntergeladen ist. Füge sie bei Web-Videos immer hinzu. - Die Eingabe nicht prüfen. Führe
ffprobeaus, bevor du deinen Befehl schreibst. Wenn du die Eingabe-Codecs, die Auflösung und das Stream-Layout kennst, wird alles einfacher. - Ins Nichts laufen lassen. Wenn FFmpeg hängen bleibt, wartet es vielleicht auf deine Antwort auf eine Rückfrage, etwa ob eine bestehende Datei überschrieben werden soll. Füge
-yhinzu, um automatisch zu überschreiben, oder-n, um niemals zu überschreiben.
Der Spickzettel
Das liegt bei mir auf dem Desktop in einer Textdatei. Damit deckst du etwa 90 % dessen ab, was ich im Alltag brauche:
# Probe a file
ffprobe -hide_banner input.mp4
# Remux (change container, no re-encode)
ffmpeg -i input.mkv -c copy output.mp4
# Compress for web
ffmpeg -i input.mov -c:v libx264 -crf 23 -preset medium \
-c:a aac -b:a 128k -movflags +faststart output.mp4
# Extract audio only
ffmpeg -i video.mp4 -vn -c:a copy audio.m4a
# Trim without re-encoding
ffmpeg -ss 00:01:00 -to 00:02:30 -i input.mp4 -c copy clip.mp4
# Resize to 720p
ffmpeg -i input.mp4 -vf "scale=-1:720" -c:a copy output.mp4
# Convert to GIF
ffmpeg -ss 5 -t 3 -i input.mp4 \
-vf "fps=12,scale=400:-1" output.gif
# Concatenate files (same codec)
echo "file 'part1.mp4'" > list.txt
echo "file 'part2.mp4'" >> list.txt
ffmpeg -f concat -safe 0 -i list.txt -c copy combined.mp4
FFmpeg meistert man nicht an einem Tag. Aber sobald du das mentale Modell verstanden hast (Container enthalten Streams, Streams haben Codecs, Optionen gelten für die nächste Datei, Filter erfordern eine Neukodierung), ergibt die Dokumentation plötzlich Sinn. Du hörst auf, Befehle blind zu kopieren, und fängst an, sie bewusst zusammenzusetzen. Und ehrlich gesagt ist dieser Moment, in dem aus „das ist Magie“ ein „ach, so funktioniert das“ wird, einer der befriedigendsten Augenblicke, die man als Entwickler erleben kann.


