Вводное руководство по FFmpeg libav

Добавлено 26 февраля 2022 в 23:20

Я искал учебник/книгу, которая показала бы, как начать использовать FFmpeg в качестве библиотеки (также известной как libav), и нашел руководство «How to Write a Video Player in Less Than 1000 Lines» (как написать видеоплеер менее чем за 1000 строк). К сожалению, оно устарело, поэтому я решил написать своё.

Большая часть кода здесь будет на C, но не беспокойтесь: вы можете легко его понять и применить к предпочитаемому вами языку. FFmpeg libav имеет множество привязок для многих языков, таких как python, go, и даже если для вашего языка ее нет, вы все равно можете поддерживать ее через ffi (вот пример с Lua).

Мы начнем с краткого урока о том, что такое видео, аудио, кодек и контейнер, затем перейдем к ускоренному курсу о том, как использовать командную строку FFmpeg, и, наконец, мы напишем код, не стесняйтесь сразу перейти к разделу «Сложный способ изучения FFmpeg libav».

Некоторые люди говорили, что потоковое видео в Интернете – это будущее традиционного телевидения, в любом случае FFmpeg – это то, что стоит изучить.

Содержание

Введение

Видео – это то, что вы видите!

Если у вас есть последовательность изображений, и вы меняете их с заданной частотой (скажем, 24 изображения в секунду), вы создадите иллюзию движения. Таким образом, это самая основная идея видео: последовательность изображений/кадров, воспроизводимых с заданной скоростью.

Иллюстрация Zeitgenssische (1886 г.)
Иллюстрация Zeitgenössische (1886 г.)

Аудио – это то, что вы слышите!

Хотя видео с отключенным звуком может выражать самые разные чувства, добавление звука привносит больше ощущений.

Звук – это вибрация, которая распространяется в виде волны давления в воздухе или любой другой передающей среде, такой как газ, жидкость или твердое тело.

В цифровой аудиосистеме микрофон преобразует звук в аналоговый электрический сигнал, затем аналого-цифровой преобразователь (АЦП) – обычно с использованием импульсно-кодовой модуляции (ИКМ) – преобразует аналоговый сигнал в цифровой сигнал.

Преобразование аудиосигнала

Кодек – сжатие данных

Кодек – это электронная схема или программное обеспечение, которое сжимает или распаковывает цифровые аудио/видео данные. Он преобразует необработанное (несжатое) цифровое аудио/видео в сжатый формат или наоборот.

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

Предположим, мы создаем видео с разрешением 1080 x 1920 (высота x ширина) и, что мы тратим 3 байта на пиксель (самая маленькая точка на экране) для кодирования цвета (т.е. 24 бита для цвета, что дает нам 16 777 216 разных цветов), и это видео воспроизводится со скоростью 24 кадра в секунду и длится 30 минут.

toppf = 1080 * 1920 //total_of_pixels_per_frame (общее количество пикселей в кадре)
cpp = 3             //cost_per_pixel (стоимость одного пикселя)
tis = 30 * 60       //time_in_seconds (время в секундах)
fps = 24            //frames_per_second (кадров в секунду)

// необходимый размер хранилища
required_storage = tis * fps * toppf * cpp

Для этого видео потребуется примерно 250,28 ГБ памяти или пропускная способность 1,11 Гбит/с! Вот почему нам нужно использовать кодек.

Контейнер – удобное место для хранения аудио и видео

Формат контейнера или оболочки – это формат метафайла, спецификация которого описывает, как различные элементы данных и метаданных сосуществуют в компьютерном файле.

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

Обычно мы можем определить формат файла, взглянув на его расширение: например, video.webm – это, вероятно, видео, использующее контейнер webm.

контейнер

Командная строка FFmpeg

Полное кроссплатформенное решение для записи, преобразования и потоковой передачи аудио и видео.

Для работы с мультимедиа мы можем использовать УДИВИТЕЛЬНЫЙ инструмент/библиотеку под названием FFmpeg. Скорее всего, вы уже знаете/используете его прямо или косвенно (вы используете Chrome?).

