В первой части мы развернули простую динамическую 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 сервере, к которому подключен зритель

Dynamic CDN for Low Latency WebRTC Streaming with Transcoding Stream transcoding on Edge servers

 

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

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

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

 

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

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

 

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

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

 

Dynamic CDN for Low Latency WebRTC Streaming with Transcoding CDN with transcoders scheme

Настройка 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. В качестве примера, рассмотрим три профиля по умолчанию:

  • транскодирование к разрешению 640×360, 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
  • транскодирование к разрешению 1280×720, видеокодек H264 c использованием кодировщика OpenH264, без транскодирования звука
-720p:
 video:
   height : 720
   codec : h264
codecImpl: OPENH264
  • транскодирование к разрешению 1280×720, 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-640×360

 

Dynamic CDN for Low Latency WebRTC Streaming with Transcoding Stream publishing and playback

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

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

 

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

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

 

Dynamic CDN for Low Latency WebRTC Streaming with Transcoding CDN with transcoders and location groups scheme

В этом случае в настройках 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 с транскодингом

 

Dynamic CDN for Low Latency WebRTC Streaming with Transcoding Stream publishing and playback

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

 

Dynamic CDN for Low Latency WebRTC Streaming with Transcoding Statistics displayed while transcoding one stream

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

Dynamic CDN for Low Latency WebRTC Streaming with Transcoding Statistics displayed when no stream transcoding

 

 

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

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

Dynamic CDN for Low Latency WebRTC Streaming with Transcoding CDN with 2 transcoders by group scheme

  • 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 выделенные серверы для транскодирования медиапотоков и, таким образом, можем обеспечить нашим зрителям качество трансляции в зависимости от возможностей их оборудования и качества каналов. Однако, мы все еще не затрагивали вопрос ограничения доступа к потокам. Его мы рассмотрим в заключительной части.