Ffmpeg линукс как пользоваться

Содержание
  1. Как установить и использовать FFmpeg в Ubuntu 20.04
  2. Установка FFmpeg в Ubuntu
  3. Примеры FFmpeg
  4. Базовая конверсия
  5. Указание кодеков
  6. Выводы
  7. 19 команд ffmpeg для любых нужд
  8. 20 команд FFmpeg для начинающих
  9. 1. Получение информации об аудио/видео файле
  10. 2. Конвертирование видеофайлов в различные форматы
  11. 3. Конвертирование видео файлов в аудио
  12. 4. Изменение разрешения видео
  13. 5. Сжатие видео
  14. 6. Сжатие аудио.
  15. 7. Удаление из медиафайла аудиопотока.
  16. 8. Удаление видеопотока из медиафайла.
  17. 9. Извлечение изображений из видео
  18. 10. Обрезка видео
  19. 11. Конвертирование части видео
  20. 12. Установка соотношения сторон видео
  21. 13. Добавление постера в аудио файлы
  22. 14. Вырезание части видео файла
  23. 15. Разрезание видео файла на несколько частей
  24. 16. Объединение нескольких видео файлов
  25. 17. Добавление субтитров в видео файл
  26. 18. Тестирование видео и аудио файлов
  27. 19. Ускорение/замедление воспроизведения видео
  28. 20. Получение помощи
  29. Руководство по FFmpeg libav
  30. Оглавление
  31. Вступление ↑
  32. Видео — это то, что ты видишь! ↑
  33. Аудио — это то, что ты слышишь! ↑
  34. Кодек — сжатие данных ↑
  35. Контейнер — удобный способ хранения аудио/видео ↑
  36. Командная строка FFmpeg↑
  37. Инструмент командной строки FFmpeg 101 ↑
  38. Основные операции над видео↑
  39. Транскодирование (перекодирование)↑
  40. Трансмультиплексирование↑
  41. Трансрейтинг↑
  42. Трансайзинг (перекалибровка)↑
  43. Бонус: адаптивный стриминг↑
  44. Выходя за рамки↑
  45. Тернистый путь изучения FFmpeg libav↑
  46. Глава 0 — простенький «Hello World»↑
  47. Архитектура FFmpeg libav↑
  48. Требования↑
  49. Собственно, код↑
  50. Глава 1 — синхронизация аудио и видео↑
  51. Глава 2 — ремультиплексирование↑
  52. Глава 3 — транскодирование↑
  53. Трансмультиплексирование↑
  54. Транскодирование↑

Как установить и использовать FFmpeg в Ubuntu 20.04

FFmpeg — это бесплатный набор инструментов с открытым исходным кодом для работы с мультимедийными файлами. Он содержит набор общих аудио и видео библиотек, таких как libavcodec, libavformat и libavutil. С FFmpeg вы можете конвертировать между различными видео и аудио форматами, устанавливать частоту дискретизации, захватывать потоковое аудио / видео и изменять размер видео.

В этой статье описывается, как установить FFmpeg в Ubuntu 20.04.

Установка FFmpeg в Ubuntu

Официальные репозитории Ubuntu содержат пакеты FFmpeg, которые можно установить с помощью диспетчера пакетов apt . Это самый простой способ установить FFmpeg в Ubuntu. Новая основная версия выпускается каждые шесть месяцев, и версия, включенная в репозитории, обычно отстает от последней версии FFmpeg.

На момент написания этой статьи текущая версия FFmpeg, доступная в репозиториях Ubuntu 20.04, — 4.2.x Чтобы установить его, введите следующую команду от имени пользователя root или пользователя с привилегиями sudo :

Чтобы проверить установку, используйте команду ffmpeg -version , которая выводит версию FFmpeg:

Результат должен выглядеть примерно так:

Чтобы распечатать все доступные кодировщики и декодеры FFmpeg, введите:

Вот и все. FFmpeg теперь установлен в вашей системе, и вы можете начать его использовать.

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