У него есть программа командной строки под названием ffmpeg, очень простой, но мощный бинарный файл. Например, вы можете преобразовать mp4 в контейнер avi, просто введя следующую команду:

$ ffmpeg -i input.mp4 output.avi

Мы только что выполнили ремультиплексирование, то есть преобразование из одного контейнера в другой. Технически FFmpeg также может выполнять перекодирование, но мы поговорим об этом позже.

Основы инструмента командной строки FFmpeg

У FFmpeg есть документация, которая отлично объясняет, как он работает.

Короче говоря, программа командной строки FFmpeg для выполнения своих действий ожидает аргументы в следующем формате

ffmpeg {1} {2} -i {3} {4} {5}

где

  1. глобальные параметры;
  2. параметры входного файла;
  3. входной URL;
  4. параметры выходного файла;
  5. выходной URL.

Частей 2, 3, 4 и 5 может быть столько, сколько вам нужно. Этот формат аргументов легче понять на примере:

# ВНИМАНИЕ: этот файл весит примерно 300 Мб
$ wget -O bunny_1080p_60fps.mp4 http://distribution.bbb3d.renderfarming.net/video/mp4/bbb_sunflower_1080p_60fps_normal.mp4

$ ffmpeg \
-y \                             # глобальные параметры
-c:a libfdk_aac -c:v libx264 \   # входные параметры
-i bunny_1080p_60fps.mp4 \       # входной url
-c:v libvpx-vp9 -c:a libvorbis \ # выходные параметры
bunny_1080p_60fps_vp9.webm       # выходной url

Эта команда берет входной файл mp4, содержащий два потока (аудио, закодированное с помощью кодека aac, и видео, закодированное с помощью кодека h264), и преобразует его в webm, также изменяя его аудио- и видеокодеки.

Мы могли бы упростить приведенную выше команду, но имейте в виду, что FFmpeg примет или угадает значения по умолчанию. Например, когда вы просто набираете ffmpeg -i input.avi output.mp4, какой аудио/видео кодек используется для создания output.mp4?

Werner Robitza написал обязательное к прочтению руководство по кодированию и редактированию с помощью FFmpeg.

Основные операции с видео

При работе с аудио/видео мы обычно выполняем набор задач по обработке медиаконтента.

Перекодирование

Перекодирование

Что это? Действие по преобразованию одного из потоков (аудио или видео) из одного кодека в другой.

Зачем? Иногда некоторые устройства (телевизоры, смартфоны, консоли и т.д.) не поддерживают кодек X, но поддерживают кодек Y; кроме того, более новые кодеки обеспечивают лучшую степень сжатия.

Как? Например, преобразование видео H264 (AVC) в H265 (HEVC).

$ ffmpeg \
-i bunny_1080p_60fps.mp4 \
-c:v libx265 \
bunny_1080p_60fps_h265.mp4

Ремультиплексирование

Ремультиплексирование

Что это? Преобразование из одного формата (контейнера) в другой.

Зачем? Иногда некоторые устройства (телевизоры, смартфоны, консоли и т. д.) не поддерживают формат X, но поддерживают формат Y, а иногда более новые контейнеры предоставляют современные необходимые функции.

Как? Например, преобразование mp4 в ts.

$ ffmpeg \
-i bunny_1080p_60fps.mp4 \
-c copy \ # просто говорим ffmpeg пропустить кодирование
bunny_1080p_60fps.ts

Изменение скорости

Изменение скорости

Что это? Изменение скорости передачи данных или создание других представлений.

Зачем? Люди будут пытаться смотреть ваше видео через 2G (edge) соединение с помощью не очень мощного смартфона или через оптоволоконное интернет-соединение на своих 4K-телевизорах, поэтому вам следует предлагать более одного представления одного и того же видео с разным битрейтом.

Как? Например, создание воспроизведения с битрейтом от 964K до 3856K.

