¿Cómo puedo usar FFmpeg para reducir la calidad del video H264 pero mantenerlo en formato H264?

8

Soy un novato en la edición de videos, así que perdóname si te pido algo ridículo.

Estoy obteniendo videoclips de un decodificador. Los clips son archivos AVI:

Resolution: 1920 x 1080
Frames Per Second: 60
Video Format: ITU H.264
Audio Format: MPEG 1 Audio, Layer 3 (MP3)

La resolución y el FPS están mucho más allá de lo que necesito, así que estoy tratando de ejecutar un comando para reducir las cosas:

ffmpeg -i highres.avi -r 30 -s 960x540 lowerres.avi

Esto tiene éxito al darme la resolución deseada, la velocidad de fotogramas y un tamaño de archivo más bajo, pero también degradó la calidad mucho más de lo que esperaba.

Miré el nuevo archivo y descubrí que, por alguna razón, FFmpeg convirtió el formato utilizado:

Video Format: FFmpeg MPEG-4
Audio Format: MPEG 1 Audio, Layer 2

No me queda claro por qué no usaría los mismos formatos de salida que los formatos de entrada. Traté de usar este comando para forzarlo a usar H.264:

ffmpeg -i highres.avi -r 30 -s 960x540 -f h264 lowerresforceh264.avi

Desafortunadamente, falló con el siguiente resultado:

ffmpeg version 0.7.3-4:0.7.3-0ubuntu0.11.10.1, Copyright (c) 2000-2011 the Libav developers
  built on Jan  4 2012 16:21:50 with gcc 4.6.1
  configuration: --extra-version='4:0.7.3-0ubuntu0.11.10.1' --arch=i386 --prefix=/usr --enable-vdpau --enable-bzlib --enable-libgsm --enable-libschroedinger --enable-libspeex --enable-libtheora --enable-libvorbis --enable-pthreads --enable-zlib --enable-libvpx --enable-runtime-cpudetect --enable-vaapi --enable-gpl --enable-postproc --enable-swscale --enable-x11grab --enable-libdc1394 --enable-shared --disable-static
  WARNING: library configuration mismatch
  avutil      configuration: --extra-version='4:0.7.3ubuntu0.11.10.1' --arch=i386 --prefix=/usr --enable-vdpau --enable-bzlib --enable-libgsm --enable-libschroedinger --enable-libspeex --enable-libtheora --enable-libvorbis --enable-pthreads --enable-zlib --enable-libvpx --enable-runtime-cpudetect --enable-vaapi --enable-libopenjpeg --enable-gpl --enable-postproc --enable-swscale --enable-x11grab --enable-libdirac --enable-libmp3lame --enable-librtmp --enable-libx264 --enable-libxvid --enable-libvo-aacenc --enable-version3 --enable-libvo-amrwbenc --enable-version3 --enable-libdc1394 --shlibdir=/usr/lib/i686/cmov --cpu=i686 --enable-shared --disable-static --disable-ffmpeg --disable-ffplay
  avcodec     configuration: --extra-version='4:0.7.3ubuntu0.11.10.1' --arch=i386 --prefix=/usr --enable-vdpau --enable-bzlib --enable-libgsm --enable-libschroedinger --enable-libspeex --enable-libtheora --enable-libvorbis --enable-pthreads --enable-zlib --enable-libvpx --enable-runtime-cpudetect --enable-vaapi --enable-libopenjpeg --enable-gpl --enable-postproc --enable-swscale --enable-x11grab --enable-libdirac --enable-libmp3lame --enable-librtmp --enable-libx264 --enable-libxvid --enable-libvo-aacenc --enable-version3 --enable-libvo-amrwbenc --enable-version3 --enable-libdc1394 --shlibdir=/usr/lib/i686/cmov --cpu=i686 --enable-shared --disable-static --disable-ffmpeg --disable-ffplay
  avformat    configuration: --extra-version='4:0.7.3-0ubuntu0.11.10.1' --arch=i386 --prefix=/usr --enable-vdpau --enable-bzlib --enable-libgsm --enable-libschroedinger --enable-libspeex --enable-libtheora --enable-libvorbis --enable-pthreads --enable-zlib --enable-libvpx --enable-runtime-cpudetect --enable-vaapi --enable-gpl --enable-postproc --enable-swscale --enable-x11grab --enable-libdc1394 --shlibdir=/usr/lib/i686/cmov --cpu=i686 --enable-shared --disable-static --disable-ffmpeg --disable-ffplay
  avdevice    configuration: --extra-version='4:0.7.3-0ubuntu0.11.10.1' --arch=i386 --prefix=/usr --enable-vdpau --enable-bzlib --enable-libgsm --enable-libschroedinger --enable-libspeex --enable-libtheora --enable-libvorbis --enable-pthreads --enable-zlib --enable-libvpx --enable-runtime-cpudetect --enable-vaapi --enable-gpl --enable-postproc --enable-swscale --enable-x11grab --enable-libdc1394 --shlibdir=/usr/lib/i686/cmov --cpu=i686 --enable-shared --disable-static --disable-ffmpeg --disable-ffplay
  avfilter    configuration: --extra-version='4:0.7.3-0ubuntu0.11.10.1' --arch=i386 --prefix=/usr --enable-vdpau --enable-bzlib --enable-libgsm --enable-libschroedinger --enable-libspeex --enable-libtheora --enable-libvorbis --enable-pthreads --enable-zlib --enable-libvpx --enable-runtime-cpudetect --enable-vaapi --enable-gpl --enable-postproc --enable-swscale --enable-x11grab --enable-libdc1394 --shlibdir=/usr/lib/i686/cmov --cpu=i686 --enable-shared --disable-static --disable-ffmpeg --disable-ffplay
  swscale     configuration: --extra-version='4:0.7.3-0ubuntu0.11.10.1' --arch=i386 --prefix=/usr --enable-vdpau --enable-bzlib --enable-libgsm --enable-libschroedinger --enable-libspeex --enable-libtheora --enable-libvorbis --enable-pthreads --enable-zlib --enable-libvpx --enable-runtime-cpudetect --enable-vaapi --enable-gpl --enable-postproc --enable-swscale --enable-x11grab --enable-libdc1394 --shlibdir=/usr/lib/i686/cmov --cpu=i686 --enable-shared --disable-static --disable-ffmpeg --disable-ffplay
  postproc    configuration: --extra-version='4:0.7.3-0ubuntu0.11.10.1' --arch=i386 --prefix=/usr --enable-vdpau --enable-bzlib --enable-libgsm --enable-libschroedinger --enable-libspeex --enable-libtheora --enable-libvorbis --enable-pthreads --enable-zlib --enable-libvpx --enable-runtime-cpudetect --enable-vaapi --enable-gpl --enable-postproc --enable-swscale --enable-x11grab --enable-libdc1394 --shlibdir=/usr/lib/i686/cmov --cpu=i686 --enable-shared --disable-static --disable-ffmpeg --disable-ffplay
  libavutil    51.  7. 0 / 51.  7. 0
  libavcodec   53.  6. 0 / 53.  6. 0
  libavformat  53.  3. 0 / 53.  3. 0
  libavdevice  53.  0. 0 / 53.  0. 0
  libavfilter   2.  4. 0 /  2.  4. 0
  libswscale    2.  0. 0 /  2.  0. 0
  libpostproc  52.  0. 0 / 52.  0. 0
Input #0, avi, from 'highres.avi':
  Metadata:
    comment         : Quality_GOOD
    encoder         : Lavf52.64.2
    encoded_by      : AverMedia_c281_1.7.2
  Duration: 00:01:59.28, start: 0.000000, bitrate: 10263 kb/s
    Stream #0.0: Video: h264 (High), yuv420p, 1920x1080, 59.94 fps, 59.94 tbr, 59.94 tbn, 119.88 tbc
    Stream #0.1: Audio: mp3, 48000 Hz, stereo, s16, 128 kb/s