Примеры FFmpeg

В этом разделе мы рассмотрим несколько основных примеров использования утилиты ffmpeg .

Базовая конверсия

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

Конвертируйте видеофайл из mp4 в webm:

Конвертируйте аудиофайл из mp3 в ogg:

Указание кодеков

При преобразовании файлов используйте параметр -c чтобы указать кодеки. Это может быть имя любого поддерживаемого декодера / кодировщика или copy специального значения, которая просто копирует входной поток.

Преобразование видео файл из mp4 в WebM , используя libvpx видеокодек и libvorbis аудиокодек:

Конвертируйте аудиофайлы из mp3 в ogg, закодированные с libopus кодека libopus .

Выводы

Мы показали вам, как установить FFmpeg в Ubuntu 20.04. Теперь вы можете посетить официальную страницу документации FFmpeg и узнать, как использовать FFmpeg для преобразования ваших видео и аудио файлов.

Если вы столкнулись с проблемой или хотите оставить отзыв, оставьте комментарий ниже.

Источник

19 команд ffmpeg для любых нужд

От переводчика:
Многие знают, что ffmpeg — это сила, но не все знают, какая именно. Он многогранен и безграничен, а его man объёмен и местами малопонятен, лишь немногие постигли дао профессиональной работы с ним. И тем не менее, этот инструмент может быть полезен почти всем, кто хоть иногда работает с видео и звуком, даже на бытовом уровне. О некоторых полезных консольных командах ffmpeg и пойдёт речь в статье. В некоторых местах я взял на себя смелость вставить ссылки на поясняющие статьи.

ffmpeg — это кроссплатформенная open-source библиотека для обработки видео- и аудиофайлов. Я собрал 19 полезных и удивительных команд, покрывающих почти все нужды: конвертация видео, извлечение звуковой дорожки, конвертирование для iPod или PSP, и многое другое.

1. Получение информации о видеофайле
2. Превратить набор картинок в видео

Эта команда преобразует все картинки из текущей директории (названные image1.jpg, image2.jpg и т.д.) в видеофайл video.mpg

(примечание переводчика: мне больше нравится такой формат:

здесь задаётся frame rate (12) для видео, формат «image_%010d.png» означает, что картинки будут искаться в виде image_0000000001.png, image_0000000002.png и тд, то есть, в формате printf)

3. Порезать видео на картинки

Эта команда создаст файлы image1.jpg, image2.jpg и т.д., поддерживаются так же форматы PGM, PPM, PAM, PGMYUV, JPEG, GIF, PNG, TIFF, SGI.

Источник

20 команд FFmpeg для начинающих

Оригинал: 20 FFmpeg Commands For Beginners
Автор: SK
Дата публикации: 10 мая 2017 года
Перевод: А. Кривошей
Дата перевода: октябрь 2017 г.

В этом руководстве мы объясним, как использовать мультимедийный фреймвок FFmpeg для преобразования различных аудио и видео файлов.

Стандартный синтаксис команды FFmpeg:

Далее мы рассмотрим некоторые важные и полезные команды FFmpeg.

1. Получение информации об аудио/видео файле

Для этого используется следующая команда:

Как можно видеть из этого примера, FFmpeg отображает информацию о мультимедийном файле вместе с данными FFmpeg, такими как версия, сведения о конфигурации, уведомления об авторских правах, варианты сборки, библиотеки и т. д.
Если вы не хотите видеть баннер FFmpeg и другие данные, а только информацию о файлах мультимедиа, используйте флаг -hide_banner, как показано ниже.

2. Конвертирование видеофайлов в различные форматы

FFmpeg — это мощный аудио и видео конвертер, позволяющий преобразовывать медиафайлы в различные форматы. Например, чтобы преобразовать файл mp4 в avi, выполните команду:

Точно так же вы можете конвертировать медиафайлы в любой формат по вашему выбору.
Например, чтобы преобразовать видео в формате FLV из YouTube в формат mpeg, выполните:

Проверить список поддерживаемых FFmpeg форматов можно с помощью следующей команды:

3. Конвертирование видео файлов в аудио

Чтобы преобразовать видео файл в аудио, просто укажите формат вывода, например .mp3 или .ogg, либо любой другой аудиоформат.
Приведенная ниже команда преобразует видео файл file.mp4 в file.mp3.

Также вы можете использовать различные опции конвертирования, как показано ниже:

-vn – говорит о том, что мы отключили запись видео в конечный файл.
-ar – задает частоту дискретизации звука конечного файла. Наиболее широко используются значения 22050, 44100, 48000 Гц.
-ac – задает количество аудиоканалов.
-ab – задает битрейт.
-f – формат конечного файла. В нашем случае это mp3.

4. Изменение разрешения видео

Предположим, вы хотите задать для видео файла определенное разрешение, это делается с помощью следующей команды:

Приведенная выше команда задает разрешение видео 1280×720.

Аналогично, чтобы преобразовать этот файл к разрешению 640×480, выполните:

5. Сжатие видео

Всегда хочется уменьшить размер медиафайлов, чтобы освободить место на жестком диске.
Следующая команда сжимает видео и уменьшает размер файла.

Помните, что при сжатии ухудшается качество. Для его сохранения можно снизить значение crf до 23 или еще ниже.

6. Сжатие аудио.

Вы также можете сжимать аудио файлы с помощью флага -ab, чтобы освободить место на диске.
Предположим, что ваш файл имеет битрейт 320 кб/с. Вы можете сжать его, уменьшив битрейт.

Ниже список доступных битрейтов:

96kbps
112kbps
128kbps
160kbps
192kbps
256kbps
320kbps

7. Удаление из медиафайла аудиопотока.

Если вам не нужен звук в видео файле, вы можете удалить аудиопоток с помощью флага -an.

Читайте также:  Загрузочная флешка windows 10 с утилитами gorskiy

Приведенная выше команда отменяет все связанные с аудио флаги, потому что мы удаляем звук из input.mp4.

8. Удаление видеопотока из медиафайла.

Аналогично, если вам не нужен видеопоток, вы можете легко удалить его из медиафайла с помощью флага «vn». Другими словами, эта команда преобразует заданный медиафайл в звуковой файл.

Следующая команда удалит видео из медиафайла.

Вы также можете задать битрейт конечного файла с помощью флага «ab», как показано ниже.

9. Извлечение изображений из видео

Еще одна полезная функция FFmpeg — извлечение изображений из видео файлов. Например, для создания фотоальбома.
Извлечение изображений из видео файла производится с помощью следующей команды:

-r – задает фреймрейт, то есть количество извлекаемых фреймов в 1 секунде видео. Значение по умолчанию — 25.
-f – формат извлекаемого изображения.
image-%2d.png – задает названия для наших файлов изображений. В этом примере это имена image-01.png, image-02.png, image-03.png и так далее. Если вы зададите %3d, то получите имена image-001.png, image-002.png и так далее.

10. Обрезка видео

В целом это похоже на изменение разрешения видео. Скажем, если вам нужно видео с разрешением 300×300, вы можете получить его с помощью следующей команды:

Необходимо помнить, что обрезка видео отрицательно влияет на его качество.

11. Конвертирование части видео

Иногда нужно конвертировать в другой формат только часть видео файла. Например, приведенная ниже команда конвертирует первые 50 секунд файла video.mp4 в файл video.avi.

Здесь мы задаем время в секундах. Также можно задавать его в формате hh.mm.ss.

12. Установка соотношения сторон видео

Вы можете задать соотношение сторон видео файла с помощью флага -aspect, как показано ниже.

Обычно используются следующие соотношения:

13. Добавление постера в аудио файлы

Вы можете добавлять изображения постеров в ваши файлы, чтобы они показывались во время воспроизведения файла. Это может быть полезно при размещении их на видеохостингах или веб-сайтах.

