Розробка мобільного додатку для домофона/відеодомофона
Нажимав кнопку на дверях — телефон зазвонив, на екрані відео з камери, відкрив двері одним тапом. Це сценарій здається простим, але всередині — WebRTC або SIP-стек, ONVIF-протокол, push-уведомлення за долі секунди при закритому додатку, управління реле замка через API пристрою та запис подій. Проєкт на 4-12 тижнів залежно від вимог сумісності обладнання.
Стек: з чого почати проектування
Перший питання: яке «залізо» на дверях?
Готові IP-домофони з SIP (Hikvision DS-KV6113, Grandstream GDS3710, Beward DS06M): підтримують SIP та ONVIF. Телефон реєструється на Asterisk/FreeSWITCH як SIP-клієнт. Входящий звонок з домофона → SIP INVITE → сервер → push на телефон → CallKit (iOS) / ConnectionService (Android).
Кастомний домофон на одноплатнику (Raspberry Pi, ESP32-S3, NXP i.MX): виберемо стек самі. WebRTC через Pion (Go) або aiortc (Python) на пристрої — сигналізація через WebSocket на наш сервер — мобільний клієнт.
Хмарний домофон (Ring, Dahua, Hikvision EZVIZ): власний P2P SDK. Інтегруємось через їх мобільний SDK — швидко, але vendor lock-in.
Звонок з домофона: доставка за <1 секунди
Затримка уведомлення критична. Нажимав кнопку в 23:00 — телефон повинен зазвонити миттєво, поки гість ще стоїт у двері.
iOS CallKit — правильний шлях. Не звичайний push, а APNs VoIP push (PKPushRegistry, PKPushType.voIP). Система будить додаток миттєво (навіть при Force Quit в деяких сценаріях) та викликає pkPushRegistry(_:didReceiveIncomingPushWith:). Там створюємо CXCallUpdate та передаємо в CXProvider — користувач бачит нативний інтерфейс входящого звонку з відео.
let update = CXCallUpdate()
update.remoteHandle = CXHandle(type: .generic, value: "Двері подъєзду")
update.hasVideo = true
update.localizedCallerName = "Домофон"
provider.reportNewIncomingCall(with: callUUID, update: update) { error in ... }
APNs VoIP-сертифікат окремий від push-сертифікату. voip в UIBackgroundModes в Info.plist.
Android ConnectionService + FCM з високим пріоритетом (priority: high в payload). TelecomManager.addNewIncomingCall() показує системний звонок. Проблема: на Xiaomi, Huawei, OPPO агресивні battery optimizations убивають FCM-з'єднання. Рішення — JobScheduler keepalive + інструкція користувачу додати додаток в виключення оптимізації. Або використовувати HMS Push для Huawei пристроїв.
Flutter: flutter_callkit_incoming + firebase_messaging. Нативні біндинги до CallKit та ConnectionService.
WebRTC-відеозвязок
Після відповіді на звонок — WebRTC peer connection. Сигналізація: обмін SDP через наш WebSocket-сервер (або Asterisk з WebSocket транспортом для SIP/WebRTC). ICE кандидати збираємо через STUN, для NAT traversal — TURN (Coturn).
Відео з камери домофона: RTCVideoTrack рендеримо в RTCMTLVideoView (Metal, iOS) або SurfaceViewRenderer (Android). Аудіо — RTCAudioTrack. AEC (echo cancellation) вбудований в WebRTC — важливо для сценарію «чую своє еховідпис через колонку домофона».
Затримка відео: 150-400 мс при хорошому Wi-Fi. На 4G — 400-800 мс. Для прийняття рішення «відкрити / не відкривати» — прийнятно.
Управління замком
HTTP або MQTT запит до пристрою або сервера. Релейний вихід: POST /api/unlock або MQTT publish("home/door/unlock", "1"). Підтвердження відкриття через датчик двері (опціонально): home/door/sensor → OPEN подія відображається в додатку.
Таймаут авторизації: кнопку «Відкрити» показуємо лише поки звонок активний. Після завершення — приховуємо. Лог подій: кожен звонок, відкриття, відмова — пишемо в БД з timestamp та userId.
Відеозапис подій
Запис відео при кожному звонку (ringback recording): медіасервер (Janus record plugin, Ant Media) пише поток в WebM/MP4. Зберігання в S3/MinIO. Ретенція: останні 30 подій або 7 днів — чистимо по lifecycle rule.
Мобільний клієнт показує історію подій: timeline з превью першого кадра, тривалістю та кнопкою відтворення. Відео грає через AVPlayer / ExoPlayer з S3 presigned URL.
Мультиквартирний дім
Кілька підъїздів, кілька квартир. Маршрутизація: домофон підъїзду 3 → звонит лише жильцям квартир в підъїзді 3, або конкретній квартирі (нажимав номер + вызов). В Asterisk: dialplan з Dial(SIP/apartment_${EXTEN}). Кожна квартира — окремий SIP-аккаунт. В додатку користувач привязан до аккаунту своєї квартири.
Гостевий доступ: власник квартири видає тимчасовий QR-код прибиральниці. QR відкриває двері через HTTP API без звонку — з обмеженим строком дії та логуванням.
Етапи розробки
| Етап | Вміст | Строк |
|---|---|---|
| Аудит обладнання та архітектура | Протоколи пристрою, вибір стека | 3-5 днів |
| Серверна частина | Asterisk/WebRTC-сервер, API | 1-2 тижні |
| Мобільний клієнт iOS + Android | CallKit, відео, управління замком | 2-3 тижні |
| Запис подій та історія | S3, плеєр, лог | 1 тиждень |
| Тестування на залізі | QA на реальному домофоні | 1 тиждень |
Разом від 1 до 3 місяців залежно від сумісності обладнання та вимог мультиквартирності.







