
Всеки ден милиони зрители гледат видеа в интернет. Но за да стане видеото достъпно, то трябва не само да се качи на сървъра, но и да се обработи. Колкото по-бързо става това — толкова по-добре за услугата и нейните потребители.
Казвам се Аскар Камалов, преди година се присъединих към екипа по видеотехнологии на Яндекс. Днес накратко ще разкажа на читателите на Хабра как с помощта на разпаралеляване на процеса на кодиране успяхме многократно да ускорим доставката на видеа до потребителите.
Тази публикация най-вече ще бъде интересна на тези, които досега не са се замисляли за това, което се случва под капака на видеосервисите. В коментарите можете да задавате въпроси и да предлагате теми за бъдещи постове.
Няколко думи за самата задача. Яндекс не само помага за търсенето на видеа на други сайтове, но и съхранява видеа за собствените си услуги. Независимо дали става въпрос за авторска програма или спортен мач на Ефир, филм на КиноПоиске или клипове в Дзене и Новини — всичко това се качва на нашите сървъри. За да гледат потребителите видеото, то трябва да бъде подготвено: да бъде конвертирано в необходимия формат, да се създаде предварителен изглед или дори да премине през технологията . Неподготвеният файл просто заема място. И става въпрос не само за оптимално използване на хардуера, но и за скоростта на доставка на съдържанието до потребителите. Пример: запис на решаващ момент от хокейния мач може да бъде търсен в търсене вече минута след самото събитие.
Последователно кодиране
И така, щастието на потребителя в значителна степен зависи от това колко бързо видеото ще стане достъпно. А това се определя основно от скоростта на транскодиране. Когато няма строги изисквания за скоростта на публикуване на видеото, тогава и проблеми няма. Вземате единен, неделим файл, конвертирате го, публикувате го. В началото на нашия път работихме именно така:

Клиентът качва видеото в хранилището, компонентът Analyzer събира метаинформация и предава видеото за конвертиране на компонента Worker. Всички стъпки се изпълняват последователно. При това може да има много сървъри за кодиране, но само един се занимава с обработката на конкретното видео. Проста, прозрачна схема. На това нейното предимство и свършва. Такава схема се мащабира само вертикално (чрез закупуване на по-мощни сървъри).
Последователно кодиране с междинен резултат
За да се облекчи мъчителното чакане, в индустрията е създаден вариант на бързо кодиране. Измамното име, защото всъщност пълноценното кодиране се извършва последователно и също толкова бавно. Но пък с междинен резултат. Идеята е: колкото се може по-бързо да се подготви и качи версия на видеото с ниска разделителна способност, а след това — версии с по-висока разделителна способност.
От една страна, видеото става достъпно по-бързо. И това е полезно за важни събития. Но от друга — картината става размазана, а това дразни зрителите.
Получава се, че трябва не само бързо да обработваме видеото, но и да запазим неговото качество. Това е, което потребителите очакват от видеосервиса в момента. Може да изглежда, че е достатъчно да закупим най-производителните сървъри (и редовно да ъпгрейдваме всичките). Но това е тупик, защото винаги ще има видео, което ще забави дори най-мощния хардуер.
Паралелно кодиране
Много по-ефективно е да се раздели сложната задача на множество по-малко сложни и да се решават паралелно на различни сървъри. Нещо като MapReduce за видео. В този случай не се натъкваме на производителността на един сървър и можем да се мащабираме хоризонтално (чрез добавяне на нови машини).
Между другото, идеята да се нарязва видеото на малки парчета, да се обработва паралелно и след това да се слепва — не е никаква тайна. Можете да намерите множество спомени за този подход (например, в Хабра препоръчвам пост за проекта ). Но от това общо не става по-лесно, защото не може просто така да вземеш готово решение и да го вградиш в себе си. Нужна е адаптация към нашата инфраструктура, нашето видео и дори нашето натоварване. Накратко, по-лесно е да напишеш свое.
И така, в новата архитектура монолитният блок Worker с последователно кодиране разделихме на микросервизи Segmenter, Tcoder, Combiner.

- Segmenter разделя видеото на фрагменти от около 10 секунди. Фрагментите се състоят от една или няколко GOP (). Всяка GOP е независима и се кодира отделно, така че може да бъде декодирана без връзка с кадри от други GOP. Тоест фрагментите могат да се възпроизвеждат независимо един от друг. Това сегментиране намалява закъснението, позволявайки да се започне обработката по-рано.
- Tcoder обработва всеки фрагмент. Той взема задача от опашката, изтегля фрагмент от хранилището, кодира в различни разрешения (да припомним, че плейърът може да избира версия в зависимост от скоростта на връзката), след което поставя резултата обратно в хранилището и маркира фрагмента като обработен в базата данни. След като обработи всички фрагменти, Tcoder изпраща задачата за генериране на резултати за следващия компонент.
- Сombiner събира резултатите заедно: изтегля всички фрагменти, направени от Tcoder, и формира потоци за различни разрешения.
Няколко думи за звука. Най-популярният аудиокодек AAC има неприятна особеност. Ако кодиране на фрагменти става отделно, тяхното безшевно свързване просто не е възможно. Преходите ще бъдат забележими. При видео кодеците този проблем не съществува. Теоретично е възможно да се търси сложно техническо решение, но в момента това не си струва (аудиото тежи значително по-малко от видеото). Затова едновременно кодиране на видео, а аудиопотокът се обработва изцяло.
Резултати
Благодарение на паралелната обработка на видеото, значително намалихме закъснението между качването на видео при нас и неговата наличност за потребителите. Например, преди за създаването на няколко напълно функционални версии с различно качество за FullHD филм с продължителност един и половина часа, можеше да отнеме два часа. Сега всичко това отнема 15 минути. Освен това, при паралелната обработка, създаваме версия в високо разрешение дори по-бързо, отколкото версия в ниско разрешение при стария подход с междинен резултат.
И още нещо. При стария подход или сървърите не стигаха, или те бяха бездействащи без задачи. Паралелното кодиране позволява да се увеличи степента на използване на хардуера. Сега нашият клъстер от над хиляда сървъра постоянно е зает с нещо.
Всъщност все още има къде да се стремим. Например, можем значително да спестим време, ако започнем да обработваме фрагменти от видеото, преди то напълно да е пристигнало при нас. Както се казва, напредването е още повече.
Напишете в коментарите какви задачи в областта на видеообработката бихте искали да прочетете.
Полезни връзки към опита на колеги в индустрията
Източник: habr.com
