Skip to content

Подготовка мультибитрейтных файлов

Для того, чтобы обеспечить комфортный просмотр видео пользователям, подключенным на разных скоростях к интернету, можно воспользоваться адаптивным стримингом. Для этого надо сделать мультибитрейтный MP4 файл и запросить для него манифест. Дальнейшее Flussonic Media Server сделает сам.

Ниже мы рассмотрим, как настроить компьютер и создать мультибитрейтный файл.

Установка программ

Вам нужно иметь установленный ffmpeg и кодеки. Процесс установки отличается для разных операционных систем.

Инструкция для Windows

  1. Скачайте ffmpeg: https://ffmpeg.org/download.html
  2. Следуйте инструкции по установке.
  3. Скачайте и установите K-Lite Mega Codec Pack: http://www.codecguide.com/download_k-lite_codec_pack_mega.htm. После запуска инсталлятора будет предложено несколько вариантов установки, нужно выбрать самый полный («Lots of stuff»).

Инструкция для Linux

Мы рекомендуем поставить уже собранный ffmpeg отсюда: http://johnvansickle.com/ffmpeg Или любой другой собранный ffmpeg с официального сайта: https://www.ffmpeg.org/download.html

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

Конструирование команды для ffmpeg на примере создания multi-bitrate потока

Допустим, у нас есть видеофайл "h.m4v" с двумя звуковыми дорожками (английская, русская) и двумя субтитрами (английские, русские).

Вначале нужно посмотреть, из чего он состоит, какие внутри есть потоки. Для этого в консоли печатаем:


ffmpeg -i h.m4v

На экран выведется огромное количество текста, из которого важно вот это:


 Stream #0:0(eng): Video: h264 (Constrained Baseline) (avc1 / 0x31637661), yuv420p, 640x360 [SAR 1331:1000 DAR 2662:1125], 1800 kb/s, 23.98 fps, 23.98 tbr, 25k tbn, 180k tbc
    Metadata:
      creation_time   : 2013-01-14 14:46:26
      handler_name    :
    Stream #0:1(rus): Audio: aac (mp4a / 0x6134706D), 48000 Hz, stereo, s16, 127 kb/s
    Metadata:
      creation_time   : 2013-01-14 14:47:59
      handler_name    :
    Stream #0:2(eng): Audio: aac (mp4a / 0x6134706D), 48000 Hz, stereo, s16, 127 kb/s
    Metadata:
      creation_time   : 2013-01-14 14:48:19
      handler_name    :
    Stream #0:3(rus): Subtitle: mov_text (tx3g / 0x67337874)
    Metadata:
      creation_time   : 2013-01-14 14:48:38
      handler_name    :
    Stream #0:4(eng): Subtitle: mov_text (tx3g / 0x67337874)
    Metadata:
      creation_time   : 2013-01-14 14:48:38
      handler_name    :

Секции Stream, а в них — номер потока (0:0,0:1,0:2,0:3,0:4), тип потока (video, audio, subtitles) и язык (в данном случае eng и rus).

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

3 потока видео + 2 потока аудио + 2 потока субтитров = 7 потоков всего.

Теперь приступаем к конструированию команды для ffmpeg.

Первая строка такая:


ffmpeg -i "/home/user/temp/h.m4v" \

Обратите внимание на символ \. Это — перевод строки в Linux. В Windows вместо него используется символ ^, т.е. строка выглядит так:


ffmpeg -i "/home/user/temp/h.m4v" ^

В целом эта строка означает, что мы будем конвертировать файл, лежащий по пути, заданному после ключа -i.

Далее, нужно указать, как мы будем получать потоки в выходном файле. Нужно три раза взять поток 0:0 и превратить его в 3 видеопотока в разных качествах. Поэтому пишем: -map 0:0 -map 0:0 -map 0:0 — "три раза взять поток 0:0" Далее взять каждый из оставшихся стримов (0:1, 0:2, 0:3, 0:4) по одному разу и просто скопировать. Поэтому пишем: -map 0:1 -map 0:2 -map 0:3 -map 0:4.

