diff --git a/frontend/src/pages/RoomPage.tsx b/frontend/src/pages/RoomPage.tsx index aa703a8..47e0e71 100644 --- a/frontend/src/pages/RoomPage.tsx +++ b/frontend/src/pages/RoomPage.tsx @@ -187,6 +187,22 @@ export function RoomPage() { const { userChoices } = usePersistentUserChoices() const roomOptions = useMemo( () => ({ + // Оба флага в LiveKit по умолчанию выключены, и без них каждый клиент + // подписан на полное качество всех чужих треков независимо от размера + // плитки, а каждый паблишер шлёт все слои симулкаста, даже если их никто + // не смотрит. На тесте 28.07.2026 (19 участников, ~8 камер) это дало + // устойчивые 140–169 Мбит/с исходящего трафика при пике 240, 662 события + // `remote bwe: channel congestion detected` и 146 переходов аллокатора + // STABLE → DEFICIENT — то есть видимый участникам лаг. + // + // adaptiveStream: подписка на слой по фактическому размеру плитки на + // экране + пауза треков, которые сейчас не отрисованы. Именно на нём + // начинает экономить уже написанный код: «скрыть остальных» + // (RoomStage) не рендерит карусель, а пагинация StageGrid рендерит + // только текущую страницу — неприаттаченные треки считаются невидимыми. + // dynacast: паблишер прекращает отдавать слои, на которые нет подписчиков. + adaptiveStream: true, + dynacast: true, audioCaptureDefaults: { deviceId: userChoices.audioDeviceId || undefined }, videoCaptureDefaults: { deviceId: userChoices.videoDeviceId || undefined }, // Аудиовыход (колонки/наушники/bluetooth) — отдельный персист, не через