Pull to refresh

Создание видео редактора — полезные рецепты avconv (ffmpeg)

Reading time 8 min
Views 27K


Недавно потребовалось написать небольшой видеоредактор с веб-интерфейсом.
До этого изредка доводилось пользоваться командами типа
ffmpeg -i file.avi file.mp3

в основном для конвертации из одного формата в другой. Все всегда было более менее гладко и сложно было представить, сколько на самом деле существует всяких нюансов для работы с видео и аудио.
Но начнем с начала. С некоторых пор моя ubuntu начала выдавать:
*** THIS PROGRAM IS DEPRECATED ***
This program is only provided for compatibility and will be removed in a future release. Please use avconv instead.

В целом, пока это использовалось по-мелочам, это было не особо важно, но закладывать уже устаревающую фичу в проект как-то «не оно». Пришлось гуглить что к чему и выяснилось, что проект ffmpeg некоторое время назад раскололся и часть разработчиков занялась созданием библиотеки libav, которая и включена в настоящее время в ubuntu по-умолчанию. Разумеется, совместимость передовых фич была принесена в жертву первой. Заодно и с переименованием проекта исполняемый файл ffmpeg был переименован в avconv, о чём и было вышеупомянутое предупреждение.

Под катом небольшая выжимка основных фич, которые пригодились.


avconv [опции входящего файла] -i входящий файл [опции преобразования] исходящий файл

входящих файлов может быть несколько, соответственно опции и -i пишутся перед каждым из них

Но на деле все оказалось немного сложнее.
Далее набор полезных рецептов и по ходу описания небольшие комментарии по поводу опций

Основные опции, часто встречающиеся в командах

-y — перезаписать файл без вопросов
-threads 8 — во сколько потоков выполнять операцию (в данном случае 8, но не все кодеки умеют распараллеливаться)
-s hd720 — размер видео (в данном случае по стандарту hd720p-1280*720)
-q 1 — задает качество кодирование (на разные кодеки действует по-разному). Не стоит забывать эту опцию, поскольку по-умолчанию от качества только название.
Для опций задающих свойства потока, есть возможность указывать этот поток непосредственно в самой опции (без этого действие опции распространяется на все потоки). Делается это следующим образом:
-q:a 1 — задаст качество аудио,
-q:v 1 — соответственно — видео.
С числом будет подразумеваться поток под номером
-q:v:0 1 — первый видео-поток (отсчёт с нуля),
-q:0 1 — первый поток вообще, зависит от компоновки файла — нужно предварительно смотреть на информацию, которую avconv выдаёт относительно содержимого входных файлов.

Разрезание большого файла на фрагменты

avconv -i in.mp4 -ss 00:00:30 -t 00:10:00 -q 1 -s hd720 -threads 8 -r 25 -y out.mp4

Говорим с какой секунды -ss 00:00:30 и какой по длине времени -t 00:10:00 взять ролик.

Отделение аудио от видео с нужной громкостью и нужной длины

avconv -i in.mp4 -ss 00:00:22 -t 00:00:30 -vol 512 -vn -f u16le -ac 2 -ar 44100 -threads 8 -y out.raw

-vn — исключает видео поток на выходе
-ss 00:00:22 — начало вырезаемого фрагмента
-t 00:00:30 — длина вырезаемого фрагмента
-vol 512 — громкость, 256 это нормальная громкость все что выше повышает что ниже соответственно
-ar 44100 — ауди сэмплрейт (частота дискретизации аудиопотока) 44100 соотвтетствует cd качеству и является стандартом
-ac 2 — задает кол-во аудио каналов (2 — значит стерео)
-f u16le — задает формат выходного потока, u16le — сохраняет сырые данные в файле без заголовков.
Экспортировать данные можно и в другом формате, но raw нам пригодится, если захотим конкатенировать много аудиофрагментов, что будет легко выполнить просто соединив файлы поочерёдно.

Тиражирование или клонирование файлов

Если нужно соединить аудио дорожки можно пользоваться простым cat
cat in1.raw in2.raw > out.raw

Подобным образом можно соединить сколько угодно файлов и можно порциями в несколько заходов, создавая промежуточные.
cat in1.raw in1.raw in1.raw > out.raw

Таким образом мы можем растиражировать фрагмент (например тишину или однотонный сигнал) на необходимое нам время, или зациклить небольшой аудиофрагмент.

Конвертация raw формата в обычный wav

avconv -q 1 -f u16le -ac 2 -ar 44100 -threads 8 -i in.raw -y out.wav

Картинки

Разбить видеофайл на изображения
avconv -i in.avi -q 1 -s hd720 -threads 8 -y "out/%08d.jpg"

На выходе мы получим множество кадров, из которых состоит видеофрагмент.

Собрать из изображений видеофайл
avconv -i "in/%08d.jpg" -q 1 -s hd720 -threads 8 -y out_v.avi

