Тестирование WebRTC в 2026: как проверить качество стрима, семь метрик, пороги и StreamTest

Пользователь пишет в поддержку «видео зависло», а вам нужно понять, что сломалось и у кого. Если коротко, тестирование WebRTC сводится к семи цифрам из браузерного API getStats(): битрейт, частота кадров, потери пакетов, RTT, джиттер, доля фризов и рассинхрон звука и видео. Каждую сравнивают с порогом и проверяют на четырёх уровнях, от вкладки разработчика до мониторинга реальных звонков. Ниже метод, по которому работают наши QA, и бесплатное расширение StreamTest, которое показывает эти цифры без единой строки кода.
Главное
• Семь метрик закрывают почти все жалобы на качество. Битрейт, частота кадров, потери, RTT, джиттер, доля фризов и рассинхрон звука и видео читаются через getStats() раз в 1–2 секунды.
• Пороги можно требовать от команды. Потери до 1% считаются нормой, больше 5% уже плохо; RTT до 150 мс в норме, больше 300 мс плохо; при доле фризов меньше 1% можно выпускать, больше 10% нельзя.
• Тестируют на четырёх слоях. Вкладка разработчика с chrome://webrtc-internals, ручной QA в StreamTest, нагрузка в webrtcperf, Loadero или CyaraRTC и телеметрия реальных звонков.
• Плохую сеть включают специально. Три профиля tc/netem (домашний Wi-Fi, 4G в поезде, перегруженная мобильная сеть) показывают большинство ошибок, о которых потом пишут пользователи.
• StreamTest обновился до версии 2.0. Расширение для Chrome от Фора Софт теперь само называет проблему и её причину. Старая ссылка на магазин Chrome больше не работает, новая есть в разделе про StreamTest.
Обновлено в ноябре 2026: статья переписана из заметки о StreamTest в полный гайд: семь метрик с порогами, нагрузочные инструменты с ценами 2026 года, голосовые ИИ-агенты, новая ссылка на StreamTest 2.0, пять схем.
Почему этот разбор пишет Фора Софт
Мы делаем видеосвязь и стриминг с 2005 года: 250+ сданных проектов, команда из 50 инженеров. В большинстве продуктов последних лет есть WebRTC: телемедицина, онлайн-обучение, корпоративные встречи, трансляции. И в каждом рано или поздно приходится цифрами доказывать, что звонок хороший. Если вы строите такой продукт, наша разработка платформ видеоконференций включает этот тест-план с первого спринта.
Первая версия статьи вышла в 2022 году и рассказывала только о расширении StreamTest. В ноябре 2026 года мы проверили факты по первоисточникам и дописали то, что спрашивают чаще всего: какие метрики смотреть, где граница нормы, чем нагружать медиасервер, как ломать сеть на стенде и как тестировать голосовых ИИ-агентов. Если WebRTC для вас новая тема, начните с разбора что такое WebRTC и как он устроен.
Звонки в вашем продукте «иногда зависают»?
Пришлите дамп chrome://webrtc-internals или отчёт StreamTest. Инженер по WebRTC разберёт его и назовёт слой, где ломается звонок: клиент, сеть, TURN или медиасервер.
Как проверить WebRTC за пять минут
Быстрый тест WebRTC проверяет три вещи по порядку: получает ли браузер камеру и микрофон, находит ли рабочий сетевой путь через STUN и TURN и насколько хорошо медиа, когда звонок уже идёт. Первые две проверки занимают минуту в браузере, третья требует живого звонка и getStats().
- Устройства и браузер. Откройте официальный пример getUserMedia из WebRTC samples. Если видите себя, разрешения и камера работают.
- Сетевой путь. Вставьте свои STUN- и TURN-серверы в пример Trickle ICE и нажмите Gather. Нужны кандидаты host, srflx и relay. Если relay нет, пользователи за строгими корпоративными файрволами не подключатся. Подробнее о кандидатах рассказано в уроке «ICE, STUN и TURN: подробный разбор».
- Качество живого звонка. Запустите звонок между двумя вкладками или двумя устройствами и откройте chrome://webrtc-internals либо щёлкните по видео правой кнопкой и запустите StreamTest. Сравните семь метрик с таблицей порогов ниже.
- Плохая сеть (по желанию, ещё около 10 минут). Повторите третий шаг под одним из профилей tc/netem из раздела про сеть. Большинство ошибок, о которых пишут пользователи, видно только здесь.
| Вид теста | На какой вопрос отвечает | Инструменты | Сколько идёт |
|---|---|---|---|
| Проверка соединения | Может ли этот браузер и эта сеть вообще подключиться? | WebRTC samples (getUserMedia, Trickle ICE), предзвонковый тестер | 1 минута |
| Тест качества потока | Достаточно ли хорош звонок, чтобы выпускать? | chrome://webrtc-internals, StreamTest, getStats() | 5–15 минут |
| Нагрузочный тест | Выдержит ли медиасервер N участников? | webrtcperf, Loadero, CyaraRTC | ночной прогон |
| Мониторинг реальных звонков | Хорошо ли пользователям прямо сейчас? | своя телеметрия getStats, watchRTC | постоянно |
| Проверка утечки IP | Раскрывает ли WebRTC мой адрес за VPN? | сервисы проверки приватности | 1 минута, это не про качество |
Семь метрик качества WebRTC-звонка
Почти все проблемы качества WebRTC видны в семи цифрах, и все они доступны через RTCPeerConnection.getStats(). Остальные поля нужны для диагноза, когда одна из семи ушла в красную зону. Удобно держать в голове три свойства звонка: разборчивость (понятно ли, что говорят), живость (ощущается ли разговор как живой) и стабильность (держится ли качество час, а не первые 30 секунд). Разборчивость зависит в основном от потерь и джиттера в аудио, живость от RTT и синхронизации, стабильность от фризов и колебаний битрейта.
Определение для цитаты: тестирование качества WebRTC — это измерение семи метрик входящего и исходящего потока из getStats() (битрейт, частота кадров, потери пакетов, RTT, джиттер, доля фризов, синхронизация звука и видео) и сравнение их с порогами на четырёх уровнях: разработка, ручной QA, нагрузка и реальные звонки.