Вместе первые две строки выглядят так:


ffmpeg -i "/home/user/temp/h.m4v" \
-map 0:0 -map 0:0 -map 0:0 -map 0:1 -map 0:2 -map 0:3 -map 0:4 \

Далее нужно объяснить, как все эти дорожки кодируются.

Важное замечание. Если в информации о файле все потоки считались равноправными (видео стоит в том же ряду, что и аудио), то дальше у каждого типа будут свои номера, начиная с 0. То есть, первое видео обозначается как v:0, а второе аудио — a:1.

-c:v:0 libx264 -b:v:0 1800k -metadata:s:v:0 language=eng \ — взять первую видеодорожку, кодировать как x264 с битрейтом как на исходном файле, указать что видео английское.

-c:v:1 libx264 -b:v:1 150k -metadata:s:v:1 language=eng \ — взять первую видеодорожку, кодировать как x264 c битрейтом 150k, указать что видео английское.

-c:v:2 libx264 -b:v:2 100k -metadata:s:v:2 language=eng \ — то же, что предыдущее, но с битрейтом 100k.

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

Когда на второй позиции стоит copy, никакого кодирования не происходит, копируется как есть.

Эти команды скопируют всё аудио:


-c:a:0 copy -metadata:s:a:0 language=rus \
-c:a:1 copy -metadata:s:a:1 language=eng \
-c:s:0 copy -metadata:s:s:0 language=rus \
-c:s:1 copy -metadata:s:s:1 language=eng \

Команда принимает вид:


ffmpeg -i "/home/user/temp/h.m4v" \
-map 0:0 -map 0:0 -map 0:0 -map 0:1 -map 0:2 -map 0:3 -map 0:4 \
-c:v:0 libx264 -b:v:0 1800k -metadata:s:v:0 language=eng \
-c:v:1 libx264 -b:v:1 150k -metadata:s:v:1 language=eng \
-c:v:2 libx264 -b:v:2 100k -metadata:s:v:2 language=eng \
-c:a:0 copy -metadata:s:a:0 language=rus \
-c:a:1 copy -metadata:s:a:1 language=eng \
-c:s:0 copy -metadata:s:s:0 language=rus \
-c:s:1 copy -metadata:s:s:1 language=eng \

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

-async 1 -vsync 1 \
"/home/user/temp/h2.m4v"

Теперь соберем все вместе. Команда будет выглядеть так:


ffmpeg -i "/home/user/temp/h.m4v" \
-map 0:0 -map 0:0 -map 0:0 -map 0:1 -map 0:2 -map 0:3 -map 0:4 \
-c:v:0 libx264 -b:v:0 1800k -metadata:s:v:0 language=eng \
-c:v:1 libx264 -b:v:1 150k -metadata:s:v:1 language=eng \
-c:v:2 libx264 -b:v:2 100k -metadata:s:v:2 language=eng \
-c:a:0 copy -metadata:s:a:0 language=rus \
-c:a:1 copy -metadata:s:a:1 language=eng \
-c:s:0 copy -metadata:s:s:0 language=rus \
-c:s:1 copy -metadata:s:s:1 language=eng \
-async 1 -vsync 1 \
"/home/user/temp/h2.m4v"

Вот еще один пример создания мультибитрейтного файла с помощью ffmpeg для файла bunny.mp4:

ffmpeg -i bunny.mp4 \
-map 0:0 -c:v copy \
-map 0:0 -c:v libx264 -b:v 150k  \
-map 0:0 -c:v libx264 -b:v 100k \
-map 0:1 -c:v libx264 -b:v 50k \
-map 0:1 -c:a copy \
-map 0:1 -c:a copy \
-y out.mp4

Кодирование участка видео

Иногда нужно перекодировать не всё видео, а только какой-то его участок. Для этого используется следующий параметр: -ss 00:00:00 -t 00:05:00. Здесь первая цифра показывает, с какой секунды должен начинаться кодируемый фрагмент, а вторая цифра — его продолжительность.