14. Вырезание части видео файла

Чтобы вырезать часть видео файла и сохранить ее в отдельный клип, используется команда вида:

–s – указывает время, с которого начинается вырезание видео, в нашем примере с 50-й секунды.
-t – указывает продолжительность нашего клипа.

15. Разрезание видео файла на несколько частей

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

Здесь -t 00:00:30 показывает, что первая часть берется от начала видео до 30-й секунды. -ss 00:00:30 задает начальную точку для второй части. То есть вторая часть берется с 30-й секунды до конца оригинального видео.

16. Объединение нескольких видео файлов

FFmpeg также позволяет объединять несколько видео файлов в один.

Создайте файл join.txt, в котором записаны пути ко всем видео файлам, которые вы хотите объединить. Все части должны иметь один формат (один кодек).

/home/sk/myvideos/part1.mp4
/home/sk/myvideos/part2.mp4
/home/sk/myvideos/part3.mp4
/home/sk/myvideos/part4.mp4

Теперь вы можете объединить их с помощью команды:

17. Добавление субтитров в видео файл

С помощью FFmpeg мы также можем добавлять субтитры в видео файл. Это делается с помощью следующей команды:

18. Тестирование видео и аудио файлов

Если вам хочется проверить, правильно ли было произведено конвертирование файла, вы можете воспроизвести его в терминале с помощью команды:

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

19. Ускорение/замедление воспроизведения видео

FFmpeg позволяет вам регулировать скорость воспроизведения. Для увеличения скорости воспроизведения используется команда:

Для замедления скорости воспроизведения:

20. Получение помощи

В этом руководстве мы показали только самые основные и часто используемые команды FFmpeg. На самом деле он имеет огромное количество различных опций для реализации разных продвинутых возможностей. Найти их описание можно на man-странице:

Источник

Руководство по FFmpeg libav

Долго искал книгу, в которой было бы разжёвано, как использовать FFmpeg-подобную библиотеку, известную как libav (название расшифровывается как library audio video). Обнаружил учебник «Как написать видеоплеер и уложиться в менее чем тысячу строк». К сожалению, информация там устаревшая, так что пришлось создавать мануал своими силами.

Большая часть кода будет на C, однако не волнуйтесь: Вы легко всё поймёте и сможете применить на любимом языке. У FFmpeg libav уйма привязок ко многим языкам (в том числе и к Python и к Go). Но даже если Ваш язык прямой совместимости не имеет, всё равно можно привязаться через ffi (вот пример с Lua).

Начнём с краткого экскурса о том, что такое видео, аудио, кодеки и контейнеры. Затем перейдем к ускоренному курсу, посвященному использованию командной строки FFmpeg, и, наконец, напишем код. Не стесняйтесь переходить сразу в раздел «Тернистый путь изучения FFmpeg libav».

Есть мнение (и не только моё), что потоковое интернет-видео уже приняло эстафету от традиционного телевидения. Как бы то ни было, FFmpeg libav точно достоин изучения.

Оглавление


Статья переведена при поддержке компании EDISON.

Мы очень любим работать с видео! 😉

Вступление ↑

Видео — это то, что ты видишь! ↑

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

Иллюстрация 1886 года.

Аудио — это то, что ты слышишь! ↑

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

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

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

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

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

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

Допустим, создаём видео с разрешением 1080×1920 (высота × ширина). Тратим 3 байта на пиксель (минимальную точку на экране) для цветового кодирования (24-битного цвета, что дает нам разных цветов). Это видео работает со скоростью 24 кадра в секунду, общая продолжительность 30 минут.

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

Контейнер — удобный способ хранения аудио/видео ↑

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

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

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

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

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

Для работы с мультимедиа у нас есть восхитительный инструмент — библиотека под названием FFmpeg. Даже если Вы не используете её в своём программном коде, то всё равно используете её (Вы ведь используете Chrome?).

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

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

Инструмент командной строки FFmpeg 101 ↑

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

