пятница, 29 апреля 2011 г.

Работа с FFMpeg


   FFmpeg - это кодировщик и конвертер аудио/видео с интерфейсом командной строки и поддержкой большого количества входных и выходных форматов. Список его возможностей и количество опций довольно велико, поэтому попробуем разобраться в некоторых из них.
Все, сказанное ниже, справедливо для Debian Squeeze и FFmpeg установленному из несвободного репозитория Multimedia.

В общем случае формат строки выглядит следующим образом:
ffmpeg [опции исходного файла] -i [исходный файл] [опции конечного файла] [конечный файл]

   Простейший пример конвертации с установленной опцией 24 кадра в секунду в конечном файле будет такой:
ffmpeg -i input.avi -r 24 output.avi


Опции ffmpeg
   Рассмотрим некоторые полезные опции (в скобках примеры). Если какие-то из опций не будут указаны, то FFmpeg подставит их из значений по умолчанию:

-i - задает имя исходного (входного) файла.
-threads - числовое значение, определяет количество ядер процессора. Что, естественно, отражается на скорости кодирования и операций над файлами. Число 0 устанавливает автоматическое определение доступного числа ядер (-threads 2).
-t - задает длительность кодируемого видео в целых секундах или же в формате чч:мм:сс.
-ss - указывает позицию в видеофайле с которой будет начинаться кодирование. Формат в целых секундах или чч:мм:сс.
-fs - числовое значение в байтах, килобайтах (k), мегабайтах (M). Регистр приставки важен. Ограничивает размер конечного файла. Полезно для экспериментов над небольшим кусочком видеофайла, чтобы не кодировать весь файл (-fs 5M).
-y - эта опция перезаписывает уже существующие файлы без запроса на подтверждение.
   Видео опции:
-vcodec - видеокодек, которым будет осуществляться кодирование видео (-vcodec mpeg4).
-vpre - выбираем предустановку для видеокодека. Сначала FFmpeg ищет файлы предустановок в ~/.ffmpeg, затем в /usr/share/ffmpeg или /usr/local/share/ffmpeg, в зависимости от пути установки. Посмотреть самим, какие присутствуют файлы предустановок, можно по этим же путям.
-f - force, указываем принудительно формат конечного файла (-f avi).
-b - битрейт видеопотока. По умолчанию: 200kb/s (-b 1500).
-bt - толерантность битрейта. По умолчанию: 4000k. При двухпроходном кодировании указывает как далеко в первом проходе можно отклониться от указанного среднего битрейта. Значение не связано с минимальным/максимальным битрейтом. Слишком сильное снижение этого параметра оказывает негативное влияние на качество.
-r - количество кадров в секунду. По умолчанию: 25 (-r 15).
-s - размер фрейма, то есть разрешение выходного видеофайла. По умолчанию определяется размером файла-источника. Может быть задано буквенными сокращениями, например svga означает размер 800x600. Просмотреть все доступные сокращения можно в man ffmpeg. (-s 640x480 или -s vga).
-aspect - числовые значения, определяет соотношение сторон выходного файла (-aspect 4:3 или -aspect 1.3333).
-croptop
-cropbottom
-cropleft
-cropright - обрезка кадров сверху, снизу, слева, справа. Значения указываются в пикселях. Может использоваться, например, для удаления черных полос (-croptop 15). В некоторых версиях ffmpeg данные опции могут быть удалены и вместо них используется опция -vf crop=width:height:x:y. Подробнее о ней в соответствующем разделе ниже.
-pass - количество проходов при кодировании, 1 или 2 (-pass 2).
-g - размер группы кадров, после которой следует ключевой кадр. Например -g 300 устанавливает по одному ключевому кадру каждые 10 секунд, при скорости исходного видеофайла 29.97fps. 30 кадров в секунду * на 10 секунд = значение опции 300 (примерное значение для рипа DVD-файла). Чем меньше битрейт и количество кадров в секунду, тем меньше должно быть это значение.
-deinterlace - удаление "гребенки".
   Аудио опции:
-ar - устанавливает частоту дискретизации звука. По умолчанию: 44100Гц (-ar 22050).
-ab - битрейт звуковой дорожки. По умолчанию: 64kb (-ab 256k).
-ac - число каналов звуковой дорожки. По умолчанию, для входящих потоков это значение равно 1, для исходящих равно числу каналов исходного файла. Другими словами, если вы делаете захват звука, то число каналов по умолчанию 1, а если берете звук из видеофайла, например, то число каналов по умолчанию будет равно исходнику (-ac 2).
-an - кодирование видео без звуковой дорожки.
-acodec - аудиокодек, которым будет осуществляться кодирование звука (-acodec flac).
-apre - набор предустановок для аудиокодека.


