Des articles approfondis sur les technologies qui façonnent l'avenir.

FFmpeg démystifié : le modèle mental qui vous manque

Arrêtez de copier les commandes FFmpeg au hasard. Découvrez le modèle mental derrière conteneurs, codecs, flux et filtres, avec des recettes pratiques.

Machine qui sépare des flux de film, d'audio et de texte à travers des entonnoirs dans un conteneur lumineux unique.

Nous y sommes tous passés. Vous devez convertir une vidéo, alors vous cherchez sur Google et tombez sur une réponse Stack Overflow avec une commande qui ressemble à quelqu'un qui aurait écrasé son clavier : ffmpeg -i input.mov -c:v libx264 -preset slow -crf 22 -c:a aac -b:a 128k -movflags +faststart output.mp4. Vous l'exécutez. Ça marche. Vous n'avez absolument aucune idée de pourquoi, et la prochaine fois que vous avez besoin de quelque chose de légèrement différent, vous revoilà sur Stack Overflow. J'ai fait ça pendant des années avant de m'asseoir enfin pour comprendre ce que FFmpeg attend vraiment de moi.

Le fait est que FFmpeg n'est pas si compliqué. Il repose sur un modèle mental cohérent qui, une fois assimilé, rend presque chaque commande lisible. Le problème, c'est que personne n'explique ce modèle : on se contente de balancer des commandes. Alors réglons ça.

Conteneurs vs codecs : le premier point à comprendre

La plus grande source de confusion avec les fichiers vidéo est la différence entre conteneurs et codecs. Un conteneur est le format de fichier — .mp4, .mkv, .webm, .mov. C'est une boîte qui contient des éléments. Un codec est la façon dont les données vidéo et audio réelles à l'intérieur de cette boîte sont compressées — H.264, H.265, VP9, AV1, AAC, Opus.

Un fichier MP4 peut contenir de la vidéo H.264 avec de l'audio AAC, ou de la vidéo H.265 avec de l'audio Opus, ou des dizaines d'autres combinaisons. Un fichier MKV peut contenir pratiquement n'importe quoi. Quand quelqu'un dit « convertir en MP4 », il veut généralement dire « mettre de la vidéo H.264 et de l'audio AAC dans un conteneur MP4 » — mais ce sont trois décisions distinctes.

# 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

Utilisez ffprobe avant de faire quoi que ce soit. Il vous indique exactement avec quoi vous travaillez. La moitié du temps, la « conversion » dont vous avez besoin n'est qu'un remuxage — déplacer les mêmes flux dans un autre conteneur sans réencoder. C'est presque instantané.

La structure des commandes FFmpeg

Chaque commande FFmpeg suit le même schéma, et une fois que vous l'avez repéré, impossible de ne plus le voir :

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)

La position compte dans FFmpeg. C'est le piège dans lequel tout le monde tombe. Le sens d'une option peut changer selon qu'elle apparaît avant ou après -i. L'exemple -ss ci-dessus est le cas le plus courant : le placer avant -i fait chercher directement FFmpeg dans le fichier d'entrée (rapide mais potentiellement imprécis), tandis que le placer après oblige FFmpeg à décoder tout jusqu'à ce point avant de commencer la sortie (lent mais précis image par image).

Sélection des flux : indiquer à FFmpeg ce que vous voulez

Les fichiers vidéo contiennent souvent plusieurs flux — vidéo, audio, sous-titres, parfois plusieurs pistes audio dans différentes langues. FFmpeg utilise une syntaxe de spécificateurs de flux pour cibler des flux précis :

  • -c:v — codec pour les flux vidéo (v = video)
  • -c:a — codec pour les flux audio (a = audio)
  • -c:s — codec pour les flux de sous-titres (s = subtitle)
  • -c copy — copie TOUS les flux sans réencodage
  • -c:v copy -c:a aac — copie la vidéo telle quelle, réencode l'audio en AAC
  • -map 0:a:1 — sélectionne le deuxième flux audio de la première entrée

L'option -c copy est la plus importante à connaître. Elle demande à FFmpeg de copier les données du flux directement, sans réencodage. C'est pratiquement instantané et sans perte — vous ne faites que déplacer des données d'un conteneur à un autre. Chaque fois que vous n'avez pas besoin de changer de codec, utilisez -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

