Je teste la conversion de certaines vidéos en encodage HEVC à l'aide de ffmpeg et de libx265 et j'ai découvert que la largeur d'entrée devait être divisible par 8 pour réussir le réencodage. Je voudrais déterminer si un recodage réussira sans tenter de le coder et d'examiner ensuite la sortie. Idéalement, j'aimerais le faire dans un script bash. Mes compétences sont quelque peu limitées à cet égard et une grande partie de ce que j'ai développé jusqu'à présent est loin d'être élégante.
Par exemple, je sais que je peux faire le calcul avec bc comme dans:
echo 'scale=2;576/8' | bc
72.00
et je peux obtenir la largeur via
width=$(mediainfo $filename | grep "Width" | sed 's/[^0-9]*//g')
mais le premier ne répond pas exactement à la question est la largeur divisible par 8 et le dernier est laid et utilise trop de tuyaux que la recherche indique moins efficace.
J'ai la ligne de commande ffmpeg pour le ré-encodage triée à ma satisfaction en utilisant:
ffmpeg -i "$f" -c:a copy -c:v libx265 -preset "$preset" -crf 25 "$target"
et j’ai l’intention de redimensionner la vidéo jusqu’à une largeur divisible par 8 si ce n’est pas déjà fait, mais je cherche de meilleures solutions que celles que j’ai imaginées jusqu’à présent pour déterminer si une mise à l’échelle est nécessaire et comment déterminer la largeur la plus proche divisible. par 8 à l'échelle à.
Ce qui suit corrigera le width en un nombre divisible par 8, puis correctement redimensionner le height à un nombre divisible par 8 tout en maintenant les proportions correctes:
ffmpeg -i <input> \
-c:a copy \
-c:v libx265 -preset medium -x265-params crf=28 \
-vf scale="trunc(iw/8)*8:-8" \
<output>
De plus, si la largeur est déjà divisible par 8, il n'y aura aucun changement dans la largeur de sortie et aucune erreur de FFmpeg.
Une explication de la syntaxe de la balance, rappelant que la syntaxe est -vf scale=width:height
:
1. Calcul de la largeur de sortie:
iw/8
: La largeur du flux vidéo en entrée sera divisée par 8. Ainsi, une largeur d'origine de 690 créerait un nombre 86.25trunc
: le nombre 86.25 serait "tronqué" à 86*8
: 86 serait multiplié par 8 pour donner une largeur finale de 688 qui est bien sûr divisible par 8!2. Calcul de la hauteur de sortie:
-8
: FFmpeg calculera une hauteur qui est divisible par 8 mais qui conserve également le format correct du fichier d'origine.Dans un monde parfait, le codage hevc est exécuté avec des unités de codage de 8x8, 16x16, 32x32, etc., et cette syntaxe le garantit. Plus de détails sur cette ici ...
Références:
L'obtention de la largeur est relativement simple avec mediainfo
. Si vous ne l'avez pas, vous pouvez l'installer avec Sudo apt-get install mediainfo
width=$(mediainfo '--Inform=Video;%Width%' $filename)
Détermination de la divisibilité par 8 peut être fait via
if [ $(( $width % 8 )) -eq 0 ] ; then
echo "Your number is divisible by 8 – you may convert it”
else
echo "Video width is not divisible by 8 – it needs scaling to re-encode it."
fi
Une approche beaucoup plus simple et plus rapide inspirée de @ andrew.46 et un peu plus de recherche et de test consiste à laisser ffmpeg faire le travail avec
ffmpeg -i $inputfilename -c:a copy -c:v libx265 -preset veryfast -x265-params crf=25 -vf scale=-8:ih $outputfilename
le paramètre -vf scale=-8:ih
garantit que la largeur est divisible par 8 (-8) et utilise la hauteur d'entrée (ih) en conséquence pour conserver le rapport de format.
Sources: man mediainfo
https://stackoverflow.com/questions/7376477/geting-video-information-from-medianfo
Comment puis-je déterminer si une vidéo peut être encodée avec succès avec l'encodage HEVC (x265)