Схематично, программа командной строки FFmpeg ожидает, что следующий формат аргументов выполнит свои действия — ffmpeg <1> <2>-i <3> <4>, где:

— глобальные параметры
— параметры входного файла
— входящий URL
— параметры выходного файла
— исходящий URL

В частях <2>, <3>, <4>, <5>указывается столько аргументов, сколько нужно. Проще понять формат передачи аргументов на примере:

Читайте также:  Включить службу обновления windows если выключена

# ПРЕДУПРЕЖДЕНИЕ: файл по ссылке весит 300 МБ

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

Если упростить приведенную выше команду, то следует учесть, что FFmpeg примет значения по умолчанию вместо Вас. Например, если просто набрать

то, какой аудио/видео кодек он использует для создания output.mp4?

Вернер Робица написал руководство по чтению/исполнению, посвященное кодированию и редактированию с помощью FFmpeg.

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

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

Транскодирование (перекодирование)↑

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

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

Как? Преобразуем, к примеру, видео H264 (AVC) в H265 (HEVC):

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

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

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

Как? Конвертируем mp4 в webm:

Трансрейтинг↑

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

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

Как? производит воспроизведение с битрейтом между 3856K и 2000K.

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

Трансайзинг (перекалибровка)↑

Что это? Изменение разрешающей способности. Как сказано выше, транссайзинг часто проводится одновременно с трансрейтингом.

Для чего? По тем же причинам, что и с трансрейтингом.

Как? Уменьшим разрешение 1080 до 480:

Бонус: адаптивный стриминг↑

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

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

Как? Создадим адаптивный WebM с использованием DASH:

Выходя за рамки↑

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

Тернистый путь изучения FFmpeg libav↑

Разве время от времени не поразительно то, что воспринимается через слух и зрение?

Биолог Дэвид Роберт Джонс

FFmpeg крайне полезен как инструмент в виде командной строки для выполнения важных операций с мультимедийными файлами. Может и в программах его тоже получится использовать?

FFmpeg состоит из нескольких библиотек, которые можно интегрировать в наши собственные программы. Обычно, при установке FFmpeg, автоматически устанавливаются все эти библиотеки. Я буду ссылаться на набор этих библиотек как FFmpeg libav.

Название раздела является данью уважения серии Зеда Шоу «Тернистый путь обучения [. ]», в частности его книге «Тернистый путь обучения языку C».

Глава 0 — простенький «Hello World»↑

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

Архитектура FFmpeg libav↑

Но прежде чем начнём писать код, давайте посмотрим, как вообще работает архитектура FFmpeg libav и как ее компоненты взаимодействуют с другими.

Вот схема процесса декодирования видео:

Сначала медиафайл загружается в компонент по имени AVFormatContext (контейнер видео также является форматом). На самом деле он не полностью загружает весь файл: часто читается только заголовок.

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

Предположим, наше видео имеет два потока: аудио, закодированное с помощью кодека AAC, и видео, закодированное с помощью кодека H264 (AVC). Из каждого потока можем извлечь фрагменты данных, называемые пакетами, которые загружаются в компоненты, называемые AVPacket.

Данные внутри пакетов по-прежнему кодируются (сжимаются), и для декодирования пакетов нам необходимо передать их конкретному AVCodec.

AVCodec декодирует их в AVFrame, в результате чего этот компонент выдает нам несжатый кадр. Отметим, что терминология и процесс одинаковы как для аудио- так и видео-потока.

Требования↑

Так как иногда возникают проблемы при компиляции или запуске примеров, мы будем использовать Docker в качестве среды разработки/выполнения. Также будем использовать видео с большим кроликом, поэтому, если у вас его нет на локальном компьютере, просто проведите в консоли команду make fetch_small_bunny_video.

Собственно, код↑

TLDR; покажи мне пример выполянемого кода, бро:

Мы опустим некоторые детали, но не волнуйтесь: исходный код доступен на github.

