¿Cómo reducir la resolución de 4k a 1080p usando ffmpeg manteniendo la calidad?

21

Tengo algunas imágenes 4K 3840x2160 en formato MP4 que necesito reducir a 1080p. Intenté correr

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

pero el resultado es de muy baja calidad, con toda la imagen compuesta de "mosaicos" cuadrados como si estuviese ampliando 4: 1.

Aquí está el resultado de ejecutar este 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%

Sé por experiencia que ffmpeg es una herramienta excelente, por lo que debo estar arruinando las opciones / parámetros de alguna manera ...

¿Cómo puedo hacer esto?

lara michaels
fuente
Muestre la salida de consola completa y completa de su comando. Simplemente puede codificar un segmento corto, así que agregue -t 10para hacer una salida de 10 segundos. ¿Por qué quieres reducir? ¿Cuál es el caso de uso para su salida escalada? Esta información me ayudará a proporcionar una respuesta más precisa.
llogan
@ LordNeckbeard Acabo de agregar la salida de la consola. Quiero reducir para poder compartir más fácilmente estos clips con las personas que trabajan conmigo.
lara michaels
1
No lo olvide -c:a copy, ya que no desea o no necesita volver a codificar la transmisión de audio. Úselo -map 0para copiar los metadatos de cualquier capítulo u otras cosas. (ffmpeg solo toma 1 vid + 1 aud por defecto.)
Peter Cordes
1
Además, -sws_flags lanczos+print_infousará un algoritmo de escala mejor que el predeterminado (creo que bilineal). La respuesta de stlb cubre la parte de codificación de video del proceso.
Peter Cordes
2
@PeterCordes Alternativamente, scale=1920:-2:flags=lanczos. También iba a mencionar la -2escala for en mi respuesta inexistente. Para aquellos que no lo saben, puede poner el -2ancho o la altura, y proporcionará automáticamente el valor correcto mientras conserva la relación de aspecto y hace que el valor sea divisible por 2 (requerido por libx264 para salidas yuv420p).
llogan

Respuestas:

17

La configuración predeterminada para ffmpeg es de muy baja calidad, y dado que no especifica ningún códec o parámetros de calidad, solo usa los valores predeterminados (no sé por qué los desarrolladores no arreglan eso porque genera muchas preguntas en los foros En todas partes).

Editar : los valores predeterminados ahora son bastante sensatos. Con una compilación reciente de ffmpeg, no necesita especificar nada más que archivos de entrada y salida para lograr buenos resultados utilizables. Puede, por supuesto, ajustar el deseo de su corazón.

Intenta agregar -c:v libx264 -crf 20 -preset slowal comando.

  • -c:v libx264 le dice que use el codificador libx264,
  • crf 20 utiliza el cuantificador de Factor de velocidad constante (que paradójicamente significa velocidad de bits variable, pero calidad constante) con un valor de 20 (bastante buena calidad; menor es mejor calidad / archivos más grandes, mayor es más desagradable / más pequeño),
  • el slowpreajuste es un acceso directo para un grupo de configuraciones de codificador que significa que le pone un poco más de esfuerzo que el predeterminado (medio).

Puede ajustar esta configuración, consulte la guía de codificación h.264 para obtener instrucciones sobre qué botones girar.

Y si está utilizando el audio tal cual, agregue c:a copy. Eso hará una copia directa de la transmisión de audio sin volver a codificar.

stib
fuente
Los valores predeterminados dependen del codificador. libx264 generalmente se usa para la salida MP4 de manera predeterminada, y produce una salida de buena calidad sin opciones adicionales, pero la compilación ffmpeg en la pregunta parece no admitir este codificador y, por lo tanto, usa el codificador antiguo que mpeg4produce video MPEG-4 Parte 2, y los valores predeterminados para él eran más sanos durante su apogeo (como para 320x240, etc.).
llogan
Es bueno saber que libx264 es el valor predeterminado ahora.
stib
Yo diría que el CRF 20 es bastante maldito bueno. 18 es funcionalmente sin pérdidas. Hago la mayoría de mis videos a las 23.
user24601
La mayor parte de mi trabajo se muestra en dispositivos de reproducción que trabajan localmente desde una tarjeta SD. No necesito optimizar mucho el tamaño, por lo que dejo la calidad lo más alta posible. Estoy de acuerdo, lo marcaría si estuviera entregando en la web.
stib
Esto no me ayudó. Todavía tengo rarezas en bloques donde se produce movimiento en el video. crf de 18, preestablecido para ralentizar. 2.7k-> 1080p.
rewolf
0

Use avconv si desea:

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