Клонирование картинок в нужном количестве
Например у нас есть картинка и нам нужно чтоб в ролике она задержалась на полминуты. Для этого в основном служит опция -loop
avconv -loop 1 -i in.jpg -t 00:00:05 -q 1 -s hd720 -threads 8 -y out.mp4


Создание скриншота
avconv -i file.mp4 -an -ss 00:00:30 -r 1 -vframes 1 -y -f mjpeg -q 1 file.jpg

-f mjpeg — указываем кодек для этой операции
Альтернативный способ микширования аудиодорожек

Для обработки аудио есть неплохой, проверенный временем инструмент, sox. Как это ни удивительно, с ним удалось без особых сюрпризов слить две аудиодорожки после ряда нестабильных результатов с avconv. Например, avconv может слить две дорожки, одинаковых по времени, и на выходе одна из них завершится раньше, чем вторая. Соответственно, при наложении звук может сильно «съезжать», особенно на длинных роликах.

sox -m in1.wav in2.wav out.wav

-m — опция, задающая режим микширования входных файлов. Без опций sox просто сконкатенирует файлы, добавив второй после первого.

Сливание звука и видео в один файл

avconv -i in.mp4 -i in.mp3 -c:v copy -q 1 out.mp4

-c — выбор кодека, соответственно
-c:a — аудиокодек
-c:v — видеокодек
-c:v copy — Не перекодировать, используя оригинальные данные

Вариант конкатенации

avconv -i "concat:in1.avi|in2.avi" -q 1 -b:a 128k -preset libvpx-720p -threads 8 -y {f_out}

-b — выбор битрейта
-b:a 128k — задаём для mp3 дорожки битрейт 128 Кбит
-preset — задаёт сразу набор настроек из заранее предопределённых
-preset libvpx-720p — устанавливает видеокодек vpx и размер кадра по стандарту hd720p
concat: — специальный «формат» входных файлов, с помощью которого задаются списки. На практике работает аналогично cat in1.avi in2.avi выдавая соединённые файлы. Соответстенно, как и cat, он файлы соединит, но кодек, их разбирающий это может не понять (именно так для большинства форматов и происходит) и нужно выбирать формат, поддерживающий подобное соединение. Из подобных форматов стоит упомянуть mpeg, avi и сырые видеоданные, которым можно было бы посвятить отдельную статью и здесь касаться не будем.

Компоновка дорожек из разных файлов

avconv -i in1.mp4 -i in2.mp4 -map 0:a -map 1:v -y -q 1 out.mp4

