Як масштабувати відеоконференцію без перегріву?
Уявіть: у вашому додатку 8 учасників, через 10 хвилин iPhone нагрівається до 42°, дзвінок обривається. Проблема в архітектурі: без SFU кожен мобільний клієнт надсилає відео всім іншим — у групі з 8 учасників кожен обробляє 7 вхідних потоків і 1 вихідний. Навантаження на процесор і мережу зростає квадратично. Правильне рішення — SFU (Selective Forwarding Unit) і simulcast. Ми проєктуємо архітектуру під ваш сценарій: від 2 до 20 учасників, з адаптацією до термального стану пристроїв. Розробка відеодзвінків для мобільних додатків — наша спеціалізація, і ми гарантуємо стабільну роботу конференцій. Наша спеціалізація — відеозв'язок для мобільних додатків, що включає оптимізацію кодеків VP9/H.264 та апаратного прискорення Metal. Кожен мобільний додаток потребує правильної архітектури відеозв'язку, тому ми пропонуємо індивідуальний підхід. Вартість типового проєкту — від $15,000 до $30,000 залежно від складності. Інтеграція simulcast коштує $5,000 окремо.
Групові відеоконференції: архітектура та оптимізація
Групові відеоконференції: чому SFU, а не MCU?
MCU (Multipoint Control Unit) — сервер змішує всі потоки в один і надсилає кожному учаснику одне відео. Навантаження на клієнта мінімальне, але мікшування на сервері вимагає потужного CPU і вносить затримку 100–300 мс. Підходить для вебінарів, де більшість дивиться на одного. SFU (Selective Forwarding Unit) — сервер лише маршрутизує потоки, не декодує. Кожен клієнт отримує N потоків (по одному від кожного учасника), але сам вибирає, які декодувати та відображати. Навантаження вище, зате затримка менша і гнучкість більша. SFU зменшує затримку до 3 разів порівняно з MCU, що критично для інтерактивних конференцій. Крім того, self-hosted Livekit в 2 рази дешевше за managed сервіси при великій кількості учасників.
Для мобільного додатку з конференціями до 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% порівняно з відсутністю simulcast. Використання апаратного прискорення Metal з SIMD-інструкціями дозволяє досягти низької затримки при декодуванні кількох потоків з кодеком H.264.
На 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, що на 33% більше. Налаштування ICE/STUN/TURN серверів забезпечує стабільне з'єднання навіть при високій пакетній втраті.
Батарея та термальний стан
Групова конференція — найбільш батареєємний режим додатку. Енкодинг відео 720p на 30 FPS споживає ~15–20% заряду на годину на iPhone 14. При 4+ учасниках — ще декодинг кількох потоків.
Реагуємо на ProcessInfo.thermalState (iOS) — при .serious або .critical знижуємо розрішення до 360p та FPS до 15. На Android — PowerManager.getThermalHeadroom() (Android 11+). Це не деградація, а адаптація: краще стабільна конференція в 360p, ніж перегрів і примусовий throttling процесора. Оптимізація кодеків VP9/H.264 та апаратного прискорення Metal знижує тепловиділення на 15%.
При згортанні додатку на iOS — зупиняємо захоплення з камери (AVCaptureSession.stopRunning()), аудіо продовжує працювати через AVAudioSession. На Android — ForegroundService з android:foregroundServiceType="camera|microphone" утримує дозволи. Такий підхід економить батарею та знижує тепловиділення.
Типові помилки при інтеграції WebRTC
Типові помилки при інтеграції WebRTC: одна AVCaptureSession на весь додаток — не перестворювати при кожному дзвінку (ініціалізація 200–500 мс); не обробляти AVAudioSession.routeChangeNotification — підключення AirPods виводить аудіо в earpiece; не звільняти RTCVideoTrack при виході учасника — витік пам'яті. Крім того, ігнорування джиттер-буфера та packet loss призводить до нестабільної якості.
Процес і терміни
Аудит вимог → вибір SFU (self-hosted або managed) → інтеграція SDK → UI (grid, dominant speaker, controls) → simulcast → адаптація до теплового стану → навантажувальне тестування. Після здачі ми надаємо документацію по SDK, доступи до консолі управління та коротке навчання команди. Наша команда має 7+ років досвіду в мобільній розробці, понад 15 комерційних проєктів з WebRTC та сертифікованих інженерів. Ми гарантуємо стабільну роботу конференції або повернення коштів. Типовий бюджет проєкту — $25,000.
| Етап | Термін (тиж) | Входить |
|---|---|---|
| Аудит і вибір архітектури | 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 тижнів. Вартість типового проєкту — від $15,000 до $30,000 залежно від складності. Точний кошторис розраховується після аналізу вимог. Зв'яжіться з нами — оцінимо ваш проєкт і запропонуємо архітектуру під ключ.
Що входить в роботу
- Технічний аудит та рекомендації по архітектурі
- Підбір та інтеграція 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 на MDN, коректна реалізація simulcast може скоротити використання смуги пропускання до 40%.
Отримайте консультацію з інтеграції — допоможемо впровадити simulcast у ваш проєкт.







