Como reduzir a amostra de 4k para 1080p usando ffmpeg, mantendo a qualidade?

20

Tenho algumas imagens 4K 3840x2160 em formato MP4 que preciso reduzir para 1080p. Eu tentei correr

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

mas o resultado é uma qualidade muito ruim, com a imagem inteira sendo composta de "ladrilhos" quadrados como se eu estivesse ampliando 4: 1.

Aqui está a saída da execução deste comando:

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%

Sei por experiência que o ffmpeg é uma excelente ferramenta, por isso devo estar estragando as opções / parâmetros de alguma forma ...

Como posso fazer isso?

Lara Michaels
fonte
Por favor, mostre a saída completa e completa do console do seu comando. Você pode apenas codificar um segmento curto, então adicione -t 10para fazer uma saída de 10 segundos. Por que você deseja fazer o downscale? Qual é o caso de uso para sua saída escalada? Esta informação me ajudará a fornecer uma resposta mais precisa.
Llogan
@LordNeckbeard Acabei de adicionar a saída do console. Quero diminuir a escala para poder compartilhar esses clipes com mais facilidade com as pessoas que estão trabalhando comigo.
Lara michaels
1
Não se esqueça -c:a copy, pois você não deseja ou precisa recodificar o fluxo de áudio. Use -map 0para copiar qualquer metadado do capítulo ou outras coisas. (ffmpeg leva apenas 1 vid + 1 aud por padrão.)
Peter Cordes
1
Além disso, -sws_flags lanczos+print_infousará algo melhor em escala do que o padrão (acho que bilinear). A resposta do stlb cobre a parte de codificação de vídeo do processo.
Peter Cordes
2
@PeterCordes Como alternativa scale=1920:-2:flags=lanczos,. Eu também mencionaria a -2escala for em minha resposta inexistente. Para quem não sabe, você pode colocar -2largura ou altura, e ele fornecerá automaticamente o valor correto, preservando a proporção e tornando o valor divisível por 2 (exigido pela libx264 para saídas yuv420p).
llogan

Respostas:

17

As configurações padrão do ffmpeg são de qualidade muito baixa e, como você não especifica nenhum parâmetro de codec ou qualidade, ele usa apenas os padrões (não sei por que os desenvolvedores não corrigem isso porque geram muitas perguntas nos fóruns). em toda parte).

Edit : os padrões agora são bastante saudáveis. Com uma compilação recente do ffmpeg, você não precisa especificar nada além de arquivos de entrada e saída para obter bons resultados utilizáveis. Você pode, é claro, ajustar o desejo do seu coração.

Tente adicionar -c:v libx264 -crf 20 -preset slowao comando.

  • -c:v libx264 diz para ele usar o codificador libx264,
  • crf 20 usa o quantizador Constant Rate Factor (que paradoxalmente significa taxa de bits variável, mas qualidade constante) com um valor de 20 (qualidade muito boa; quanto menor for a melhor qualidade / arquivos maiores, maior é o porcaria / menor),
  • a slowpredefinição é um atalho para várias configurações do codificador, o que significa que ela coloca um pouco mais de esforço do que o padrão (médio).

Você pode ajustar essas configurações, consulte o guia de codificação h.264 para obter instruções sobre quais botões girar.

E se você estiver usando o áudio como está, adicione c:a copy. Isso fará uma cópia direta do fluxo de áudio sem recodificação.

stib
fonte
Os padrões dependem do codificador. A libx264 é geralmente usada para saída MP4 por padrão e produz uma saída de boa qualidade sem opções adicionais, mas a compilação ffmpeg na pergunta parece não suportar esse codificador e, portanto, usa o codificador antigo que mpeg4produz o vídeo MPEG-4 Parte 2 e os padrões para ele eram mais saudáveis ​​durante o auge (como 320x240, etc.).
Llogan
É bom saber que a libx264 é o padrão agora.
stib 23/02
Eu diria que crf 20 é muito danado bom. 18 é funcionalmente sem perdas. Eu faço a maioria dos meus vídeos aos 23 anos
#
A maior parte do meu trabalho é exibida em dispositivos de reprodução que trabalham localmente a partir de um cartão SD. Como não preciso otimizar muito o tamanho, deixo a qualidade o mais alta possível. Eu concordo, eu discaria se estivesse entregando pela web.
STIB
Isso não me ajudou. Eu ainda tenho estranheza em blocos onde quer que ocorra movimento no vídeo. crf de 18, predefinido para diminuir. 2.7k-> 1080p.
rewolf
0

Use avconv se você quiser:

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