Рисунок 1. Один вызов getStats() и семь цифр, которые он отдаёт, по семействам отчётов. Восьмое поле, qualityLimitationReason, объясняет причину.
Битрейт, кбит/с
Считается по разнице bytesReceived (или bytesSent) между двумя замерами, делённой на разницу timestamp. При фиксированном разрешении плавность картинки растёт почти линейно с битрейтом. Для VP9 в 720p нужно около 800 кбит/с, для H.264 в том же разрешении примерно 1,2–1,5 Мбит/с. Кодек AV1 в Chrome, по данным Google, снижает битрейт видеозвонка на 30–40% против VP9, но заметно сильнее нагружает процессор без аппаратного кодирования.
Частота кадров, FPS
Поле framesPerSecond во входящем видеоотчёте. Ниже 15 кадров в секунду движение дёргается, ниже 10 воспринимается как слайд-шоу. Если частота падает, а на стороне отправителя qualityLimitationReason показывает cpu, узкое место в кодировщике отправителя, а не в сети.
Потери пакетов, %
Считаются как packetsLost / (packetsLost + packetsReceived). До 1% потерь не видно и не слышно: их прикрывают повторные запросы (NACK) и избыточное кодирование (FEC). От 1 до 5% появляются квадраты на картинке и короткие провалы в звуке. При потерях больше 5% декодер начинает часто просить ключевые кадры (растёт pliCount), и это замечают все.
Задержка туда и обратно, RTT
Поле currentRoundTripTime у выбранной пары кандидатов. До 150 мс разговор ощущается мгновенным. На 300 мс собеседники начинают перебивать друг друга. Больше 500 мс звонок по сути превращается в рацию.
Джиттер, мс
Сглаженное отклонение интервалов прихода RTP-пакетов по RFC 3550, поле jitter. До 30 мс его поглощает буфер. От 30 до 100 мс буфер растёт и добавляет задержку. Больше 100 мс звук начинает маскировать потерянные фрагменты и ускорять воспроизведение, чтобы догнать поток (растут concealedSamples и removedSamplesForAcceleration).
Доля фризов, %
Фризы пользователи замечают раньше всего. Спецификация статистики WebRTC от W3C (Candidate Recommendation Draft от 25 сентября 2025 года, актуальна на ноябрь 2026-го) отдаёт freezeCount и totalFreezesDuration и точно определяет фриз: пауза между двумя показанными кадрами длиннее большего из двух значений — трёх средних длительностей кадра или средней длительности плюс 150 мс (MDN). Делим суммарную длительность фризов на длину сессии и получаем долю. Хороший звонок держится ниже 1%, при 10% и выше выпускать нельзя. MDN по-прежнему не относит freezeCount к Baseline: Chromium поле отдаёт, другие движки могут не отдавать, поэтому перед сравнением браузеров проверяйте, есть ли оно.
Синхронизация звука и видео, мс
Сравните среднюю задержку буфера (jitterBufferDelay / jitterBufferEmittedCount) у аудио- и видеоотчётов одного участника. Расхождение до 100 мс незаметно, 100–200 мс ощущается как «что-то не так», больше 200 мс пользователи называют это рассинхроном губ. Как метрики качества связаны с оценками зрителей, подробно разобрано в уроке «Метрики QoE стриминга» нашего курса по измерению качества видео.
Пороги качества: зелёный, жёлтый, красный
Ниже пороги, которые мы ставим в свои панели мониторинга. Они собраны из спецификации W3C, рекомендации ITU-T G.107 и того, на что реально жалуются пользователи наших продуктов. Берите их по умолчанию и ужесточайте для медицины, вещания и синхронного перевода.
| Метрика | Зелёный | Жёлтый | Красный | Частая причина красного |
|---|---|---|---|---|
| Потери пакетов | < 1% | 1–5% | > 5% | перегруженный исходящий канал, нестабильный Wi-Fi, перегрузка TURN |
| RTT | < 150 мс | 150–300 мс | > 300 мс | не тот регион, принудительный TURN, ретрансляция через океан |
| Джиттер | < 30 мс | 30–100 мс | > 100 мс | мобильная сеть, раздутые буферы роутера, Wi-Fi в кафе |
| Частота кадров (входящее видео) | ≥ 24 | 15–24 | < 15 | процессор отправителя или декодер теряет кадры |
| Доля фризов | < 1% | 1–10% | > 10% | пачки потерь, переключения TURN, ошибка аппаратного декодера |
| Битрейт (720p, VP9) | 700–1200 кбит/с | 400–700 кбит/с | < 400 кбит/с | оценка канала занижена, слой simulcast отключён |
| Рассинхрон звука и видео | < 100 мс | 100–200 мс | > 200 мс | разные буферы у аудио и видео |

