Контроль качества канала при публикации и воспроизведении¶
При публикации WebRTC видеопотоков качество получаемой картинки зависит от канала передачи медиаданных между клиентом и сервером, особенно это касается потоков высокого разрешения (HD, FullHD, 4K). Для того, чтобы контролировать канал и вовремя оповещать публикующего клиента о снижении пропускной способности, в сборке 5.2.398 добавлена возможность контроля качества канала публикации при помощи WebSDK. Возможность оповещения подписчика об изменении качества канала добавлена в сборке 5.2.409.
На стороне клиента периодически сравнивается битрейт публикации или воспроизведения с битрейтом на стороне сервера. При устойчивом их расхождении диагностируется снижение пропускной способности канала. Пики и резкие изменения сглаживаются фильтром Калмана.
Настройка сервера¶
Передача текущего битрейта публикации, получаемого сервером, на клиента для последующего сравнения включается настройкой в файле flashphoner.properties
Передача на клиента текущего битрейта воспроизведения потока на сервере включается настройкой
Эти параметры задают интервал отправки значений битрейта в секундах. Рекомендуется отправлять битрейт один раз в секунду.
Отображение качества канала на клиенте¶
Рассмотрим отображение качества канала и графиков изменения клиентского и серверного битрейтов на клиенте на примере Media Devices
-
Подготовка к отображению графика битрейта code
при публикации codefunction createOrClearChart(chartId, bitrateComparisonChart) { if (!bitrateComparisonChart) { var canvas = document.getElementById(chartId); var ctx = canvas.getContext('2d'); bitrateComparisonChart = new ComparisonChart(ctx); } else { bitrateComparisonChart.clearBitrateChart(); } return bitrateComparisonChart; }
при воспроизведении codefunction publish() { ... publishConnectionQualityStat.chart = createOrClearChart('publishBitrateChart', publishConnectionQualityStat.chart); publishStream = session.createStream({ ... }); publishStream.publish(); }
-
Получение оценки качества канала и значений битрейта, отображение графиков
обработка событияCONNECTION_QUALITY.UPDATE
при публикации code
при воспроизведении codepublishStream = session.createStream({ ... }).on(CONNECTION_QUALITY.UPDATE, function (quality, clientFiltered, serverFiltered) { updateChart(quality, clientFiltered, serverFiltered, publishConnectionQualityStat); }); publishStream.publish();
функция обновления графиков codepreviewStream = session.createStream({ ... }).on(CONNECTION_QUALITY.UPDATE, function (quality, clientFiltered, serverFiltered) { updateChart(quality, clientFiltered, serverFiltered, playConnectionQualityStat); }); previewStream.play();
function updateChart(calculatedQuality, clientFiltered, serverFiltered, connectionQualityStat) { var timestamp = new Date().valueOf(); connectionQualityStat.connectionQualityUpdateTimestamp = timestamp; connectionQualityStat.chart.updateChart(clientFiltered, serverFiltered); connectionQualityStat.quality = calculatedQuality; }
-
Установка качества канала в
UNKNOWN
, если событиеCONNECTION_QUALITY.UPDATE
не приходит
при публикации code
при воспроизведении codefunction loadStats() { if (publishStream) { ... if(new Date().valueOf() - CONNECTION_QUALITY_UPDATE_TIMEOUT_MS > publishConnectionQualityStat.connectionQualityUpdateTimestamp) { publishConnectionQualityStat.quality = CONNECTION_QUALITY.UNKNOWN; } ... } ... }
-
Отображение качества канала
при публикации code
при воспроизведении codefunction loadStats() { if (publishStream) { ... if (publishConnectionQualityStat.quality !== undefined) { showStat({"quality": publishConnectionQualityStat.quality}, "outConnectionStat"); ... } ... } ... }
функция отображения качества codefunction loadStats() { ... if (previewStream) { ... if (playConnectionQualityStat.quality !== undefined) { showStat({"quality": playConnectionQualityStat.quality}, "inConnectionStat"); ... } ... } ... }
function showStat(stat, type) { Object.keys(stat).forEach(function(key) { if (typeof stat[key] !== 'object') { let k = key.split(/(?=[A-Z])/); let metric = ""; for (let i = 0; i < k.length; i++) { metric += k[i][0].toUpperCase() + k[i].substring(1) + " "; } if ($("#" + key + "-" + type).length == 0) { let html = "<div style='font-weight: bold'>" + metric.trim() + ": <span id='" + key + "-" + type + "' style='font-weight: normal'></span>" + "</div>"; // $(html).insertAfter("#" + type); $("#" + type).append(html); } else { $("#" + key + "-" + type).text(stat[key]); } } }); }
Тестирование¶
-
Для теста используем:
- WCS 5.2.409 или новее
- пример Media Devices в браузере Chrome
- канал пропускной способностью 100 Мбит/с на загрузку и выгрузку
- инструмент ограничения пропускной способности канала, например, winShaper на Windows или Network Link Conditioner на MacOS
-
Публикуем и играем поток 720p в примере Media Devices
Отображается качество каналаPERFECT
для воспроизведения и публикации -
Смотрим графики битрейта публикации и воспроизведения при хорошем канале
-
Ограничиваем исходящий трафик до 768 кбит/с, имитируя типичное подключение по 3G
Качество канала публикации сPERFECT
меняется наBAD
График битрейта публикации выглядит следующим образом
-
Снимаем ограничение канала, смотрим графики битрейта публикации
После того, как графики вновь сходятся, отображается качество канала публикацииPERFECT
-
Ограничиваем входящий трафик до 768 кбит/с
Качество канала воспроизведения сPERFECT
меняется наBAD
, видны фризы и артефакты изображения
График битрейта воспроизведения выглядит следующим образом
-
Снимаем ограничение канала, смотрим графики битрейта воспроизведения
После того, как графики вновь сходятся, отображается качество канала воспроизведенияPERFECT
Рекомендации публикующим клиентам¶
Если качество канала диагностируется как PERFECT
или GOOD
, это означает, что пропускной способности канала достаточно для публикации потока с текущими разрешением и битрейтом.
Если качество канала устойчиво изменилось на BAD
, пропускной способности недостаточно, подписчики наблюдают проблемы. Рекомендуется снижать битрейт и/или разрешение публикации, если это возможно.
Если качество канала устойчиво изменилось на UNKNOWN
, видео пакеты не доходят до сервера. Рекомендуется опубликовать поток заново.
Рекомендации подписчикам¶
Если качество канала диагностируется как PERFECT
или GOOD
, это означает, что пропускной способности канала достаточно для просмотра потока с текущими разрешением и битрейтом. Если при воспроизведении потока в этом случае наблюдаются проблемы, вероятный их источник находится на стороне публикации.
Если качество канала устойчиво изменилось на BAD
, пропускной способности недостаточно, наблюдаются фризы и артефакты изображения. Рекомендуется запросить поток с более низким битрейтом и/или разрешением, если это возможно.
Если качество канала устойчиво изменилось на UNKNOWN
, видео пакеты не доходят от сервера. Рекомендуется переподключиться и перезапустить воспроизведение потока.