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


Однако, кроме низкой задержки, важно обеспечить зрителям хорошее качество трансляции, ведь за это они и платят. В реальной жизни, каналы между Edge серверами и подписчиками могут быть разными по пропускной способности и качеству. Например, мы публикуем поток разрешением 720p с битрейтом 2 Мбит/с, а пользователь играет его на Android-смартфоне, используя 3G подключение в зоне неуверенного приема сигнала, и максимальное разрешение, при котором картинка будет плавной, всего 360p с битрейтом 400 Мбит/с.


Устройства и браузеры, которыми пользуются зрители, бывают очень разными. Например, мы публикуем WebRTC поток с использованием кодека VP8 из браузера Chrome на ПК, а зритель играет поток в Safari на iPhone, который поддерживает только кодек H264. Или наоборот, мы публикуем RTMP поток из OBS Studio, кодируя видео в H264, а звук в AAC, а клиент использует браузер на основе Chromium, в котором поддерживается только VP8 или VP9 для видео и opus для звука.


Может понадобиться и повышение качества исходной публикации. Например, мы раздаем поток с IP-камеры в каком-нибудь заповеднике, большую часть времени картинка статична, камера ее отдает с частотой 1 кадр в секунду. В то же время зрителю мы хотим играть 24 кадра в секунду. Как быть, если заменить камеру или изменить ее настройки невозможно?


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


Транскодинг: как, где и почему?


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



Если же клиент не поддерживает кодек, используемый при публикации потока, можно возложить транскодинг как на Edge, так и на Origin сервер.


И то, и другое может быть только временным решением, при условии, что конфигурации Origin и/или Edge серверов были выбраны с запасом. Транскодинг всегда производится покадрово, поэтому он очень требователен к ресурсам процессора. Так, одно процессорное ядро способно транскодировать совсем небольшое число потоков:


Разрешение Битрейт, кбит/с Количество потоков
360p 1300 5
480p 1800 3
720p 3000 2

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


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


Добавляем Transcoder узлы в CDN


Итак, развернем в нашей CDN по одному серверу с ролью Transcoder в европейском и американском дата-центрах



Настройка Transcoder серверов:


  • Transcoder 1 EU

cdn_enabled=true
cdn_ip=t-eu1.flashphoner.com
cdn_point_of_entry=o-eu1.flashponer.com
cdn_nodes_resolve_ip=false
cdn_role=transcoder

  • Transcoder 1 US

cdn_enabled=true
cdn_ip=t-us1.flashphoner.com
cdn_point_of_entry=o-eu1.flashponer.com
cdn_nodes_resolve_ip=false
cdn_role=transcoder

Параметры транскодирования потоков должны быть описаны на Edge серверах в виде специальных профилей в файле cdn_profiles.yml. В качестве примера, рассмотрим три профиля по умолчанию:


  • транскодирование к разрешению 640x360, 30 кадров в секунду, ключевой кадр передается на каждые 90 кадров, видеокодек H264 c использованием кодировщика OpenH264, аудиокодек Opus 48 кГц

-640x360:
  audio:
    codec : opus
    rate : 48000
  video:
    width : 640
    height : 360
    gop : 90
    fps : 30
    codec : h264
    codecImpl : OPENH264

  • транскодирование к разрешению 1280x720, видеокодек H264 c использованием кодировщика OpenH264, без транскодирования звука

 -720p:
  video:
    height : 720
    codec : h264
    codecImpl : OPENH264

  • транскодирование к разрешению 1280x720, 30 кадров в секунду, ключевой кадр передается на каждые 90 кадров, битрейт 2 Мбит/с, видеокодек H264 c использованием кодировщика OpenH264, без транскодирования звука

 -720p-2Mbps:
  video:
    height : 720
    bitrate : 2000
    gop : 90
    fps : 30
    codec : h264
    codecImpl : OPENH264

Публикуем поток test разрешением 720p на сервере o-eu1 и играем этот поток на e-eu1, указав профиль в имени потока, например, test-640x360



Поток транскодируется!


Теперь мы можем описать на Edge серверах ряд профилей, например -240p, -360p, -480p и, если на стороне клиента по данным WebRTC статистики диагностируется большое число потерянных кадров, автоматически перезапрашивать поток с более низким разрешением.


Группируем узлы CDN по континентам


Сейчас наши Transcoder серверы равноправны. А что делать, если мы хотим транскодировать потоки по географии: для американских зрителей в Америке, для европейских — в Европе? Это, кстати, позволит уменьшить нагрузку на трансатлантические каналы, поскольку в этом случае с Origin EU сервера в Америку и наоборот пойдут только исходные потоки, а не все варианты транскодированных.



В этом случае в настройках Transcoder узлов необходимо указать группу


  • Transcoder 1 EU

cdn_enabled=true
cdn_ip=t-eu1.flashphoner.com
cdn_point_of_entry=o-eu1.flashponer.com
cdn_nodes_resolve_ip=false
cdn_role=transcoder
cdn_groups=EU

  • Transcoder 1 US

cdn_enabled=true
cdn_ip=t-us1.flashphoner.com
cdn_point_of_entry=o-eu1.flashponer.com
cdn_nodes_resolve_ip=false
cdn_role=transcoder
cdn_groups=US

Также группу необходимо добавить в настройки Edge серверов


  • Edge 1-2 EU

cdn_groups=EU

  • Edge 1-2 US

cdn_groups=US

Перезапускаем узлы с новыми настройками. Публикуем поток test разрешением 720p на сервере o-eu1, играем этот поток на e-eu1 с транскодингом



Убедимся, что поток транскодируется на t-eu, для этого открываем страницу статистики http://t-eu1.flashphoner.com:8081/?action=stat и видим кодировщик и декодировщик видео в разделе Native resources



При этом на t-us1 в статистике нет кодировщиков видео



Больше транскодеров: балансируем нагрузку


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



  • Transcoder 2 EU

cdn_enabled=true
cdn_ip=t-eu2.flashphoner.com
cdn_point_of_entry=o-eu1.flashponer.com
cdn_nodes_resolve_ip=false
cdn_role=transcoder
cdn_groups=EU

  • Transcoder 2 US

cdn_enabled=true
cdn_ip=t-us2.flashphoner.com
cdn_point_of_entry=o-eu1.flashponer.com
cdn_nodes_resolve_ip=false
cdn_role=transcoder
cdn_groups=US

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


cdn_node_load_average_threshold=0.95

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


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


cdn_transcoder_video_encoders_threshold=10000

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


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


Окончание следует


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


Ссылки


CDN для стриминга WebRTC с низкой задержкой — сеть доставки контента на базе Web Call Server.

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


  1. dzsysop
    29.11.2019 00:42

    У вас есть какой-то публичный форум где клиенты задают вопросы и получают ответы?

    Статья написана как-будто описывается некий стандарт архитектуры. Потом погуглил немного Edge и понял что вы продвигаете конкретную имплементацию — свой продукт.

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

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


    1. fpn Автор
      29.11.2019 04:41

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