company_banner

Как мы ускорили кодирование видео в восемь раз



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

    Меня зовут Аскар Камалов, год назад я присоединился к команде видеотехнологий Яндекса. Сегодня я коротко расскажу читателям Хабра о том, как с помощью распараллеливания процесса кодирования нам удалось в разы ускорить доставку видео до пользователя.

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

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

    Последовательное кодирование


    Итак, счастье пользователя во многом зависит от того, как быстро видео станет доступно. А это в основном определяется скоростью транскодирования. Когда жёстких требований к скорости выкладки видео нет, то и проблем нет. Берёте единый, неделимый файл, конвертируете его, выкладываете. В начале своёго пути мы так и работали:



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

    Последовательное кодирование с промежуточным результатом


    Чтобы хоть как-то сгладить мучительное ожидание, в индустрии придумали вариант быстрого кодирования. Обманчивое название, потому что на самом деле полноценное кодирование происходит последовательно и так же долго. Но зато с промежуточным результатом. Идея такая: как можно быстрее подготовить и выложить версию видео в низком разрешении, а уже потом — версии более высоких разрешений.

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

    Получается, нужно не только быстро обрабатывать видео, но и сохранять его качество. Это то, чего ждут от видеосервиса пользователи сейчас. Может показаться, что достаточно купить наиболее производительные серверы (и регулярно разом их все апгрейдить). Но это путь в тупик, потому что всегда найдётся видео, которое заставит тормозить даже самое мощное железо.

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


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

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

    Итак, в новой архитектуре монолитный блок Worker c последовательным кодированием мы разделили на микросервисы Segmenter, Tcoder, Combiner.



    1. Segmenter разбивает видео на фрагменты примерно по 10 секунд. Фрагменты состоят из одной или нескольких GOP (group of pictures). Каждая GOP независима и кодируется отдельно, так что может быть декодирована без ссылки на кадры из других GOP. То есть фрагменты могут воспроизводиться независимо друг от друга. Такое сегментирование уменьшает задержку, позволяя начать обработку раньше.
    2. Tcoder обрабатывает каждый фрагмент. Он берёт задание из очереди, скачивает фрагмент из хранилища, кодирует в разные разрешения (напомним, что плеер может выбирать версию, исходя из скорости соединения), затем складывает результат обратно в хранилище и помечает фрагмент обработанным в базе данных. Обработав все фрагменты, Tcoder отправляет задачу на формирование результатов для следующего компонента.
    3. Сombiner собирает результаты вместе: скачивает все фрагменты, сделанные Tcoder, формирует потоки для разных разрешений.

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

    Результаты


    Благодаря параллельной обработке видео мы значительно сократили задержку между загрузкой видео к нам и его доступностью для пользователей. Например, раньше на создание нескольких полноценных версий разного качества для FullHD-фильма длительностью полтора часа могло уйти два часа. Теперь всё это занимает 15 минут. Более того, при параллельной обработке мы создаём версию в высоком разрешении даже быстрее, чем версию в низком разрешении при старом подходе с промежуточным результатом.

    И ещё кое-что. При старом подходе либо могло не хватать серверов, либо они простаивали без задач. Параллельное кодирование позволяет повысить долю утилизации железа. Теперь наш кластер более чем из тысячи серверов всё время чем-то занят.

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

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

    Полезные ссылки на опыт коллег по индустрии


    Яндекс
    Как мы делаем Яндекс

    Комментарии 26

      +4

      Здорово! А что на Яндексе вернули аналог ютуба?

        +1
        Если вы про Яндекс.Эфир, то он работает с 2018 года, но недавно открыли платформу для загрузки видео.
        +1
        Каким кодеком кодируете и как справились при склеивании GOP фрагментов с возросшим размером?
        Теоретически размер файла при склеивании д/б больше, чем при полном кодировании.
          +1

          А если резать кратно опорным кадрам, почему размер будет больше?

            +1
            Кодек h264. Про возросший размер — по нашим замерам изменения размера не критичны.
            +1
            Как мы ускорили кодирование — перешли на AV1. (Сарказм).
            Только не делайте размер тайла бесконечно малым. Да, этим вы решите проблему кодирования, но появится проблема декодирования несколькими ядрами.
              +1
              Что-то как-то не очень. Быстрее в 8 раз, это всего лишь по времени, но не по производительности. Объем вычислений у вас остался прежним, плюс/минус.
              И для кодирования используете ли вы GPU или какое-то спец железо?
              И в рамках перфоманса, было бы интересно узнать как скопилирован код кодеков и на сколько там все векторизуется или оптимизируется.
                +4

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

                  0
                  Какой Яндекс — такая и статья. Скоро будут рассказывать как файлы архивировать, чтобы место на диске экономить.
                  0
                  С aac в частности и звуком вообще все равно рано или поздно прийдется заниматься, когда захочется транскодировать сегменты по требованию. Хранить во всех требуемых и перспективных разрешениях будет весьма накладно. Кроме этого, падение сегментера неизбежно будет приводить к дефектам в звуке на стыке. Не сильно критично, но все же.
                    0
                    Согласен! Со временем это понадобится.
                    +1
                    Главное чтобы количество машин справлялось с количеством одновременно загружаемых видео, так как по сути быстродействие не меняется. Вот возможность масштабирования системы за счёт добавления новых машин это однозначно плюс, но скорость транскодирования(если посчитать её со всех машин обрабатывающих эту задачу) скорее всего только возросла. Вроде как h264 мягко скажем не очень для веба нет? Он довольно тяжёлый.
                      0
                      Скорость кодирования видео при достаточном количестве свободных машин приблизительно равна скорости кодирования одного фрагмента. Что конечно быстрее чем последовательное кодирование.

                      h264 тяжелее чем аналоги, однако играется везде. Поэтому пока выбор очевиден)
                        0
                        Аналоги — это VP8? HEVC и VP9 ему вроде не аналоги, а следующее поколение (с VP могу ошибаться, правда), и они ещё тяжелее.
                      0

                      Когда можно будет получить Deep HD кодек в виде плагина примочки к видео плееру или видеоредактору? Хочется на какое нибуть старье взглянуть по новому.

                      • НЛО прилетело и опубликовало эту надпись здесь
                          0
                          За 10 лет у нас многое изменилось — точно стоит попробовать вновь. Причём не для сравнения по выборочным запросам, а именно пожить какое-то время.
                          • НЛО прилетело и опубликовало эту надпись здесь
                              0
                              А можете прислать мне конкретный пример такого запроса с отметкой, какой именно сайт вы хотели там выбрать?

                              Но повторюсь, пара выборочных запросов за 10 лет это не слишком информативно. Смысл эксперимента («пожить недельку») в том, чтобы комплексно понять чего не хватает не только после временного переезда, но и после обратного возвращения. Иначе сравнение опыта одностороннее. Мы и сами такое практикуем. Рекомендую, в общем.
                                0
                                Я от просмотра на яндексе любого видео отказался, это какой то рекламный терроризм, да и на счет поиска соглашусь, все больше в дукдуке.
                                Но тема очень интересная. Да и впихивают рекламу явно не эти ребята.
                                Яндекс ( askamalov ), к вам небольшая просьба.
                                Передайте своим коллегам, ну прям швах, когда буквально в 2 клика с яндекс новостей попадаешь на сайт мошейников. С яндекс новостей на сайт novosti24.site, а потом на сайт мошейников depertamentsg.website. Сейчас эти сайты, когда я пишу не активные, но есть скрины, логи. Событие было 22 марта 2020 в 11 часов. (хотел написать статью, но забил)
                                Деньги не пахнут? Как так получается?
                                Конечно не к вам лично вопрос, но все же.
                              +1
                              Я бы с вами поспорил, я в основном пользуюсь поиском Яндекса, только вот если надо искать в англоязычных источниках, только в таком случае прибегаю к Google.
                              • НЛО прилетело и опубликовало эту надпись здесь
                              0
                              А как кодируется видео на Яндекс.Диске? Там для часового HD превьюшка готова к просмотру мгновенно, как только файл залит.
                                0
                                Загрузил утром несколько роликов в Яндекс.Эфир.
                                Все висят на стадии обработки. Кроме этого ещё и загрузка роликов шла не непрерывно, а прерывисто. Файл 15 Гб загружался около 2 часов при хорошем интернете
                                  +1
                                  Пришлите, пожалуйста, ссылку на канал. Перешлю коллегам проверить.
                                  0
                                  Добрый день. Вопрос про связку от кодера к комбайну в новой схеме.
                                  «Обработав все фрагменты, Tcoder отправляет задачу»

                                  Как получается понять что всё готова при параллельной обработки 2х последних частей кодирующихся в один момент времени на разных машинах?

                                  Как понимаю у вас при кодирование фрагмента идет апдейт. Потом запрос select по видео «готовы ли все фрагменты».
                                  Если машина1 на стадии выборки и селектится что всё готова посылается сообщение следующему процессу
                                  Но если на машине2 в этот же момент происходила обработка этогоже видео, то селект вернет что всё части готовы и пошлет еще одно сообщение, получается дубли сообщений

                                  Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                                  Самое читаемое