$ ffmpeg \
-i bunny_1080p_60fps.mp4 \
-minrate 964K -maxrate 3856K -bufsize 2000K \
bunny_1080p_60fps_transrating_964_3856.mp4

Обычно мы будем использовать изменение скорости одновременно с изменением разрешения. Вернер Робица (Werner Robitza) написал еще одну серию обязательных к прочтению статей об управлении скоростью с помощью FFmpeg.

Изменение разрешения

Изменение разрешения

Что это? Преобразование от одного разрешения к другому. Как было сказано ранее, изменение разрешения часто используется с изменением скорости.

Зачем? Причины примерно те же, что и для изменения скорости.

Как? Например, изменение разрешения 1080p на разрешение 480p.

$ ffmpeg \
-i bunny_1080p_60fps.mp4 \
-vf scale=480:-1 \
bunny_1080p_60fps_transsizing_480.mp4

Бонус: адаптивная потоковая передача

адаптивная потоковая передача

Что это? Создание множества разрешений (битрейтов) и разделение медиаконтента на куски и их выдача через http.

Зачем? Для обеспечения гибкого медиаконтента, который можно смотреть на бюджетном смартфоне или на телевизоре 4K, его также легко масштабировать и развертывать, но это может увеличить задержку.

Как? Например, создание адаптивного WebM с использованием DASH.

# видеопотоки
$ ffmpeg -i bunny_1080p_60fps.mp4 -c:v libvpx-vp9 -s 160x90 -b:v 250k -keyint_min 150 -g 150 -an -f webm -dash 1 video_160x90_250k.webm

$ ffmpeg -i bunny_1080p_60fps.mp4 -c:v libvpx-vp9 -s 320x180 -b:v 500k -keyint_min 150 -g 150 -an -f webm -dash 1 video_320x180_500k.webm

$ ffmpeg -i bunny_1080p_60fps.mp4 -c:v libvpx-vp9 -s 640x360 -b:v 750k -keyint_min 150 -g 150 -an -f webm -dash 1 video_640x360_750k.webm

$ ffmpeg -i bunny_1080p_60fps.mp4 -c:v libvpx-vp9 -s 640x360 -b:v 1000k -keyint_min 150 -g 150 -an -f webm -dash 1 video_640x360_1000k.webm

$ ffmpeg -i bunny_1080p_60fps.mp4 -c:v libvpx-vp9 -s 1280x720 -b:v 1500k -keyint_min 150 -g 150 -an -f webm -dash 1 video_1280x720_1500k.webm

# аудиопотоки
$ ffmpeg -i bunny_1080p_60fps.mp4 -c:a libvorbis -b:a 128k -vn -f webm -dash 1 audio_128k.webm

# манифест DASH
$ ffmpeg \
 -f webm_dash_manifest -i video_160x90_250k.webm \
 -f webm_dash_manifest -i video_320x180_500k.webm \
 -f webm_dash_manifest -i video_640x360_750k.webm \
 -f webm_dash_manifest -i video_640x360_1000k.webm \
 -f webm_dash_manifest -i video_1280x720_500k.webm \
 -f webm_dash_manifest -i audio_128k.webm \
 -c copy -map 0 -map 1 -map 2 -map 3 -map 4 -map 5 \
 -f webm_dash_manifest \
 -adaptation_sets "id=0,streams=0,1,2,3,4 id=1,streams=5" \
 manifest.mpd

PS: этот пример я украл из Инструкции по воспроизведению адаптивного WebM с помощью DASH.

Это еще не всё

Есть много других способов использования FFmpeg. Я использую его вместе с iMovie для создания/редактирования видео для YouTube, и вы, безусловно, можете использовать его профессионально.

Теги

FFmpeglibavДекодирование видеоКодирование видеоОбработка аудиоОбработка видеоПрограммированиеРемультиплексирование

На сайте работает сервис комментирования DISQUS, который позволяет вам оставлять комментарии на множестве сайтов, имея лишь один аккаунт на Disqus.com.

В случае комментирования в качестве гостя (без регистрации на disqus.com) для публикации комментария требуется время на премодерацию.