Рисунок 2. Те же пороги в виде матрицы: норма — выпускаем, внимание — следим, плохо — пользователи уже жалуются.
Когда пороги строже: телемедицина (RTT до 200 мс, потери до 2%), синхронный перевод (рассинхрон до 60 мс), вещание (доля фризов до 0,1%). Если продукт работает с персональными данными пользователей из России, держите и телеметрию качества на серверах в РФ: в ней есть IP-адреса и идентификаторы сессий.
Где смотреть цифры: chrome://webrtc-internals
Прежде чем писать свою телеметрию, откройте то, что уже есть в браузере: во время звонка вкладка chrome://webrtc-internals показывает все отчёты getStats() с графиками. Отчёты в ней делятся на четыре семейства:
- Пары кандидатов (candidate-pair). Активный путь между участниками, выбранная пара выделена. Смотрите currentRoundTripTime и availableOutgoingBitrate. Если выбранная пара сменилась с srflx на relay, звонок ушёл через TURN, и RTT подскочит.
- Входящие потоки (inbound-rtp). По одному на каждую удалённую дорожку: framesDecoded, framesDropped, packetsLost, jitter и пара freezeCount / totalFreezesDuration.
- Исходящие потоки (outbound-rtp). По одному на каждую свою дорожку. Самое полезное поле здесь qualityLimitationReason: оно говорит, во что упирается качество (cpu, bandwidth, other или none), а qualityLimitationDurations раскладывает это по секундам.
- Журнал вызовов API. Каждый вызов методов PeerConnection и каждое событие по порядку. Без него не понять, почему сработала повторная договорённость или почему отброшен ICE-кандидат.
Кнопка Create Dump вверху сохраняет всё в JSON. По этому файлу разработчик восстановит звонок, не подходя к компьютеру пользователя. На разборах инцидентов мы просим снять дамп до, во время и после проблемы: чаще всего причина видна по разнице между ними.
В Edge та же страница называется edge://webrtc-internals. В Firefox есть about:webrtc: раскройте разделы RTCPeerConnection и RTP Stats, кнопка Copy Report даёт снимок в JSON, а Save Page сохраняет полную HTML-копию; историю звонков в релизных сборках включает настройка media.aboutwebrtc.hist.enabled (документация Mozilla). В Safari такой страницы нет, там getStats() читают из своего кода. Минимальный пробник для консоли DevTools:
// Минимальный пробник getStats для консоли DevTools во время звонка.
// Сначала сделайте RTCPeerConnection доступным, например window._pc = pc.
// Печатает главные метрики каждые 2 секунды.
const t0 = performance.now();
setInterval(async () => {
const pc = window._pc;
const stats = await pc.getStats();
let inV, outV, pair;
stats.forEach(r => {
if (r.type === 'inbound-rtp' && r.kind === 'video') inV = r;
if (r.type === 'outbound-rtp' && r.kind === 'video') outV = r;
if (r.type === 'transport' && r.selectedCandidatePairId)
pair = stats.get(r.selectedCandidatePairId);
});
console.log({
rtt_ms: pair && pair.currentRoundTripTime * 1000,
jitter_ms: inV && inV.jitter * 1000,
packet_loss: inV && inV.packetsLost / (inV.packetsLost + inV.packetsReceived),
fps: inV && inV.framesPerSecond,
freeze_ratio: inV && inV.totalFreezesDuration / ((performance.now() - t0) / 1000),
limitation: outV && outV.qualityLimitationReason,
});
}, 2000);
StreamTest 2.0: проверка качества стрима без кода
StreamTest — бесплатное расширение Google Chrome от Фора Софт, которое показывает качество входящего WebRTC-потока прямо поверх звонка. Мы сделали его, потому что наши QA постоянно упирались в одну проблему: чтобы оценить стрим, нужно снять несколько метрик, а для этого приходилось держать открытыми десяток инструментов. Расширение работает в любом видеочате на WebRTC: Google Meet, наших продуктах iMind и ProVideoMeeting и в вашем собственном приложении.
Важно: старая карточка StreamTest в магазине Chrome, на которую ссылалась первая версия статьи, снята. Актуальная версия 2.0.0 (обновлена 28 сентября 2026 года) лежит в магазине Chrome Web Store. Исходный код открыт по лицензии MIT в репозитории forasoft/video-testing-tool.
Определение для цитаты: StreamTest — бесплатное расширение Chrome от Фора Софт: щелчок правой кнопкой по видео участника запускает посекундный разбор входящего WebRTC-потока по семи метрикам и называет найденную проблему, её причину и что проверить.
Как запустить тест
- Установите StreamTest из магазина Chrome. Нужен Chrome 116 или новее; аккаунт, сервер и регистрация не нужны.
- Откройте звонок. Расширение работает на страницах https://, на корневой странице http-сайта и на http://localhost и http://127.0.0.1 с любым путём.
- Щёлкните правой кнопкой по видео участника и выберите в меню пункт Test stream. Первые 5 секунд панель собирает данные, затем показывает цифры.
Если за видео нет WebRTC-соединения (плеер HLS, превью своей камеры), StreamTest сообщит об этом понятной ошибкой. Так QA сразу видит, что расширение смотрит не туда.
Что показывает панель
Компактная панель (350 пикселей) показывает семь плиток: частота кадров, задержка видео, задержка звука, потери пакетов, разрешение, фризы и битрейт. Каждая плитка зелёная, жёлтая или красная по фиксированному порогу, рядом с ней график за последние 2 минуты. Частота кадров обновляется 4 раза в секунду, остальные плитки раз в секунду. Есть мини-режим на 190 пикселей и развёрнутый режим 900 × 700 с вкладками Timeline и Report.
Версия 2.0 объясняет цифры сама. Когда что-то ломается, расширение называет одну из десяти проблем, время начала, тяжесть, вероятную причину (сеть, отправитель, страница или это устройство) и что проверить:
- проблемы сети: падение пропускной способности, переподключение и смена сетевого пути;
- фриз видео, заикание звука и медленный старт;
- проблемы страницы и устройства: подвисание страницы и рассинхрон звука и видео;
- проблемы отправителя: ограничение отправки процессором или каналом и размытая картинка.
Как отдать результат разработчику
Раньше мы советовали сделать скриншот статуса и скачать CSV. В версии 2.0 это не нужно. Timeline выкладывает битрейт, частоту кадров, потери и задержку на одну шкалу времени, а кнопка Mark отмечает секунду, когда тестировщик увидел сбой. Report добавляет перцентили и сравнение с прошлым прогоном на том же сайте. Copy summary кладёт в буфер обмена вердикт и ключевые цифры для тикета, а экспорт в JSON или CSV содержит каждый посекундный замер, события, отметки и оба SDP (offer и answer). Всё считается внутри страницы: расширение не отправляет данные на сервер.
Разбираться в цифрах самому не обязательно: скопируйте сводку и отправьте её разработчику вместе с JSON. Пошаговый разбор каждого экрана и всех десяти проблем есть в README репозитория.
getStats() в продакшене: телеметрия и MOS
chrome://webrtc-internals рассчитан на разработчика, а для реальных пользователей те же данные нужно отправлять на бэкенд. Схема у нас одинаковая во всех продуктах:
- Замер раз в 1–2 секунды. Чаще получится шум, реже вы пропустите короткие фризы.
- Дельты на клиенте. Отправляйте битрейт в кбит/с, а не сырые bytesSent: у браузера есть контекст для расчёта, у конвейера приёма его нет.
- Пачки и сжатие. Копите окна по 30 секунд, сжимайте gzip и отправляйте через WebSocket или отдельный эндпоинт.
- Метки на каждой точке. ID сессии, браузер и версия, ОС, аппаратный декодер, регион, использованный TURN, согласованный кодек. Без меток регрессию не разрезать по срезам.
- Хранилище временных рядов. ClickHouse, TimescaleDB, InfluxDB или облачный сервис. Мы чаще берём ClickHouse: запросы вида «p95 RTT за 7 дней по регионам» колоночные по природе.
- Алерты по опыту, а не по сырым полям. «Потери больше 2%» срабатывает на каждый скачок чужого Wi-Fi. «p95 доли фризов в комнате больше 3% три минуты подряд» срабатывает, только когда что-то действительно сломалось.
Как посчитать MOS для звука и видео
Сырые метрики нужны инженерам, бизнесу нужна одна цифра на звонок: MOS (Mean Opinion Score), оценка от 1 до 5, которая коррелирует с тем, что сказал бы человек после звонка. Для звука есть каноническая модель ITU-T G.107 (E-model): задержка, потери и кодек дают R-фактор от 0 до 100, который переводится в MOS. Узкополосная E-модель упирается примерно в 4,4, широкополосные кодеки вроде Opus описывает G.107.1. Открытая библиотека rtcscore считает MOS прямо из getStats. Рабочий звонок держит MOS выше 4,0, ниже 3,5 для бизнеса неприемлемо.
Для видео готовой модели под живой WebRTC нет: ITU-T P.1203/P.1204 написаны для адаптивного стриминга. Обычно строят регрессию по битрейту, разрешению, частоте кадров и кодеку и калибруют её субъективными тестами раз в квартал. В итоговой оценке для разговорных продуктов (колл-центр, телемедицина) звук весит 60%, видео 40%; для продуктов, где смотрят контент (вебинары, спорт), наоборот.
Нужна телеметрия качества звонков в вашем продукте?
Подключим сбор getStats, хранилище, дашборды с MOS и синтетические тесты в CI. Начнём с разбора вашего текущего дампа и назовём, что чинить первым.
Четыре слоя тест-плана WebRTC
Полная стратегия тестирования WebRTC складывается из четырёх независимых слоёв; пропустите один, и целый класс ошибок дойдёт до продакшена.

