RTCRemoteOutboundRtpStreamStats: свойство localId
Свойство localId словаря RTCRemoteOutboundRtpStreamStats — строка, которая может использоваться для идентификации объекта RTCInboundRtpStreamStats, у которого свойство remoteId совпадает с этим значением.
Вместе эти два объекта предоставляют статистику о входящей и исходящей сторонах одного и того же источника синхронизации (SSRC).
Значение
Строка, которую можно сравнить со значением свойства RTCInboundRtpStreamStats объекта для проверки, представляют ли эти две записи статистику каждой из двух сторон одних и тех же данных, полученных локальным узлом.
Примечания по использованию
Можно представить локальный и удалённый представления одного и того же RTP потока как пары, каждая из которых содержит ссылку на другую. Таким образом, если RTCStatsReport включает объект статистики remote-outbound-rtp (типа RTCRemoteOutboundRtpStreamStats), то он также должен содержать соответствующий объект inbound-rtp. Оба предоставляют информацию о той же группе пакетов, передаваемых от удалённого узла к локальному устройству.
Разница заключается в том, что remote-outbound-rtp описывает статистику о данных, отправленных удалённым узлом с точки зрения удалённого узла, в то время как inbound-rtp предоставляет статистику о входящих данных с точки зрения локального узла.
Вы можете исследовать, опробовать и экспериментировать с этим примером на Glitch.
Примеры
В этом примере у нас есть пара функций: первая, networkTestStart(), захватывает начальный отчёт, а вторая, networkTestStop(), захватывает второй отчёт. Вторая функция использует два отчёта, чтобы вывести некоторую информацию о состоянии сети.
networkTestStart()
Эта функция вызывает метод RTCPeerConnection getStats() для запроса RTCStatsReport и сохраняет его в переменной startReport.
let startReport;
async function networkTestStart(pc) {
if (pc) {
startReport = await pc.getStats();
}
}
Учитывая RTCPeerConnection, pc, она вызывает его метод getStats() для получения объекта отчёта о статистике, который сохраняется в startReport для использования после того, как данные об окончании теста будут собраны networkTestStop().
networkTestStop()
Функция networkTestStop() получает второй отчёт, endReport, затем вычисляет и выводит результаты.
Поиск парной статистики
Каждая запись статистики типа type remote-outbound-rtp (описывающая статистику удалённого узла об отправке данных локальному узлу) имеет соответствующую запись типа inbound-rtp, которая описывает точку зрения локального узла на те же данные, перемещаемые между двумя узлами. Давайте создадим вспомогательную функцию, которая поможет нам найти значение ключа в объекте парной статистики.
Функция findReportEntry() ниже рассматривает RTCStatsReport, возвращая запись статистики, основанную на RTCStatsReport, которая содержит указанный key — и для которой ключ имеет указанное значение value. Если соответствие не найдено или в отчёте о статистике нет записи, соответствующей категории статистики, указанной key.
function findReportEntry(report, key, value) {
for (const stats of report.values()) {
if (stats[key] === value) {
return stats;
}
}
return null;
}
Поскольку RTCStatsReport является JavaScript Map, мы можем перебрать values() карты, чтобы рассмотреть каждую запись статистики, основанную на RTCStats в отчёте, пока мы не найдём запись, у которой свойство key имеет указанное значение value. При совпадении объект статистики возвращается.
Если соответствие не найдено, функция возвращает null.
Основная функция networkTestStop()
Теперь давайте рассмотрим саму функцию networkTestStop(). Она принимает на вход RTCPeerConnection для тестирования, вызывает getStats() для получения нового RTCStatsReport с текущей статистикой, затем вычисляет искомые результаты, выводя их пользователю, добавляя соответствующий HTML в содержимое элемента <div> с классом stats-box.
async function networkTestStop(pc) {
if (pc) {
const statsBox = document.querySelector(".stats-box");
const endReport = await pc.getStats();
for (const endRemoteOutbound of endReport.values()) {
if (endRemoteOutbound.type === "remote-outbound-rtp") {
const startRemoteOutbound = startReport.get(endRemoteOutbound.id);
if (startRemoteOutbound) {
const startInboundStats = findReportEntry(
startReport,
"remoteId",
startRemoteOutbound.id,
);
const endInboundStats = findReportEntry(
endReport,
"remoteId",
endRemoteOutbound.id,
);
// Elapsed time in seconds
const elapsedTime =
(endRemoteOutbound.timestamp - startRemoteOutbound.timestamp) /
1000;
const packetsSent =
endRemoteOutbound.packetsSent - startRemoteOutbound.packetsSent;
const bytesSent =
endRemoteOutbound.bytesSent - startRemoteOutbound.bytesSent;
const framesDecoded =
endInboundStats.framesDecoded - startInboundStats.framesDecoded;
const frameRate = framesDecoded / elapsedTime;
let timeString = "";
if (!isNaN(elapsedTime)) {
timeString = ` representing ${elapsedTime}s`;
}
let frameString = "";
if (!isNaN(framesDecoded)) {
frameString = `Decoded ${framesDecoded} frames for a frame rate of ${frameRate.toFixed(
2,
)} FPS.<br>`;
}
const logEntry =
`<div class="stats-entry"><h2>Report ID: ${endRemoteOutbound.id}</h2>` +
`Remote peer sent ${packetsSent} packets ${timeString}.<br>` +
`${frameString}` +
`Data size: ${bytesSent} bytes.</div>`;
statsBox.innerHTML += logEntry;
} else {
statsBox.innerHTML += `<div class="stats-error">Unable to find initial statistics for ID ${endRemoteOutbound.id}.</div>`;
}
}
statsBox.scrollTo(0, statsBox.scrollHeight);
}
}
}
Вот что происходит в функции networkTestStop(): после вызова метода RTCPeerConnection getStats() для получения последнего отчёта о статистике подключения и сохранения его в endReport. Это объект RTCStatsReport, который сопоставляет строки с объектами соответствующего типа, основанного на RTCStatsReport.
Теперь мы можем начать обработку результатов, начиная с конечной статистики, найденной в endReport. В данном случае мы ищем записи статистики, у которых type равно remote-outbound-rtp, поэтому мы перебираем записи в отчёте о статистике, пока не найдём запись такого типа. Этот объект, конкретно, типа RTCRemoteOutboundRtpStreamStats, и он предоставляет статистику, дающую подробности о состоянии с точки зрения удалённого узла. Эта запись статистики сохраняется в endRemoteOutbound.
После того, как конечная запись remote-outbound-rtp найдена, мы используем её свойство id для получения её идентификатора. С этим в руках, мы можем найти запись remote-outbound-rtp в начальной записи статистики (startReport), которую мы сохраним в startRemoteOutbound.
Теперь мы получаем статистику inbound-rtp , соответствующую этим двум записям remote-outbound-rtp , найдя свойство remoteId внутри них, значение которого равно идентификатору записи remote-outbound-rtp . Для этого мы используем функцию findReportEntry() , описанную в предыдущем разделе, сохранив найденные записи inbound-rtp в startInboundStats и endInboundStats.
Теперь у нас есть все необходимые исходные данные для расчёта нужной нам информации, поэтому мы делаем это:
- Мы вычисляем прошедшее время —
elapsedTime— между двумя отправленными отчётами, вычитая значениеtimestampstartReportиз значенияendReport. Затем мы делим результат на 1000, чтобы перевести результат из миллисекунд в секунды. - Мы вычисляем количество отправленных пакетов за этот интервал —
packetsSent— вычитая значения свойстваpacketsSentиз двух отчётов. - Аналогично, количество отправленных байтов за этот интервал —
bytesSent— рассчитывается путём вычитания свойстваbytesSentначального объекта статистики от значения конечного объекта. - Количество декодированных кадров за этот интервал —
framesDecoded— определяется путём вычитания значенияframesDecodedобъектаstartRecordиз значения объектаendRecord.framesDecoded. - Наконец, частота кадров за этот интервал времени рассчитывается путём деления
framesDecodedнаelapsedTime.
Остальная часть функции networkTestStop() строит HTML, используемый для отображения результатов сбора и вычислений пользователю, а затем добавляет его к элементу statsBox, который используется для отображения обновлений состояния пользователю.
Вывод лога, учитывая стили, используемые в примере, выглядит следующим образом:
На скриншоте мы видим заголовок, за которым следует прокручиваемый <div>, который мы называем statsBox. Блок содержит ряд записей лога, последняя часть из которых видна. Каждая запись представляет примерно одну секунду времени (поскольку в примере довольно долго ожидается между вызовами networkTestStart() и networkTestStop()).
Попробуйте и создайте копию
Этот пример доступен на Glitch для того, чтобы вы могли его опробовать, изучить или переделать.
Спецификации
Совместимость с браузерами
| Рабочий стол | Мобильный телефон | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
| Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on IOS | Samsung Internet | WebView Android | |
localId |
91 | 91 | 68 | 77 | Нет | 91 | 68 | 64 | Нет | 16.0 | 91 |
© 2005–2024 MDN contributors.
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.
https://developer.mozilla.org/en-US/docs/Web/API/RTCRemoteOutboundRtpStreamStats/localId