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

Tengo material de archivo 4K 3840x2160 en formato MP4 que necesito reducir a 1080p. traté de correr

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

pero el resultado es de muy mala calidad, con toda la imagen compuesta de "mosaicos" cuadrados como si estuviera 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, así que debo estar arruinando las opciones/parámetros de alguna manera...

¿Cómo puedo hacer esto?

Muestre la salida completa y completa de la consola de su comando. Solo puede codificar un segmento corto, así que agregue -t 10para hacer una salida de 10 segundos. ¿Por qué quieres bajar de escala? ¿Cuál es el caso de uso para su salida escalada? Esta información me ayudará a proporcionar una respuesta más precisa.
@LordNeckbeard Acabo de agregar la salida de la consola. Quiero reducir la escala para poder compartir más fácilmente estos clips con las personas que trabajan conmigo.
Parece que se omitieron algunas cosas. También estoy buscando la información de la versión y cómo se configuró. ¿Puedes mostrar la salida completa?
Todavía proporcionaré una respuesta con información adicional si se proporciona la salida completa de la consola.
No lo olvide -c:a copy, ya que no desea ni 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).
Además, -sws_flags lanczos+print_infoutilizará un algoritmo de escala mejor que el predeterminado (creo que es bilineal). La respuesta de stlb cubre la parte de codificación de video del proceso.
@PeterCordes Alternativamente, scale=1920:-2:flags=lanczos. También iba a mencionar la -2escala for en mi respuesta inexistente. Para aquellos que no saben, puede poner -2ancho o alto, 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).
-sws_flagsusará lanczos para escalar croma al pasar de 4:4:4: a 4:2:0 o viceversa, por ejemplo. Así que creo que no es una mala idea tenerlo en su línea de comandos en todo momento, en caso de que haga algo que inserte automáticamente un filtro de escala. Pero sí, altura calculada automáticamente = ganar. No siempre obtendrá píxeles perfectamente cuadrados en su salida, si la altura requerida no es un múltiplo de 2 (o incluso un número entero), pero ffmpeg establecerá la relación de aspecto de la pantalla en la salida para que los jugadores la escalan correctamente si escalar hacia arriba o hacia abajo.

Respuestas (3)

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 solucionan eso porque genera muchas preguntas en los foros En todas partes).

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

Intente agregar al comando.-c:v libx264 -crf 20 -preset slow

  • -c:v libx264le dice que use el codificador libx264, este es el predeterminado ahora, no es necesario especificarlo
  • crf 20utiliza el cuantificador Constant Rate Factor (que paradójicamente significa tasa de bits variable, pero calidad constante) con un valor de 20 (bastante buena calidad; menor es mejor calidad/archivos más grandes, mayor es peor/más pequeño); el valor predeterminado es 23,
  • el slowajuste preestablecido es un atajo para un montón de configuraciones de codificador, lo que significa que pone un poco más de esfuerzo que el predeterminado (medio). Tenga en cuenta que los ajustes preestablecidos de velocidad no cambian la calidad del archivo codificado, solo la eficiencia, lo que significa que una codificación más lenta dará como resultado un archivo más pequeño de la misma calidad y una codificación más rápida significará un archivo más grande de la misma calidad.

Puede modificar estas configuraciones, consulte la guía de codificación h.264 para obtener instrucciones sobre qué perillas 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.

Los valores predeterminados dependen del codificador. libx264 generalmente se usa para la salida MP4 de forma predeterminada, y produce una salida de buena calidad sin opciones adicionales, pero la compilación ffmpeg en la pregunta parece no ser compatible con este codificador y, por lo tanto, usa el codificador antiguo mpeg4que produce video MPEG-4 Parte 2, y los valores predeterminados eran más sensatos durante su apogeo (como 320x240, etc.).
Es bueno saber que libx264 es el predeterminado ahora.
Yo diría que crf 20 es bastante bueno . 18 es funcionalmente sin pérdidas. Hago la mayoría de mis videos a los 23.
La mayor parte de mi trabajo se muestra en dispositivos de reproducción que funcionan localmente desde una tarjeta SD. No necesito optimizar mucho el tamaño, así que dejo la calidad lo más alta que puedo. Estoy de acuerdo, lo reduciría si estuviera entregando a través de la web.
Esto no me ayudó. Todavía tengo rarezas en bloques dondequiera que ocurra movimiento en el video. crf de 18, preajustado a lento. 2.7k->1080p.
@rewolf publica una pregunta, en lugar de preguntar en los comentarios.
@stib No estoy haciendo una pregunta. Estoy diciendo que esta no es una respuesta definitiva al problema planteado (o uno de la misma naturaleza). Eso es útil para otros en la misma posición.
¿Qué sucede si la calidad ya es inferior a 1080 y no queremos mejorarla?
@OliverDixon No estoy seguro de lo que estás preguntando. Si la resolución es inferior a 1080p y no desea aumentarla, ¿puede mostrarla en su resolución actual?
@stib Encontré una solución usando 'min'. Estaba viendo problemas de rendimiento con esto porque los videos de baja calidad intentaban mejorar de los usuarios.

Convierta 4k a 1080 (sin cambios en el códec)

ffmpeg -i input4kvid.mp4 -vf scale=1920:1080 -c:a copy output1080vid.mp4

Convierta h.264 a h.265 (sin cambios en la resolución)

ffmpeg -i input.mp4 -c:v libx265 -vtag hvc1 -c:a copy output.mp4

Convertir 4k (h.264) a 1080 (h.265)

  • Reducción de escala + Cambio en el códec de compresión
ffmpeg -i input.mp4 -c:v libx265 -vtag hvc1 -vf scale=1920:1080 -crf 20 -c:a copy output.mp4

Opciones explicadas

-iingrese el nombre del archivo o la ruta del archivo

-c:v libx265 -vtag hvc1seleccionando compresión. El valor predeterminado eslibx264

-vf scale=1920:1080especificando la resolución de salida

-c:a copycopiar audio tal como está sin ningún tipo de compresión

-preset slowsolicite al algoritmo de compresión que tome más tiempo y busque más áreas para la compresión. El valor predeterminado es medium. Otras opciones son faster, fast, medium, slow,slower

-crf 20Calidad de compresión

-crf 0alta calidad, baja compresión, archivo grande

-crf 23defecto

-crf 51baja calidad, alta compresión, archivo pequeño

Usa avconv si quieres:

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