Обрезка видео (Crop)

   Формат опции следующий:
-vf crop=width:height:x:y

Опция содержит много переменных, приведу лишь несколько примеров простой обрезки:
-vf crop=100:100 - обрезка изображения от центра до размера 100х100.
-vf crop=in_w-2*10:in_h-2*20 - обрезка по 10 пикселей слева и справа и по 20 пикселей сверху и снизу, исходя из размера исходного изображения.
-vf crop=2/3*in_w:2/3*in_h - обрезка от центра до 2/3 от исходного изображения.

   Назначение переменных x и y я объяснить затрудняюсь, но в общих чертах они задают положение верхнего левого угла выходной области (необрезанной). Вычисляется для каждого кадра. Если полученное значение не является допустимым, то округляется до ближайшего допустимого значения.
Выражение для y может зависеть от x и наоборот.
К примеру -vf crop=800:600:0:0 - вырежет окошко размером 800х600 не из центра, а точно от левого верхнего угла.


Общие функции

   Просмотр доступных форматов:
ffmpeg -formats

   Просмотр доступных кодеков:
ffmpeg -codecs

   Просмотр доступных фильтров:
ffmpeg -filters

   Получение информации о мультимедийном файле:
ffmpeg -i input.avi

   Конвертирование из одного формата в другой:
ffmpeg -i input.mov output.avi

   Сохранение звуковой дорожки:
ffmpeg -i input.avi -vn -ab 128k output_audio.mp3
Желательно указывать битрейт, потому что 64кб/с по умолчанию вас вряд ли устроят.

   Вырезаем нужный фрагмент видео без перекодирования видео и звуковой дорожки:
ffmpeg -i input.avi -ss 00:10:00 -t 00:03:00 -vcodec copy -acodec copy cut.avi
В этом примере мы вырезали 3-х минутный фрагмент, начиная с 10-й минуты видео.

   Микшируем видеодорожку со звуковой:
ffmpeg -i video.avi -vcodec copy -i audio.mp3 -acodec copy output.avi

   Можно засунуть несколько видеофайлов в один и переключаться между ними:
ffmpeg -i test1.avi -i test2.avi -vcodec copy -acodec copy -vcodec copy -acodec copy output.avi -newvideo -newaudio
В данном случае у вас получится в одном файле 2 видеодорожки и 2 аудиодорожки, между которыми можно переключаться при воспроизведении. Размер исходного файла будет меньше, чем у двух файлов по отдельности.
Опции -newvideo, -newaudio и -newsubtitle должны быть указаны непосредственно после имени файла, в котором вы собираетесь их объединить.

   Делаем скриншот с видео:
ffmpeg -i input.vob -an -ss 00:02:00 -r 1 -vframes 1 -s 720x480 -f image2 screenshot.jpg
Будет получен скриншот второй минуты видео, с разрешением 720х480


Кодирование видео с помощью кодека libx264 в формат mkv

   Однопроходное кодирование с пресетом slow и пережатием звука в mp3:
ffmpeg -i input.mov -vcodec libx264 -vpre slow -crf 22 -threads 0 -acodec libmp3lame -ar 44100 -ab 128k output.mkv
Чем меньше значение -crf, тем лучше качество и больше размер файла. Примерные пределы от 18 до 28.

   Однопроходное кодирование DVD файла с пресетом slow, с сохранением исходного формата звука, деинтерлейсом (удалением "гребенки"), и обрезкой черных полос:
ffmpeg -i input.vob -vcodec libx264 -vpre slow -crf 22 -threads 0 -deinterlace -vf crop=in_w-2*15:in_h-2*10 -acodec copy output.mkv

   Двухпроходное кодирование с примерным битрейтом 1000k/s и с пережатием звука в aac:
ffmpeg -i input.avi -pass 1 -vcodec libx264 -vpre fast_firstpass -b 1000k -bt 1000k -threads 0 -f mp4 -an /dev/null && ffmpeg -i input.avi -pass 2 -vcodec libx264 -vpre slow -b 1000k -bt 1000k -threads 0 -acodec libfaac -ar 48000 -ab 128k -f mp4 output.mkv


Кодирование видео с помощью кодека Xvid

   Однопроходное кодирование:
ffmpeg -i input.mkv -vcodec libxvid -qscale 8 -me_method full -mbd rd -flags +gmc+qpel+mv4 -trellis 1 -threads 0 -acodec libmp3lame -ab 128k -ac 2 output.avi
Опция -qscale отражается на качестве итогового видео. Чем меньше значение, тем выше качество, больше размер видео и дольше кодирование. Значения лежат в пределах от 1 (лучшее качество) до 31 (худшее).

   Двухпроходное кодирование кодеком Xvid с пережатием звука в Ogg vorbis:
ffmpeg -i input.vob -an -vcodec libxvid -bt 4000k -pass 1 -f rawvideo -threads 0 -y NUL && ffmpeg -i input.vob -vcodec libxvid -b 1500k -pass 2 -threads 0 -y -acodec libvorbis -ab 128k -ac 2 output.avi


Некоторые советы

   Параметры опций для кодирования с высоким качеством в mp4:
'-mbd rd -flags +mv4+aic -trellis 2 -cmp 2 -subcmp 2 -g 300 -pass 1/2', также можно попробовать: '-bf 2', '-flags qprd', '-flags mv0', '-flags skiprd'.

   Параметры опций для кодирования с высоким качеством в MPEG-1/MPEG-2:
'-mbd rd -trellis 2 -cmp 2 -subcmp 2 -g 100 -pass 1/2' но учтите, что '-g 100' могут вызывать проблемы с некоторыми декодерами. Еще стоит попробовать: '-bf 2', '-flags qprd', '-flags mv0', '-flags skiprd.

Запись скринкастов (видео с рабочего стола)

   Использование формата mov (QuickTime) без сжатия позволит сэкономить ресурсы процессора во время записи, но сильно скажется на размере конечного файла. В отличии от кодирования "на лету", которое создает файлы гораздо меньшего размера, но сильно нагружает процессор. Пример записи скринкаста без сжатия:
ffmpeg -f x11grab -s 1280x1024 -r 25 -i :0.0 -vcodec qtrle screencast.mov
где:
-f x11grab - источник сигнала, в данном случае вывод Х-сервера.
-s 1280x1024 - размер захватываемой области, в данном случае соответствует разрешению монитора.
-r 25 - количество кадров в секунду.
-i :0.0 - экран X-сервера / номер монитора. Дополнительно можно указать смещение захватываемой области (положение верхнего левого угла) по X и Y следующим образом -i :0.0+10,20
-vcodec qtrle - видеокодек QuickTime.

   Захват области определенного размера со смещением от левого верхнего угла:
ffmpeg -f x11grab -s 640x500 -r 25 -i :0.0+200,300 -vcodec qtrle screencast.mov
В данном случае мы захватываем окошко размером 640х500, со смещением от левого верхнего угла на 200 пикселей по оси X и 300 пикселей по оси Y.

   Раскадровка видеофайла:
ffmpeg -i input.mov -r 25 -f image2 images%05d.png
создаст 25 изображений в формате PNG для каждой секунды исходного видеофайла. Изображения будут сохранены в текущий каталог. Созданные файлы изображений будут начинаться со слова "images" и будут последовательно пронумерованы так: images000001.png, images000002.png images000003.png и т.д.

   Сохранение изображений в отдельный подкаталог tmp:
ffmpeg -i input.mov -r 25 -f image2 tmp/images%05d.png

   Раскадровка первой секунды видео от начала видеофайла:
ffmpeg -i input.mov -r 25 -t 00:00:01 -f image2 images%05d.png
Ключ -t в FFmpeg указывает длительность декодируемого видео, которую можно задать в формате целых секунд или же в формате чч:мм:сс.

   Раскадровка с заданного участка времени:
ffmpeg -i input.mov -r 25 -ss 00:00:10 -t 00:00:05 -f image2 images%05d.png
Ключ -ss используется для указания отметки времени, с которой начинается обработка. Формат времени такой же.

   Сохранение одного изображения первой секунды:
ffmpeg -i input.mov -r 1 -t 00:00:01 -f image2 images%05d.png
Если нужен один кадр из другой части клипа, используйте ключ -ss в команде, аналогичной приведённой выше команде.

   Раскадровка всего видео с уменьшенным размером сторон кадра:
ffmpeg -i input.mov -r 1 -f image2 -s 120x96 images%05d.png

   Объединение последовательности изображений в видеофайл:
ffmpeg -f image2 -i images%05d.png -r 25 -s 1280x1024 output.avi

   Конвертируем видео в gif-анимацию:
ffmpeg -i screencast.mov -an -pix_fmt rgb24 -vframes 100 -r 6 -s 640x480 -loop_output 0 -f gif -y screencast.gif
Параметром -vframes 100 мы указываем, что хотим получить 100 кадров в нашей анимации. Параметром -r 6 говорим, что хотим брать по 6 кадров с каждой секунды видео. -loop_output - задает число повторений анимации, при значении 0 она будет повторяться бесконечно.

   Запись видео со звуком (предварительно в микшере нужно включить соответствующие входы и выставить уровни записи):
ffmpeg -f alsa -ac 2 -i hw:0,0 -acodec pcm_s16le -f x11grab -s 1280x1024 -r 25 -threads 0 -i :0.0 -vcodec qtrle screencast.mov
Список доступных для записи устройств ALSA можно посмотреть командой: arecord -l

   Лично у меня запись с QuickTime'ом шла не очень гладко, еще и наблюдалось расхождение видео со звуком. Предпочтительнее оказался вариант все с тем же libx264 и пресетом lossless_ultrafast:
ffmpeg -f alsa -i hw:0,0 -acodec pcm_s16le -ac 2 -ab 128k -f x11grab -s 1280x1024 -r 30 -i :0.0 -threads 0 -vcodec libx264 -vpre lossless_ultrafast screencast.mkv
Размер файла получился даже несколько меньше, в сравнении с .mov и отсутствовали рывки и рассинхронизация звука.


Те, кто не любят консоль, могут воспользоваться графической оболочкой, поставив пакет winff. Но у меня большие сомнения относительно ее возможностей.

12 комментариев:

  1. Пять баллов за статью!

    ОтветитьУдалить
  2. молодец, отличная статья, мне очень помогла!

    ОтветитьУдалить
  3. Очень полезная статья. Благодарю.

    ОтветитьУдалить
  4. Анонимный14 июня 2012 г., 22:22

    Супер!спасибо!!

    ОтветитьУдалить
  5. Спасибо, кратко и по существу! Очень помогло!

    ОтветитьУдалить
  6. Мои молитвы услышаны. Наконец-то я нашел способ пакетно извлечь звук из видео!!!

    ОтветитьУдалить
  7. А куда подевался libfaac? Выдает ошибку unknow encoder 'libfaac'. За статью респект до земли))

    ОтветитьУдалить
  8. Анонимный21 мая 2013 г., 16:43

    >А куда подевался libfaac?
    Он теперь по-другому называется: -acodec libvo_aacenc -ab 160k -ac 2
    (сжать в AAC с качеством 160kbps и много каналов свести первые два в стерео)

    А у меня не склеивает .mp4 =((
    Там есть пример с "cat" но куда этот "cat" нужно вписать "ffmpeg cat -i..." или по-другому? Известно, что ffmpeg "умеет" клеить только mpg, так?

    ОтветитьУдалить
  9. Анонимный21 мая 2013 г., 19:23

    И еще вопрос. Вместо огромного числа файлов в команде ffmpeg -i concat:"VTS_01_1.VOB|VTS_01_2.VOB|VTS_01_3.VOB|VTS_01_4.VOB"

    Можно как-то указать их в списке video.txt и вписать имя списка ffmpeg -i concat:"video.txt"

    Но какие ключи, я не могу нагуглить. Например, для обработки списка изображений используется ffmpeg -f image2 -i image%d.jpg video.mpg где каждый "виток" вместо "image%d.jpg" подставляется цифра (image1.jpg,image2.jpg,image3.jpg...) Подскажите, кто знает.

    ОтветитьУдалить
  10. Анонимный22 мая 2013 г., 14:18

    Все, разобрался, пришлось делать свой гуй ))) "files.mail.ru/0C96EC7882BD405FAEDDD5BE9842E64B"

    ffmpeg -i concat:"VTS_01_1.VOB|VTS_01_2.VOB" -vcodec h264 -vf yadif=0 -crf 20 -threads 2 -acodec libvo_aacenc -ab 160k -ac 2 -f mp4 -y kino.mp4

    ОтветитьУдалить
  11. Анонимный23 мая 2013 г., 15:05

    Извиняюсь за СПАМ, но прога стала еще лучше "http://files.mail.ru/B851ECD82B264CB29FD75F3BC58952A8". Возможно, кому-то поможет с dvd-рипом. Майл-ру удалит файл 23.06.2013, скачивайте, перезаливайте.

    ОтветитьУдалить