Page régulièrement augmentée
====== Quelques commandes FFMPEG utiles ======
[[https://ffmpeg.org/|FFMPEG]] est un logiciel libre, multi-plateforme, en ligne de commande, de traitement audio et vidéo.
FFMPEG permet de convertir/réencoder des fichiers entre différents formats, d'extraire l'audio d'une vidéo, ainsi que d'appliquer des filtres audios (compression acoustique, égalisation, ...) et vidéos (conversion du taux de rafraîchissement, de la résolution, de la colorimétrie, désentrelacement, ...). C'est un logiciel aux vastes possibilités, dont je ne connais qu'1%. Je vais simplement sur cette page détailler les quelques commandes auxquelles il m'arrive d'avoir recours.
===== Remarques préliminaires =====
* Sur Linux, afin de bénéficier des dernières évolutions du logiciel, je n'utilise pas la version packagée de ma distribution Linux, mais un binaire statique. Je vous encourage à faire de même et à l'installer dans le dossier ///opt// prévu à cet effet. Voir la page des téléchargements : https://ffmpeg.org/download.html \\ Vous n'êtes pas concerné par ce genre de considération sous Windows ou MacOS.
* FFMPEG étant un logiciel **velu**, j'encourage tout un chacun à parcourir la [[https://ffmpeg.org/documentation.html|documentation]], complète (mais velue également, j'en conviens), afin d'un savoir plus sur chacune des possibilités présentées dans ce très modeste mémo.
* Il existe également un [[https://trac.ffmpeg.org/wiki|wiki]], très bien fait, qui reprend des informations de manière plus synthétique que la documentation sur diverses opérations courantes qu'on peut être amenés à effectuer avec FFMPEG.
===== Ré-encodage d'une vidéo =====
__Conversion d'un 4K/50 en FHD/25 :__
ffmpeg -i fichier-original.mp4 -r 25 -vf scale=1920:1080 -c:v libx265 -crf 20 -preset slow -c:a copy fichier-1080.mp4
* -i : spécification du fichier d'entrée
* -r : modification du taux de rafraîchissement à 25
* -vf : application d'un filtre vidéo (ici une mise à l'échelle en 1920x1080)
* -c : choix de l'encodeur à utiliser (-c:v pour vidéo, -c:a pour audio). Plus spécifiquement, on va ici utiliser l'encodeur libx265 pour encoder la vidéo en h.265 (HECV), avec les options //-crf 20// et une vitesse d'encodage //slow//. Je renvoie le lecteur à la documentation sur le codec : https://trac.ffmpeg.org/wiki/Encode/H.265 pour en savoir plus. L'audio, quand à lui, est simplement recopié tel quel, sans ré-encodage.
* on termine par le nom que l'on souhaite donner au fichier de sortie
Bien sûr, les différentes options sont facultatives. Par exemple, on peut omettre //-r 25// si on souhaite conserver le taux de rafraîchissement original.
==== Mémo rapide sur l'encodage en x.264 et x.265 ====
* En matière de choix du débit (cbr, vbv, crf, double passe, ...) il faut pas s'embêter. Dans la majorité des cas, on utilise ''-crf''. Par contre si on souhaite faire du lossless, réduire la latence pour du streaming, ou autre cas particulier, les autres options peuvent être utiles. Voir le [[https://trac.ffmpeg.org/wiki/Encode/H.264|wiki]].
* Plus la paramètre du bitrate ''-crf'' (réglant la qualité) est élevé, plus l'image est compressée et donc moins la qualité est bonne
* Il est estimé que le codec x.265 permet d'obtenir une qualité équivalente au codec x.264 avec un réglage de bitrate inférieur de 5 points
* En x.264 la valeur de bitrate par défaut est 28
* En x.265 la valeur de bitrate par défaut est 23 et devrait donc donner un résultat équivalent à x.264 (28)
* Pour visionnage direct du fichier dans un navigateur (sans passer par un player), x.265 ne semble à ce jour pas bien supporté. Lui préférer x.264
===== Concaténation de plusieurs vidéos =====
De nos jours la plupart des gens utilisent leur téléphone ou leur appareil photo pour filmer. Ça convient à la plupart des situations, mais ces appareils présentent une limitation très contraignante : la durée des vidéos est limitée à 29m59s (pour des raisons juridiques sur lesquelles je ne m'étendrai pas). Si on veut filmer en continu pour une durée plus longue (conférence, pièce de théâtre, entrevue, ...), on est obligé de passer par un caméscope, une caméra pro, bref tout appareil destiné en premier lieu à filmer... qui eux ne présentent pas cette limitation.
Il existe cependant une manière de contourner la limitation sur smartphone Android ((Il existe certainement des applications ayant cette fonctionnalité pour les téléphones Apple, mais je ne peux vous en nommer.)), en installant une application de caméra en remplacement de celle fournie avec le smartphone, comme par exemple, l'excellent Open Camera (gratuit)(([[https://play.google.com/store/apps/details?id=net.sourceforge.opencamera|Lien Google Play Store]], [[https://f-droid.org/en/packages/net.sourceforge.opencamera/|lien F-Droid]]. )). Open Camera vous permet en effet de poursuivre automatiquement l'enregistrement vidéo sur un nouveau fichier chaque fois que la limite est atteinte, sans aucune coupure. Il est ainsi possible de filmer en continu pendant des heures si on le souhaite. Il ne restera alors plus qu'à joindre toutes les vidéos ainsi créées en un seul fichier pour une lecture en continu, sans transition. Cette technique permet aussi de s'affranchir de la limitation à 4 Go par fichier présente sur certain téléphones Android et qui peut aussi dépendre du type de système de fichier dans lequel la carte SD a été formatée.
Remarque : tout ce qui suit provient tout simplement du [[https://trac.ffmpeg.org/wiki/Concatenate|wiki]], déjà mentionné plus haut.
On va utiliser le filtre //concat demuxer//. Celui-ci aura besoin d'un fichier texte contenant les noms de fichiers à assembler. On va générer ce fichier automatiquement en ligne de commande. Il suffit de se rendre dans le dossier contenant les vidéos et d'entrer les commandes suivantes :
Linux :
printf "file '%s'\n" ./*.mp4 > liste.txt
Windows :
(for %i in (*.mp4) do @echo file '%i') > liste.txt
Une fois le fichier texte créé, on peut lancer la concaténation avec la commande :
ffmpeg -f concat -safe 0 -i liste.txt -c copy fichier.mp4
C'est tout ! Quelques secondes plus tard, un nouveau fichier vidéo nommé //fichier.mp4// aura été créé. Il contiendra toutes les vidéos à la suite sans coupure.
===== Normaliser l'audio =====
FFMPEG a un filtre appelé ''loudnorm'' qui permet de niveler le son selon la norme EBU R128. Si je comprends bien, c'est l'addition d'un normaliseur, un AGC lent et un Peak Limiter. Ça n'agit donc pas comme ReplayGain ou une normalisation classique, qui se contentent d'ajuster le niveau global de manière linéaire en fonction du passage où le volume de la piste est le plus fort. Au contraire ''loudnorm'' va quand à lui dénaturer de manière irréversible la piste sonore par écrasement de la dynamique en rendant plus fort certains passages faibles et vice-versa. Ça ne me pose pas de problème mais il faut le signaler. Par défaut, ''loudnorm'' copie le résultat de son travail dans un sous-dossier.
On peut bien entendu l'utiliser sur des vidéos mais également sur des signaux audio seuls. Ça pourrait être une solution facile pour les petits podcasteurs qui n'ont pas forcément les compétences techniques pour régler des chaînes de compression, etc. dans leur éditeur audio.
J'ai trouvé ''lournorm'' très efficace pour du contenu de type documentaire, voix, musique de fond ou classique. Pour de la musique moderne, du rock ou quoi que ce soit ayant une dynamique variant de manière rapide, je ne l'ai pas trouvé adapté : c'est un AGC lent, on a donc une variation de volume sur plusieurs secondes comme si quelqu'un tournait progressivement le bouton de volume, ce qui est très audible par exemple au passage entre un couplet calme et un refrain pêchu. Je précise que je ne l'ai testé qu'avec ses réglages par défaut, mais il est possible d'utiliser ses propres paramètres.
Voici ce qu'en dit le créateur du filtre : http://k.ylo.ph/2016/04/04/loudnorm.html
Le wiki FFMPEG en parle en bas de cette page : https://trac.ffmpeg.org/wiki/AudioVolume
Pour plus de facilité, j'utilise ce script Python : https://github.com/slhck/ffmpeg-normalize avec la syntaxe suivante :\\
''ffmpeg-normalize fichier.mp4 -c:a libopus -b:a 192k -ar 48000 -ext opus''
* [[https://opus-codec.org/|Opus]] (par exemple).
* Bitrate 192kbit/s
* Comme ''loudnorm'' ré-échantillonne à 192 kHz pour effectuer son travail, il est nécessaire de préciser qu'il faut redescendre à 48 kHz au moment de l'encodage final. En l'occurence, ça ne semble pas obligatoire pour Opus qui ne connait que cette fréquence d’échantillonnage, mais c'est une bonne habitude à prendre en cas d'utilisation d'autres formats, qui eux permettent un encodage à 192 kHz.
* Il faut préciser l'extension si on souhaite juste extraire l'audio. Sinon par défaut ça sort le contenu vidéo + audio dans un container .mkv (la piste vidéo est juste copiée, sans traitement)
Il est aussi possible d'utiliser la syntaxe suivante pour effectuer une simple normalisation sur les crêtes à 0 dB, sans modification de la dynamique :
''ffmpeg-normalize fichier.mp4 -nt peak -t 0 -c:a libopus -b:a 192k -ar 48000 -ext opus''
* -nt pour le //type de normalisation//
* -t pour le //target//
===== Extraire la piste audio d'une vidéo =====
Les méthodes de base décrites ci-dessous fonctionne bien de manière générale. Cependant, il est fort probable que la durée du fichier audio ainsi extrait ne soit pas exactement égale à celle de la vidéo d'origine (si j'ai bien compris, c'est dû au taux d’échantillonnage variable du codec d'enregistrement utilisé, qui fait que tous les échantillons n'ont pas la même durée ?). Sur des vidéos d'une durée "normale" ça ne pose pas de problème. Récemment, j'ai dû travailler sur des vidéos de 3-4 heures d'un seul tenant, et la différence de longueur avoisinait 1 seconde, ce qui eut pour conséquence qu'au plus on s'approchait de la fin de la vidéo, au plus le son était désynchronisé de l'image. Pour y remédier, il faut utiliser la commande suivante pour l'extraction :
''ffmpeg -i video.mp4 -af "aresample=async=1" audio.wav''
Ceci a pour effet d'allonger ou rétrécir certains échantillons (de manière imperceptible) afin que son et image restent synchronisés. Pour information, ça a réduit sur une vidéo de 4 heures le décalage à seulement une dizaine de millisecondes. Ce qui n'était plus problématique, mais n'était toujours pas la durée exacte de la vidéo.
==== Vers le format FLAC afin de pouvoir travailler sans perte ====
ffmpeg -i video.mp4 [-compression_level 12] [-sample_fmt s16] audio.flac
La détection du format est automatique avec l'extension du nom de fichier.
* [-sample_fmt s16] pour resampler en 16 bits
Pour une raison que j'ignore, l'extraction de l'audio avec encodage en FLAC est chez moi d'une lenteur anormale. Par conséquent, je sors le fichier en WAV puis le ré-encode manuellement avec Sound Converter.
==== Vers le format d'origine ====
Pour simplement extraire une piste audio qu'on ne souhaite pas retravailler, il suffit d'extraire les données telles quelles sans conversion.
Pour ce faire, il faut d'abord connaître quel codec sonore est utilisé dans la vidéo :\\ ''ffprobe video.mp4''
Muni de cette information, on peut lancer la commande d'extraction. Prenons l'exemple où le codec audio utilisé est le AAC d'Apple, on utilisera :\\ ''ffmpeg video.mp4 -vn -acodec copy audio.aac''
* ''-vn'' précise qu'on ne veut pas la vidéo
* ''-acodec copy'' précise d'utiliser le flux audio déjà présent
* il ne reste qu'à spécifier l'extension adéquate