[buffer @ 0x8f438a0] w:1920 h:1080 pixfmt:yuv420p
[scale @ 0x8f431e0] w:1920 h:1080 fmt:yuv420p -> w:960 h:540 fmt:yuv420p flags:0x4
[libx264 @ 0x8f0fb40] broken ffmpeg default settings detected
[libx264 @ 0x8f0fb40] use an encoding preset (e.g. -vpre medium)
[libx264 @ 0x8f0fb40] preset usage: -vpre <speed> -vpre <profile>
[libx264 @ 0x8f0fb40] speed presets are listed in x264 --help
[libx264 @ 0x8f0fb40] profile is optional; x264 defaults to high
Output #0, h264, to 'lowerresforceh264.avi':
    Stream #0.0: Video: libx264, yuv420p, 960x540, q=2-31, 200 kb/s, 90k tbn, 30 tbc
Stream mapping:
  Stream #0.0 -> #0.0
Error while opening encoder for output stream #0.0 - maybe incorrect parameters such as bit_rate, rate, width or height

No estoy seguro de por qué no puedo hacer esto. Ejecutar "ffmpeg -formats" enumeró h264 como uno que podría usar tanto para entrada como para salida.

Si alguien pudiera señalarme en la dirección correcta, lo agradecería enormemente. Gracias.

PD: estoy usando FFmpeg versión 0.7.3-4: 0.7.3-0 en Ubuntu 11.10.

EDITAR

He encontrado una solución mirando el uso de presets. Después de buscar información sobre presets, encontré el siguiente tutorial discutiéndolos:

http://juliensimon.blogspot.com/2009/01/howto-ffmpeg-x264-presets.html

Solo necesitaba especificar el códec y la configuración predeterminada adecuada de esta manera:

ffmpeg -i highres.avi -r 30 -s 960x540 -vcodec libx264 -vpre medium lowerresforceh264vpremedium.avi

Todavía tengo algunos ajustes que hacer, pero esto es básicamente lo que quería. Gracias.

BigBeagle
fuente
Claro, algunas personas simplemente quieren saber cómo convertir archivos .avi de Avermedia .mp4 para que puedan jugar en Mountain Lion / Mavericks <pre> ffmpeg -i 140203-1229.avi -vcodec copy -acodec copy fromavermedia_cog.mp4 </pre>

Respuestas:

3

Estoy tratando de ayudar Primero, no entiendo por qué dice que FFMPEG H.264 no es el formato de entrada.

No conozco la línea de comando FFMPEG lo suficientemente bien (¿hay alguien que lo sepa?)). Tiene que haber un interruptor para la codificación multipass. Sé que hay algunos ajustes preestablecidos incorporados que probablemente podría usar y, casi con certeza, hacen lo que buscan. Normalmente se denominan preajustes x264 o melodía x264. ¿Puedes encontrar algo así?

Zettt
fuente
Gracias. Su charla sobre presets me ha ayudado a encontrar una solución probable. Editaré la publicación para mostrar lo que hice.
BigBeagle
Buena solución Agregado a mi colección de fragmentos. Gracias.
Zettt
2
@BigBeagle: cuando encuentre una respuesta a su pregunta, puede publicarla como respuesta. La edición de su pregunta se realiza para proporcionar más claridad a la pregunta. Según tengo entendido, las respuestas van en la sección de respuestas.
Nav
8

ffmpeg ha eliminado sus preajustes x264, por lo que la configuración -vpre ya no funciona.

Ahora, tengo un script para convertir archivos de video a un formato que mi celular pueda manejar.

ffmpeg -i input.avi -sws_flags lanczos+accurate_rnd -vf "scale=320:240" -c:v libx264 -crf 20 -preset veryslow -profile:v main -tune fastdecode -c:a copy output.mkv

Explicaré cada opción

-sws_flags lanczos+accurate_rnd esta opción es el algoritmo de reducción de escala, se recomienda lanczos ya que produce la menor cantidad de artefactos sin borronear pero es lento.

-vf "scale=..." es autoexplicativo especificar la resolución de salida

-crf 20esta es la calidad, 20 es una buena configuración de salida final (no la use antes de editar), esta es una calidad constante y es la mejor opción cuando el tamaño del archivo no es ajustado y producirá una mejor calidad con el tamaño de archivo más bajo que cualquier otra cosa , de lo contrario, utilice dos pasadas para obtener la máxima calidad en un tamaño de archivo específico (como la necesidad de ajustarlo en un CD o DVD), la tasa de bits fija (ej. -b 2000k) solo debe usarse cuando se transmite, un caso especial es '0' que es sin pérdidas y El rango de esta opción es de 1 (calidad más alta) a 50 (calidad más baja).

