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