Розроблення групових відеоконференцій у мобільному застосунку
Конференція на 2 учасники та конференція на 10 — технічно різні задачі. При peer-to-peer WebRTC на 5 учасників кожен надсилає відео четирьом іншим — всього 20 потоків на групу. iPhone 13 починає перегріватися через 10 хвилин. Правильне рішення для групи — SFU (Selective Forwarding Unit) або MCU.
Архітектура: 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: ключ до масштабованості
Без simulcast на конференції 10+ людей мобільний пристрій надсилає один поток 720p — та його отримують всі учасники, навіть ті, у кого малий тайл на екрані. З simulcast клієнт надсилає три якості одночасно (наприклад 180p/360p/720p), а SFU надсилає кожному одержувачу підходяще якість по ширині тайла.
На 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 у одержувачів при великій кількості учасників.
Відображення учасників: grid та dominant speaker
Grid на 2–4 учасника — статичний layout. На 5–16 учасників — динамічний grid, який змінюється при входженні/виходженні. Правило: не пересоздавайте RTCVideoRenderer при кожному оновленні grid — тільки переназначайте track до існуючого renderer. Пересоздання вичивает миготіння та перевідріодку.
Dominant speaker detection — визначаємо, хто зараз говорить, та виводимо його більшим. Livekit та 100ms пропонують це з коробки через eventos 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 → адаптація до теплового стану → нагрузкове тестування.
Конференція до 8 учасників через managed SFU (100ms, Daily) з готовим SDK — 2–4 тижні. Self-hosted Livekit з кастомним UI та simulcast — 4–8 тижнів. Вартість розраховується після аналізу вимог.







