web-dev-qa-db-fra.com

Redimensionner des vidéos avec ffmpeg/avconv pour les adapter à un lecteur de taille statique

J'ai un lecteur vidéo html 5 de 700 pixels de large et 400 pixels de haut. J'essaie d'utiliser avconv pour utiliser ffmpeg pour redimensionner (tout en conservant le rapport hauteur/largeur) et pour m'assurer qu'il s'intègre parfaitement dans mon lecteur.

L'entrée peut être un fichier de n'importe quelle taille, je dois donc redimensionner les plus gros mais centrer les plus petits avec des barres noires. Jusqu'ici, j'ai essayé: -s et -aspect, j'ai vu pad être utilisé avec le commutateur -vf mais je ne comprends pas comment cela fonctionne assez pour obtenir ce dont j'ai besoin.

Images

Ceci est une idée approximative de ce dont j'ai besoin. Je ne sais pas si c'est même possible. C'est presque comme les max-width/max-height de CSS. Je me rends bien compte que ce n'est peut-être qu'un mélange de mots, mais si quelqu'un comprenait de quoi je parle, j'apprécierais de l'aide, merci.

commande avconv:

avconv -y -i control.avi -vcodec libx264 -b 2000k -bufsize 20M -acodec aac -strict experimental -ar 44100 -ab 256k bigbuck_out.mp4

59
Jamie Taylor

Une méthode simple consiste à utiliser l'option force_original_aspect_ratio dans le filtre d'échelle .

original image
Image originale. Représente une vidéo au format 640x480, 4: 3.

Dans ces exemples, l'image d'origine sera mise à l'échelle pour tenir dans une sortie au format 16: 9 tout en préservant le format d'origine. Pour ce faire, vous pouvez soit:

Pilier ou boîte aux lettres

pillarboxed image
Image pilarbox. Insertion d’une entrée 640x480 (4: 3) dans une sortie 1280x720 (16: 9).

ffmpeg -i input -vf "scale=1280:720:force_original_aspect_ratio=decrease,pad=1280:720:(ow-iw)/2:(oh-ih)/2" output
  • Cela va redimensionner l'image. Si vous voulez éviter la montée en gamme, voir l'exemple ci-dessous.

  • Le Letterboxing se produirait à la place si le format d'image en entrée est plus large que le format d'image en sortie. Par exemple, une entrée dont le format d'image correspond à 2,35: 1 dans une sortie 16: 9 entraîne un Letterboxing.

Comme ci-dessus mais sans upscaling

no upscaling
640x480 (4: 3) entrée en sortie 1280x720 (16: 9) sans conversion ascendante.

ffmpeg -i input -vf "scale='min(1280,iw)':min'(720,ih)':force_original_aspect_ratio=decrease,pad=1280:720:(ow-iw)/2:(oh-ih)/2" output

Surgir

enter image description here
Image recadrée. Rapport d'aspect d'entrée 4: 3, rapport d'aspect de sortie 16: 9.

ffmpeg -i input -vf "scale=1280:720:force_original_aspect_ratio=increase,crop=1280:720" output
46
llogan

Voici la commande qui ajouterait pillar ou letterboxing pour une largeur de sortie fixe. C'est un peu long, mais vous devrez spécifier le rembourrage d'une manière ou d'une autre.

Tout d’abord, dans votre Shell, définissez la largeur et la hauteur de la sortie:

width=700
height=400

Puis lancez la commande:

ffmpeg -i in.mp4 -filter:v "scale=iw*min($width/iw\,$height/ih):ih*min($width/iw\,$height/ih), pad=$width:$height:($width-iw*min($width/iw\,$height/ih))/2:($height-ih*min($width/iw\,$height/ih))/2" out.mp4

Ceci est réduit au strict nécessaire pour redimensionner et garnir: ajoutez vos autres options vidéo et audio à votre guise. Notez que les nombres pour width et height doivent être divisibles par 2 pour fonctionner avec la plupart des codecs.

Voici l'explication de ce qui se passe:

  • Mise à l'échelle:
    • Nous devons d’abord déterminer s’il faut redimensionner en largeur ou en hauteur.
    • Pour ce faire, nous divisons la largeur de sortie par la largeur d'entrée et la hauteur de sortie par la hauteur d'entrée. Cela nous donnera les facteurs d'échelle pour chaque dimension.
    • Nous vérifions ensuite lequel est le plus bas (avec min()) et choisissons uniquement ce facteur pour le redimensionnement.
    • Enfin, nous multiplions la largeur et la hauteur en entrée par ce facteur (iw*min(…):ih*min(…)).
  • Rembourrage:
    • $width:$height est la largeur et la hauteur de sortie
    • Pour déterminer où placer la vidéo obtenue, nous devons soustraire la largeur mise à l'échelle de la largeur de sortie maximale et la hauteur mise à l'échelle de la hauteur de sortie maximale.
    • Les largeurs et les hauteurs mises à l'échelle sont les expressions du filtre scale.
    • Nous divisons le décalage résultant par 2 pour ajouter des bordures des deux côtés.
60
slhck

Il me semble que vous devez le faire en trois étapes:

  1. Vérifier le format d'image
  2. Redimensionnez les vidéos avec un DAR> 7/4 en largeur (modifiez la largeur en 700 et redimensionnez la hauteur pour conserver le rapport de format) et redimensionnez les vidéos avec un DAR <7/4 en hauteur
  3. Compilez la vidéo afin qu'elle tienne dans l'espace 700: 400.

FFmpeg/avconv peut effectuer la mise à l'échelle/le remplissage avec des filtres vidéo en une seule étape, en transcodant une seule fois. Par exemple, pour prendre une vidéo 16: 9, redimensionnez-la en largeur, puis en letterbox, les résultats:

ffmpeg -i input.avi -filter:v 'scale=700:-1,pad=700:400:(ow-iw)/2:(oh-ih)/2' \
-c:v libx264 -b:v 2000k -bufsize 20M -c:a aac -strict experimental -ar 44100 -b:a 256k output.mp4

... mais pour la première étape (détecter le rapport de format et le comparer au 7: 4 requis), vous devrez utiliser un script quelconque.

ffprobe input.avi 2>&1 | sed -n '/Video:/s/.*DAR \([0-9]*:[0-9]*\)].*/\1/p'

... vous obtiendrez le format de la vidéo, qui ressemblera à "16: 9" ou "4: 3". Dans un script bash, j'utiliserais quelque chose comme:

#!/bin/bash

##  Get the aspect ratio in the form x/y
dar=$(ffprobe test0.mp4 2>&1 | sed -n '/Video:/s/.*DAR \([0-9]*:[0:9]*\)].*/\1/p' | sed 's|:|/|')
##  use bc to do x/y*100 (bash can't handle floats)
DAR=$(bc <<< 'scale=2; $dar*100')

##  ${DAR%.00} will remove the trailing .00 left by bc
if [ ${DAR%.00} -ge 175 ]; then
    ffmpeg -i "$1" -filter:v 'scale=700:-1,pad=700:400:(ow-iw)/2:(oh-ih)/2' \
    -c:v libx264 -b:v 2000k -bufsize 20M -c:a aac -strict experimental -ar 44100 -b:a 256k "${1%.*}.mp4
else
    ffmpeg -i "$1" -filter:v 'scale=-1:400,pad=700:400:(ow-iw)/2:(oh-ih)/2' \
    -c:v libx264 -b:v 2000k -bufsize 20M -c:a aac -strict experimental -ar 44100 -b:a 256k "${1%.*}.mp4
fi

exit 0

Évidemment, vous devrez l'adapter à vos besoins.

8
evilsoup