Рисунок 3. Четыре независимых слоя: от проверки разработчика на каждом PR до постоянного мониторинга реальных звонков.
- Слой 1 — разработчик. Один инженер, две вкладки, chrome://webrtc-internals. Запускается на каждый PR и сразу ловит грубые ошибки.
- Слой 2 — ручной QA. Тестировщик проходит 10–20 реалистичных сценариев в StreamTest перед каждым релизом. Ловит то, что не видно в цифрах, например не появившееся уведомление о переподключении.
- Слой 3 — нагрузка и плохая сеть. webrtcperf, Loadero, CyaraRTC или своя сетка Selenium поднимают от 100 до 10 000 виртуальных клиентов в реалистичных сетевых условиях. Прогоны идут ночью или перед крупным релизом и находят пределы SFU, ёмкость TURN и горячие точки процессора.
- Слой 4 — реальные звонки. Замеры getStats от каждого пользователя, ClickHouse, алерты по p95. Работает постоянно и ловит регрессии после обновления стороннего SDK, смены пиринга у провайдера или TURN-сервера, который тихо начал терять пакеты.
Тестирование WebRTC входит в общую практику QA. Зачем она бизнесу и сколько на неё закладывать, мы разобрали в статье зачем нужно тестирование ПО в 2026 году.
Нагрузочное тестирование WebRTC: webrtcperf, Loadero, CyaraRTC, KITE
Функциональный тест проходит на одном пользователе, а продукт ломается на пятистах. На нагрузке выясняется, что SFU спокойно держит 200 отправителей, но путь подписчиков рушится на тысяче, или что в конфиге TURN стоит лимит сессий, о котором никто не помнит. Четыре инструмента ниже покрывают весь диапазон цен.
webrtcperf: открытый и лёгкий
webrtcperf написан на Node.js и Puppeteer, живёт в одном репозитории и запускается везде, где есть Docker; последние изменения в проекте датированы июлем 2026 года. Создан для бенчмарка медиасерверов: LiveKit, Janus, mediasoup, Jitsi. 100–500 клиентов на одной машине среднего размера, без интерфейса, всё через конфиг. Работает только с Chromium. Это самый быстрый способ проверить, держит ли новая сборка SFU 500 отправителей.
Loadero: облачный сервис для QA
Сценарии на Selenium (JavaScript, Java, Python), настоящие Chrome и Firefox в разных регионах, подмена камеры и микрофона, сетевые профили, посекундный getStats по каждому участнику. На ноябрь 2026 года тарифы Loadero такие: план с оплатой по факту стоит от $250 в месяц (Essential), подписка от $399 в месяц с 10 000 вычислительных единиц, каждая следующая единица стоит $0,045. Одна единица равна половине ядра и 1 ГБ памяти на участника. Подходит командам без своего SRE. Как оплачивать зарубежный сервис из России, лучше решить заранее.
CyaraRTC (бывший testRTC): корпоративный уровень
Cyara продаёт бывший testRTC как единую платформу CyaraRTC: testingRTC для сценарной нагрузки, watchRTC как виджет мониторинга реальных пользователей внутри вашего приложения и qualityRTC для проверки сети перед звонком. Для QA это самый проработанный вариант, цены корпоративные (подписка на места и кредиты на прогоны). Его выбирают, когда бизнесу нужен вендор с поддержкой и бюджет это позволяет.
KITE: архивирован, новый стенд на нём не начинать
Открытый движок кросс-браузерных тестов на Selenium-сетке. Репозиторий webrtc/KITE архивирован и доступен только для чтения, исправлений под новые версии браузеров не будет. Если у вас уже есть сетка KITE, её можно держать, но новый стенд начинайте на webrtcperf или на своей сетке Selenium или Playwright.
| Инструмент | Для чего лучше | Масштаб | Модель оплаты | Главное ограничение |
|---|---|---|---|---|
| StreamTest | ручной QA, отладка вживую, поддержка | 1 входящий поток | бесплатно | только Chrome 116+ на компьютере, один поток за раз |
| webrtcperf | бенчмарк SFU | 100–500 на узел | открытый код + ваша инфраструктура | без интерфейса, только Chromium |
| Loadero | нагрузочные прогоны для QA | тысячи | вычислительные единицы, от $250–399 в месяц | цена растёт с минутами сессий |
| CyaraRTC | корпоративный QA и мониторинг | десятки тысяч | подписка на места + кредиты | долгое внедрение |
| KITE | кросс-браузерные тесты на готовой сетке | по размеру сетки | открытый код + ваша инфраструктура | архивирован, дорог в поддержке |
| Свой getStats + ClickHouse | мониторинг реальных пользователей | без ограничений | хранение и трафик | нужно время команды на сборку |
Правило выбора: для бенчмарка своего SFU берите webrtcperf, для результата на этой неделе без своей инфраструктуры Loadero, для вендора с поддержкой и корпоративных требований CyaraRTC. KITE оставляйте, только если сетка уже есть.

