Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

При публикации WebRTC видеопотоков качество получаемой картинки зависит от канала передачи медиаданных между клиентом и сервером, особенно это касается потоков высокого разрешения (HD, FullHD, 4K). Для того, чтобы контролировать канал и вовремя оповещать публикующего клиента о снижении пропускной способности, в сборке 5.2.398 добавлена возможность контроля качества канала публикации при помощи WebSDK. Возможность оповещения подписчика об изменении качества канала добавлена в сборке 5.2.409.

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

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

Передача текущего битрейта публикации, получаемого сервером, на клиента для последующего сравнения включается настройкой в файле flashphoner.properties

Code Block
themeRDark
incoming_bitrateinbound_video_rate_stat_send_interval=1

Передача на клиента текущего битрейта воспроизведения потока на сервере включается настройкой

Code Block
themeRDark
outbound_video_rate_stat_send_interval=1

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

Отображение качества канала на клиенте

Рассмотрим отображение качества канала и графиков изменения клиентского и серверного битрейтов на клиенте на примере Media Devices

1. Подготовка к отображению графика битрейта code

Code Block
languagejs
themeRDark
function publishcreateOrClearChart(chartId, bitrateComparisonChart) {
    ...if (!bitrateComparisonChart) {
    $("#bitrateChart").show();
    var canvas = document.getElementById('bitrateChart'chartId);
        var ctx = canvas.getContext('2d');

    if (!bitrateComparisonChart) {
        bitrateComparisonChart = new ComparisonChart(ctx);
    } else {
        bitrateComparisonChart.clearBitrateChart();
    }
     ...

...

return bitrateComparisonChart;
}

при публикации code

Code Block
languagejs
themeRDark
function publish() {
    ...
    publishConnectionQualityStat.chart = createOrClearChart('publishBitrateChart', publishConnectionQualityStat.chart);

    publishStream = session.createStream({
    ...
    }).on(STREAM_STATUS.PUBLISHING, function (stream;
    publishStream.publish();    
}

при воспроизведении code

Code Block
languagejs
themeRDark
function play() {
    ...
    lastConnectionQualityUpdateTimestampplayConnectionQualityStat.chart = new Date().valueOf();createOrClearChart('playBitrateChart', playConnectionQualityStat.chart);

    previewStream = session.createStream({
    ...
    });
    previewStream.play();
}

32. Получение оценки качества канала и значений битрейта, отображение графиков

CONNECTION_QUALITY.UPDATE

при публикации code

Code Block
languagejs
themeRDark
    publishStream = session.createStream({
        ...
    }).on(CONNECTION_QUALITY.UPDATE, function (quality, clientFiltered, serverFiltered) {
        updateChart(quality, clientFiltered, serverFiltered, publishConnectionQualityStat);
    });
    publishStream.publish();

при воспроизведении code

Code Block
languagejs
themeRDark
   var timestamppreviewStream = new Date().valueOf();session.createStream({
        ...
    }).on(CONNECTION_QUALITY.UPDATE, function (quality, clientFiltered, serverFiltered) {
        lastConnectionQualityUpdateTimestamp = timestampupdateChart(quality, clientFiltered, serverFiltered, playConnectionQualityStat);
    });
    bitrateComparisonChart.updateChart(previewStream.play();

функция обновления графиков code

Code Block
languagejs
themeRDark
function updateChart(calculatedQuality, clientFiltered, serverFiltered, connectionQualityStat); {
    var timestamp =  connectionQualitynew Date().valueOf();
    connectionQualityStat.connectionQualityUpdateTimestamp = qualitytimestamp;
    }connectionQualityStat.chart.updateChart(clientFiltered, serverFiltered);
    publishStream.publish();

...

connectionQualityStat.quality = calculatedQuality;
}

3. Установка качества канала в UNKNOWN, если событие CONNECTION_QUALITY.UPDATE не приходит приходит

при публикации code

Code Block
languagejs
themeRDark
function loadStats() {
    if (publishStream) {
                    ...
                    if(new Date().valueOf() - CONNECTION_QUALITY_UPDATE_TIMEOUT_MS > lastConnectionQualityUpdateTimestamp publishConnectionQualityStat.connectionQualityUpdateTimestamp) {
                        publishConnectionQualityStat.quality = CONNECTION_QUALITY.UNKNOWN;
                    }
                    ...

при воспроизведении code

Code Block
languagejs
themeRDark
function loadStats() {
    ...
    if (previewStream) {
                    ...
                    if(new Date().valueOf() - CONNECTION_QUALITY_UPDATE_TIMEOUT_MS > publishConnectionQualityStat.connectionQualityUpdateTimestamp) {
                        connectionQualitypublishConnectionQualityStat.quality = CONNECTION_QUALITY.UNKNOWN;
                    }
                    ...

54. Отображение качества канала

при публикации code

Code Block
languagejs
themeRDark
function loadStats() {
    if (publishStream) {
            ...
            if (publishConnectionQualityStat.quality !== undefined) {
                showStat({"quality": publishConnectionQualityStat.quality}, "outConnectionStat");
            ...

при воспроизведении code

Code Block
languagejs
themeRDark
function loadStats() {
    if (publishStream) {
                ...
                if (connectionQualityplayConnectionQualityStat.quality !== undefined) {
                    showStat({"quality": connectionQuality}, "connection");
 playConnectionQualityStat.quality}, "inConnectionStat");
                }
                ...

функция отображения качества code

Code Block
languagejs
themeRDark
    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]);
                }
            }
        });
    }

Тестирование

1. Для теста используем:

  • WCS 5.2.398409 или новее
  • пример Media Devices в браузере Chrome
  • канал пропускной способностью 100 Мбит/с на загрузку и выгрузку
  • инструмент ограничения пропускной способности канала, например, winShaper на Windows или Network Link Conditioner на MacOS

2. Публикуем и играем поток 720p в примере Media Devices

Image RemovedImage Added

Отображается качество канала PERFECT для воспроизведения и публикации

3. Смотрим графики битрейта публикации и воспроизведения при хорошем канале

Image RemovedImage Added

4. Ограничиваем исходящий трафик до 768 кбит/с, имитируя типичное подключение по 3G

Image RemovedImage Added

Качество канала публикации с PERFECT меняется на BAD

График битрейта публикации выглядит следующим образом

Image Added

5. Снимаем ограничение канала, смотрим графики битрейта в период действия ограниченияImage Removedпубликации

Image Added

После того, как графики вновь сходятся, отображается качество канала публикации PERFECT

6. Ограничиваем входящий трафик до 768 кбит/с

Image Added

Качество канала воспроизведения с PERFECT меняется на BAD, видны фризы и артефакты изображения

График битрейта воспроизведения выглядит следующим образом

Image Added

7. Снимаем ограничение канала, смотрим графики битрейта воспроизведения

Image Added

После того, как графики вновь сходятся, отображается качество канала воспроизведения PERFECT

Рекомендации публикующим клиентам

Если качество канала диагностируется как PERFECT или GOOD, это означает, что пропускной способности канала достаточно для публикации потока с текущим битрейтом

...

Если качество канала устойчиво изменилось на UNKNOWN, видео пакеты не доходят до сервера. Рекомендуется опубликовать поток заново.

Рекомендации подписчикам

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

Если качество канала устойчиво изменилось на BAD, пропускной способности недостаточно, наблюдаются фризы и артефакты изображения. Рекомендуется запросить поток с более низким битрейтом и/или разрешением, если это возможно.

Если качество канала устойчиво изменилось на UNKNOWN, видео пакеты не доходят от сервера. Рекомендуется переподключиться и перезапустить воспроизведение потока.