web-dev-qa-db-fra.com

Maintenir le rapport d'aspect FFMPEG

J'ai besoin de convertir un tas de fichiers vidéo en utilisant ffmpeg. J'exécute un fichier bash qui convertit bien tous les fichiers, mais il y a un problème si un fichier converti n'est pas au format 16: 9. Comme je fixe la taille de l'écran à -s 720x400, si le rapport d'aspect de l'original est 4: 3, le ffmpeg crée un fichier de sortie 16: 9, en vissant le rapport d'aspect.

Existe-t-il un paramètre permettant de définir un rapport hauteur/largeur comme paramètre principal, la taille étant ajustée (par exemple, en fixant une dimension X ou Y uniquement)?

41
0-alpha

Je l'ai demandé il y a longtemps, mais j'ai en fait une solution que je ne connaissais pas à l'époque - afin de conserver le rapport d'aspect, vous devez utiliser l'échelle du filtre vidéo, qui est un outil très puissant filtre.

Vous pouvez simplement l'utiliser comme ceci:

-vf "scale=640:-1" 

Ce qui fixera la largeur et fournira la hauteur requise pour conserver le rapport hauteur/largeur. Mais vous pouvez également utiliser de nombreuses autres options et même des fonctions mathématiques, consultez la documentation ici - http://ffmpeg.org/ffmpeg.html#scale

20
0-alpha
-vf "scale=640:-1"

fonctionne très bien jusqu'à ce que vous rencontriez une erreur

[libx264 @ 0x2f08120] height not divisible by 2 (640x853)

Donc, l'approche la plus générique consiste à utiliser des expressions de filtre:

scale=640:trunc(ow/a/2)*2

Il prend la largeur de sortie (ow), le divise par le rapport d'aspect (a), divise par 2, tronque les chiffres après le point décimal et multiplie par 2. Il garantit que la hauteur résultante est divisible par 2.

Crédits à ffmpeg trac

[~ # ~] mise à jour [~ # ~]

Comme les commentaires l'ont souligné, la manière la plus simple serait d'utiliser -vf "scale=640:-2". Crédits à @BradWerth pour une solution élégante

58
mente

Par exemple:

format d'image 1920x1080 16: 9 => aspect 640x480 4: 3:

ffmpeg -y -i import.media -aspect 16:9 scale=640x360,pad=640:480:0:60:black output.media

format 16: 9, largeur de taille 640 pixels => hauteur 360 pixels:
Avec une taille de sortie finale de 640x480 et une image noire de 60 pixels (en haut et en bas):

"-vf scale=640x360,pad=640:480:0:60:black"
28
cool2ikou

Bien que la plupart de ces réponses soient excellentes, je cherchais une commande qui pourrait redimensionner à une dimension cible (largeur ou hauteur) tout en conservant le rapport hauteur/largeur. J'ai pu accomplir cela en utilisant Expression Evaluation de ffmpeg.

Voici le filtre vidéo pertinent, avec une dimension cible de 512:

-vf "thumbnail,scale='if(gt(iw,ih),512,trunc(oh*a/2)*2)':'if(gt(iw,ih),trunc(ow/a/2)*2,512)'"


Pour la largeur de sortie:

'if(gt(iw,ih),512,trunc(oh*a/2)*2)'

Si la largeur est supérieure à la hauteur, renvoyez la cible, sinon, renvoyez la largeur proportionnelle.


Pour la hauteur de sortie:

'if(gt(iw,ih),trunc(ow/a/2)*2,512)'

Si la largeur est supérieure à la hauteur, renvoyez la hauteur proportionnelle, sinon, renvoyez la cible.

9
Charlie

Utilisation force_original_aspect_ratio, depuis le ffmpeg trac :

ffmpeg -i input.mp4 -vf scale=720:400:force_original_aspect_ratio=decrease output.mp4
9
xmedeko

Si vous essayez d'ajuster une boîte englobante, alors utiliser force_original_aspect_ratio Selon réponse de xmedeko est un bon point de départ.

Cependant, cela ne fonctionne pas si votre vidéo d'entrée a une taille étrange et vous encodez dans un format qui nécessite que les dimensions soient divisibles par 2, résultant dans une erreur.

Dans ce cas, vous pouvez utiliser l'évaluation d'expression dans la fonction scale, comme celle utilisée dans réponse de Charlie .

En supposant une boîte englobante de sortie de 720x400:

-vf "scale='trunc(min(1,min(720/iw,400/ih))*iw/2)*2':'trunc(min(1,min(720/iw,400/ih))*ih/2)*2'"

Pour décomposer cela:

  • min(1,min(720/iw,400/ih) trouve le facteur d'échelle pour tenir dans le cadre de délimitation (de ici ), le contraignant à un maximum de 1 pour ne garantir que des réductions d'échelle, et
  • trunc(<scaling factor>*iw/2)*2 et trunc(<scaling factor>*iw/2)*2 s'assurent que les dimensions sont divisibles par 2 en divisant par 2, faisant du résultat un entier, puis en le multipliant par 2.

Cela élimine le besoin de trouver les dimensions de la vidéo d'entrée avant l'encodage.

6
tvStatic

vous pouvez utiliser ffmpeg -i pour obtenir les dimensions du fichier d'origine et l'utiliser dans vos commandes pour le codage. Sur quelle plateforme utilisez-vous ffmpeg?

0
box86rowh