2010-03-30 FFmpeg и именованные каналы

Материал из YourcmcWiki
Перейти к: навигация, поиск

Прикольная фишка консольного ffmpeg’а — его можно использовать вместе с именованными каналами (named pipes) для нарезки и слияния видео.

Шаг первый: создаём именованные каналы. А допустим, у нас ещё и аудиодорожек несколько.

Сначала я хотел написать, как завещал великий FAQ — по одному файлу на каждую дорожку, то есть целую кучу: file1.v file1.a1 file1.a2 file2.v file2.a1 file2.a2 file.v file.a1 file.a2. Однако обнаружил, что AVI-контейнер прекрасно переживает конкатенацию и что в этом случае результат получается даже лучше — на мгновении, когда Балу дёргает Багиру за хвост в процессе пения Bare Necessities, не возникает никакого затупа. А в случае с кучей raw-файлов — возникало. Так что попробуем AVI.

mkfifo file1.avi
mkfifo file2.avi
mkfifo file.avi

Шаг второй: запускаем декодирующие в сырые форматы ffmpeg’и и конкатенирующий потоки cat в фоновом режиме — пускай ждут, пока им разрешат писать в каналы. Пусть входные файлы у нас — это грёбаные DVD’шные VOB’ы с тремя аудиодорожками, дискретизированными на 48 KHz, первые две — 5.1, последняя — моно.

Кстати 1: -ss нужно указывать время либо в секундах, либо в формате HH:MM:SS[.mmm]. Именно в таком, то есть просто MM:SS не прокатит.

Командная строка FFmpeg’а некоммутативна :) от перемены аргументов местами меняется смысл. Например, если указать -ss после -i файл, вы задолбаетесь ждать, пока оно перейдёт к нужному месту в файле, потому что будет seek’ать на уровне кодека. А если указать -ss до -i файл, seek’ать оно будет на уровне контейнера и сделает это быстро.

Кстати 2: для сырых аудиоформатов обязательно указывать параметры -ac -ar и -f (например s16le) либо -acodec (например pcm_s16le), как при кодировании, так и при декодировании, иначе как же оно узнает, какой raw формат мы хотим? При чтении raw формата эти параметры нужно указывать до -i входного_файла.

А -newaudio, например, нужно указывать после имени выходного файла. А опции для добавляемой -newaudio аудиодорожки — непосредственно перед -newaudio.

Кстати 3: -y поможет нам избежать предупреждений.

Кстати 4: запуск ffmpeg’ов с «выпуском» в именованный канал нормально не удавался под непривилигерованным юзером — ffmpeg получал SIGSTOP. В чём дело, я разбираться особенно не стал, а просто пускал его под рутом.

ffmpeg -y -ss 00:24:18 -i VTS_01_1.VOB -map 0.0 -map 0.1 -map 0.2 -map 0.3 \
  -vcodec rawvideo -acodec pcm_s16le -ac 6 -ar 48000 file1.avi \
  -acodec pcm_s16le -ac 6 -ar 48000 -newaudio -acodec pcm_s16le \
  -ac 1 -ar 48000 -newaudio &>log1 &
ffmpeg -y -t 91 -i VTS_01_2.VOB -map 0.0 -map 0.1 -map 0.2 -map 0.3 \
  -vcodec rawvideo -acodec pcm_s16le -ac 6 -ar 48000 file2.avi \
  -acodec pcm_s16le -ac 6 -ar 48000 -newaudio -acodec pcm_s16le \
  -ac 1 -ar 48000 -newaudio &>log2 &
cat file1.avi file2.avi > file.avi &

Шаг третий: запускаем кодирующий ffmpeg.

Кстати: для libx264, начиная с какой-то (Х-З какой) версии ffmpeg’а, нужно указывать опцию -vpre. А ещё лично я люблю забивать максимальный фактор квантования и не париться о качестве.

ffmpeg -y -i file.avi -vcodec libx264 -vpre hq -qmax 28 \
  -acodec libfaac -ab 448k -ac 6 BareNecessities6ch.avi \
  -acodec libfaac -ab 384k -ac 6 -newaudio \
  -acodec libfaac -ab 96k -ac 1 -newaudio

И всё, с данного момента вся спящая в фоновом режиме машинерия активизируется и начнёт кодировать-декодировать.

Изначально вкурено с http://ffmpeg.org/faq.html#SEC29, но сильно исправлено и дополнено :)

[ Хронологический вид ]Комментарии

(нет элементов)

Войдите, чтобы комментировать.