Parámetros óptimos para que FFMPEG mantenga el tamaño del archivo

Parámetros óptimos para que FFMPEG mantenga el tamaño del archivo

entonces la idea es: quiero convertir cada video que tengo en una unidad de 1 terabyte a un formato que mi Chromecast pueda reproducir (https://developers.google.com/cast/docs/media) y estaré encantado de dejar funcionando mi no tan nueva PC durante unos días (¿semanas?) para hacerlo. Genial, FFMPEG a la salvación.

Un poco de historia: soy un desarrollador de Android/Java (muy activo en StackOverflow) y sé que en algún momento necesitaré codificar algún script por lotes o una línea de comando rápida de Java (porque me siento más cómodo con Java). ) para hacer el trabajo, pero todavía no estoy seguro de qué argumentos usar en mi línea de comando FFMPEG.

Entonces mis necesidades son: - códec de video: H.264 High Profile Level 5 - códec de audio: cualquiera de HE-AAC, LC-AAC, MP3 (honestamente, no conozco la diferencia, ¿tal vez algo de AAC sea mejor? ) manténgalo igual - Ciertamente quiero usar el modo lento o más lento (para una mejor calidad) - Ciertamente quiero usar el de 2 pasadas con tasa de bits variable (para una mejor calidad)

Todo lo anterior lo vi en los tutoriales y manuales de cómo lograrlo, ahora la parte que realmente no estoy seguro de cómo lograr:

Quiero que el tamaño del archivo final sea aproximadamente el mismo que el original. Esto se debe a que el disco está lleno aproximadamente en un 80% y no quiero llenarlo simplemente convirtiendo cosas. En el script, volveré a codificar el archivo y eliminaré el original para que todo siga moviéndose sin problemas.

Entonces, ¿cómo puedo pasar del tamaño del archivo a video_bitrate y audio_bitrate para incluirlos en el script?

PD: Estoy igualmente feliz de usar el freno de mano si alguien sabe cómo realizar el mismo trabajo.

gracias de antemano por la ayuda.

Respuesta1

El comando ffmpeg que necesitas es algo como:

ffmpeg -i input.foo -c:v libx264 -profile:v high -level 5 -preset slow -b:v $videobitrate -an -pass 1 output.bar;
ffmpeg -y -i input.foo -c:v libx264 -profile:v high -level 5 -preset slow -b:v $videobitrate -b:a $audiobitrate -pass 2 output.bar

libx264 es el codificador h264, y todas las opciones se pasan de ffmpeg a él, se explican por sí mismas. El primer paso no necesita audio, de ahí el -an. Puedes canalizar la salida a /dev/null si quieres, pero como sea. Simplemente uso el modificador -y en la segunda pasada para que sobrescriba el archivo temporal sin preguntar. El códec de audio predeterminado es aac, por lo que no es necesario especificarlo.

sonda ffpuede ayudarle a obtener el valor de $videobitrate y $audiobitrate (supongo que es un entorno posix; de lo contrario, será %videobitrate% y %audiobitrate%). Tendrás que hacer algo de sed, awk o perl voodoo para obtener los valores en un formato que puedas usar. Aquí está el resultado de ffprobe en un mp4 aleatorio en mi máquina:

ffprobe version 2.1.3 Copyright (c) 2007-2013 the FFmpeg developers
  built on Feb 12 2014 22:10:38 with Apple LLVM version 5.0 (clang-500.2.79) (based on LLVM 3.3svn)
  configuration: --prefix=/usr/local/Cellar/ffmpeg/2.1.3 --enable-shared --enable-pthreads --enable-gpl --enable-version3 --enable-nonfree --enable-hardcoded-tables --enable-avresample --enable-vda --cc=clang --host-cflags= --host-ldflags= --enable-libx264 --enable-libfaac --enable-libmp3lame --enable-libxvid --enable-libfreetype --enable-libtheora --enable-libvorbis --enable-libvpx --enable-librtmp --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libvo-aacenc --enable-libass --enable-ffplay --enable-libspeex --enable-libschroedinger --enable-libfdk-aac --enable-openssl --enable-libopus --enable-frei0r --enable-libcaca --enable-libopenjpeg --extra-cflags='-I/usr/local/Cellar/openjpeg/1.5.1/include/openjpeg-1.5 '
  libavutil      52. 48.101 / 52. 48.101
  libavcodec     55. 39.101 / 55. 39.101
  libavformat    55. 19.104 / 55. 19.104
  libavdevice    55.  5.100 / 55.  5.100
  libavfilter     3. 90.100 /  3. 90.100
  libavresample   1.  1.  0 /  1.  1.  0
  libswscale      2.  5.101 /  2.  5.101
  libswresample   0. 17.104 /  0. 17.104
  libpostproc    52.  3.100 / 52.  3.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'loop.mp4':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    encoder         : Lavf55.19.104
  Duration: 00:00:19.56, start: 0.000000, bitrate: 201 kb/s
    Stream #0:0(eng): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 400x226 [SAR 226:225 DAR 16:9], 129 kb/s, 25 fps, 25 tbr, 12800 tbn, 50 tbc (default)
    Metadata:
      handler_name    : VideoHandler
    Stream #0:1(und): Audio: aac (mp4a / 0x6134706D), 44100 Hz, mono, fltp, 75 kb/s (default)
    Metadata:
      handler_name    : SoundHandler

De manera molesta, ffprobe descarga todo en stderr, por lo que debes redirigirlo a stdout. No te diré cómo chupar huevos, tu sed-fu puede ser mejor que el mío, pero porLos que llegaron tarde, para obtener la tasa de bits de todo el asunto en el ejemplo anterior, puedes hacer algo como:

videobitrate=$(ffprobe input.foo 2>&1|grep bitrate |sed "s/.*bitrate: \([0-9]*\) \([km]*\).*/\1\2/")

y para el audio:

audiobitrate=$(ffprobe input.foo 2>&1|grep Audio|sed "s/.* \([0-9]*\) \([km]*\)b\/s.*/\1\2/")

No estoy seguro de por qué se especificó la tasa de bits del audio pero no la del video, podría deberse a que normalmente comprimo con un factor de tasa constante (calidad constante en lugar de tasa de bits constante). Tendrás que comprobar la salida de ffprobe en tus películas. A partir de ahí, depende de usted convertir eso en las variables que necesita. Tenga en cuenta que ffmpeg analizará números como 100k o 3m.

información relacionada