![Оптимальные параметры FFMPEG для сохранения размера файла](https://rvso.com/image/1400009/%D0%9E%D0%BF%D1%82%D0%B8%D0%BC%D0%B0%D0%BB%D1%8C%D0%BD%D1%8B%D0%B5%20%D0%BF%D0%B0%D1%80%D0%B0%D0%BC%D0%B5%D1%82%D1%80%D1%8B%20FFMPEG%20%D0%B4%D0%BB%D1%8F%20%D1%81%D0%BE%D1%85%D1%80%D0%B0%D0%BD%D0%B5%D0%BD%D0%B8%D1%8F%20%D1%80%D0%B0%D0%B7%D0%BC%D0%B5%D1%80%D0%B0%20%D1%84%D0%B0%D0%B9%D0%BB%D0%B0.png)
Итак, идея такова: я хочу преобразовать каждое видео, которое есть на моем терабайтном диске, в формат, который может воспроизвести мой 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.