Можно использовать этот параметр в сочетании со многими другими. Например:


ffmpeg -i "/home/user/temp/h.m4v" \
-ss 00:00:00 -t 00:05:00 \
-map 0:0 -map 0:0 -map 0:0 -map 0:1 -map 0:2 -map 0:3 -map 0:4 \
-c:v:0 libx264 -b:v:0 1800k -metadata:s:v:0 language=eng \
-c:v:1 libx264 -b:v:1 150k -metadata:s:v:1 language=eng \
-c:v:2 libx264 -b:v:2 100k -metadata:s:v:2 language=eng \
-c:a:0 copy -metadata:s:a:0 language=rus \
-c:a:1 copy -metadata:s:a:1 language=eng \
-c:s:0 copy -metadata:s:s:0 language=rus \
-c:s:1 copy -metadata:s:s:1 language=eng \
-async 1 -vsync 1 \
"/home/user/temp/h2.m4v"

Это кодирование из предыдущей части, но сделанное только для первых 5 секунд фильма.

Cмена разрешения для треков с пониженным битрейтом

Иногда нужно не только изменить битрейт, но и уменьшить разрешение видео. Для этого используется следующий параметр: -filter:v:3 scale=320:240 Этот параметр нужно добавить к свойству трека так же, как в предыдущих примерах добавлялся битрейт или субтитры.

Разберемся, что здесь написано.

"-filter" означает, что дальше будет следовать описание фильтра, ":v:3" — это номер видеотрека, который будет присвоен треку в новом разрешении,

"scale" — название фильтра (ffmpeg поддерживает разные фильтры, конкретно этот отвечает за смену разрешения),

"320:240" — новое разрешение. Важно отметить, что если мы знаем только необходимую ширину, то высоту можно заменить на -1, т.е. "320:-1". Это позволит автоматически сохранить правильное соотношение сторон.

Теперь посмотрим, как это выглядит на практике. Для этого возьмем код из предыдущих примеров, и добавим четвертый видеотрек ("-c:v:3") с шириной 320 ("scale=320:-1"). Количество "-map 0:0" теперь 4 штуки, что соответствует четырем трекам.


ffmpeg -i "/home/user/temp/h.m4v" \
-ss 00:00:00 -t 00:05:00 \
-map 0:0 -map 0:0 -map 0:0 -map 0:0 -map 0:1 -map 0:2 -map 0:3 -map 0:4 \
-c:v:0 libx264 -b:v:0 1800k -metadata:s:v:0 language=eng \
-c:v:1 libx264 -b:v:1 150k -metadata:s:v:1 language=eng \
-c:v:2 libx264 -b:v:2 100k -metadata:s:v:2 language=eng \
-c:v:3 libx264 -b:v:3 100k -metadata:s:v:3 language=eng -filter:v:3 scale=320:-1 \
-c:a:0 copy -metadata:s:a:0 language=rus \
-c:a:1 copy -metadata:s:a:1 language=eng \
-c:s:0 copy -metadata:s:s:0 language=rus \
-c:s:1 copy -metadata:s:s:1 language=eng \
-async 1 -vsync 1 \
"/home/user/temp/h2.m4v"

Конвертация файлов для потоковой передачи в Интернете

Flussonic поддерживает следующие Контейнеры и кодеки. Если ваш видеофайл закодирован в другой формат, он не будет воспроизводиться через Flussonic. Например, могут быть старые кодеки, такие как Xvid или MPEG4-Video, которые не поддерживаются новыми версиями браузеров. В таких случаях необходимо транскодировать файл.

Чтобы преобразовать файл любого формата в H.264, в командной строке перейдите в директорию с файлом, затем выполните команду:

ffmpeg -i input_file.avi -c:v libx264 -g 100 -c:a aac -f mp4 output_file.mp4

Аналогично можно преобразовать файл любого формата в H.265/HEVC:

ffmpeg -i input_file.avi -c:v libx265 -g 100 -c:a aac -f mp4 output_file.mp4