Рисунок 4. Выбор инструмента нагрузки по трём вопросам: есть ли SRE, свой ли SFU и какие браузеры нужны.
Плохая сеть на стенде: профили tc/netem
Тест в офисном Wi-Fi почти ничего не доказывает: пользователи сидят в гостиничном Wi-Fi, в 4G в поезде и на раздаче с телефона. Плохую сеть нужно включать специально, и для этого обычно берут Linux tc с дисциплиной netem.
# netem задерживает только исходящий трафик: задержка ниже добавляется один раз за круг.
# Профиль 1: домашний Wi-Fi (+50 мс RTT, 1% потерь, джиттер 10 мс)
sudo tc qdisc add dev eth0 root netem delay 50ms 10ms loss 1%
# Профиль 2: 4G в поезде (+150 мс RTT, 3% потерь, джиттер 40 мс, канал 1 Мбит/с)
sudo tc qdisc add dev eth0 root netem delay 150ms 40ms loss 3% rate 1mbit
# Профиль 3: перегруженная мобильная сеть (+300 мс RTT, пачки потерь, модель Гилберта-Эллиотта)
sudo tc qdisc add dev eth0 root netem delay 300ms 60ms loss gemodel 2% 30%
# Убрать профиль
sudo tc qdisc del dev eth0 root
Каждый релиз мы прогоняем через все три профиля в CI до слияния. В Loadero те же профили включаются кнопкой, в webrtcperf задаются одной строкой конфига. Большой джиттер ещё и переставляет пакеты местами, а это полезный стресс-тест сам по себе. При 5% потерь звонок не будет идеальным, и это нормально. Важно точно знать, как он деградирует и совпадает ли это с порогами, которые вы пообещали бизнесу.
Для мобильных клиентов есть свои способы замедлить сеть: эмулятор, adb и сетевые фермы. Они собраны в статье эмуляция медленного интернета на Android: 5 способов, а способы без кода для iOS и Android описаны в QA-гайде по медленному соединению.
Синтетический мониторинг или реальные пользователи
Нужны оба: синтетика находит проблему до пользователя, мониторинг реальных звонков (RUM) показывает то, что синтетика никогда не воспроизведёт.
Синтетический мониторинг каждые N минут запускает скриптовых пользователей против вашей инфраструктуры. Алерт срабатывает раньше, чем настоящий клиент наткнётся на ошибку, а путь каждый раз одинаковый, поэтому регрессия видна как ступенька на графике. Минус: покрыты только заскриптованные сценарии, домашнюю сеть реального пользователя синтетика не повторит.
RUM пассивно собирает getStats со всех продакшен-звонков. О проблеме вы узнаёте после того, как с ней столкнулись люди, зато выборка отражает реальный мир: все браузеры, ОС, провайдеры и регионы TURN. Только RUM на объёме покажет, что конкретная версия Safari на конкретной iOS даёт свой узор потерь. Недорогая связка: Loadero или CyaraRTC для синтетики и своя телеметрия getStats для RUM.
Как тестировать голосовых ИИ-агентов на WebRTC
Голосового агента нужно тестировать как звонок, а не как код: текстовые проверки не трогают аудиопуть, перебивания и задержку, которую чувствует собеседник. Агент на LiveKit или Pipecat может отвечать правильно и всё равно проваливать разговор.
Решает всё время до первого слова ответа после того, как человек закончил фразу. До 300 мс разговор ощущается человеческим, при 300–600 мс медленно, но терпимо, после 600 мс люди начинают говорить с агентом как с автоответчиком, после 1,5 секунды растёт число брошенных звонков. По данным Hamming за 2026 год медиана полной задержки в продакшене составляет 1,5–1,7 секунды, p90 около 3 секунд, так что выиграть есть где.
Слои тестов те же, что для любого WebRTC-продукта, плюс три проверки для агента. Меряйте время до первого слова под профилями tc/netem, а не только на чистой линии. Скриптуйте перебивания: замолкает ли агент, когда его прерывают. Следите за паузами в аудиоконвейере даже при правильном ответе модели: идеальная расшифровка с двухсекундной паузой всё равно теряет собеседника. Сервисы Hamming, Coval и Cekura имитируют звонящих на масштабе и покрывают диалог и задержку, а сетевые тесты из этой статьи проверяют путь WebRTC под ними. Архитектуру таких агентов мы разобрали в статье ИИ-агенты на WebRTC: архитектура и задержки.
Мини-кейс: доля фризов с 12% до 0,8%
Ситуация. Клиент с платформой онлайн-обучения на SFU mediasoup жаловался, что «уроки зависают». Жалобы шли только из ОАЭ и ЮАР, а в наших тестах из Европы всё выглядело нормально. NPS падал, и продуктовую команду подталкивали к переезду на коммерческий SDK.
Что сделали. Сначала собрали RUM-конвейер на getStats с метками региона и использованного TURN-сервера. Данные показали p95 доли фризов 12% из ОАЭ и 9% из ЮАР против 1,5% из Европы. Трассировки и дампы WebRTC объяснили причину: местные провайдеры тихо блокировали UDP на высоких портах, и звонки уходили на TURN по TCP с RTT 350 мс. Мы поставили региональные TURN-кластеры внутри этих стран и добавили ранний переход на TCP при проверке соединения. Исправление подтвердили синтетическими тестами Loadero на профиле в 500 учеников, а RUM-дашборды оставили как сигнальную систему.
Результат. Доля фризов в ОАЭ упала с 12% до 0,8%, в ЮАР с 9% до 1,1%. Обращений в поддержку за квартал стало на 73% меньше, разговор о переезде на SDK закрыли, а тот же конвейер теперь ловит регрессии раньше, чем их увидит поддержка. Похожие задачи мы решаем и в конференц-сервисах: например, в видеоконференциях ProVideoMeeting на WebRTC и FreeSWITCH с SIP-дозвоном.