-map — указывает дорожку-источник, которую нужно включить в выходной файл (если map'ы не указаны, avconv просто сконвертирует первый файл в формат выходного файла).
-map 0:a — аудиодорожка из первого файла (отсчёт с нуля).
-map 1:v — видеодорожка из второго.

Новое в версии 0.9 -filter_complex

Эта опция определят порядок фильтров для сложных (комплексных) операций.
Нормально работает с файлами когда у них одинаковый фреймрейт.

Фильтр описывается строкой, которая выглядит примерно так:
[in1][in2] преобразование [out]

На входе — это, собственно, то же самое, что мы пишем в -map, например [0:a][1:a] — аудиоканалы первого и второго роликов.
На выходе — мы даём название новосозданному после выполненных преобразований каналу, например mix_a. Его так же можно использовать в map в дальнейшем или в качестве названия потока на входе следующего преобразования.

По-умолчанию в преобразование попадают все входящие потоки (или первый поток, если фильтр принимает только один), поэтому их можно не указывать. Канал, получающийся на выходе, становится каналом по-умолчанию для итогового файла, поэтому в большинстве случаев, его также можно отбросить.

Операции преобразования можно условно разделить на «генераторы» — они вообще не принимают ничего на вход, а только создают поток с заданными свойствами, «фильтры» — принимают на вход один поток и преобразовывают его и «микшеры» — принимают на вход несколько потоков и соединяют их.

На выходе также может оказаться несколько потоков, например, если фильтр разбивает стерео на две моно дорожки, их так же нужно описывать списком [out1][out2] и т.п.

Пример генератора

avconv -filter_complex 'color=white' -t 5 -q 1 out.mkv

color=white — генерирует изображение с чистым белым цветом. Это можно использовать, например, для создания фона субтитрам или как паузу между видеосюжетами.

Примеры видеофильтров

avconv -i in.avi -vf "hflip" out.avi

hflip — зеркально отражает изображение по горизонтали

avconv -i in.avi -vf "smooth=type=blur" -q 1 out.avi

smooth — выполняет размывание изображения по одному из нескольких алгоритмов: «blur», «blur_no_scale», «median», «gaussian», «bilateral».

avconv -i in.avi -vf "scale=w=200:h=100" -q 1 out.avi

scale — выполняет масштабирование изображения. На его примере можно рассмотреть как фильтрам передаются параметры. «scale=...» — если после имени фильтра, как в данном примере, указан знак равенства, то дальше должен следовать список параметров вида «название=значение». Параметры также указываются со знаком равенства, поэтому, первоначально это несколько сбивает с толку, но привыкнуть можно. Сами параметры в списке разделяются двоеточиями.
w=200:h=100 — жёстко задаёт высоту и ширину выходного изображения. Разумеется, при жестком способе задания размера изображение получается контролируемых размеров, но пропорции могут исказиться.
scale=w=iw/2:h=ih/2 — размеры выходного изоборажения можно указать в зависимости от входного. В данном случае мы указываем уменьшить в два раза. Подобрав соответствующим образом коэффициенты можно отрегулировать пропорции. Это, кстати, позволяет добиваться интересных эффектов, например, уменьшенную картинку можно вставить как дополнительную информацию в угол или совместить несколько видеоизображений как это делается на системах видеонаблюдения.
ow=200:oh=200 — обрежет изображение под указанный размер
Также в вычислениях можно использовать более сложные выражения и функции.

Примеры микширования

avconv -i in1.mp4 -i in2.mp4 -filter_complex amix=inputs=2 -q 1 -b:a 128k -preset libvpx-720p -threads 2 -y out.mp4

amix=inputs=2 Микширование аудиопотоков. Здесь мы указываем сколько потоков на входе и отбрасываем само их перечисление.
У amix также есть полезный параметр duration, который позволяет подстраивать длину выходного потока и может принимать одно из трёх значений:
longest — по длительности самого большого микшируемого аудиопотока,
shortest — соответственно, самого короткого,
first — по длине первого из перечисленных потоков.

Картинка налагается на видео

avconv -i video.mkv -i logo.png -filter_complex overlay=x=10:y=main_h-overlay_h-10 -q 1 out.mkv

overlay — позволяет накладывать один поток на другой. В качестве потока можно использовать и картинку. В примере выше мы задаём наложить логотип с отступом слева и снизу на десять пикселей. Чтобы вычислить отступ снизу мы вычитаем высоту накладываемого потока от высоты основного потока и дополнительно вычитаем сам отступ.

На этом примере мы можем продемонстрировать использование нескольких фильтров вместе. Для разделения списка фильтров используется ";".

avconv -i in1.avi -i in2.avi -filter_complex "[1:v]scale=w=iw/3:h=ih/3[v_small];[0:v][v_small]overlay=x=main_w-overlay_w-main_w/20:y=main_h-overlay_h-main_w/20" -q 1 out.avi

Берём второе изображение, уменьшаем его в три раза и размещаем в правый нижний угол, сделав отступ от края равный по горизонтали и вертикали одной двадцатой ширины этого изображения.

P.S. Хотелось бы сказать в конце о том, что конечный вариант сильно отличался от того, как всё виделось в начале. Не в последнюю очередь на это повлияло множество багов даже в самой последней версии. В качестве стабильной предлагается версия из ветки 0.8, но там, к сожалению, отсутствует множество интересных возможностей. С другой стороны, avconv из ветки 0.9 весьма нестабильна и ухитрялась, в уже казалось бы протестированных местах, на некоторых входных файлах съедать всю оперативную память за несколько секунд и вешать сервер. Конечно, использоание памяти можно лимитировать текущему пользователю, но проблему это всё равно не решает, поскольку avconv в любом случае выпадает с ошибкой. Иногда пропадали отдельные ролики из видеоряда, в некоторых случаях неожиданно расходилось время на звуковой дорожке и видеоряде — приходилось искать другие инструменты и другие способы выполнять те же задачи.

UPD: Наложить одну картинку на звук:
ffmpeg -r 1 -loop 1 -i aa.jpg -i aa.mp4 -acodec copy -vcodec mjpeg -t 326 -q 1 -y a.mp4


У кого в системе нет avconv 0.9
1) клонируем git и кофигурируем
git clone git://git.libav.org/libav.git; ./configure

2) Компиляцию лучше указать в несколько потоков чтоб побыстрее. Install лучше не делать чтоб потом ничего не пришлось в системе востанавливать.
make -j 8

Если не будет каких кодеков:
 ./configure --help

И там просто посмотреть что --enabled например ./configure --enable-vdpau

Полезные ссылки

Справка avconv (англ.)
Вычисляемые выражения, которые можно использовать в -filter_complex
Видеофильтры
Аудиофильтры
Также на хабре есть неплохой перевод статьи по конвертации видеофайлов 19 команд ffmpeg для любых нужд, где можно почерпнуть ещё полезных рецептов. Практически всё будет работать с avconv.
Tags:
Hubs:
+20
Comments 13
Comments Comments 13

Articles