Розробка мобільного додатка для вебінарів
Вебінар на мобільному — це конкурент Zoom, Webex і Google Meet у конкретній ніші. Значит, вимоги не «зробити відеодзвінок», а: стабільний потік при погіршенні якості сітки, демонстрація екрана, чат з реакціями, ролі учасників (організатор / спікер / слухач), запис і відтворення. І все це на iOS і Android з затримкою < 500 мс.
Архітектурний вибір: WebRTC проти готового SDK
Написати конференцію відео з нуля на WebRTC — реально, але це 3–6 місяців тільки на медіа-рушій. Для більшості продуктів правильний вибір — спеціалізований SDK, який закриває SFU, кодеки, адаптивний бітрейт і перевантаження мережі.
Livekit SDK — open source, self-hosted SFU, MIT ліцензія. iOS/Android/Flutter SDK. Стандарт для нових проектів де важливий контроль над даними. Room, LocalParticipant, RemoteParticipant — простої об'єктна модель.
Agora SDK — потужна, але хмарна з посекундною тарифікацією. Хороша коли важливі глобальна CDN і мінімум DevOps.
Daily.co, 100ms, Whereby — хмарні альтернативи з різними моделями ціноутворення.
Twilio Video — зрілий API, але Twilio заморозила розвиток Video у 2023.
Для self-hosted: Livekit + Janus + MediaSoup — три найактивніше підтримувані SFU.
Відео та аудіо: адаптивність під мережу
Головна проблема мобільних вебінарів — перехід між Wi-Fi і LTE посередині виступу. SFU з simulcast вирішує це: спікер відправляє 3 якості відео (720p/360p/180p), сервер вибирає для кожного слухача оптимальне залежно від його пропускної здатності.
Livekit: simulcast включається прапором VideoPublishOptions(simulcast: true). iOS: LKLocalVideoTrack з CameraSource. Android: LocalVideoTrack + Camera2Source. Автоматичне зниження розширення при втраті пакетів — вбудовано в SFU.
Dynacast (Livekit) — автоматично паузує відео-треки спікерів, яких не видить ніхто з слухачів. Економить пропускну здатність на стороні сервера при >50 учасниках.
Аудіо: Opus кодек, 48 кГц, AEC + NS + AGC вбудовано в WebRTC. Спікерфон vs навушниця: AVAudioSession.overrideOutputAudioPort(.speaker) / AudioManager.setSpeakerphoneOn(true). Автоматично при >2 учасниках — включаємо speakerphone, для 1-на-1 — навушниця.
Демонстрація екрана
iOS (ReplayKit). RPScreenRecorder.shared().startCapture(handler:) — працює з iOS 11, доступна з Control Center в iOS 12+. Захист екрана повертає CMSampleBuffer — передаємо в WebRTC RTCVideoCapturer через користувальницький RTCVideoCapturerDelegate. Обмеження: в RPBroadcastSampleHandler (Extension) не можна напряму викликати код основного додатка — використовуємо App Group + CFMessagePort або Darwin notifications для передачі стану.
iOS 15+ RPSystemBroadcastPickerView — нативна кнопка запуску трансляції без коду.
Android (MediaProjection API). MediaProjectionManager.createScreenCaptureIntent() → користувач підтверджує → VirtualDisplay → захист кадрів через ImageReader → VideoEncoder → WebRTC VideoSource. Потребує Foreground Service з типом mediaProjection (Android 10+). У маніфесті: <service android:foregroundServiceType="mediaProjection"/>.
Flutter: flutter_screen_capture (нативні вв'язання до обох API) або користувальницький плагін з platform channels.
Чат, реакції, Q&A
Чат у реальному часі: WebSocket або Livekit DataChannel (LocalParticipant.publishData). DataChannel працює через те ж RTC-з'єднання — не потрібен окремий WebSocket сервер.
Реакції (👏🔥❤️): миттєва анімація у всіх учасників. Відправляємо через DataChannel, рендеримо з particle animation поверх відео-сітки. iOS: UIViewPropertyAnimator + CAEmitterLayer. Android/Compose: AnimatedVisibility + LaunchedEffect.
Q&A: черга питань з upvote. Зберігання на сервері (Livekit RPC або окремий REST). Організатор видить пріоритизований список.
Ролі та права доступу
Організатор, со-організатор, спікер, слухач. Різниця в правах: слухач не публікує відео/аудіо (економія пропускної здатності), може тільки підняти руку → організатор дає слово.
Livekit: ParticipantPermission — canPublish, canPublishData, canSubscribe. Встановлюється сервером при створенні токена або змінюється через RoomServiceClient.updateParticipant.
«Підняти руку»: повідомлення DataChannel {type: "raise_hand", participantId: "..."} → у організатора з'являється індикатор у учасника.
Запис вебінара
Livekit Egress: хмарний запис у S3/R2. EgressServiceClient.startRoomCompositeEgress() — записує composite view (відео всіх учасників в сітці) або track-by-track (окремі треки для монтажу). Формат: MP4 з H.264 + AAC.
Доступ до запису: presigned S3 URL з TTL 24h. У додатку — плеєр (AVPlayer / ExoPlayer) з позиціюванням і швидкістю відтворення.
Етапи та терміни
| Етап | Термін |
|---|---|
| Вибір SFU і настройка сервера | 1 тиждень |
| Відео/аудіо-кімната, ролі | 2–3 тижні |
| Чат, реакції, Q&A | 1 тиждень |
| Screen share iOS + Android | 1 тиждень |
| Запис і playback | 1 тиждень |
| Тестування навантаження (50+ учасників) | 1 тиждень |
Всього: MVP-вебінарне додаток — 6–8 тижнів. З реєстрацією подій, email-розсилками, аналітикою присутності — 10–12 тижнів.