Рисунок 5. До и после региональных TURN-кластеров: p95 доли фризов упала в разы, обращений в поддержку стало на 73% меньше.
Как выбрать набор инструментов: пять вопросов
- Сколько участников в самом большом звонке? До 10 хватит ручного QA и getStats. При 10–100 добавьте webrtcperf для нагрузки SFU, при 100–1000 нужен Loadero или своя сетка браузеров, а больше 1000 участников потребуют CyaraRTC и собственного RUM.
- Нужны Safari, Firefox и Chrome? Тогда CyaraRTC, Loadero (Chrome и Firefox) или своя сетка Selenium или Playwright: webrtcperf работает только с Chromium, а у Safari свои особенности ICE и кодеков.
- Продукт регулируется (152-ФЗ, медицина, финансы)? Нужны журналы инцидентов качества, которые можно показать проверяющему. Стройте свой RUM, чтобы данные хранились там, где требует закон.
- Как часто выходят релизы? При ежедневных выкладках нагрузочные тесты нужны в CI с гейтом по метрикам. Если релизы раз в неделю и реже, хватит ночных прогонов.
- Свой SFU или облачный (LiveKit Cloud, Agora, Twilio)? Со своим SFU бенчмарк на вас (webrtcperf и своя нагрузка). С облачным нагрузку сервера проверяет вендор, а ваш бюджет уходит на клиентский RUM и кросс-браузерную синтетику. Варианты сравниваются в разборе облачные SDK или свой WebRTC.
Если звонки уже в продакшене и вы не уверены, что архитектура выдержит рост, начните с независимого ревью архитектуры видеосервиса: мы проверяем SFU, TURN, регионы и телеметрию до того, как пользователи начнут жаловаться.
Пять ошибок, из-за которых тесты WebRTC бесполезны
- Замеры только в офисном Wi-Fi. Пользователи сидят не в вашем офисе. В каждом тестовом окружении нужен принудительный профиль плохой сети, а дашборды должны делить данные по типу сети (Wi-Fi, мобильная, проводная).
- Алерты по сырым полям getStats. Потери больше 2% на полсекунды случаются у каждого. Алерт ставят на устойчивый p95 в окне 3–5 минут, иначе дежурный просто выключит канал.
- Игнорирование qualityLimitationReason. Самое недооценённое поле. Если там cpu, никакая работа с сетью не поможет: снижайте разрешение, включайте аппаратные кодеки или переходите на AV1, где клиент его тянет.
- Нет ID сессии в телеметрии. Без общего идентификатора в логах, метриках и событиях приложения разбор инцидента превращается в археологию. Пробрасывайте UUID сессии от бэкенда до консоли браузера.
- Только счастливый путь. Переподключение, отказ в доступе к камере, камера, выдернутая посреди звонка, канал, упавший с 5 Мбит/с до 200 кбит/с: именно здесь пользователи уходят. Отдайте этим сценариям 30% тестовой матрицы.
Какие KPI качества показывать бизнесу
Инженерам и бизнесу нужны разные метрики: на дашборд руководителя выносят три группы показателей, а сырые цифры оставляют на клик ниже.
| Группа | Показатель | Цель |
|---|---|---|
| Качество | итоговый MOS, p50 и p5 | p50 ≥ 4,2, p5 ≥ 3,5 |
| Качество | доля фризов, p95 по регионам | < 2% |
| Качество | время до первого кадра, p95 | < 3 с |
| Бизнес | доля звонков без видимой ошибки | > 98% |
| Бизнес | переподключений на час звонка | < 0,5 |
| Бизнес | обращений в поддержку на 1000 часов звонков | < 1 |
| Надёжность | доступность SFU по регионам | 99,95% |
| Надёжность | доля звонков через TURN | < 20% |
| Надёжность | доля сбоев ICE | < 0,5% |
Как связать эти цели с SLO и бюджетом ошибок для всего сервиса, мы описали в статье надёжное ПО: SLO, паттерны и DORA.
Когда не стоит строить свой стенд
Свой конвейер тестов окупается только начиная с определённого объёма и темпа. Если верно хотя бы одно из условий ниже, начните с CyaraRTC или Loadero на 6–12 месяцев:
- Меньше 50 нагрузочных прогонов в месяц. Вы будете платить за простаивающую инфраструктуру, а облачные кредиты в тихие недели не тратятся.
- Нет SRE на полную ставку. Сетка Selenium на спотовых машинах сама не работает. Без владельца тесты краснеют по причинам, не связанным с продуктом, и им перестают верить.
- Вы на облачном WebRTC SDK. Нагрузка сервера на стороне вендора. От вас требуется проверять его SLA, бенчмаркать чужой SFU заново незачем.
- Продукт до product-market fit. Тратьте часы инженеров на продукт. До появления заметной выручки хватит ручного QA и платного тарифа Loadero для релизных гейтов.
С чего начать на этой неделе
Программа качества WebRTC держится на трёх привычках. «Хорошо» описано семью цифрами с опубликованными порогами. Эти цифры проверяются на четырёх слоях, чтобы ни один класс ошибок не проскочил. А бизнес видит качество как MOS и долю успешных звонков, а не как сырые потери пакетов.
Начните со StreamTest на этой неделе, добавьте телеметрию getStats в следующем месяце и нагрузочный стенд в следующем квартале. Если хрупкое место уже найдено и его нужно стабилизировать, команда доработки и оптимизации ПО возьмёт на себя исправления и закрепит результат тестами.
Хотите знать, где ломается ваш звонок?
Принесите дамп webrtc-internals или экспорт StreamTest, а мы вернём план: что чинить в клиенте, сети, TURN и медиасервере и в каком порядке.
Частые вопросы о тестировании WebRTC
Какая метрика важнее всего для качества WebRTC-звонка?
Доля фризов. Пользователи прощают пикселизацию и низкое разрешение, но не прощают остановившееся видео. Если следить можно только за одной цифрой, делите totalFreezesDuration на длину сессии и ставьте алерт, когда p95 переходит 2%.
Можно ли проверить WebRTC-стрим без кода?
Да. Установите бесплатное расширение StreamTest для Chrome, щёлкните правой кнопкой по видео участника и выберите Test stream. Вы увидите семь метрик в реальном времени, названные проблемы с вероятной причиной и отчёт, который можно скопировать в тикет или выгрузить в JSON и CSV.
Где скачать StreamTest, если старая ссылка не открывается?
Старая карточка в магазине Chrome снята. Актуальная версия 2.0.0 опубликована в Chrome Web Store под названием StreamTest от ForaSoft, исходный код открыт на GitHub в репозитории forasoft/video-testing-tool.
Какие потери пакетов допустимы для видео в WebRTC?
До 1% потерь не видно благодаря NACK и FEC. От 1 до 5% появляются артефакты, и получатель чаще просит ключевые кадры. Больше 5% качество быстро рушится. Для телемедицины и вещания держите планку ниже 2%.
Как читать дамп chrome://webrtc-internals?
Во время звонка нажмите Create Dump: браузер сохранит JSON с парами кандидатов, входящими и исходящими RTP-отчётами и журналом вызовов API. Загрузите его в просмотрщик вроде webrtc-dump-importer или в Jupyter с pandas, постройте RTT и число фризов по времени, найдите перелом и сверьте его с журналом API в ту же секунду.
Сколько пользователей может имитировать нагрузочный тест WebRTC?
webrtcperf на одной машине среднего размера держит 100–500 клиентов Chrome без интерфейса. Loadero масштабируется до тысяч настоящих браузеров в разных регионах, CyaraRTC — до десятков тысяч на корпоративных тарифах. Большинству продуктов реально нужно 500–2000 виртуальных пользователей.
Как протестировать WebRTC в плохой сети?
Linux tc с netem добавляет задержку, джиттер, потери и ограничение канала на уровне ядра. Три профиля покрывают большую часть реальных условий: домашний Wi-Fi (50 мс, 1% потерь), 4G в поезде (150 мс, 3%), перегруженная мобильная сеть (300 мс, пачки потерь).
Что такое MOS и нужен ли он?
MOS (Mean Opinion Score) — оценка качества от 1 до 5, которая коррелирует с восприятием звонка. Для звука есть строгая модель ITU-T G.107, для видео строят регрессию по битрейту, разрешению, частоте кадров и кодеку. Итоговый MOS на дашборде позволяет обсуждать качество без знания RTP; цель для p50 — 4,2 и выше.
Поддерживается ли ещё KITE?
Нет. Репозиторий webrtc/KITE на GitHub архивирован и доступен только для чтения. Готовые сетки работают, но для нового нагрузочного стенда берите webrtcperf, Loadero, CyaraRTC или свою сетку Selenium или Playwright.
«WebRTC leak test» — это проверка качества?
Нет, это разные задачи. Тест утечки WebRTC проверяет, раскрывает ли браузер ваш настоящий IP-адрес при включённом VPN; это вопрос приватности. Проверка качества, о которой эта статья, меряет, хорошо ли звонок выглядит и звучит: потери, джиттер, фризы, MOS.
Что почитать дальше
Основы
Что такое WebRTC: как работает, STUN, TURN и SFU (2026)
WebRTC — это открытый стандарт видеосвязи в браузере. Как он работает: сигналинг, SDP, ICE, STUN и TURN, P2P и SFU, безопасность и цена TURN в 2026 году.
Задержка
Снижение задержки в массовых видеотрансляциях до менее чем 1 секунды с помощью WebRTC
Узнайте, как добиться ультранизкой задержки в прямых трансляциях для тысяч зрителей — на примере проекта WorldCast Live.
Архитектура
Какой тип архитектуры выбрать для видеочата: P2P, MCU или SFU?
Одной из главных сильных сторон WebRTC — гибкость. В этой статье мы разберём разницу между P2P, MCU и SFU, чтобы помочь вам выбрать подходящее решение.
Плохая сеть
Эмуляция медленного интернета на Android: 5 способов 2026
Как замедлить сеть на Android для тестов: флаги эмулятора, tc/netem, Charles, DevTools и фермы устройств. Профили, команды для CI и пороги Android vitals.
Безопасность
Как работает безопасность WebRTC — просто и понятно
О безопасности WebRTC: как создать защищённый видеочат и избежать утечек данных пользователей. Понятно и по делу.
