Три складові, одна мета
Усередині Timmy влаштований доволі практично: Flutter для застосунку, WebRTC для аудіо й відео в реальному часі та Firebase для координації. Я не хотів створювати величезну платформу, яка пропускає все через хмару. Кожна частина має знати якомога менше й водночас надійно працювати з іншими.
WebRTC: пряме з’єднання та шифрування за замовчуванням
WebRTC (Web Real-Time Communication) передає аудіо й відео між пристроями дитини та батьків. В ідеалі дані передаються безпосередньо між двома пристроями, за одноранговою схемою, без проміжного медіасервера.
Кожне з’єднання WebRTC за замовчуванням використовує DTLS-SRTP. Якщо хтось перехопить мережеві пакети, він не отримає придатного для прослуховування аудіо чи перегляду відео. Це шифрування є частиною протоколу, і його не можна просто вимкнути у WebRTC.
Для мене це було принципово: медіаданим із дитячої кімнати не місце на моєму сервері. Вони залишаються між вашими пристроями.
Сигнальний обмін через Firebase Firestore
Перш ніж WebRTC зможе запуститися, пристрої мають знайти одне одного та узгодити спосіб з’єднання. Ця частина називається сигнальним обміном. Для цього Timmy використовує Firebase Firestore — хмарну базу даних Google.
Передаються лише технічні дані з’єднання:
- SDP-пропозиції та відповіді: Описують можливості пристроїв (підтримувані кодеки, роздільну здатність тощо).
- ICE-кандидати: Можливі мережеві маршрути, якими пристрої можуть з’єднатися один з одним.
Аудіо та відео не потрапляють у Firebase. Firestore передає лише технічні дані з’єднання. Timmy також шифрує цей сигнальний рівень, тож Firestore не стає місцем, де SDP та ICE зберігаються у відкритому вигляді.
TURN-сервери: коли прямий маршрут не працює
Деякі мережі блокують прямі з’єднання, наприклад суворі брандмауери або окремі мобільні оператори. Тоді WebRTC потрібен TURN-ретранслятор (Traversal Using Relays around NAT).
Timmy спершу намагається використати локальний TURN-сервер, а якщо локальний ретранслятор недоступний або перевантажений, використовує Cloudflare як резервний варіант. Ретранслятор пересилає зашифровані пакети. Він не отримує ключів до аудіо чи відео, тому шифрування WebRTC залишається чинним.
Облікові дані TURN надходять із Firebase Cloud Function і дійсні лише 24 години. Постійні облікові дані в застосунку радіоняні, на мій погляд, були б надто ризикованими.
Nearby Connections: пристрої знаходять одне одного автоматично
Щоб уникнути незручних кроків налаштування між пристроями дитини та батьків, Timmy використовує Nearby Connections. Google надає цей рівень виявлення через Bluetooth і Wi‑Fi.
Автоматичне сполучення в Timmy працює без ручного введення коду: пристрої знаходять одне одного та спільну точку для обміну ключами. Якщо це не спрацює, можна ввести код із 4 символів. Код сполучення ніколи не залишає пристрій; Firestore бачить лише криптографічний хеш (SHA-256) як ідентифікатор документа.
Анонімна автентифікація
Timmy використовує анонімну автентифікацію Firebase. Під час першого запуску кожен пристрій отримує тимчасовий анонімний ідентифікатор. Не потрібно створювати обліковий запис, указувати адресу електронної пошти чи пароль. Ідентифікатор потрібен лише для застосування правил Firestore: читати й записувати дані сеансу можуть тільки автентифіковані пристрої.
Архітектура: хто надсилає, а хто отримує
Timmy має два режими:
- Режим дитини (відправник): Пристрій захоплює аудіо з мікрофона й передає його на батьківський пристрій через WebRTC. За потреби можна ввімкнути камеру; тоді відео також передається безпосередньо.
- Режим батьків (одержувач): Пристрій отримує аудіо й відео, показує потік із камери та має функцію «натисни й говори» для коротких голосових повідомлень на пристрій дитини.
Елементи керування, як-от «натисни й говори» та ввімкнення або вимкнення камери, використовують DataChannel, ще один канал WebRTC, який надсилає невеликі зашифровані повідомлення безпосередньо між пристроями.
Чому Flutter?
Flutter — це фреймворк Google для застосунків на різних платформах. Для Timmy це означає, що я можу один раз написати значну частину логіки й використовувати її на Android та iOS. Timmy доступний на Android, а версія для iOS уже майже готова до випуску. Менше дубльованого коду означає менше місць, де можуть з’явитися помилки.
Підсумок
Технічне правило просте: Timmy має працювати лише з даними, які йому справді потрібні. WebRTC захищає медіадані, Firebase координує налаштування з’єднання, TURN бачить лише зашифровані пакети, а Nearby Connections робить сполучення простішим.
Хороша технологія майже непомітно вписується в повсякденне життя. Вона просто працює, не перетворюючи дитячу кімнату на хмарний проєкт.