Comment compresser une vidéo avec FFmpeg
Pour réduire la taille d’une vidéo destinée au web, commencez par une vidéo H.264 et un son AAC dans
un conteneur MP4. Cette commande crée output.mp4 à partir d’un fichier local
input.mp4, avec un encodage fondé sur la qualité :
if [ -e "./output.mp4" ] || [ -L "./output.mp4" ]; then
printf '%s\n' 'Choose a new filename: ./output.mp4 already exists.' >&2
false
else
ffmpeg -n -nostdin -xerror -i "./input.mp4" \
-map 0:V:0 -map '0:a:0?' \
-c:v libx264 -crf 23 -preset medium -pix_fmt yuv420p \
-c:a aac -b:a 128k -ac 2 -movflags +faststart "./output.mp4"
fi
La compression avec perte supprime des détails. Le résultat peut être plus petit, mais une source déjà encodée efficacement peut grossir lors du réencodage. Conservez l’original et comparez le résultat avant de choisir les réglages pour d’autres vidéos. Le CRF contrôle la qualité ; il ne garantit pas une taille de fichier précise.
La commande sélectionne le premier flux vidéo qui ne correspond pas à une image de couverture et
la première piste audio, si elle existe. Elle produit un son AAC stéréo en présence d’audio, et une
vidéo sans son dans le cas contraire. Les autres pistes audio, les flux de sous-titres et les flux
de données sont omis. Le mappage audio facultatif et le refus d’écrasement assuré par
-n sont documentés dans la
référence des commandes de FFmpeg.
-nostdin désactive la saisie interactive et -xerror
interrompt le traitement en cas d’erreurs détectées par FFmpeg. Une erreur peut laisser un fichier
de sortie incomplet ; ne le publiez pas et ne considérez pas sa petite taille comme une compression
réussie.
Vérifier les prérequis
Utilisez Bash sous Linux avec ffmpeg et ffprobe dans
votre PATH. Ces exemples ont été testés avec FFmpeg 6.1.1 sous Ubuntu 24.04 et FFmpeg 9.0.1 sous
Linux. Ils nécessitent l’encodeur vidéo libx264, l’encodeur audio natif
aac et le multiplexeur MP4. Vérifiez votre compilation :
ffmpeg -version &&
ffprobe -version &&
ffmpeg -hide_banner -h encoder=libx264 &&
ffmpeg -hide_banner -h encoder=aac
La sortie de l’aide doit décrire les deux encodeurs ; un message « unknown » ou « not recognized » signifie que la compilation ne convient pas, même si la commande d’aide se termine avec succès. Si vous avez besoin de FFmpeg, sa page de téléchargement propose des liens vers des paquets Linux et des compilations pour macOS et Windows. Les exemples de commandes shell présentés ici sont destinés à Linux.
Utilisez une séquence progressive à plage dynamique standard (SDR), avec des pixels carrés et une
largeur et une hauteur paires. Ces commandes ne redimensionnent pas la vidéo et n’effectuent pas de
mappage tonal HDR. yuv420p sélectionne une vidéo 4:2:0 sur 8 bits ; ce réglage
ne transforme pas les couleurs HDR en couleurs SDR correctes. Gardez les noms de fichiers entre
guillemets, y compris le préfixe ./ pour les noms commençant par un
trait d’union. Chaque encodage refuse de remplacer un MP4 existant ; choisissez donc une nouvelle
destination pour comparer les réglages. La vérification dans le shell renvoie également un statut
d’échec si la destination existe déjà : le refus d’écrasement propre à FFmpeg peut se terminer avec
un statut de succès dans certaines versions.
Choisir séparément le CRF et le préréglage
Pour libx264, commencez avec un CRF de 23. Essayez 20 si les petits textes ou
les détails fins semblent dégradés, ou 26 si la réduction du nombre d’octets est prioritaire. Les
valeurs de CRF plus basses préservent davantage de détails et produisent généralement des fichiers
plus volumineux ; les valeurs plus élevées sacrifient davantage de détails pour réduire le nombre
d’octets. Réencodez à partir de l’original pour chaque comparaison.
Le préréglage contrôle la quantité de travail d’encodage effectuée par x264.
medium est un point de départ raisonnable ; slow
consacre plus de temps à rechercher des méthodes d’encodage efficaces. Il peut améliorer
l’efficacité de la compression, mais ne promet ni un pourcentage fixe de réduction ni une qualité
identique pour un même CRF. Consultez les
options de l’encodeur x264 pour découvrir les réglages distincts de
qualité et de préréglage.
Les valeurs de CRF et les noms de préréglages sont propres à un encodeur. Un CRF de 23 avec x264
n’équivaut pas à la même qualité avec x265, VP9 ou AV1, et slow n’est pas
une échelle de qualité commune aux encodeurs. Si la résolution de la source dépasse celle de
l’affichage prévu, un redimensionnement peut être plus utile qu’une nouvelle augmentation du CRF.
Toutefois, examinez les petits textes et les autres détails à la taille d’affichage prévue avant
de supprimer des pixels.
Comparer la qualité et la taille des fichiers
Examinez la source et le résultat avec ffprobe. Cette commande affiche les propriétés des flux, la durée en secondes et la taille du fichier en octets :
ffprobe -v error -show_format -show_streams -of json "./input.mp4" &&
ffprobe -v error -show_format -show_streams -of json "./output.mp4"
Vérifiez la présence de codec_name: "h264" et de pix_fmt: "yuv420p" dans le
flux vidéo. Pour une source sans métadonnées de rotation, la largeur et la hauteur doivent
correspondre à celles de la source. Un flux audio doit indiquer aac avec
deux canaux si l’entrée contenait du son. Comparez format.size et
format.duration aux valeurs de la source. De petits écarts dus au remplissage audio
sont normaux ; la perte de secondes de contenu ne l’est pas.
Décodez le résultat complet pour détecter les erreurs au-delà des métadonnées :
ffmpeg -v error -nostdin -xerror -i "./output.mp4" \
-map 0:V:0 -map '0:a:0?' -f null -
Un décodage réussi ne produit ici aucun message d’erreur. Il ne mesure pas la qualité visuelle. Lisez les deux fichiers à la taille d’affichage prévue et examinez les mouvements, les dégradés, les petits textes et la synchronisation audio. Un fichier plus petit n’est utile que si son image et son son restent acceptables pour votre page.
Utiliser deux passes pour un budget de taille
Si vous avez une limite de téléversement, choisissez un débit binaire moyen plutôt que le CRF.
Un calcul de départ est video bits/s = (target bytes × 8 ÷ duration seconds) − audio bits/s. Réservez une partie du budget total au
conteneur et aux variations de débit, puis mesurez le fichier terminé. L’encodage en deux passes
vise un débit vidéo moyen ; il n’impose pas une limite exacte en octets.
Par exemple, une séquence de 60 secondes devant rester sous 10 MB (10 000 000 octets) dispose d’environ
1 333 kbit/s au total. En réservant 5 % et en allouant 128 kbit/s à l’audio, il reste environ
1 139 kbit/s pour la vidéo. Arrondissez à la baisse à 1100k pour un premier
essai. Utilisez la durée réelle de votre source fournie par ffprobe et refaites le calcul pour
une autre limite. Sans audio, cet exemple laisse inutilisée la part allouée à l’audio.
Exécutez ce bloc complet dans Bash. Il crée target.mp4 indépendamment du fichier
produit précédemment avec le CRF :
(
if [ -e "./target.mp4" ] || [ -L "./target.mp4" ]; then
printf '%s\n' 'Choose a new filename: ./target.mp4 already exists.' >&2
exit 1
fi
pass_dir=$(mktemp -d) || exit 1
trap 'rm -rf -- "$pass_dir"' EXIT
ffmpeg -y -nostdin -xerror -i "./input.mp4" \
-map 0:V:0 -c:v libx264 -b:v 1100k -preset medium -pix_fmt yuv420p \
-pass 1 -passlogfile "$pass_dir/stats" -an -f null /dev/null &&
ffmpeg -n -nostdin -xerror -i "./input.mp4" \
-map 0:V:0 -map '0:a:0?' \
-c:v libx264 -b:v 1100k -preset medium -pix_fmt yuv420p \
-pass 2 -passlogfile "$pass_dir/stats" \
-c:a aac -b:a 128k -ac 2 -movflags +faststart "./target.mp4"
)
La première passe recueille des statistiques ; && empêche l’exécution de
la seconde si la première échoue. Le répertoire temporaire sépare les
journaux des passes entre les exécutions et est supprimé à la fin du
bloc. L’option -y de la première passe ne s’applique qu’à la sortie
abandonnée dans /dev/null ; la seconde passe utilise
-n pour protéger target.mp4. Gardez les mêmes réglages
d’entrée, de débit binaire et de préréglage, ainsi que les mêmes filtres vidéo éventuels, pour les
deux passes.
Répétez les commandes d’inspection et de décodage avec target.mp4 à la place de
output.mp4. Si le fichier dépasse votre limite, réduisez le débit vidéo et
réexécutez les deux passes avec un nouveau nom de fichier de sortie. Si l’image devient
inacceptable avant que le fichier respecte la limite, revoyez la durée ou la résolution. Un simple
changement de codec ne peut pas garantir un résultat acceptable pour tous les budgets de taille.
Compatibilité avec les navigateurs
H.264 est le codec vidéo ; MP4 est le conteneur qui contient cette vidéo et son audio AAC. Cette combinaison constitue un point de départ pratique pour une lecture sur de nombreux navigateurs, mais sa prise en charge dépend aussi du navigateur, du système d’exploitation, du profil et du niveau du codec, de la résolution et du décodeur de l’appareil. Par exemple, Firefox peut dépendre des codecs du système d’exploitation pour H.264. Consultez le guide des codecs vidéo de MDN et testez le fichier réel sur les navigateurs et appareils de votre public. HEVC, VP9 et AV1 sont des solutions à évaluer pour ce public, et non des remplacements universellement meilleurs ou universellement pris en charge.
-movflags +faststart place l’index MP4 avant les données multimédias, ce qui permet à un
lecteur prenant cette disposition en charge de commencer la lecture sans télécharger d’abord la
fin du fichier. Ce réglage ne réduit pas la taille de la vidéo encodée et ne crée pas de variantes
de streaming adaptatif. La documentation du multiplexeur MP4
explique cette étape d’indexation supplémentaire. Même après un décodage local réussi, vous devez
vérifier la lecture avec votre serveur web et votre lecteur réels avant la mise en ligne.
Réutiliser les réglages avec précaution
Essayez les réglages choisis sur des séquences représentatives avant d’encoder une collection. Un enregistrement d’écran avec de petits textes et une séquence filmée à main levée peuvent nécessiter des valeurs de CRF différentes. Gardez une destination distincte pour chaque source et vérifiez le statut de chaque commande avant d’examiner ou de publier son résultat. Après un échec d’encodage, choisissez un nouveau nom de fichier de sortie ou supprimez uniquement le fichier incomplet que vous venez de créer ; le refus d’écrasement s’applique aussi aux fichiers partiels laissés par les exécutions précédentes.
