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

Для наглядности представим трансляцию турнира по боулингу, в которой есть элемент интерфейса, отображающий текущий счёт.

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

Доставка видео и событий до клиента

Давайте рассмотрим типичную схему работы стримингового сервиса.

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

Проблема произвольной задержки

Кажется очевидным отсрочить выполнение событий на время задержки видео, однако "из коробки" у нас нет информации о том, какая задержка у воспроизводимого видео на клиенте. Измерить её эмпирическим путём также не удастся, так как у каждого клиента она может быть разной.

Размер задержки может зависеть от множества факторов: производительности клиентского устройства, качества сети, равномерности подачи контента, а также протокола, используемого для доставки и воспроизведения видео (WebRTC, DASH, HLS и т.д.).

Варианты решения

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

Сопоставление с текущим временем проигрывания видео

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

Передача событий через дорожку субтитров

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

Однако у этого способа есть ряд недостатков.

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

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

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

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

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

Использование графических меток

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

SMPTE Timecode

Не все знают, что знаменитая «хлопушка», которую мы видим в начале дублей на съемках, представляет собой не что иное, как графическую метку, используемую для синхронизации событий видеопроизводства, таких как свет, звук и механические изменения сцены.

Для менее заметной передачи временных меток в видео используются протоколы LTC (Linear Timecode) и VITC (Vertical Interval Timecode).

Пример зари цифрового ТВ
Пример зари цифрового ТВ

Стеганография

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

Однако все подобные методы накладывают значительные расходы на внедрение и извлечение меток. Необходим более простой и экономичный способ.

PRFT метки времени

При использовании формата MPEG-DASH наши видеоданные заворачиваются в медиаконтейнер, например, MPEG-4, который содержит метаданные, определенные стандартом, такие как: время создания файла, продолжительность, языковой код потока, название альбома, правовой статус произведения и т. п.

Это то, что нам нужно. Поскольку данные содержатся в бинарном виде, нам нужно обратиться к стандарту ISO/IEC 14496-12 для их извлечения. Не буду вдаваться в подробности конвертации бинарного кода в movie box-ы, остановлюсь только на том как высчитать из имеющихся боксов нужную нам информацию.

Нам понадобится prft-бокс (ISO/IEC 14496-12:2012 - 8.16.5 Producer Reference Time), представляющий собой ntp-метку в самих чанках видео.

Поскольку в основе расчета временных меток внутри контейнера используется эпоха 1 января 1900 года в качестве начала отсчета, эта дата берется как отправная точка (start).

Соответственно, код для получения серверного времени генерации чанка (wallClockTime) можно получить примерно следующим образом:

const start = Date.UTC(1900, 0, 1, 0, 0, 0);
const ntpTime = prft.ntpTimestampSec * 1000 + (prft.ntpTimestampFrac / 2 ** 32) * 1000;
const wallClockTime = start + ntpTime;

Для получения времени чанка в рамках таймлайна самой трансляции (сколько времени прошло от начала стрима) нам понадобится бокс mdhd (ISO/IEC 14496-12:2012 - 8.4.2 Media Header Box), находящийся в структуре по пути moov > trak > mdia > mdhd в init-файлах.

const mediaTimeInSec = (prft.mediaTime / mdhd.timescale) * 1000;

Таким образом, мы получили размер текущей задержки и можем применять события, опираясь на эти данные.

Стоит обратить внимание, что нам не нужно рассчитывать время каждого чанка; достаточно первого полученного, а дальше нужно делать поправку на currentTime видеоэлемента.

Проблема синхронизации нескольких стримов

Теперь рассмотрим более сложную ситуацию, когда у нас одновременно идет больше одного стрима.

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

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

Более типичными примерами могут быть одновременные трансляции двух и более спикеров или дополнительный стрим демонстрации экрана.

Варианты решения

MCU

Одним из вариантов решения может быть использование подхода MCU (Multipoint Control Unit), заключающегося в объединении всех видеопотоков в один общий.

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

Управление задержкой

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

Стоит обратить внимание, что оптимальное отклонение от естественной скорости не должно превышать 10%, так как большее отклонение будет заметно зрителю.

Проблемы стабильной подачи данных

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

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

Равномерное поступление чанков

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

Проблемы на ведущем

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

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

Частой причиной проблем являются сетевые сбои. В случае низкой пропускной способности канала на помощь снова приходят алгоритмы ABR. Но, к сожалению, это не единственная проблема, которая часто встречается в сети. Часто наблюдаются значительные потери пакетов, и приходится применять ретрансмиты, запрашивая потерянные пакеты повторно. Нередки и ситуации, когда пакеты приходят не по порядку. Для исправления этой ситуации приходится использовать Jitter-очередь, дожидаться прихода всех пакетов и потом выстраивать их в правильном порядке.

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

Проблемы на транскодере

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

Проблемы с доставкой чанков зрителю

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

Однако, к сожалению, CDN не способны решить проблемы "последней мили". Представим ситуацию, когда несколько пользователей из одной локальной сети смотрят трансляцию. Каждый из них обращается к EDGE-серверу, создавая нагрузку на пропускную способность сети. При достаточном количестве таких зрителей они могут перегрузить канал, и никто больше не сможет просматривать контент. Обратите внимание, что при этом каждый из них получает один и тот же контент, но для каждого отдельно.

Для решения таких проблем в ключевых локальных сетях устанавливают кэш-серверы или используют подход eCDN. Об этом подробнее я писал в статье “Трансляция видео посредством P2P-сетей”.

Проблемы на зрителе

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

Заключение

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

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

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