Comment sous-échantillonner 4k à 1080p en utilisant ffmpeg tout en maintenant la qualité?

21

J'ai des séquences 4K 3840x2160 au format MP4 que je dois ramener à 1080p. J'ai essayé de courir

ffmpeg -i orig.mp4 -vf scale=1920:1080 smaller.mp4  

mais le résultat est de très mauvaise qualité, l'image entière étant composée de "tuiles" carrées comme si j'agrandissais 4: 1.

Voici le résultat de l'exécution de cette commande:

Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'origs/P1000003.MP4':
  Metadata:
    major_brand     : mp42
    minor_version   : 1
    compatible_brands: mp42avc1
    creation_time   : 2015-02-19 17:10:38
  Duration: 00:05:14.48, start: 0.000000, bitrate: 95903 kb/s
    Stream #0.0(und): Video: h264 (High), yuvj420p, 3840x2160 [PAR 1:1 DAR 16:9], 95792 kb/s, 25 fps, 25 tbr, 90k tbn, 50 tbc
    Metadata:
      creation_time   : 2015-02-19 17:10:38
    Stream #0.1(und): Audio: aac, 48000 Hz, stereo, s16, 125 kb/s
    Metadata:
      creation_time   : 2015-02-19 17:10:38
Incompatible pixel format 'yuvj420p' for codec 'mpeg4', auto-selecting format 'yuv420p'
[buffer @ 0x22a3420] w:3840 h:2160 pixfmt:yuvj420p
[scale @ 0x22a3ce0] w:3840 h:2160 fmt:yuvj420p -> w:1920 h:1080 fmt:yuv420p flags:0x4
Output #0, mp4, to '1-short.mp4':
  Metadata:
    major_brand     : mp42
    minor_version   : 1
    compatible_brands: mp42avc1
    creation_time   : 2015-02-19 17:10:38
    encoder         : Lavf53.21.1
    Stream #0.0(und): Video: mpeg4, yuv420p, 1920x1080 [PAR 1:1 DAR 16:9], q=2-31, 200 kb/s, 25 tbn, 25 tbc
    Metadata:
      creation_time   : 2015-02-19 17:10:38
    Stream #0.1(und): Audio: libvo_aacenc, 48000 Hz, stereo, s16, 200 kb/s
    Metadata:
      creation_time   : 2015-02-19 17:10:38
Stream mapping:
  Stream #0.0 -> #0.0
  Stream #0.1 -> #0.1
Press ctrl-c to stop encoding
frame=  125 fps=  6 q=31.0 Lsize=     968kB time=5.00 bitrate=1586.7kbits/s    
video:842kB audio:123kB global headers:0kB muxing overhead 0.421047%

Je sais par expérience que ffmpeg est un excellent outil, donc je dois visser les options / paramètres d'une manière ou d'une autre ...

Comment puis-je faire ceci?

lara michaels
la source
Veuillez afficher la sortie console complète de votre commande. Vous pouvez simplement encoder un court segment, alors ajoutez-le -t 10pour faire une sortie de 10 secondes. Pourquoi voulez-vous réduire l'échelle? Quel est le cas d'utilisation de votre sortie mise à l'échelle? Ces informations m'aideront à fournir une réponse plus précise.
llogan
@LordNeckbeard Je viens d'ajouter la sortie console. Je souhaite réduire l'échelle afin de pouvoir partager plus facilement ces clips avec des personnes qui travaillent avec moi.
lara michaels
1
N'oubliez pas -c:a copy, car vous ne voulez pas ou n'avez pas besoin de ré-encoder le flux audio. Utilisez-le -map 0pour copier les métadonnées d'un chapitre ou d'autres éléments. (ffmpeg ne prend que 1 vidéo + 1 aud par défaut.)
Peter Cordes
1
En outre, -sws_flags lanczos+print_infoutilisera un meilleur algo de mise à l'échelle que la valeur par défaut (bilinéaire je pense). La réponse de stlb couvre la partie encodage vidéo du processus.
Peter Cordes
2
@PeterCordes Alternativement, scale=1920:-2:flags=lanczos. J'allais également mentionner l' -2échelle pour dans ma réponse inexistante. Pour ceux qui ne savent pas, vous pouvez mettre -2en largeur ou en hauteur, et cela fournira automatiquement la valeur correcte tout en préservant le rapport d'aspect et en rendant la valeur divisible par 2 (requis par libx264 pour les sorties yuv420p).
llogan

Réponses:

17

Les paramètres par défaut de ffmpeg sont de très faible qualité, et puisque vous ne spécifiez aucun codec ou paramètre de qualité, il utilise simplement les valeurs par défaut (je ne sais pas pourquoi les développeurs ne corrigent pas cela car cela génère beaucoup de questions sur les forums partout).

Edit : les valeurs par défaut sont maintenant assez saines. Avec une version récente de ffmpeg, vous n'avez pas besoin de spécifier autre chose que des fichiers d'entrée et de sortie pour obtenir de bons résultats utilisables. Vous pouvez, bien sûr, modifier le désir de votre cœur.

Essayez d'ajouter -c:v libx264 -crf 20 -preset slowà la commande.

  • -c:v libx264 lui dit d'utiliser l'encodeur libx264,
  • crf 20 utilise le quantificateur à facteur de débit constant (ce qui signifie paradoxalement un débit binaire variable, mais une qualité constante) avec une valeur de 20 (assez bonne qualité; inférieur est de meilleure qualité / fichiers plus gros, plus élevé est plus crappier / plus petit),
  • le slowpréréglage est un raccourci pour un tas de paramètres d'encodeur, ce qui signifie qu'il y met un peu plus d'effort que celui par défaut (moyen).

Vous pouvez modifier ces paramètres, consultez le guide d'encodage h.264 pour obtenir des instructions sur les boutons à manipuler.

Et si vous utilisez l'audio tel quel, ajoutez-le c:a copy. Cela fera une copie directe du flux audio sans ré-encodage.

stib
la source
Les valeurs par défaut dépendent de l'encodeur. libx264 est généralement utilisé pour la sortie MP4 par défaut, et il produit une sortie de bonne qualité sans options supplémentaires, mais la construction ffmpeg dans la question semble ne pas prendre en charge cet encodeur et utilise donc l'ancien encodeur mpeg4produisant la vidéo MPEG-4 Part 2, et les valeurs par défaut étaient plus saines à son apogée (comme pour 320x240, etc.).
llogan
Il est bon d'entendre que libx264 est la valeur par défaut maintenant.
stib
Je dirais que le CRF 20 est sacrément bon. 18 est fonctionnellement sans perte. Je fais la plupart de mes vidéos à 23
ans
La plupart de mon travail est affiché sur des appareils de lecture fonctionnant localement à partir d'une carte SD. Je n'ai pas besoin d'optimiser beaucoup pour la taille, donc je laisse la qualité aussi élevée que possible. Je suis d'accord, je composerais si je livrais sur le Web.
stib
Cela ne m'a pas aidé. J'ai toujours une étrangeté polyédrique partout où un mouvement se produit dans la vidéo. crf de 18, préréglé pour ralentir. 2,7k-> 1080p.
rewolf
0

Utilisez avconv si vous voulez:

avconv -i 4kfile.mp4 -s hd1080 -c:v libx264 -c:a copy fullhdfile.mp4
Guray Celik
la source