На фото — первый летающий четырёхколёсный велосипед. Источник.

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

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

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

Формат


H264 High-profile, несмотря на свою популярность, оказывается, работает не везде — некоторые браузеры не включают его поддержку. К счастью, на современных устройствах, почти везде, где не поддерживается H264, работают VP8/9. VP9 использовать предпочтительнее, т.к. старых версий декодеров, умеющих VP8, но не VP9 или H264, я не встречал. VP9 даёт сравнимое с H264 качество картинки при битрейте на ~30% ниже — это важно для снижения нагрузки на каналы. Дополнительно, если к использованию MPEG-кодека потенциально могут быть юридические претензии (очень запутанная история), то у VP9 с этим всё хорошо. Правда, скорость кодирования у VP9 ниже примерно на порядок, поэтому на его обработку нужно выделять больше ресурсов.

Если есть необходимость поддержки старого оборудования, которое не справляется с H264 High, то можно в качестве третьего формата добавить 480p H264 Main с битрейтом пониже.

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

Soft vs Hard


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

И, разумеется, для работы аппаратного кодировщика нужен аппарат — видеокарта или процессор с видеоядром, которые есть не во всех серверах.

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

Обработка аппаратными способами очень сильно зависит от поставщика решения — каждый вендор имеет свой набор библиотек и утилит для этого, и выбрать есть из чего: Intel Quick Sync, NVenc, AMD VCE.

При программной обработке таких ограничений нет и при эквивалентном битрейте результат лучше. Для работы с различными форматами и кодеками есть ffmpeg; у «аппаратчиков» такой роскоши нет (с оговорками).

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


Для определения целевого качества, проще всего считать в битах на пиксель, BPP. Этот параметр не зависит от разрешения, частоты кадров и длительности. От него уже считать битрейт по формуле
BPP * Framerate * Width * Height
Оптимальные значения BPP лучше подбирать самостоятельными экспериментами под то видео, которое планируется обрабатывать. Хорошее начальное значение для H264 находятся в районе 0.09 бит/пиксель. Для высокоэффективных кодеков, вроде H265 и VP9, этот параметр можно уменьшить пропорционально сравнительному коэффициенту сжатия. Также BPP можно несколько уменьшить для видео высокого разрешения, т.к. эффективность кодеков немного растёт с разрешением, однако для этой поправки нужно учитывать разрешение секции кодирования (slices, фича кодеков, позволяющая кодировать видео полунезависимыми блоками дробного разрешения).

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

Именно поэтому неудобно использовать Q-параметры кодеков (попугаи качества) — фиксированные значения дают непредсказуемый итоговый битрейт.

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

Для сохранения качества динамичных сцен лучше включить VBR-режим работы кодеков, однако minRate лучше ставить не ниже 90% итогового битрейта, чтобы rate-пики не приводили к опустошению буфера.

При контроле качества полезны утилиты, вроде Intel VPA, ffprobe и Python. С помощью последнего удобно делать сравнения исходника и преобразованного видео, считать произвольные метрики, вроде средней девиации пикселей.

Рассчёт PSNR и SSIM на практике оказывается крайне неэффективным из-за психовизуальных оптимизаций, по умолчанию включённых в кодеках. Если есть желание посчитать именно эти метрики более-менее адекватно, можно отключить оптимизации через
-tune [psnr|ssim]
Однако итоговый файл, разумеется, будет отличаться от сделанного без этих флагов.

Превью


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

-ss [позиция] -vf \"select='eq(pict_type,PICT_TYPE_I)'\" -vsync vfr

Стандартные кодировщики сжимают не самым лучшим образом, поэтому после получения изображения его лучше дожать чем-нибудь вроде optipng — экономия в среднем 500кБ на FHD превью.

Изображения высокого разрешения лучше делать чересстрочными (interlaced). Таким образом, мы несколько увеличим размер (на 5-10%), но серьёзно уменьшим время отображения на загружающейся странице.

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

Платформа закрытая, но посмотреть на её работу можно здесь.

*Я не имею никакого отношения к авторам соответствующих сайтов и могу не разделять их взгляды и мнение. Решения о том, кому и как предоставляется доступ к коду, я комментировать не могу.

Готов ответить на вопросы.

Комментарии (16)


  1. aim17
    23.01.2019 22:13
    +1

    Интересно, спасибо! Правда мне показалось маловато, статья больше похожа на «памятку для самого себя». Впрочем, буду ждать продолжения, материал понравился, смысл аббревиатур искать не пришлось :).


    1. SleepingLion Автор
      24.01.2019 05:32

      Такого типа материал вообще очень сложно подавать в повествовательном стиле; это же не курс «for dummies». Потому в шапке и выделил полтора абзаца на предупреждение о формате.
      Впрочем, некоторые из готовящихся статей, похоже, будут легче в этом плане.


  1. SleepingLion Автор
    24.01.2019 05:30

    Deleted. Причина: ошибся веткой.


  1. remzalp
    24.01.2019 08:01
    +2

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


    1. SleepingLion Автор
      24.01.2019 18:58

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


  1. lleo_aha
    24.01.2019 09:54
    +1

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


    1. SleepingLion Автор
      24.01.2019 18:20

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


      1. lleo_aha
        24.01.2019 18:59

        Я больше про то как условно входной формат XXX отдать скажем на iphone — вроде бы не очень тривиальная задача, если на входе сильно разное видео по параметрам


        1. SleepingLion Автор
          24.01.2019 19:12

          А, понятно. Я думал, для разных устройств, на которых кодируется. Думаю, включу в следующую статью.


  1. Alexus819
    24.01.2019 14:12
    +1

    На фото — первый летающий четырёхколёсный велосипед

    image


  1. GooG2e
    24.01.2019 18:21
    +1

    Интересно было бы услышать:
    1)Чем на пальцах отличаются профили кодирования у h264
    2)Примеры кодирования, чтобы получить минимальный размер при сохранении приемлемого качества
    3)Способы доставки в плеер, а также обеспечения просмотра рекламы (т.е. чтобы пользователь не мог по прямой ссылке скачать, а только с сайта)
    4)Возможно не сильно относится к теме, но интересен опыт проброс видеокарт в виртуальные машины. Собственно для использования их в кодировании.


    1. SleepingLion Автор
      24.01.2019 19:02

      1 — Хорошо, включу в следующую, или одну из следующих статей. Не знаю только, как глубоко — тема возможностей и особенностей h264 сама по себе тянет не на один цикл статей.
      2 — Будет в следующей статье.
      3 — Я постараюсь затронуть методы ограничения доступа в статье про доставку.
      4 — Особого опыта нет, т.к. я работал с гибридными облачными решениями, а там пробрасывать не приходилось. Пробросы я делал, разве что, на рабочей машине и по руководствам — не на том уровне, чтобы писать статьи на тему. К тому же это очень сильно зависит от платформы.


      1. GooG2e
        24.01.2019 21:29

        1 — ну вот конкретно тут меня интересует одна такая практическая вещь, что иногда для проигрывания текущего места нужно, чтобы было прогружено что-то из будущего видеопотока при кодировании main. И это немного напрягает, да и хотелось бы избавиться без потерь качества


        1. SleepingLion Автор
          25.01.2019 03:04

          Вы имеете в виду метаданные, которые находятся в конце файла?


          1. GooG2e
            26.01.2019 09:37

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


            1. SleepingLion Автор
              26.01.2019 06:40

              С обычным видео такого быть не должно. Может быть вы используете DASH и есть проблемы с доступом к какому-то блоку?