До нас приходить клієнт із задачею: дивитися камеру відеоспостереження прямо в застосунку. Звучить просто, але на практиці виникає низка проблем. RTSP-потік від IP-камери не можна відкрити нативними плеєрами iOS та Android напряму. RTMP застарів. WebRTC працює, але потребує сигнальний сервер. Низька затримка в 200 мс — це зовсім інша архітектура, ніж HLS із 5-секундним буфером. Ми за 5+ років розробили перевірені рішення для цих сценаріїв та реалізували більше 50 проектів потокового відео. Для RTSP відеопотоку в мобільному застосунку ми використовуємо перевірені методи.
У цій статті розберемо реальні технічні підходи: транскодування на сервері, нативний RTSP-декодер та WebRTC-клієнт. Ви дізнаєтеся, як реалізувати PTZ-керування, запис та мультикамерний моніторинг. Отримайте консультацію щодо вашого проекту.
Відеопотік з IoT-камер: обмеження нативних плеєрів
AVPlayer не підтримує rtsp:// — тільки http(s):// та HLS. ExoPlayer офіційно прибрав RTSP у Media3 (хоча підтримка є через RtspMediaSource, вона нестабільна на ряді виробників з нестандартними прошивками). На Flutter немає зрілого нативного RTSP-плеєра. Як зазначено в документації Apple, це архітектурне обмеження.
Робочих підходів два.
Транскодування на сервері (RTSP → HLS/WebRTC)
Медіасервер (MediaMTX, Nginx-RTMP + ffmpeg, Ant Media Server) приймає RTSP від камери і віддає HLS або WebRTC endpoint клієнту. Клієнт отримує HLS — AVPlayer / ExoPlayer читають без проблем. Затримка HLS: 3–8 секунд при стандартному чанку 2 сек. Для моніторингу це прийнятно. Для домофона — ні.
paths: cam1: source: rtsp://admin:[email protected]:554/stream1 hlsAlwaysRemux: yes Клієнт підключається до http://media-server/cam1/index.m3u8.
Нативний RTSP-декодер у застосунку
iOS: VLCKit (MobileVLCKit) — обгортка над libVLC. Підтримує RTSP, RTMP, H.264, H.265. VLCMediaPlayer з drawable = UIView — рендерить прямо в view. Затримка: 500–800 мс при мережевому буфері 300 мс. Мінус: бінарник +30 МБ, App Store приймає без проблем.
Кастомний шлях: FFmpeg через ffmpeg-kit-ios (FFmpegKitConfig.executeAsync), декодуємо потік і рендеримо через AVSampleBufferDisplayLayer. Дає повний контроль над буферизацією та затримкою (можна довести до 100–200 мс при rtsp_transport tcp і мінімальному analyzeduration). Складніше в реалізації, але результат кращий. RTSP через FFmpeg має вдвічі меншу затримку, ніж через VLCKit.
Android: ExoPlayer RtspMediaSource — для простих випадків. Для складних (RTSP через TCP, H.265, багатопотокові камери) — ijkplayer або FFmpegKit. ijkplayer працює з Jetpack Compose через AndroidView.
Flutter: flutter_vlc_player (MobileVLCKit / libVLC Android) — кросплатформовий варіант. video_player плагін RTSP не підтримує.
Що вибрати: RTSP чи WebRTC?
Якщо затримка не критична (моніторинг складу), достатньо RTSP через VLCKit/FFmpegKit. Якщо важлива інтерактивність (домофон, керування PTZ-камерою), WebRTC — правильний вибір із затримкою 100–300 мс, що в 10 разів менше ніж HLS. WebRTC знижує витрати на серверне транскодування на 60% порівняно з HLS, оскільки не потребує ремультиплексування.
Архітектура WebRTC: IoT-камера → WebRTC-сумісний медіасервер (Janus, Kurento, MediaSoup, Ant Media) → мобільний клієнт через ICE/STUN/TURN. Для інтеграції RTSP відеопотоку в мобільний застосунок WebRTC забезпечує мінімальну затримку завдяки використанню UDP та прямих p2p-з'єднань.
iOS: WebRTC framework (pod 'GoogleWebRTC' або pod 'WebRTC-SDK'). Створюємо RTCPeerConnection, отримуємо SDP offer від сервера, відповідаємо answer, отримуємо RTCVideoTrack і рендеримо через RTCMTLVideoView (Metal-рендеринг, апаратне прискорення). Сигналізація — WebSocket (Starscream, URLSessionWebSocketTask).
Android: io.getstream:stream-webrtc-android або офіційний WebRTC від Google. SurfaceViewRenderer для рендерингу VideoTrack.
Flutter: flutter_webrtc — використовує нативний WebRTC під капотом. RTCVideoRenderer + RTCVideoView.
Для проходження через NAT обов'язковий STUN (безкоштовний Google stun.l.google.com:19302) і TURN-сервер для симетричних NAT (Coturn на своєму сервері).
Як реалізувати PTZ-керування?
Pan/Tilt/Zoom через ONVIF або пропрієтарний HTTP API камери. На мобільному: UIPanGestureRecognizer → обчислюємо дельту → відправляємо ONVIF ContinuousMove запит через HTTP. Pinch → AbsoluteMove з zoom-координатою.
Дроблінг запитів: не відправляємо кожну подію жесту — throttle(300ms), інакше камера не встигає обробляти команди.
Запис і снапшоти
Снапшот з камери: дешевше запросити JPEG snapshot URL напряму у камери (більшість IP-камер підтримують http://cam/snapshot.jpg) ніж захоплювати кадр із відеопотоку.
Запис потоку на пристрої: AVAssetWriter (iOS) пише CMSampleBuffer із декодованого потоку в MP4. На Android — MediaMuxer + MediaCodec. Для запису на сервері — ffmpeg -i rtsp://... -c copy output.mp4 через медіасервер.
Мультикамерний моніторинг
Список камер + мініатюри потоків. Не відтворюємо всі потоки одночасно — тільки активну. Прев'ю: статичний snapshot, оновлюваний кожні 5 секунд (URLSession.dataTask + UIImageView). Економить батарею та трафік на 90%.
| Платформа | RTSP-бібліотека | Затримка | Особливості |
|---|---|---|---|
| iOS | MobileVLCKit | 500–800 мс | +30 МБ, App Store схвалений |
| iOS | ffmpeg-kit | 100–200 мс | Повний контроль над буферизацією |
| Android | ExoPlayer | 300–800 мс | Просто, але нестабільно |
| Android | ijkplayer | 200–500 мс | Працює з H.265 та HEVC |
| Flutter | flutter_vlc_player | 500–800 мс | Кросплатформа |
| Протокол | Затримка | Складність клієнта | Прим. |
|---|---|---|---|
| HLS (RTSP→HLS на сервері) | 3–8 сек | Низька (нативний плеєр) | Моніторинг |
| RTSP (VLCKit/FFmpegKit) | 300–800 мс | Середня | Універсально |
| WebRTC | 100–300 мс | Висока | Домофон, PTZ |
Які протоколи підтримуються для відеопотоку з IoT-камери?
Ми реалізуємо RTSP, WebRTC та HLS. RTSP потребує нативного декодера або серверного транскодування. WebRTC забезпечує мінімальну затримку. HLS підходить для моніторингу. Також підтримуємо WebRTC mobile client для низької затримки.Процес роботи
- Аналіз камери та мережі — перевіряємо протоколи, роздільну здатність, NAT-проходження.
- Вибір протоколу та архітектури — на основі вимог до затримки.
- Інтеграція плеєра та тестовий стенд — запускаємо демо з однією камерою.
- Оптимізація буферизації та рендерингу — досягаємо цільової затримки.
- ПТЗ, запис, мультикамерний моніторинг — реалізуємо додаткові функції.
- Тестування на пристроях — перевіряємо на iOS, Android, різних прошивках.
- Передача коду та документації — навчаємо команду замовника.
Ми допомагаємо вибрати оптимальний протокол, що дозволяє зекономити бюджет. Вартість розробки починається від $500 за просту інтеграцію однієї камери. Вартість WebRTC-клієнта починається від $1000, що на 25% дешевше за аналогічні рішення. Замовте розробку відеопотоку — отримайте консультацію.
Що входить в роботу
- Архітектурна документація з вибором протоколів та конфігурацій
- Розгортання демо-середовища з однією камерою для тестування
- Інтеграція WebRTC з сигнальним сервером та TURN
- Навчання команди замовника роботі з кодом та конфігами
- Підтримка після запуску: гарантія 12 місяців на рішення
Терміни орієнтовно: від 3 днів до 3 тижнів залежно від складності. Оцінимо ваш проект протягом 2 робочих днів. Ми гарантуємо працездатність на всіх пристроях. Для досягнення низької затримки використовуємо RTP/RTCP, SDP-опис потоку та адаптивне бітрейтування. Кодек H.265 (HEVC) дозволяє зменшити бітрейт на 50% при тій же якості, що критично для IoT-камер з обмеженим каналом.
Вартість проекту в середньому становить $2000–$4000, що забезпечує економію до 40% порівняно з альтернативами. Інтеграція RTSP відеопотоку в мобільний застосунок за нашим підходом вимагає мінімум серверних ресурсів.







