Comment puis-je utiliser ffmpeg
pour réduire la taille d'une vidéo en diminuant la qualité (le moins possible, naturellement, car j'en ai besoin pour fonctionner sur un appareil mobile qui ne fonctionne pas) ont beaucoup d'espace disponible)?
J'ai oublié de mentionner que lorsque la vidéo peut utiliser des sous-titres (* .srt ou * .sub), je voudrais également les convertir pour s'adapter aux paramètres du fichier vidéo converti.
Voir cette réponse. Cité ci-dessous pour plus de commodité:
Calculez le débit dont vous avez besoin en divisant 1 Go par la durée de la vidéo en secondes. Donc, pour une vidéo d'une durée de 16:40 (1000 secondes), utilisez un débit binaire de 1000000 octets/sec:
ffmpeg -i input.mp4 -b 1000000 output.mp4
Des options supplémentaires qui pourraient être envisagées sont la définition du facteur de débit constant, qui abaisse le débit binaire moyen, mais conserve une meilleure qualité. Faites varier le CRF entre 18 et 24 environ - plus le débit binaire est bas, plus il est élevé.
ffmpeg -i input.mp4 -vcodec libx265 -crf 20 output.mp4
Modifiez le codec selon vos besoins - libx264 peut être disponible si libx265 ne l'est pas, au prix d'une taille de fichier résultante légèrement plus grande.
Vous avez mentionné vouloir réduire la taille des fichiers pour accueillir plus de vidéos sur un appareil mobile, ce qui est également mon cas d'utilisation. Toutes les réponses ici concernent la réduction de la qualité de la compression, mais personne n'a mentionné la réduction de la taille de l'image vidéo. C'est beaucoup plus rapide, environ 3 à 5 fois plus rapide que la recompression selon mon expérience. Voir les documents ffmpeg sur scaling pour plus d'informations.
ffmpeg -i input.mkv -vf "scale=iw/2:ih/2" half_the_frame_size.mkv
ffmpeg -i input.mkv -vf "scale=iw/3:ih/3" a_third_the_frame_size.mkv
ffmpeg -i input.mkv -vf "scale=iw/4:ih/4" a_fourth_the_frame_size.mkv
À moins que vous ne recherchiez un débit binaire spécifique, je recommanderais le -crf
option. C'est le plus couramment utilisé pour x264
encodage: http://slhck.info/articles/crf
En bref: un CRF de 23 produirait un film de qualité "DVD" (~ 700 Mo-1 Go) et des valeurs de CRF inférieures seraient de meilleure qualité (fichiers plus gros).
J'ai testé la plupart des autres réponses proposées à cette question. Les conclusions des données de test sont ci-dessous. Ce sont les réponses proposées que j'ai testées:
(BR) Modifiez le débit binaire en utilisant:
ffmpeg -i $infile -b $bitrate $newoutfile
(CR) Variez le facteur de taux constant, en utilisant:
ffmpeg -i $infile -vcodec libx264 -crf 23 $outfile
(SZ) Modifiez la taille de l'écran vidéo (par exemple, la moitié de sa taille en pixels), en utilisant:
ffmpeg -i $infile -vf "scale=iw/2:ih/2" $outfile
(BL) Changez le profil H.264 en "ligne de base", en utilisant:
ffmpeg -i $infile -profile:v baseline $outfile
(DF) Utilisez le traitement ffmpeg par défaut, en utilisant:
ffmpeg -i $infile $outfile
[~ # ~] données [~ # ~]
J'ai calculé le débit binaire cible pour (BL) en utilisant la méthode proposée.
=== Fichier A - Comment Node aide à propulser Angular-Fnbixa7Ts6M.mkv ===
original BR CR SZ BL DF
-------- --- -- -- -- --
size 64152 kb 214% 76% 40% 83% 76%
bitrate 411 kb/s 883 313 165 342 313
definition 1920x1080 1920x1080 1920x1080 960x540 1920x1080 1920x1080
convert -- 648 509 225 427 510
=== Fichier B - Utilisation de GraphQL avec Angular _ By - Lee Costello-OGyFxqt5INw.mkv ===
original BR CR SZ BL DF
-------- --- -- -- -- --
size 410301 kb 33% 109% 28% 143% 109%
bitrate 2687 kb/s 880 2920 764 3843 2920
definition 3840x2160 3840x2160 3840x2160 1920x1080 3840x2160 3840x2160
convert -- 2307 3188 1116 2646 3278
[~ # ~] conclusions [~ # ~]
La méthode (SZ) est certainement la méthode la plus rapide. C'était 2X à 4X plus rapide. Cela peut être très problématique sur les vidéos haute définition, car toutes les autres méthodes ont pris plus de temps à convertir que la durée réelle de la vidéo! Par exemple, la méthode (CR) a pris 53 minutes pour convertir la vidéo de 21 minutes.
La méthode (SZ) est certainement la meilleure méthode si la définition de la vidéo est plus grande que la définition de l'écran qui l'affichera. Par exemple, si votre téléphone ne peut afficher qu'une image 1080p, lui envoyer une vidéo 3840x2160 est tout simplement inutile. Il serait préférable de réduire de moitié sa taille à 1080p.
Certaines des réponses proposées ont en fait AUGMENTÉ la taille de certaines vidéos. Par exemple, la méthode (BR) a plus que doublé la taille de l'échantillon 1080p. Il a cependant fait un tiers de la taille 2160p. Pour l'échantillon haute définition, les méthodes (CR), (BL) et (DF) ont toutes AUGMENTÉ la taille de la vidéo.
Réponse correcte (ou meilleure)
Il est toujours préférable d'abaisser d'abord la résolution au maximum pris en charge par votre écran cible.
Si vous souhaitez réduire davantage la taille du fichier, cela dépendra de vos choix personnels. Vous pouvez soit réduire le contenu des informations, soit augmenter la compression.
Vous pouvez réduire davantage la résolution si cela ne vous concerne pas.
Si la vidéo ne comprend pas de scènes d'action rapide, vous souhaiterez peut-être réduire la fréquence d'images.
Si vous avez un processeur puissant et que l'espace est le seul problème, vous pouvez augmenter le taux de compression.
Le débit binaire est une combinaison de plusieurs facteurs. Donc, simplement dire à ffmpeg de réduire le débit binaire peut ne pas vous donner les résultats que vous souhaitez.
Une autre façon de réduire le contenu de l'information consiste à réduire la profondeur de couleur. Comment faire cela n'a pas encore été discuté.
Notez qu'il semble que ffmpeg
déjà effectue une optimisation lorsqu'il est exécuté sans options, donc avant d'essayer d'utiliser des paramètres que vous ne comprenez pas ou de décider de perdre explicitement des informations, essayez un conversion par défaut:
ffmpeg -i input.mp4 output.mp4
Dans mon cas, cela a réduit le débit binaire de la vidéo et de l'audio (vous pouvez vérifier et comparer le fichier d'entrée et de sortie en exécutant ffprobe
dessus), transformant une vidéo de 700 Mo en 60 Mo de qualité apparemment similaire .
J'ai compressé une présentation vidéo HD de 40 minutes de 505 Mo à 183 Mo
C'est comme passer de 100 Mo à 36 Mo.
La vidéo d'origine était en HD et la sortie était presque nulle différence notable.
C'est un fichier vidéo "Je voudrais rester, mais la HD est exagérée."
Voici la commande que j'ai utilisée avec des raisons:
ffmpeg -n -loglevel error -i inputfile.mp4 -vcodec libx264 -crf 28 -preset faster -tune film outputfilename.mp4
-n
: à éviter écrasement des fichiers de sortie (plus sûr pour les tests puis le traitement par lots)-loglevel error
: afficher les erreurs et masquer les lignes et les lignes de progression-i inputfile.mp4
: nom du fichier d'entrée-vcodec libx264
: glissé de la réponse du haut ci-dessus-crf 28
: compression en un seul passage avec une différence notable mineure ( "0 = sans perte, 23 = par défaut, 51 = pire; la plage subjectivement saine est de 17 - 28 ") documents de référence-preset faster
: semble 2x plus rapide que le temps d'encodage par défaut de 'medium' ref docs-tune film
: spécifiez que l'entrée est une vidéo HQ (les autres options incluent 'cartoon', 'stillimage' ..) ref docsoutputfilename.mp4
: nom du fichier de sortiePour un répertoire de fichiers vidéo:
for i in *.{avi,flv,m4v,mov,wmv,mp4,MP4,TS,mkv}; do ffmpeg -n -loglevel error -i "$i" -vcodec libx264 -crf 28 -preset faster -tune film "cc${i}"; done
Problèmes:
.webm
les fichiers ne fonctionnent pas avec la commande. J'ai dû échanger "cc${i}"
→ "${i%.*}.mp4"
Handbrake est une alternative open-source avec une interface utilisateur
J'ai une recette que je me suis forgée à l'origine pour convertir les vidéos Motion JPEG générées par mon ancien appareil photo (ce sont de très grandes vidéos, car chaque image est une image JPEG entière) en h264. Voici une adaptation pour d'autres types de vidéos (cours, etc.).
Je suis n'utilise pas ffmpeg, mais mplayer et mencoder. Tout d'abord, nous devons démultiplexer l'audio avec mplayer:
mplayer -vo null -ao pcm:fast:file=<audio_pcm.wav> <video>
-vo null
et -ao null
parameters indique à mplayer de ne pas extraire la vidéo.Dans les étapes suivantes, nous ferons une compression en 3 passes avec mencoder. À la première passe, nous choisirons une compression appropriée du mode de qualité constante (crf paramètre) comme point de départ:
mencoder <video> -ovc x264 \
-x264encopts ratetol=100:preset=veryslow:crf=<value>:pass=1 \
-nosound -o video1.h264
Vous pouvez ajouter slow_firstpass paramètre au -x264encopts si vous êtes paranoïaque avec la qualité finale de la vidéo. Le manuel de Mencoder indique que cette option désactive certains paramètres qui "améliorent considérablement la vitesse d'encodage tout en ayant peu ou pas d'impact sur la qualité de la passe finale". Donc, utilisez-le uniquement à la dernière étape.
Vous devez essayer plusieurs valeurs pour crf - essayez de partir de 25 et continuez à l'augmenter jusqu'à ce que vous notiez des artefacts à la vidéo résultante (des valeurs plus élevées compriment davantage). N'oubliez pas que les passes d'encodage suivantes amélioreront la qualité pour laquelle vous avez choisi crf.
Alternatives pour le très lent prédéfinis sont ralentissez, lent, moyen etc. Voir le manuel de mencoder pour la liste complète.
ratétol contrôle la variation du débit binaire - je ne sais pas si je fais la bonne chose ici, mais je l'ai réglé à la valeur maximale afin de laisser la liberté totale au mencoder de choisir le bon débit binaire pour chaque scène.
Après la première passe, vous remarquerez que la dernière ligne vous donne le débit moyen que vous utiliserez aux étapes suivantes:
(...)
x264 [info]: kb/s:526.43
Changer la crf paramètre, recommandé lors de la première passe, débit binaire, requis lors des passes suivantes:
mencoder <video> -ovc x264 \
-x264encopts slow_firstpass:ratetol=100:preset=veryslow:bitrate=526:pass=3 \
-nosound -o video2.h264
Ce deuxième encodage passe lira les statistiques générées lors de la première passe (divx2pass.log
et divx2pass.log.mbtree
) afin d'optimiser la compression.
Notez que vous utiliserez la même entrée vidéo, pas celle générée par le premier passage - la sortie vidéo du premier passage n'est utile que pour vérifier la qualité initiale.
Notez également que le pass=3
(paspass=2
) va générer un nouveau fichier de statistiques, vous pouvez donc répéter la dernière étape autant de fois que vous le souhaitez. Je fais habituellement pass=3
deux fois, en faisant toujours attention au débit binaire résultant.
Pendant ce temps, vous pouvez également compresser l'audio, en utilisant lame
ou oggenc
:
oggenc -q<n> <audio_pcm.wav>
Enfin, nous remuxerons audio et vidéo
mencoder -audiofile <audio>.ogg video2.h264 -oac copy -ovc copy \
-of lavf -lavfopts format=mp4 -o <video>.mp4
-of lavf -lavfopts format=mp4
génère mp4
format de fichier utilisant les multiplexeurs lavopts.Vous devrez utiliser un encodage en 2 passes pour "adapter" une vidéo dans une taille de fichier (bitrate) désignée, sans réduire trop radicalement la qualité. Il s'agit d'un sujet assez détaillé: http://web.archive.org/web/20171130050515/http://www.mpabo.com/2014/12/14/ffmpeg-and-x264-encoding-guide /
J'ai écrit un script bash pour réduire la taille de la vidéo et essayer automatiquement différentes valeurs de crf.
Fondamentalement, vous
Ceci est vraiment pratique lorsque vous avez une limite de taille que vous souhaitez atteindre et que vous ne savez pas quelle est la valeur crf qui vous permettra de le faire.
J'espère que cela aidera quelqu'un. J'ai partagé avec mes collègues et tout le monde l'a trouvé utile.
#!/bin/bash
# bigger values of crf will lead to a bigger compression (smaller video size)
#for i in 1 2 3 4 5
for i in {25..28}
do
# you can remove the option -y if you want to be asked if to overwrite a file with the same name (leave the -y only if you understand what you are doing, otherwise you might rewrite an important file)
ffmpeg -y -i NAMEOFTHEVIDEOTOCOMPRESS.mp4 -c:v libx264 -crf $i -preset veryfast -profile:v baseline -level 3.0 -strict -2 out_$i.mp4
printf "\n>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>Done compression at crf=$i \n\n"
done
Voici un exemple en 2 passes. Assez codé en dur mais ça met vraiment la pression#!/bin/bash ffmpeg -y -i "$1" -c:v libvpx-vp9 -pass 1 -deadline best -crf 30 -b:v 664k -c:a libopus -f webm /dev/null && ffmpeg -i "$1" -c:v libvpx-vp9 -pass 2 -crf 30 -b:v 664k -c:a libopus -strict -2 "$2"