Мы собираемся выделить память для компонента AVFormatContext, который будет содержать информацию о формате (контейнере).

Теперь мы собираемся открыть файл, прочитать его заголовок и заполнить AVFormatContext минимальной информацией о формате (обратите внимание, что обычно кодеки не открываются). Для этого используется функция avformat_open_input. Он ожидает AVFormatContext, имя файла и два необязательных аргумента: AVInputFormat (если вы передадите NULL, FFmpeg определит формат) и AVDictionary (которые являются опциями демультиплексора).

Также можно напечатать название формата и длительность медиа:

Чтобы получить доступ к потокам, нам нужно прочитать данные с носителя. Это делает функция avformat_find_stream_info. Теперь pFormatContext-> nb_streams будет содержать количество потоков, а pFormatContext-> streams[i] даст нам i-й по счёту поток (AVStream).

Пройдемся в цикле по всем потокам:

Для каждого потока мы собираемся сохранить AVCodecParameters, описывающий свойства кодека, используемого i-м потоком:

Используя свойства кодеков можем найти соответствующий, запрашивая функцию avcodec_find_decoder, также можем найти зарегистрированный декодер для идентификатора кодека и вернуть AVCodec — компонент, который знает, как кодировать и декодировать поток:

Теперь мы можем распечатать информацию о кодеках:

С помощью кодека выделяем память для AVCodecContext, который будет содержать контекст для нашего процесса декодирования/кодирования. Но затем нужно заполнить этот контекст кодека параметрами CODEC — мы делаем это с помощью avcodec_parameters_to_context.

После того, как мы заполнили контекст кодека, необходимо открыть кодек. Вызываем функцию avcodec_open2 и затем можем ее использовать:

Теперь мы собираемся прочитать пакеты из потока и декодировать их в кадры, но сначала нам нужно выделить память для обоих компонентов (AVPacket и AVFrame).

Давайте скормим наши пакеты из потоков функции av_read_frame, пока у нее есть пакеты:

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

И давайте получим кадр необработанных данных (несжатый кадр) от декодера через тот же контекст кодека, используя функцию avcodec_receive_frame:

Мы можем напечатать номер кадра, PTS, DTS, тип кадра и т.д.:

И напоследок, можем сохранить наш декодированный кадр в простое серое изображение. Процесс очень прост: мы будем использовать pFrame->data, где индекс связан с цветовыми пространствами Y, Cb и Cr. Просто выбираем 0 (Y), чтобы сохранить наше серое изображени:

И вуаля! Теперь у нас есть полутоновое изображение размером 2Мб:

Глава 1 — синхронизация аудио и видео↑

Быть в игре — это когда юный JS-разработчик пишет новый MSE-видеоплеер.

Прежде чем перейдем написанию кода транскодирования, давайте поговорим о синхронизации или о том, как видеоплеер узнаёт правильное время для воспроизведения кадра.

В предыдущем примере мы сохранили несколько кадров:

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

Читайте также:  При запуске windows открываются блокнот

Поэтому нам нужно определить некую логику для плавного воспроизведения каждого кадра. В этом отношении каждый кадр имеет временнýю метку представления (PTS — от presentation timestamp), которая представляет собой увеличивающееся число, учитываемое в переменной timebase, которая представляет собой рациональное число (где знаменатель известен как временно́й масштаб — timescale), делимое на частоту кадров (fps).

Проще понять на примерах. Давайте смоделируем некоторые сценарии.

Для fps = 60/1 и timebase = 1/60000 каждый PTS будет увеличивать timescale / fps = 1000, поэтому реальное время PTS для каждого кадра может быть (при условии, что оно начинается с 0):

Почти по тому же сценарию, но с timescale, равной 1/60:

Для fps = 25/1 и timebase = 1/75 каждая PTS будет увеличивать timescale / fps = 3, и время PTS может быть:

Теперь с pts_time мы можем найти способ визуализировать это синхронизированным со звуком pts_time или с системными часами. FFmpeg libav предоставляет эту информацию через свой API:

Просто из любопытства, сохраненные нами кадры были отправлены в порядке DTS (кадры: 1, 6, 4, 2, 3, 5), но воспроизведены в порядке PTS (кадры: 1, 2, 3, 4, 5). Также обратите внимание, насколько дешевле обходятся B-кадры по сравнению с P или I-кадрами:

Глава 2 — ремультиплексирование↑

Ремультиплексирование (перекомпоновка, remuxing) — переход от одного формата (контейнера) к другому. Например, мы можем без особого труда заменить видео MPEG-4 на MPEG-TS с помощью FFmpeg:

MP4-файл будет демультиплексирован, при этом файл не будет декодирован или кодирован (-c copy), и, в конце концов, на выходет получим mpegts-файл. Если не указывать формат -f, ffmpeg попытается угадать его на основании расширения файла.

Общее использование FFmpeg или libav следует такому шаблону/архитектуре или рабочему процессу:

  • уровень протокола — принятие входных данных (например, файл, но это может быть также загрузка по rtmp или HTTP)
  • уровень формата — демультиплексирование контента, открытие, в основном, метаданных и потоков
  • уровень кодека — декодирование данных для сжатых потоков при необходимости
  • уровень пикселей — также возможно применение некоторых фильтров к необработанным кадрам (например, изменение размера), необязательный пункт
  • … а затем он происходит движение в обратном направлении:
  • уровень кодека — кодирование (или перекодирование или даже транскодирование) необработанных кадров
  • уровень формата — мультиплексирование (или ремультиплексирование) необработанных потоков (сжатых данных)
  • уровень протокола — и, наконец, мультиплексированные данные отправляются на выход (в другой файл или, возможно, на сетевой удаленный сервер)


(Этот график сильно вдохновлен работами Leixiaohua и Slhck)

Теперь давайте создадим пример с использованием libav, чтобы обеспечить тот же эффект, что и при выполнении такой команды:

Мы собираемся читать из ввода (input_format_context) и изменять его на другой вывод (output_format_context):

Обычно начинаем с того, что выделяем память и открываем формат ввода. Для этого конкретного случая мы собираемся открыть входной файл и выделить память для выходного файла:

Будем ремультиплексировать только потоки видео, аудио и субтитров. Поэтому фиксируем, какие потоки будем использовать, в массив индексов:

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

Теперь создаём выходной файл:

После этого можно копировать потоки, пакет за пакетом, из нашего ввода в наши выходные потоки. Это происходит в цикле, пока есть пакеты (av_read_frame), для каждого пакета нужно пересчитать PTS и DTS, чтобы наконец записать его (av_interleaved_write_frame) в наш контекст выходного формата.

Для завершения нам нужно записать трейлер потока в выходной медиафайл с помощью функции av_write_trailer:

Теперь мы готовы протестировать код. И первым тестом будет преобразование формата (видео-контейнера) из MP4 в видеофайл MPEG-TS. В основном мы создаем командную строку ffmpeg input.mp4 -c для копирования output.ts с помощью libav.

Это работает! Не верите?! Проверьте с помощью ffprobe:

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

Прежде чем закончим эту главу, хотелось бы показать такую важную часть процесса ремультиплексрования, где можно передавать параметры мультиплексору. Допустим, надо предоставить формат MPEG-DASH, поэтому нужно использовать фрагментированный mp4 (иногда называемый fmp4) вместо MPEG-TS или обычного MPEG-4.

С помощью командной строки это легко:

Почти так же просто это и в libav-версии, просто передаём опции при записи выходного заголовка, непосредственно перед копированием пакетов:

Теперь можем сгенерировать этот фрагментированный mp4-файл:

Чтобы убедиться, что тут всё по-честному, Вы можете использовать удивительный сайт-инструмент gpac/mp4box.js или сайт http://mp4parser.com/, дабы увидеть различия — сначала загрузите mp4.

