Как масштабировать видеоконференцию без перегрева?
Представьте: в вашем приложении 8 участников, через 10 минут iPhone нагревается до 42°, звонок обрывается. Проблема в архитектуре: без SFU каждый мобильный клиент отправляет видео всем остальным — в группе из 8 участников каждый обрабатывает 7 входящих потоков и 1 исходящий. Нагрузка на процессор и сеть растёт квадратично. Правильное решение — SFU (Selective Forwarding Unit) и simulcast. Мы проектируем архитектуру под ваш сценарий: от 2 до 20 участников, с адаптацией к термальному состоянию устройств.
Почему SFU, а не MCU?
MCU (Multipoint Control Unit) — сервер смешивает все потоки в один и отправляет каждому участнику одно видео. Нагрузка на клиент минимальная, но микширование на сервере требует мощного CPU и вносит задержку 100–300 мс. Подходит для вебинаров, где большинство смотрит одного. SFU (Selective Forwarding Unit) — сервер только маршрутизирует потоки, не декодирует. Каждый клиент получает N потоков (по одному от каждого участника), но сам выбирает, какие декодировать и отображать. Нагрузка выше, зато задержка ниже и гибкость больше.
Для мобильного приложения с конференциями до 20 участников оптимален SFU. Готовые решения: Livekit (open-source, self-hosted), Mediasoup, Jitsi Videobridge, или managed-сервисы — Daily.co, 100ms, Twilio Video Rooms. Livekit — хороший выбор для self-hosted: Go-сервер, WebRTC SFU, поддержка simulcast и dynacast, нативные SDK для iOS (LiveKit-iOS), Android (LiveKit-Android), Flutter и React Native. MIT-лицензия.
Как simulcast снижает нагрузку на CPU?
Без simulcast на конференции 10+ человек мобильное устройство отправляет один поток 720p — и его получают все участники, даже те, у кого маленький тайл на экране. С simulcast клиент отправляет три качества одновременно (например 180p/360p/720p), а SFU отправляет каждому получателю подходящее качество по ширине тайла. Экономия ресурсов заметна: нагрузка на CPU снижается до 40% при большом числе участников.
На iOS simulcast настраивается через RTCRtpEncodingParameters с тремя слоями:
let encodings = [ RTCRtpEncodingParameters(rid: "q", scaleResolutionDownBy: 4, maxBitrateBps: 150_000), RTCRtpEncodingParameters(rid: "h", scaleResolutionDownBy: 2, maxBitrateBps: 500_000), RTCRtpEncodingParameters(rid: "f", scaleResolutionDownBy: 1, maxBitrateBps: 1_200_000), ] На Android — аналогично через RtpParameters.Encoding. Это снижает нагрузку на сеть и CPU у получателей при большом числе участников.
| Слой | Разрешение | Битрейт (bps) | Сценарий использования |
|---|---|---|---|
| q (quarter) | 180p | 150 000 | Миниатюры, 9+ участников |
| h (half) | 360p | 500 000 | Средний тайл, 4–8 участников |
| f (full) | 720p | 1 200 000 | Главный докладчик, 1–2 участника |
Как отображать участников: grid и dominant speaker
Grid на 2–4 участника — статичный layout. На 5–16 участников — динамический grid, который меняется при входе/выходе. Правило: не пересоздавать RTCVideoRenderer при каждом обновлении grid — только переназначать track к существующему renderer. Пересоздание вызывает мигание и повторную отрисовку.
Dominant speaker detection — определяем, кто сейчас говорит, и выводим его крупнее. Livekit и 100ms предоставляют это из коробки через события onActiveSpeakersChanged. В сыром WebRTC — через анализ audioLevel из RTCPeerConnection.getStats().
На iOS рендеринг видео через RTCMTLVideoView (Metal) — обязательно для конференций. Старый RTCEAGLVideoView (OpenGL ES) не поддерживает несколько экземпляров с хорошей производительностью на A15+. При 6 участниках RTCEAGLVideoView даёт 40 FPS, RTCMTLVideoView — стабильные 60 FPS.
Батарея и термальное состояние
Групповая конференция — самый батареоёмкий режим приложения. Энкодинг видео 720p на 30 FPS потребляет ~15–20% заряда в час на iPhone 14. При 4+ участниках — ещё декодинг нескольких потоков.
Реагируем на ProcessInfo.thermalState (iOS) — при .serious или .critical понижаем разрешение до 360p и снижаем FPS до 15. На Android — PowerManager.getThermalHeadroom() (Android 11+). Это не деградация, а адаптация: лучше стабильная конференция в 360p, чем перегрев и принудительный throttling процессора.
При сворачивании приложения на iOS — останавливаем захват с камеры (AVCaptureSession.stopRunning()), аудио продолжает работать через AVAudioSession. На Android — ForegroundService с android:foregroundServiceType="camera|microphone" удерживает разрешения. Такой подход экономит батарею и снижает тепловыделение.
Типичные ошибки
- Одна
AVCaptureSessionна всё приложение — не пересоздавать при каждом звонке. Инициализация сессии занимает 200–500 мс, пересоздание при каждом звонке заметно пользователю. - Не обрабатывать
AVAudioSession.routeChangeNotification— подключение AirPods во время конференции без обработки этого уведомления уводит аудио в earpiece. - Не освобождать
RTCVideoTrackпри выходе участника из конференции — утечка памяти, которая накапливается при длинных сессиях и больших комнатах.
Процесс и сроки
Аудит требований → выбор SFU (self-hosted или managed) → интеграция SDK → UI (grid, dominant speaker, controls) → simulcast → адаптация к тепловому состоянию → нагрузочное тестирование. После сдачи мы предоставляем документацию по SDK, доступы к консоли управления и краткое обучение команды. Наша команда имеет 7+ лет опыта в мобильной разработке и более 15 коммерческих проектов с WebRTC.
| Этап | Срок (нед) | Входит |
|---|---|---|
| Аудит и выбор архитектуры | 1–2 | Технический анализ, рекомендация SFU |
| Интеграция SDK и базовый UI | 2–3 | Подключение Livekit/100ms, grid, controls |
| Simulcast и адаптивное качество | 1–2 | Настройка encoding, thermal state |
| Нагрузочное тестирование и батарея | 1 | Профилирование, оптимизация |
Конференция до 8 участников через managed SFU (100ms, Daily) с готовым SDK — 2–4 недели. Self-hosted Livekit с кастомным UI и simulcast — 4–8 недель. Стоимость рассчитывается после анализа требований. Свяжитесь с нами — оценим ваш проект и предложим архитектуру под ключ.
Что входит в работу
- Технический аудит и рекомендации по архитектуре
- Подбор и интеграция SFU (self-hosted или managed)
- Разработка UI: grid, dominant speaker, элементы управления
- Настройка simulcast и адаптивного качества
- Оптимизация батареи и термального состояния
- Нагрузочное тестирование до 20 участников
- Документация по интеграции SDK
- Доступы к консоли управления
- Краткое обучение команды
Пошаговая настройка simulcast на iOS
- Создайте объект
RTCRtpEncodingParametersдля каждого слоя с параметрамиrid,scaleResolutionDownBy,maxBitrateBps. - Установите эти encoding на видео-трек через
RTCRtpSender.setParameters(). - На стороне SFU включите поддержку simulcast (в Livekit — флаг
SimulcastConfig). - Проверьте, что получатели корректно переключаются между слоями при изменении размера тайла.
- Профилируйте нагрузку на CPU и сеть при 10+ участниках.
Согласно документации WebRTC, корректная реализация simulcast может сократить использование полосы пропускания до 40%.
Получите консультацию по интеграции — поможем внедрить simulcast в ваш проект.







