Оптимальные параметры FFMPEG для сохранения размера файла

Оптимальные параметры FFMPEG для сохранения размера файла

Итак, идея такова: я хочу преобразовать каждое видео, которое есть на моем терабайтном диске, в формат, который может воспроизвести мой Chromecast (https://developers.google.com/cast/docs/media) и я с радостью оставлю свой не такой уж новый ПК работать на несколько дней (недель?), чтобы сделать это. Отлично, FFMPEG в помощь.

Немного предыстории: я разработчик Android/Java (очень активный участник StackOverflow) и знаю, что в какой-то момент мне просто понадобится написать какой-нибудь пакетный скрипт или быструю командную строку Java (потому что мне удобнее работать с Java), чтобы выполнить эту работу, но я все еще не уверен, какие аргументы использовать в командной строке FFMPEG.

Итак, мне нужно: - видеокодек: H.264 High Profile Level 5 - аудиокодек: любой из HE-AAC, LC-AAC, MP3 (честно говоря, я не знаю, в чем разница, может, какой-нибудь AAC будет лучше?) оставить прежним - я определенно хочу использовать slow или медленнее (для лучшего качества) - я определенно хочу использовать 2-проходной с переменным битрейтом (для лучшего качества)

Все вышеперечисленное я видел в руководствах и руководствах, как это сделать, а теперь та часть, в которой я действительно не уверен, как это сделать:

Я хочу, чтобы конечный размер файла был примерно таким же, как и у оригинала. Это потому, что диск заполнен примерно на 80%, и я не хочу заполнять его просто конвертацией. В сценарии я перекодирую файл и удалю оригинал, чтобы все продолжалось без проблем.

так как мне из filesize получить video_bitrate и audio_bitrate, чтобы вставить в скрипт?

P.S.: Я бы с удовольствием использовал ручной тормоз, если кто-то знает, как выполнить ту же работу.

Заранее спасибо за помощь.

решение1

Нужная вам команда ffmpeg выглядит примерно так:

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 — это кодировщик h264, и все параметры передаются ему из ffmpeg, они довольно понятны. Первому проходу не нужен звук, отсюда и -an. Вы можете перенаправить вывод в /dev/null, если хотите, но как хотите. Я просто использую переключатель -y во втором проходе, чтобы он перезаписывал временный файл без запроса. Аудиокодек по умолчанию — aac, поэтому вам не нужно его указывать.

ffprobeможет помочь вам получить значения $videobitrate и $audiobitrate (я предполагаю среду posix, в противном случае это будут %videobitrate% и %audiobitrate%). Вам придется применить sed, awk или perl voodoo, чтобы получить значения в форме, которую вы можете использовать. Вот вывод ffprobe на случайном mp4 на моей машине:

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

раздражает, что ffprobe вываливает все в stderr, поэтому вам нужно перенаправить его в stdout. Я не буду рассказывать вам, как сосать яйца, ваш sed-fu может быть лучше моего, но дляТе, кто пришел поздноЧтобы получить битрейт для всего комплекса в примере выше, можно сделать что-то вроде:

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

и для аудио:

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

не уверен, почему был указан битрейт аудио, а не видео, возможно, потому что я обычно сжимаю с постоянным коэффициентом скорости (постоянное качество, а не постоянный битрейт). Вам придется проверить вывод ffprobe в ваших фильмах. А дальше уже вам решать, как преобразовать его в нужные вам переменные. Обратите внимание, что ffmpeg будет анализировать такие числа, как 100k или 3m.

Связанный контент