Des recettes pratiques que vous utiliserez vraiment

Voici les commandes que j'utilise constamment. Chacune est expliquée pour que vous puissiez la modifier selon vos besoins.

Compresser une vidéo pour le web

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

La valeur CRF (Constant Rate Factor) est le réglage de qualité le plus important. Plus le chiffre est bas, meilleure est la qualité et plus le fichier est volumineux. Pour la plupart des vidéos web, un CRF entre 20 et 25 est le juste milieu. J'utilise généralement 22 pour tout ce qui doit être beau, et 26 pour les vidéos d'arrière-plan ou d'accompagnement où la qualité compte moins.

Découper une vidéo sans réencodage

# 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

Générer des miniatures

# 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

Créer un GIF à partir d'un extrait vidéo

# 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)

Comprendre les filtres : la fonctionnalité phare

Les filtres sont ce qui fait passer FFmpeg de « outil utile » à « absurdement puissant ». Les options -vf (filtre vidéo) et -af (filtre audio) permettent d'enchaîner des opérations de traitement. Les filtres sont séparés par des virgules pour un traitement séquentiel, ou par des points-virgules pour des graphes de filtres complexes.

# 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

Le système de filtres est assez profond pour remplir un article à lui seul, mais l'idée clé est la suivante : les filtres traitent des images décodées. Cela signifie qu'on ne peut pas utiliser -c copy avec des filtres — la vidéo doit être décodée, filtrée, puis réencodée. Si votre commande utilise -vf, prévoyez du temps pour un réencodage complet.

Accélération matérielle : utiliser votre GPU

Si vous encodez régulièrement de la vidéo, l'accélération matérielle peut accélérer les choses par 5 à 10. Les GPU modernes disposent de circuits d'encodage dédiés que FFmpeg peut exploiter.

# 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)'

Un mot de prudence : les encodeurs matériels sont plus rapides mais produisent généralement des fichiers légèrement plus lourds à qualité visuelle égale, comparés à l'encodage logiciel (libx264). Pour des transcodages ponctuels où la qualité compte, l'encodage logiciel reste meilleur. Pour le traitement par lots ou le streaming en temps réel, l'accélération matérielle est clairement gagnante. J'utilise libx264 pour les encodages finaux de production et NVENC pour le reste.

Erreurs courantes et comment les éviter

  • Réencoder alors que ce n'est pas nécessaire. Si vous ne faites que découper, extraire l'audio ou changer de conteneur, utilisez -c copy. Pas besoin de passer 20 minutes à réencoder une vidéo dont vous ne retirez que 30 secondes.
  • Utiliser une valeur de CRF trop basse. Un CRF de 18 produit des fichiers énormes avec des gains de qualité que la plupart des gens ne voient pas. Commencez à 23, descendez seulement si vous voyez des artefacts. Pour le contenu web, 23 à 25 suffit largement.
  • Oublier -movflags +faststart. Sans cette option, les métadonnées MP4 se trouvent à la fin du fichier, ce qui signifie que les navigateurs ne peuvent pas commencer la lecture avant le téléchargement complet. Ajoutez-la toujours pour la vidéo web.
  • Ne pas vérifier l'entrée d'abord. Lancez ffprobe avant d'écrire votre commande. Connaître les codecs d'entrée, la résolution et la structure des flux simplifie tout.
  • Envoyer dans le vide. Si FFmpeg semble bloqué, il attend peut-être que vous répondiez à une question (par exemple s'il faut écraser un fichier existant). Ajoutez -y pour écraser automatiquement, ou -n pour ne jamais écraser.

La fiche-mémo

Voici ce que je garde dans un fichier texte sur mon bureau. Ces commandes couvrent environ 90 % de mes besoins au quotidien :

# 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 n'est pas un outil qu'on maîtrise en une journée. Mais une fois que vous avez compris le modèle mental — les conteneurs contiennent des flux, les flux ont des codecs, les options s'appliquent au fichier suivant, les filtres impliquent un réencodage — la documentation commence à faire sens. Vous arrêtez de copier les commandes à l'aveugle et vous commencez à les composer en connaissance de cause. Et honnêtement, passer de « c'est de la magie » à « ah, voilà ce qu'il fait » est l'un des moments les plus satisfaisants pour un développeur.