Розробка мобільного додатку для відеонаблюдення (IP-камери)
IP-камери транслюють відео по кількох протоколах: RTSP — стандарт де-факто для локальних мереж, HLS/DASH — для хмарних рішень, WebRTC — якщо потрібна мінімальна затримка (< 500 мс). Мобільний додаток для відеонаблюдення починається з вибору протоколу під конкретну задачу, та це рішення визначає всю архітектуру.
RTSP: декодування відео на мобільному
RTSP-потік з камери — це H.264/H.265 відео, завернене в RTP-пакети. Нативного RTSP-плеєра ні в iOS, ні в Android немає. Варіанти:
Android: ExoPlayer з розширенням extension-rtsp (починаючи з Media3 1.0). До цього — тільки VLC for Android SDK (libvlc-android). ExoPlayer Media3 з RTSP працює коректно для більшості камер на H.264, але на H.265 з деякими RTSP-серверами дає SOURCE_ERROR через нестандартні SDP-атрибути.
class CameraPlayerManager(private val context: Context) {
private var player: ExoPlayer? = null
fun startStream(rtspUrl: String, surfaceView: SurfaceView) {
val mediaItem = MediaItem.Builder()
.setUri(Uri.parse(rtspUrl))
.build()
player = ExoPlayer.Builder(context)
.setMediaSourceFactory(
DefaultMediaSourceFactory(context)
.setLiveTargetOffsetMs(500)
)
.build()
.also { exo ->
exo.setVideoSurfaceView(surfaceView)
exo.setMediaItem(mediaItem)
exo.prepare()
exo.play()
}
}
fun release() {
player?.release()
player = null
}
}
iOS: AVPlayer не підтримує RTSP. Шляхи: VLCKit (працює, але бінарник ~20 МБ), FFmpegKit з нативною компіляцією FFmpeg (важче, але максимально гібко), либо власний RTSP-клієнт на RTP/UDP через Network.framework. Останній варіант трудомісткий, але дає повний контроль над буферизацією та затримкою.
ONVIF: обнаруження камер в мережі
ONVIF — стандарт для IP-камер (Hikvision, Dahua, Axis, Reolink). Профіль S визначає GetStreamUri, GetSnapshotUri, PTZ-управління. WS-Discovery для обнаруження пристроїв у локальній мережі.
// Android: WS-Discovery multicast
class ONVIFDiscovery {
private val MULTICAST_ADDRESS = "239.255.255.250"
private val MULTICAST_PORT = 3702
suspend fun discoverDevices(timeout: Long = 3000): List<ONVIFDevice> {
val socket = MulticastSocket(MULTICAST_PORT)
socket.joinGroup(InetAddress.getByName(MULTICAST_ADDRESS))
socket.soTimeout = timeout.toInt()
val probeMessage = buildWSDiscoveryProbe()
val packet = DatagramPacket(
probeMessage.toByteArray(),
probeMessage.length,
InetAddress.getByName(MULTICAST_ADDRESS),
MULTICAST_PORT
)
socket.send(packet)
val devices = mutableListOf<ONVIFDevice>()
val buffer = ByteArray(4096)
try {
while (true) {
val response = DatagramPacket(buffer, buffer.size)
socket.receive(response)
parseWSDiscoveryResponse(String(response.data, 0, response.length))
?.let { devices.add(it) }
}
} catch (e: SocketTimeoutException) { /* нормальне завершення */ }
socket.close()
return devices
}
}
Для отримання RTSP URL: SOAP-запрос GetStreamUri з аутентифікацією WS-Security (Digest auth). Бібліотека onvif4java спрощує, але часто відстає від актуальних прошивок камер — простіше написати SOAP-клієнт на Retrofit з кастомним конвертером.
Многокамерний просмотр
Сітка з 4 або 9 камер одночасно — важка задача. Кожен RTSP-потік потребує окремого декодера. На Android з 9 камерами Full HD ризикуємо исчерпати апаратні декодери (їх зазвичай 4-8 на чипі); решта йдуть на програмний декодер з просадкою FPS до 5-10 кадрів.
Рішення: для сітки використовуємо MJPEG-снапшоти через ONVIF GetSnapshotUri з оновленням раз в 2-3 секунди замість повного відеопотоку. Повний RTSP включаємо тільки при тапі на камеру — режим повного екрана. Це компромис між навантаженням та інформативністю.
Запис та історія: локальне та хмарне сховище
Запис кліпів з камери на телефон: завантажуємо через ONVIF GetRecordings або ISAPI (Hikvision). Локально зберігаємо в MediaStore (Android 10+) або Photos Library (iOS). Для хмарних камер — прямі посилання на MP4 з хмари виробника.
Motion detection: либо апаратний (у самій камері, события приходять через ONVIF Event Service), либо програмний на мобільному через порівняння кадрів по YUV різниці між попередним та поточним. Апаратний надійніше — менше хибних срабатувань.
Розробка мобільного додатку з RTSP-просмотром однієї камери та базовим ONVIF-управлінням: 4-5 тижнів. Многокамерна система з WS-Discovery, PTZ-управлінням, історією записів та пуш-алертами по motion: 8-12 тижнів. Вартість розраховується індивідуально після аналізу модельного ряду камер та вимог до зберігання.







