FFmpeg pour les débutants : Les commandes dont vous avez réellement besoin
Ma première commande FFmpeg a pris 45 minutes à écrire et a produit un fichier de 0 octet. Je l'avais copiée depuis Stack Overflow, changé le nom de fichier d'entrée, appuyé sur Entrée, et regardé le terminal défiler avec des messages cryptiques sur le "surcharge de muxage" et "duplication de trame" avant de cracher un fichier qui ne s'ouvrait dans aucun lecteur. J'ai essayé à nouveau. Un autre fichier de 0 octet. La troisième tentative a fait planter mon ordinateur portable. Maintenant, sept ans plus tard, je peux transcoder n'importe quoi dans mon sommeil. J'ai écrit plus de 10 000 commandes FFmpeg pour tout, de l'étalonnage de couleur 4K HDR à des pipelines de streaming en temps réel qui gèrent des millions de spectateurs. Je tiens le wiki interne FFmpeg de notre entreprise, qui a grandi pour atteindre 247 pages de recettes, d'astuces et de connaissances acquises difficilement sur des particularités de codec qui ne sont documentées nulle part ailleurs. Voici ce que j'aurais aimé que quelqu'un me dise dès le premier jour : FFmpeg n'est pas difficile parce que la syntaxe est compliquée. C'est difficile parce que personne n'explique le modèle mental. Une fois que vous comprenez comment FFmpeg pense en termes de flux, de conteneurs et de codecs, tout s'imbrique. Vous arrêtez de copier les commandes aveuglément et commencez à les composer comme des phrases. Ce guide contient les commandes que j'utilise réellement chaque semaine, et non les cas particuliers exotiques qui remplissent la plupart des tutoriels. Ce sont les bêtes de somme qui gèrent 90 % des tâches vidéo du monde réel. Je vais expliquer non seulement ce que chaque commande fait, mais pourquoi elle fonctionne et quand vous l’utiliseriez plutôt que les alternatives.Comment FFmpeg fonctionne réellement (et pourquoi votre première commande a échoué)
FFmpeg fonctionne sur un principe simple que tout le monde se trompe d'abord sur : il lit les flux des entrées, les traite à travers des filtres, et les écrit dans des sorties. La confusion vient du fait qu'un fichier vidéo unique contient plusieurs flux—généralement un flux vidéo, un ou plusieurs flux audio, et parfois des flux de sous-titres ou des flux de métadonnées. Lorsque vous exécutez `ffmpeg -i input.mp4 output.mp4`, FFmpeg fait un certain nombre d'hypothèses sur ce que vous voulez. Il choisit le "meilleur" flux vidéo, le "meilleur" flux audio, les copie à travers des encodeurs par défaut, et les mux dans le conteneur de sortie. Cela fonctionne bien pour des conversions simples, mais cela se gâte au moment où vous avez besoin de contrôle. La raison pour laquelle ma première commande a produit un fichier de 0 octet était que j'avais spécifié des combinaisons de codec et de conteneur incompatibles. J'essayais de mettre un flux vidéo VP9 dans un conteneur MP4, ce qui n'est pas supporté. FFmpeg a commencé à encoder, a réalisé qu'il ne pouvait pas écrire la sortie, et a abandonné. Le message d'erreur était enfoui dans 200 lignes de sortie que je ne savais pas comment lire. Voici le modèle mental qui a tout changé pour moi : pensez à FFmpeg comme à un pipeline en trois étapes. D'abord, le démuxage—FFmpeg ouvre votre fichier d'entrée et le sépare en flux individuels. Deuxièmement, le traitement—chaque flux passe à travers un codec (encodeur/décoder) et des filtres optionnels. Enfin, le muxage—les flux traités sont emballés dans un conteneur de sortie. Chaque commande FFmpeg suit ce schéma : ``` ffmpeg [options globales] [options d'entrée] -i input [options de sortie] output ``` L'ordre est extrêmement important. Les options avant `-i` s'appliquent à l'entrée. Les options après `-i` s'appliquent à la sortie. Si vous mettez `-c:v libx264` avant `-i`, FFmpeg essaiera de décoder l'entrée en H.264, ce qui n'est probablement pas ce que vous voulez. Mettez-le après `-i`, et il encode la sortie en H.264. L'autre concept crucial est les spécificateurs de flux. Lorsque vous écrivez `-c:v`, vous dites "appliquez ce codec aux flux vidéo." `-c:a` cible les flux audio. `-c:s` cible les sous-titres. Vous pouvez même être plus spécifique avec `-c:v:0` pour le premier flux vidéo ou `-c:a:1` pour le deuxième flux audio. Une fois que j'ai compris cette structure, j'ai arrêté de produire des fichiers de 0 octet. Je pouvais lire la sortie de FFmpeg et comprendre ce qu'il faisait à chaque étape. Je pouvais déboguer les problèmes en isolant si le problème provenait du démuxage, du traitement ou du muxage.Le jour où j'ai transcodé 50 000 vidéos (et ce que j'ai appris)
Il y a trois ans, notre entreprise a acquis un concurrent. Une partie de l'acquisition incluait leur bibliothèque vidéo entière—50 000 vidéos dans un format que nous ne supportions pas. Ils avaient utilisé un codec propriétaire qui nécessitait un lecteur spécifique, et nous avions besoin que tout soit converti en H.264 standard pour notre plateforme. L'approche naïve aurait été d'écrire une simple boucle : pour chaque vidéo, exécuter FFmpeg avec des paramètres de base, attendre qu'il termine, passer à la suivante. À une moyenne de 2 minutes par vidéo, cela aurait pris 69 jours de traitement continu. Nous avions deux semaines. Ce projet m'a appris plus sur FFmpeg que les trois années précédentes combinées. J'ai appris sur l'accélération matérielle, le traitement parallèle, et les dizaines de paramètres d'encodeur qui comptent réellement. J'ai appris quels indicateurs de qualité sont significatifs et lesquels sont du marketing absurde. Plus important encore, j'ai appris que la "meilleure" commande FFmpeg dépend entièrement de vos contraintes. Nous avons fini par construire un système de transcoding distribué qui traitait 200 vidéos simultanément à travers 40 machines. Chaque machine exécutait 5 instances de FFmpeg, soigneusement réglées pour maximiser l'utilisation du CPU sans trop saccader. Nous avons utilisé le décodage accéléré par matériel lorsque disponible, mais l'encodage logiciel parce que la différence de qualité était significative pour notre cas d'utilisation. La commande sur laquelle nous nous sommes finalement arrêtés ressemblait à ceci : ```bash ffmpeg -hwaccel auto -i input.mov \ -c:v libx264 -preset medium -crf 23 \ -c:a aac -b:a 128k \ -movflags +faststart \ -max_muxing_queue_size 1024 \ output.mp4 ``` Laissez-moi expliquer pourquoi chaque option est importante. `-hwaccel auto` indique à FFmpeg d'utiliser le décodage matériel si disponible—cela a réduit notre temps de décodage de 60 % sur les machines avec des GPU compatibles. `-preset medium` équilibre la vitesse d'encodage avec l'efficacité de compression. Nous avons testé tous les presets ; `medium` était le meilleur choix où nous avons obtenu 95 % de la qualité de `slower` en moitié moins de temps. Le paramètre `-crf 23` contrôle la qualité en utilisant le facteur de taux constant. Des chiffres plus bas signifient une qualité plus élevée et des fichiers plus lourds. Nous avons testé des valeurs CRF de 18 à 28 sur un échantillon de 100 vidéos et avons demandé à notre équipe vidéo de faire des comparaisons de qualité à l'aveugle. Personne ne pouvait distinguer de manière fiable CRF 23 de CRF 20, mais les tailles de fichiers étaient 30 % plus petites. `-movflags +faststart` déplace l'atome moov au début du fichier, ce qui permet une lecture progressive via HTTP. Sans ce drapeau, les navigateurs doivent télécharger l'intégralité du fichier avant de pouvoir commencer à le lire. Cette seule option a amélioré nos indicateurs d'expérience utilisateur de 15 %. L'option `-max_muxing_queue_size 1024` a résolu un problème qui nous a coûté trois jours de débogage. Certaines des vidéos sources avaient des taux de trame variables qui ont causé un débordement des tampons internes de FFmpeg. La taille de file d'attente par défaut est de 8 paquets, ce qui n'est pas suffisant pour le contenu VFR. L'augmentation à 1024 a éliminé les erreurs "Trop de paquets mis en mémoire tampon pour le flux de sortie" qui échouaient 5 % de nos conversions. Nous avons terminé le projet en 11 jours. Le système distribué a traité 4 545 vidéos par jour, avec un taux de réussite de 99,2 %. Les échecs étaient tous des fichiers sources qui étaient corrompus ou utilisaient des codecs que nous ne pouvions pas décoder. J'utilise encore des variations de cette commande aujourd'hui—c'est la base de notre pipeline de traitement vidéo entier.Matrice de compatibilité des codecs et des conteneurs
L'un des aspects les plus frustrants de FFmpeg pour les débutants est de comprendre quels codecs fonctionnent avec quels conteneurs. Vous pouvez passer une heure à élaborer la commande parfaite pour la voir échouer parce que vous essayez de mettre un codec incompatible dans un conteneur qui ne le supporte pas. Voici la matrice de compatibilité à laquelle je fais référence constamment :| Conteneur | Codecs vidéo | Codecs audio | Meilleur pour |
|---|---|---|---|
| MP4 | H.264, H.265, AV1 | AAC, MP3, Opus | Lecture sur le Web, appareils mobiles, compatibilité universelle |
| WebM | VP8, VP9, AV1 | Vorbis, Opus | Streaming Web, projets open-source, YouTube |
| MKV | Tout | Tout | Archivage, plusieurs pistes audio, sous-titres |
| MOV | H.264, ProRes, DNxHD | AAC, PCM | Montage professionnel, écosystème Apple |
| AVI | MPEG-4, H.264 (limité) | MP3, PCM | Systèmes hérités (évitez pour les nouveaux projets) |
| TS | H.264, H.265, MPEG-2 | AAC, MP3, AC-3 | Diffusion, streaming HLS |
Les paramètres de qualité que personne n'explique correctement
Chaque tutoriel FFmpeg vous dit d'utiliser `-crf 23` pour une "bonne qualité" ou `-b:v 5M` pour "5 mégabits par seconde." Mais personne n'explique ce que ces paramètres font réellement ou comment choisir les bonnes valeurs pour votre contenu. J'ai passé des centaines d'heures à tester les paramètres de qualité sur différents types de contenu. Voici ce que j'ai appris : il n'y a pas de paramètre "meilleur" universel. Les paramètres de qualité optimaux dépendent de votre type de contenu, de votre public cible et de votre méthode de distribution."Le facteur de taux constant (CRF) est un mode d'encodage basé sur la qualité où vous spécifiez un niveau de qualité et laissez l'encodeur utiliser autant de bits que nécessaire pour atteindre cette qualité. Des valeurs CRF plus basses signifient une qualité supérieure et des fichiers plus volumineux. La plage est de 0 à 51 pour H.264, où 0 est sans perte et 51 est la pire qualité possible. La valeur par défaut est 23, considérée comme 'visuellement transparente' pour la plupart des contenus—ce qui signifie que la plupart des gens ne peuvent pas faire la différence avec la source."Le problème avec le CRF est qu'il produit une sortie à débit binaire variable. Une scène d'action à mouvement rapide peut utiliser 10 Mbps tandis qu'une scène statique de discussion utilise 2 Mbps. Cela est efficace pour la taille du fichier, mais cela peut causer des problèmes de streaming où vous avez besoin d'une utilisation prévisible de la bande passante. Pour le streaming, vous voulez un débit binaire constant (CBR) ou un débit binaire variable avec des contraintes (VBR). Voici la commande que j'utilise pour le streaming : ```bash ffmpeg -i input.mp4 \ -c:v libx264 -preset medium \ -b:v 5M -maxrate 5M -bufsize 10M \ -c:a aac -b:a 128k \ output.mp4 ``` Le `-b:v 5M` définit le débit binaire cible à 5 mégabits par seconde. `-maxrate 5M` garantit qu'il ne dépasse jamais ce taux. `-bufsize 10M` définit la taille du tampon du décodeur à deux fois le débit binaire, ce qui est la recommandation standard. Cela produit une sortie qui diffuse en douceur sans mise en mémoire tampon. Mais voici ce que la plupart des gens se trompent : les exigences en matière de débit binaire évoluent avec la résolution et le mouvement, pas de manière linéaire. Une vidéo 1080p n'a pas besoin du double du débit binaire d'une vidéo 720p—elle a besoin d'environ 1,5x. Une vidéo 4K n'a pas besoin de quatre fois le débit binaire de 1080p—elle a besoin d'environ 2,5x.
"Le système visuel humain est logarithmique, pas linéaire. Doubler le débit binaire ne