Una buena prueba para esto es ejecutar la codificación con -crf 20, tomar nota de la tasa de bits, y luego usarla como la configuración de -b para una segunda versión del archivo, ambos deben tener el mismo tamaño de archivo, comparar los dos para determinar la calidad diferencias

-preset veryslow esto elige la cantidad de CPU que desea usar, cuanto más lento es, menor es el tamaño del archivo y mejor calidad.

-profile:v mainEste es el perfil H.264 a utilizar. alto es el tamaño de archivo más eficiente, pero utiliza mucha CPU para decodificar en comparación con los otros formatos, ya que es el más popular ya que la mayoría de los teléfonos celulares tienen un decodificador de hardware incorporado y el reproductor flash lo admite, el mío no, así que no tengo que hacerlo. use main.

-tune fastdecode mi teléfono celular no le gusta reproducir los archivos sin esta opción, pero generalmente esto puede dejarse en blanco o configurarse como 'película' para videojuegos, la razón principal por la que usa esto es para obtener un poco de calidad adicional.

Y lo último que recomiendo encarecidamente es usar un formato de contenedor moderno .avi no está diseñado para contener H.264 y, por lo que entiendo, no hay un estándar para almacenar H.264 o hacer que el archivo sea más grande que 2GB, la mayoría de las implementaciones son piratas y propensas para tener problemas, use mkv o mp4.

Daniel Hill
fuente
Los ajustes preestablecidos para libx264 ahora se especifican -presetcomo en-preset slow
stib
-tune fastdecodedesactiva el desbloqueo y los marcos ponderados B y P, así como CABAC. ¿Hay decodificadores que pueden manejar marcos B, pero no CABAC? Sugeriría -profile:v baseline, si necesita apuntar a viejos decodificadores de hardware. ( fastdecodepodría ser útil si apunta a un decodificador de software en una CPU lenta, pero no a un decodificador de hardware). Principal con marcos B pero sin desbloqueo o CABAC puede o no verse mejor que la línea base con el desbloqueo. +1 por recomendar no AVI para almacenar h.264. IIRC, el principal son los cuadros B, pero sí, h.264 en avi no está bien estandarizado, y es hacky.
Peter Cordes
Yo llamaría -crf 20una final alta. Puede cambiar eso a 22 o incluso 24 y probablemente esté bien, a menos que sea de alta velocidad, como un evento deportivo.
user24601
2

Hay algunas cosas que dejar en claro:

  • Un formato no es un códec; desea obtener un archivo en formato avi con video codificado con códec h264 . Simplemente use -vcodec libx264 y un nombre de archivo con .avi . Ffmpeg debería reconocer un formato mirando una extensión de archivo, pero también puede ser específico agregando -f avi . Definitivamente no quieres usar mpeg1, porque da peor calidad que mpeg2 o incluso peor en comparación con mpeg4, que recomiendo.
  • Su problema fue que ffmpeg usó la calidad más baja posible porque no especificó ninguna. La opción -sameq rara vez parece funcionar para mí. De hecho, es muy útil establecer la tasa de bits manualmente. Agregue, por ejemplo, -vb 3000k para obtener un archivo con una tasa de bits de video promedio de 3Mb / s, lo que brinda una calidad bastante buena. Supongo que sería suficiente para que tengas 2Mb / s para la resolución mencionada.
  • La clave para reducir el tamaño del archivo no es la resolución, sino la tasa de bits mencionada anteriormente. Prefiero apegarme a la resolución original y simplemente manipular la tasa de bits.
  • Supongo que también desea mantener el audio sin conversión (por lo tanto, sin pérdida de calidad), así que use -acodec copy .

Pruebe esto: ffmpeg -i highres.avi -acodec copy -vcodec libx264 -vb 2000k lowerres.avi

Piotr
fuente
44
La velocidad de bits constante es la peor (en términos de calidad frente a tamaño) de todos los modos de control de velocidad en x264 y debe evitarse. Use -crfpara establecer un modo de calidad constante en su lugar.
slhck