ffmpeg регистрирует в stderr и может записывать в файл с уровнем регистрации, отличным от stderr. Параметр командной строки -report
не позволяет управлять именем файла журнала или уровнем журнала, поэтому установка переменной среды предпочтительнее.
(-v
является синонимом -loglevel
. Запустите ffmpeg -v help
, чтобы увидеть уровни. Выполните ffmpeg -h full | less
, чтобы увидеть ВСЕ. Или обратитесь к онлайн-документам или к их вики-страницам, таким как руководство по кодированию h.264 ).
#!/bin/bash
of=out.mkv
FFREPORT="level=32:file=$of.log" ffmpeg -v verbose -i src.mp4 -c:a copy -preset slower -c:v libx264 -crf 21 "$of"
Это будет транскодировать src.mp4
с x264 и установить уровень ведения журнала для stderr на «verbose», а уровень ведения журнала на out.mkv.log
на «status».
(AV_LOG_WARNING=24
, AV_LOG_INFO=32
, AV_LOG_VERBOSE=40
и т. Д.). Поддержка этого была добавлена 2 года назад , поэтому вам нужна не древняя версия ffmpeg. (Всегда хорошая идея для безопасности / исправления ошибок и ускорений)
Несколько кодеков, например -c:v libx265
, пишут напрямую в stderr вместо использования инфраструктуры ведения журнала ffmpeg. Таким образом, их сообщения журнала не попадают в файл отчета. Я предполагаю, что это элемент списка ошибок / TODO.
Для входа в stderr, пока он еще видится в терминале, вы можете использовать tee(1)
.
Если вы используете уровень журнала, который включает в себя обновления строки состояния (по умолчанию -v info
или выше), они будут включены в файл журнала, разделенные ^M
(возврат каретки aka \r
). Нет уровня журнала, который бы включал статистику кодировщика (например, SSIM), но не обновлял строки состояния, поэтому, вероятно, лучше всего фильтровать этот поток.
Если вы не хотите фильтровать (например, в файле есть частота кадров / битрейт в каждом интервале обновления состояния), вы можете использовать less -r
, чтобы передать их прямо на ваш терминал, чтобы вы могли просматривать файлы чисто. Если у вас есть .enc
журналов из нескольких кодов, которые вы хотите пролистать, less -r ++G *.enc
отлично работает. (++ G означает начало в конце файла для всех файлов). С привязками одноклавишных клавиш , такими как .
и ,
для следующего файла и предыдущего файла, вы можете очень легко пролистывать некоторые файлы журнала. (привязки по умолчанию :n
и :p
).
Если вы хотите фильтровать, sed 's/.*\r//'
отлично работает для вывода ffmpeg. (В общем случае вам нужно что-то , например vt100.py
, но не только для возврата каретки). Есть (по крайней мере) два способа сделать это с помощью tee + sed: tee
to / dev / tty и вывести трубу tee в sed, или использовать подстановку процесса, чтобы перейти в трубу к sed.
# pass stdout and stderr through to the terminal,
## and log a filtered version to a file (with only the last status-line update).
of="$1-x265.mkv"
ffmpeg -v info -i "$1" -c:a copy -c:v libx265 ... "$of" |& # pipe stdout and stderr
tee /dev/tty | sed 's/.*\r//' >> "$of.enc"
## or with process substitution where tee's arg will be something like /dev/fd/123
ffmpeg -v info -i "$1" -c:a copy -c:v libx265 ... "$of" |&
tee >(sed 's/.*\r//' >> "$of.enc")
Для тестирования нескольких различных параметров кодирования вы можете создать функцию , такую как эта, которую я недавно использовал для тестирования некоторых вещей. У меня все это было в одной строке, поэтому я мог легко поднять стрелку вверх и отредактировать ее, но здесь я не буду обфусцировать ее (Вот почему в конце каждой строки ;
)
ffenc-testclip(){
# v should be set by the caller, to a vertical resolution. We scale to WxH, where W is a multiple of 8 (-vf scale=-8:$v)
db=0; # convenient to use shell vars to encode settings that you want to include in the filename and the ffmpeg cmdline
of=25s@21.15.${v}p.x265$pre.mkv;
[[ -e "$of.enc" ]]&&echo "$of.enc exists"&&return; # early-out if the file exists
# encode 25 seconds starting at 21m15s (or the keyframe before that)
nice -14 ffmpeg -ss $((21*60+15)) -i src.mp4 -t 25 -map 0 -metadata title= -color_primaries bt709 -color_trc bt709 -colorspace bt709 -sws_flags lanczos+print_info -c:a copy -c:v libx265 -b:v 1500k -vf scale=-8:$v -preset $pre -ssim 1 -x265-params ssim=1:cu-stats=1:deblock=$db:aq-mode=1:lookahead-slices=0 "$of" |&
tee /dev/tty | sed 's/.*\r//' >> "$of.enc";
}
# and use it with nested loops like this.
for pre in fast slow; do for v in 360 480 648 792;do ffenc-testclip ;done;done
less -r ++G *.enc # -r is useful if you didn't use sed
Обратите внимание, что он проверяет наличие выходного видеофайла, чтобы избежать выброса лишнего мусора в файл журнала, если он уже существует. Тем не менее, я использовал и добавляю (>>
) редирект.
Было бы «чище» написать функцию оболочки, которая бы принимала аргументы вместо просмотра переменных оболочки, но это было удобно и легко написать для моего собственного использования. Вот почему я сэкономил место, неправильно указав в кавычках все мои расширения переменных. ($v
вместо "$v"
)