Presentation Generale
ffmpeg est un soft open source (GPL) qui peut encoder et decoder des flux videos et audio sur de tres nombreux formats, la liste est impressionnante ( https://en.wikipedia.org/wiki/FFmpeg#Supported_formats ou encore https://ffmpeg.org/general.html#Sup [...] -Features)
Il y a egalement un support de mux, c'est a dire que il peut (de)multiplexer des flux audio, video, et sous titres, ensemble (ou les separer). A ces mux sont associes des formats, les plus connus etant AVI, MKV, ISO, … que supporte egalement ffmpeg (cf lien ci-dessus)
Egalement des filtres sur une echelle tres large, allant du simple equalizer audio en passant par des resampling audio ou video
https://en.wikipedia.org/wiki/FFmpeg#Supported_filters ou encore https://ffmpeg.org/ffmpeg-filters.html
De maniere generale, pour aborder ffmpeg en details et retrouver ses petits, cette page est un bon point d'entrée / reference documentaire (options, filtres, etc).
https://ffmpeg.org/documentation.html
Recuperer ffmpeg
Il existe le repo officiel sur git, des builds linux mac et windows, les sources, et des builds complementaires.
https://ffmpeg.org/download.html
En source de build complementaire, celui ci inclue les librairies d'acceleration GPU de nvidia: (j'en parle plus bas un peu en details)
http://ffmpeg.zeranoe.com/builds
Les plus curieux peuvent aller lire l'application note de Nvidia sur l'utilisation de ffmepg avec l'acceleration HW des GPU (necessite un login Nvidia, gratuit)
https://developer.nvidia.com/design [...] ration-pdf
Utiliser ffmpeg
Utiliser la ligne de commande de ffmpeg est au premier abord un peu brutal (d'ou ce tuto ), d'ou pas mal de personnes se tournant vers des GUI, ou certes il faut cliquer au lieu de taper une ligne de commande, mais avec une comprehension sur les actions entreprises pas si aboutie.
A noter un point tres con, si on n'a pas ffmpeg dans son path, le plus simple est de le copier dans le directiory de la video a encoder, mais Powershell a malgre tout parfois du mal a le trouver. Il suffit donc de lui demander de le chercher ... dans le repertoire courant, ce qui se fait en remplacant ffmpeg par .\ffmpeg dans tous les exemples de lignes de commandes ci dessous.
Malgre tout on trouve sur les forums beaucoup de questions pour trouver une ligne de commande magique pour encoder une video+audio aux bons formats, avec les bons params de qualite, de vitesse d'encodage, la bonne resolution, etc.
Dans ce post je ne traiterai que les options classiques pour encoder en H264 et H265/hevc, vu que ce sont les principaux codecs du moment. H264 commence à être dépassé, mais c'est l'écrasante majorité des contenus disponibles, et les decodeurs hardware supportent beaucoup plus facilement h264 que h265.
Encodage H264
Citation :
ffmpeg -i video.mp4 -c:v libx264 output.mp4
|
Gestion qualite video http://trac.ffmpeg.org/wiki/Encode/H.264#crf
Pour gerer la taille du fichier et sa qualite video, un parametre est tres souvent utilise, le -crf (constant rate factor).
Crf 0 correspond a aucune perte,. Mais la taille est gigantesque. 51 est le plus compact, et evidemment le moins acceptable visuellement. L'optimal se situe entre 18 et 23, et est donc recommandé. LE codec se charge alors d'adapter le bitrate en fonction du contenu video et de la valeur de crf. A noter monter le crf de 6 revient a diviser la taille de la video par 2. A noter que cette echelle est valide pour du contenu 8 bits. Pour le contenu 10 bits nettement plus rare, il faut utiliser une echelle de 0 a 61.
Exemple:
Citation :
ffmpeg -i video.mp4 -c:v libx264 -crf 21 output.mp4
|
Qualite de l'encodage http://trac.ffmpeg.org/wiki/Encode/H.264#Preset
Un autre parametre est souvent utilise pour gerer la qualite de l'encodage, le preset . La regle est simplissime, plus l'encodage est lent, meilleur est son resultat pour un bitrate donné.
Par defaut sans renseigner ce parametre la valeur medium est utilisee. Elle peut varier de Ultrafast a veryslow. J;'aime bien cette recommandation : utilisez le setting le plus lent que votre patience vous permet.
Tuning en fonction du contenu http://trac.ffmpeg.org/wiki/Encode/H.264#Preset
Il est possible de renseigner au codec le type de video, du slide show d'images -stillimage- , au bon vieux classic en noir et blanc -grain-.
En pratique je n'ai pas beaucoup utilise ce parametre.
Exemple h264 avec ces differents elements:
Citation :
ffmpeg -i input.avi -c:v libx264 -preset slow -crf 22 -c:a copy output.mkv
|
A noter le -c:a copy qui specifie une simple copie du stream audio.
2 pass encoding
Il est possible, notamment a des buts de mieux controller le bitrate, de proceder a un encodage en deux passes. Les tests montrent que maintenant utiliser un crf21 et un preset slow suffit a obtenir des resultats visuellement comparables. Reste a l'encodage deux passes un meilleur controle du debit donc de la taille finale du fichier. Au vu de la lenteur du process on peut faire deux passes en slow ca peut valoir le coup de se poser la question, si c'est bien necessaire.
Ca se lance comme ca:
En pratique on lance donc deux fois a la suite ffmpeg, avec pratiquement les memes settings, sauf les suivants:
• Sur les pass 1 et 2, utiliser -pass 1 and -pass 2 respectivement.
• Sur la pass 1 la sortie est un null file descriptor, et pas un fichier. (ca genere en fait un log file logfile que ffmpeg utilise sur la pass 2)
• Sur la pass 1 on doit specifier le format de sortie (-f) qui correspond au format de sortie de la pass 2.
• Sur la pass 1, on peut ne pas s'occuper de l'audio, avec l'option -an.
• Sur vous fonctionnez sous linux la fin de la pass 1 est a changer = Au lieu de NUL utiliser /dev/null et le " \" remplace le "^".
Citation :
ffmpeg -y -i input -c:v libx264 -b:v 2600k -pass 1 -an -f mp4 NUL && ^
ffmpeg -i input -c:v libx264 -b:v 2600k -pass 2 -c:a aac -b:a 128k output.mp4
|
Resize - Rescale https://ffmpeg.org/ffmpeg-filters.html#scale
ffmpeg est capable de faire des scalings tres avances. Le lien ci-dessus en donne une version très detaillee, je vous presente ici juste les bases
La ligne de commande ci-dessous fait un simple rescale en 320:240
Citation :
ffmpeg -i input.avi -vf scale=320:240 output.avi
|
Ca peut etre utile de ne pas se taper le calcul de l'aspect ration, auquel cas vous pouvez utiliser -1 pour la seconde dimension
Citation :
ffmpeg -i input.jpg -vf scale=320:-1 output_320.png
|
Edit 15-02-2024 = je me suis rendu compte sur certaines videos qua la qualite du resize pouvait etre catastrophique. Ca semble du a deux facteurs: methode de resize au nearest pixel, et encodage rapide de la video mais avec des parametres crados
Je l'ai resolu en selectionnant un filtre de resize plus elaboré (Lanzcos, il y en a d'autres... ) et en specifiant la qualité d'encodage explicitement (a vous de mettre la votre ).
Citation :
ffmpeg -i input.avi -c:v libx264 -preset slow -crf 22 -vf scale=1068:600:flags=lanczos output.avi
|
Extraire une partie de la video uniquement
le principe est de "chercher une position, puis de faire une copie sur une duree donnée
-ss permet de chercher le timestamp
-t specifie la duree de la copie (a partir du timestamp)
Le timestamp est au format HH:MM:SS.xxx ou on peut mettre aussi une duree en secondes (s.msec)
La on saute les premières 30 secondes, puis on extrait juste 10 secondes de video
Citation :
ffmpeg -ss 00:00:30.0 -i input.wmv -c copy -t 10.0 output.wmv
|
Recompression et manipulations audio https://trac.ffmpeg.org/wiki/Encode/HighQualityAudio
Ffmpeg a des librairies qui permettent la compression audio, aac, lame/mp3, vorbis…
Les fameuses libs audio possibles:
Dolby Digital: ac3
Dolby Digital Plus: eac3
MP2: libtwolame, mp2
Windows Media Audio 1: wmav1
Windows Media Audio 2: wmav2
AAC LC: libfdk_aac, aac (<https://trac.ffmpeg.org/wiki/Encode/AAC> )
HE-AAC: libfdk_aac
Vorbis: libvorbis, vorbis
MP3: libmp3lame, libshine
Opus: libopus
Un exemple d'encodage aac a 128k, avec copie simple du flux video (a remplacer par vos options video favorites, cf plus haut):
Citation :
ffmpeg -i input.mp4 -c:v copy -c:a libfdk_aac -b:a 128k output.mp4
|
Les encodages vbr sont egalement supportes: (attention les options dependent evidemment des librairies utilisees)
Citation :
ffmpeg -i input.mp4 -c:v copy -c:a libfdk_aac -vbr 3 output.mp4
|
Convertion video libx264, et downmix de l'audio sur deux voies (stereo):
Citation :
ffmpeg -i input.mp4 -c:v libx264 -crf 22 -preset:v veryfast -ac 2 -c:a libfdk_aac -vbr 3 output.mp4
|
Manipulation et Selection des flux audio
Sur ce point il y a au moins deux grands themes = manipuler les channels audio d'un seul flux video, par exemple passer du 5.1 a un flux stereo, ou de stereo a mono…etc tout ca a l'interieur d'un seul flux video. Les options sont detaillees ici https://trac.ffmpeg.org/wiki/AudioChannelManipulation
Le plus classique est le downmix 5.1 vers stereo qui se lance comme ca:
Citation :
ffmpeg -i 6channels.wav -ac 2 stereo.wav
|
Le deuxieme theme est la selection de flux audio au sein d'une video, par exemple quand vous avez un flux audio VOST et un flux VF, vous pouvez vouloir retirer un des flux, ce qui peut representer une grosse reduction de la taille du fichier final, par exemple si le flux retirer est un flux DTS 5.1 a 1500Kbit/s.
<https://ffmpeg.org/ffmpeg.html#Stream-selection> et https://trac.ffmpeg.org/wiki/Map
Citation :
ffmpeg -I input.mp4
|
vous donne la liste des flux video et audio.
Si un fichier a les flux suivants: (exemple integralement repris de https://trac.ffmpeg.org/wiki/Map> )
Citation :
fmpeg -i input.mkv
ffmpeg version ... Copyright (c) 2000-2012 the FFmpeg developers
...
Input #0, matroska,webm, from 'input.mkv':
Duration: 01:39:44.02, start: 0.000000, bitrate: 5793 kb/s
Stream #0:0(eng): Video: h264 (High), yuv420p, 1920x800, 23.98 fps, 23.98 tbr, 1k tbn, 47.95 tbc (default)
Stream #0:1(ger): Audio: dts (DTS), 48000 Hz, 5.1(side), s16, 1536 kb/s (default)
Stream #0:2(eng): Audio: dts (DTS), 48000 Hz, 5.1(side), s16, 1536 kb/s
Stream #0:3(ger): Subtitle: text (default)
At least one output file must be specified
|
Alors pour :
• copier le flux video
• encoder le flux audio Allemand en mp3 (128kbps) et aac (96kbps) (donc creer 2 audio streams sur l'output)
• Retirer le flux audio anglais
• Copier le flus de sous titres
Il faut lancer la commande suivante:
Citation :
ffmpeg -i input.mkv \
-map 0:0 -map 0:1 -map 0:1 -map 0:3 \
-c:v copy \
-c:a:0 libmp3lame -b:a:0 128k \
-c:a:1 libfaac -b:a:1 96k \
-c:s copy \
output.mkv
|
A partir de cet exemple je pense que vous pouvez tisser les differentes solutions possibles pour l'extraction des flux qui vous interessent. Il y a des modes audio de selection, mais je pense que le plus simple est de faire son marche a la main.
Edit 18-09-2022: Exemple plus simple, je viens de lutter 20 minutes pour virer 2 flux audio et des sous titres:
Le fichier initial a 1 flux video, 3 streams audio, et 2 streams de sous titres.
Je veux ne recuperer que le flux video, et le troisieme flux audio, le reste ne m'interesse pas.
La commande map donne le "menu" de la selection, ensuite il faut dire quoi faire avec les flux:
- copie pour la video
- encodage audio pour le flux audio, car dans le fichier original il etait en flac, ce que certains decodeurs n'aiment pas trop. Je ne specifie rien, je pense que ffmpeg encode simplement au format par defaut (aac128 / 48KHz pour le mp4).
Citation :
ffmpeg -i input.mkv -map 0:v -map 0:a:2 -c:v copy output.mp4
|
Encodage H265 https://trac.ffmpeg.org/wiki/Encode/H.265
Un gros atout de ffmpeg est le support des librairies h265/HEVC a travers le support de x265 (http://x265.org/)
H265 apporte des taux de compression largement meilleurs a qualite equivalente, la principale proposition "commerciale" du h265 etant la meme qualite video pour 50% de moins en taille de fichier. Une simple recherche h265 vs h264 vous donnera une tonne de papiers et etudes plus ou moins poussees pour expliquer les deltas, pour les curieux. En pratique on constate une amelioration de 20 a 50% en effet, en fonction des contenus video. LE temps d'encodage est beaucoupo plus long en H265, et le decodage h265 demande aussi pas mal de CPU, en plus d'etre moins facilement supporte par les differentes plateformes (seul chromecast ultra le supporte, ainsi que les dernieres versions de raspberry 3b+ et 4).
Les options sont proches de l'encodage h264, avec quelques nuances. Les encodages 1 et 2 passes sont toujours possibles. On peut specifier le bitrate ( -b:v ) , ou le quantifieur crf, ce qui est plus pratique car indique directement une qualite donnee. Difference avec h264 le crf qui vise une qualite vs bitrate optimale n'est plus de 21 mais de 28. Les memes preset existent, medium reste l'option par defaut, slow ameliorant la qualite audio au prix d'un temps d'encoadge plus long et de plus de RAM utilisee a l'encodage.
Exemple:
Citation :
ffmpeg -i input -c:v libx265 -crf 28 -preset slow -c:a aac -b:a 128k output.mp4
|
Utilisation Acceleration HW GPU Nvidia
Ffmpeg peut etre builde avec les librairies necessaire pour encodage CUDA par le GPU. Nvidia a publie un guide sur son blog ( https://devblogs.nvidia.com/nvidia- [...] ing-guide/ ) ainsi que un papier asssez complet https://developer.download.nvidia.c [...] v01.4.pdf? , sur comment decoder et encoder en HW en utilisant le GPU.
Ce sujet reste assez discute, car
- On y gagne tres fortement en vitesse d'encodage, c'est particulierement spectaculaire en h264, mais aussi en h265. (qques chiffes plus bas)
- La qualite video semble degradee quand on accelere avec le GPU, les libraires d'acceleration fournissent moins d'options, et le support de certaines options en h265 est en cours d'ajout par nvidia sur leur encodeur HW. (see https://developer.nvidia.com/video- [...] rt-matrix)
- l'encodage GPU semble clairement plus econome en watts, pour ceux qui surveillent leur conso electrique
Chiffres: Sur i7 7700k avec 16GB de RAM et un nvme de compette, en sw/cpu intel, reglage preset slow, - crf 28, je fais du 0. 4x sur une video full hd h264 a encoder en h265 (copie directe du flux audio).
Quand j'active l'accélération hw gpu (gtx980), je passe a environ 6x de vitesse d'encodage sur le meme flux vidéo. La différence de temps est énorme ! Le fait d'activer le decodage en hw par le gpu ne change rien sur ma machine. A noter que la qualité d'encodage en hw est nettement en dessous de l'encodage sw, dans les scènes rapides et dense, les yeux sensibles repereront l'apparition de macro blocs..
La ligne de commande suivante force :
- le decodage HW h264 -hwaccel cuvid -c:v h264_cuvid -i 'input.mkv'
- et l'encodage HW en h265 en utilisant le codec video -c:v hevc_nvenc
- copie simple du flux audio
- A noter l'option -crf n'est pas supportee par hevc_nvenc
Citation :
ffmpeg -hwaccel cuvid -c:v h264_cuvid -i 'input.mkv' -c:v hevc_nvenc -preset slow -c:a copy 'output.mkv'
|
idem avec du H264:
- le decodage HW h264 -hwaccel cuvid -c:v h264_cuvid -i 'input.mkv'
- l'encodage HW en h264 en utilisant le codec video -c:v h264_nvenc
- copie simple du flux audio
Citation :
ffmpeg -hwaccel cuvid -c:v h264_cuvid -i 'input.mkv' -c:v h264_nvenc -preset slow -c:a copy 'output.mkv'
|
Et voici une ligne plus complete, pour pouvoir regler un peu plus des settings de qualité video, selon le papier Nvidia:
Citation :
./ffmpeg -y -vsync 0 -hwaccel cuvid -c:v h264_cuvid -i input.mp4 -c:a copy -c:v h264_nvenc -preset slow -profile:v high -b:v 5M -bufsize 5M -maxrate 10M -qmin 0 -g 250 -bf 2 -temporal-aq 1 -rc-lookahead 20 -i_qfactor 0.75 -b_qfactor 1.1 output.avi
|
Il y a pas mal de lecture si on veut sur l'encodage GPU, perso j'aime bien ce commentaire qui ouvre plusieurs portes, pour ceux que ca interesse:
Cf reponse de destiny_functional
https://www.reddit.com/r/ffmpeg/com [...] ality/>
PS: si des solutions existent avec des GPU AMD, je serai tres content de les ajouter !
Bon encodage a tous
Edit 14-02-2024
besoin de faire une mosaique pour un projet specifique. Ca se fait comme ca (exemple pour 3 videos, mais il peut y avoir d'autres logiques)
Je rajoute en fin de commande la qualite de la video pour etre sur d'avoir un contenu correct (-c:v libx264 -preset slow -crf 22 )
Citation :
ffmpeg -i left.avi -i center.avi -i right.avi -filter_complex "[0:v][1:v][2:v]hstack=inputs=3[v]" -map "[v]" -c:v libx264 -preset slow -crf 22 Mosaic.avi
|
Plus d'options ici, je trouve ces solutions plus digestes que la page ffmpeg
https://stackoverflow.com/questions [...] ing-ffmpeg
Et Pour le crop sur une video en entree de 800*600, on peut extraire le carré droit (puis gauche) de la maniere suivante:
crop=SizeX:SizeY:StartPointX:StartPointY
Citation :
ffmpeg -i input.avi -c:v libx264 -preset slow -crf 22 -vf "crop=400:600:0:0" OutputLeft.avi
ffmpeg -i input.avi -c:v libx264 -preset slow -crf 22 -vf "crop=400:600:400:0" OutputRight.avi
|
plus d'explications ici
https://video.stackexchange.com/que [...] ith-ffmpeg
Message édité par ManuLM le 14-02-2024 à 14:52:50