Как видно, он имеет один неделимый блок mdat — это место, где находятся видео и аудио кадры. Теперь загрузите фрагментированный mp4, чтобы увидеть, как он расширяет блоки mdat:

Глава 3 — транскодирование↑

TLDR; покажи мне код и исполнение:

Мы пропустим некоторые детали, но не волнуйтесь: исходный код доступен на github.

В этой главе создадим минималистичннй транскодер, написанный на C, который может конвертировать видео из H264 в H265 с использованием библиотек FFmpeg libav, в частности libavcodec, libavformat и libavutil.

AVFormatContext — это абстракция для формата медиа-файла, т.е. для контейнера (MKV, MP4, Webm, TS)
AVStream представляет каждый тип данных для данного формата (например: аудио, видео, субтитры, метаданные)
AVPacket — это фрагмент сжатых данных, полученных из AVStream, которые могут быть декодированы с помощью AVCodec (например: av1, h264, vp9, hevc), генерирующих необработанные данные, называемые AVFrame.

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

Начнем с простого преобразования, затем загрузим входной файл.

Теперь настроим декодер. AVFormatContext предоставит нам доступ ко всем компонентам AVStream, и для каждого из которых можем получить их AVCodec и создать конкретный AVCodecContext. И, наконец, можем открыть данный кодек, чтобы перейти к процессу декодирования.

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

Также нужно подготовить выходной медиа-файл для преобразования. Сначала выделим память для выходного AVFormatContext. Создадим каждый поток в выходном формате. Чтобы правильно упаковать поток, копируем параметры кодека из декодера.

Устанавливаем флаг AV_CODEC_FLAG_GLOBAL_HEADER, который сообщает кодировщику, что он может использовать глобальные заголовки, и, наконец, открываем выходной файл для записи и сохраняем заголовки:

Получаем AVPacket от декодера, корректируем метки времени и записываем пакет правильно в выходной файл. Несмотря на то, что функция av_interleaved_write_frame сообщает «write frame», сохраняем пакет. Заканчиваем процесс перестановки, записывая трейлер потока в файл.

Транскодирование↑

В предыдущем разделе была простая программа для преобразования, теперь добавим возможность кодировать файлы, в частности, перекодирование видео с h264 на h265.

После того, как подготовлен декодер, но перед тем, как организовать выходной медиафайл, настроим кодировщик.

  • Создаём видео AVStream в кодировщике avformat_new_stream.
  • Используем AVCodec с именем libx265, avcodec_find_encoder_by_name.
  • Создаём AVCodecContext на основе созданного кодека avcodec_alloc_context3.
  • Устанавливаем основные атрибуты для сеанса транскодирования и.
  • … открываем кодек и копируем параметры из контекста в поток (avcodec_open2 и avcodec_parameters_from_context).

Необходимо расширить цикл декодирования для транскодирования видеопотока:

  • Отправляем пустой AVPacket декодеру (avcodec_send_packet).
  • Получаем несжатый AVFrame (avcodec_receive_frame).
  • Начинаем перекодирование необработанного кадра.
  • Отправляем необработанный кадр (avcodec_send_frame).
  • Получаем сжатие, основанное на нашем кодеке AVPacket (avcodec_receive_packet).
  • Устанавливаем отметку времени (av_packet_rescale_ts).
  • Записываем в выходной файл (av_interleaved_write_frame).

Мы преобразовали поток мультимедиа из h264 в h265. Как и ожидалось, версия медиа-файла h265 меньше, чем h264, при этом у программы широкие возможности:

Положа руку на сердце, признаюсь, что было несколько посложнее, чем представлялось в начале. Пришлось ковыряться в исходном коде командной строки FFmpeg и много тестировать. Наверное, что-то где-то упустил, потому что пришлось применять force-cfr для h264, и всё ещё выскакивают некоторые предупреждающие сообщения, например о том, что тип кадра (5) принудительно был изменен на тип кадра (3).

Источник

Оцените статью