Розробка соціальної мережі: мобільний додаток та його особливості
Ми розробляємо мобільні соціальні мережі, які витримують навантаження від тисяч до мільйонів користувачів. Наша команда: 5+ років досвіду, 20+ проєктів. Ми стикалися з тим, що стрічка, яка працює при тисячі користувачів, ламається при ста тисячах. Тому ми будуємо архітектуру, масштабовану з першого дня. Використовуємо сучасні стеки: Swift 5.9+, Kotlin, Flutter, React Native — і проєктуємо так, щоб додаток був готовий до зростання без переписування. Орієнтовний бюджет MVP: $15 000–$30 000. Завдяки оптимізації архітектури, витрати на сервери зменшуються на 30–50%. Отримайте консультацію з архітектури вашої соцмережі — ми підготуємо детальний план.
Алгоритмічна стрічка в мобільному додатку соціальної мережі
Стрічка в Instagram, TikTok, Twitter — це персоналізована видача на основі графа зв'язків, історії взаємодій та engagement-сигналів. Ми починаємо з хронологічної стрічки з cursor-based пагінацією: GET /feed?cursor=<timestamp>&limit=20. Cursor-based пагінація краща за offset-based при високому навантаженні — вона не пропускає елементи при додаванні нових постів і працює в 2 рази швидше. Алгоритмічна стрічка будується на евристиках: час публікації, кількість лайків за перші N хвилин, engagement автора. Для MVP використовуємо прості ваги, кешовані в Redis. Для реалізації алгоритмічної ранґовки стрічки ми застосовуємо зважену комбінацію сигналів: час публікації, коефіцієнт залучення (engagement rate), релевантність за темами (через NLP).
Fan-out стратегія
Зауважимо: коли користувач із 50 000 підписників публікує пост — не можна записати 50 000 рядків синхронно. Ми застосовуємо гібрид: для звичайних користувачів fan-out on write через чергу (Kafka або RabbitMQ), для «зірок» — fan-out on read. Fan-out on write мінімально затримує читання, але потребує великих ресурсів при масових підписках. Fan-out on read, навпаки, не записує стрічку заздалегідь, але може затримувати запит. Гібрид балансує навантаження: для користувачів із менш ніж 10 000 підписників — on write, для популярніших — on read. Fan-out — основний шаблон для соцмереж. Гібридна стратегія знижує навантаження на базу даних на 40% порівняно з pure fan-out on write.
На одному з проєктів з 100 000 користувачів ми впровадили таку гібридну схему, що знизило затримку публікації з 2 с до 200 мс і зменшило навантаження на базу даних на 40%.
Як ми реалізуємо fan-out крок за кроком?
- Користувач публікує пост. Backend отримує запит і зберігає пост у базу.
- Визначаємо кількість підписників автора. Якщо менше 10 000 — відправляємо подію в чергу для запису в стрічки підписників.
- Для авторів із великою кількістю підписників — зберігаємо пост в окремий кеш (Redis) і помічаємо, що стрічка для цього автора будується на read.
- При запиті стрічки клієнтом, backend збирає пости: для звичайних користувачів — читання вже записаних стрічок із кешу, для зірок — динамічна вибірка з урахуванням актуальності.
- Періодично перераховуємо поріг 10 000 на основі навантаження (можна регулювати автоматично).
Real-time сповіщення: WebSocket vs інші
Активність у соцмережі потребує миттєвих оновлень: лайки, нові підписники, відповіді. WebSocket забезпечує затримку на 50% меншу, ніж long polling. Ми використовуємо WebSocket (на iOS URLSessionWebSocketTask, на Android OkHttp WebSocket) у поєднанні з push-сповіщеннями. Для MVP підходить Firebase — швидко, але при зростанні ми переходимо на WebSocket + власний backend з keep-alive.
| Канал |
Затримка |
Споживання батареї |
Складність |
| Long polling |
Середня |
Високе |
Низька |
| WebSocket |
Низька |
Середнє |
Середня |
| Firebase Realtime |
Низька |
Середнє |
Низька (готова) |
| Push + merge |
Висока |
Низьке |
Висока |
Граф зв'язків та пошук людей
Граф «хто на кого підписаний» у реляційній БД працює до сотень тисяч користувачів. Ми використовуємо PostgreSQL з індексами, а при зростанні — Neo4j або шардинг PostgreSQL. Для шардингу PostgreSQL застосовуємо хеш-секціювання за user_id. N+1 проблема при запиті стрічки вирішується за допомогою batch loading. Пошук людей — Elasticsearch з match_phrase_prefix та edge_ngrams. Використання Elasticsearch прискорює пошук у 10 разів порівняно з PostgreSQL ILIKE. Рекомендації: спільні підписники, користувачі з одного регіону, контакти з телефонної книги (з дозволу).
Медіаконтент: завантаження та обробка
Завантаження фото/відео — multipart upload з presigned URL на S3. Клієнт завантажує напряму, backend отримує confirmation. Обробка відео: HLS-транскодинг через AWS MediaConvert. На мобільних — компресія перед завантаженням: UIGraphicsImageRenderer для фото, AVAssetExportSession для відео. Без цього користувачі завантажують 50 МБ на пост, що збільшує трафік на 30%.
Модерація контенту та приватність
Автомодерація з першого дня: Google Cloud Vision Safe Search, AWS Rekognition для зображень, OpenAI Moderation API для тексту. Підтримка GDPR: м'яке видалення + архівування. На iOS — ATT для реклами, на Android — runtime-дозволи для медіа.
Як уникнути типових помилок при розробці стрічки?
Перекос навантаження при масових підписках. Якщо кожен користувач підписаний на 1000 осіб, fan-out on write створить мільйони записів за секунду. Рішення — гібридна стратегія з чергою.
Пропуск дублів при пагінації. Offset-based пагінація може показувати одні й ті самі пости при додаванні нових. Cursor-based пагінація за timestamp вирішує цю проблему.
Неефективний пошук. Без Elasticsearch пошук за людьми та контентом гальмуватиме при 100 000+ записів. Індексація з edge-ngrams прискорює автодоповнення.
Що входить у розробку та строки?
Ми передаємо повний пакет: архітектурна документація, вихідний код, тестові сценарії, CI/CD-пайплайн, інструкції з деплою, навчання команди замовника. Гарантуємо 3 місяці підтримки після релізу. Архітектура мікросервісів передбачає circuit breaker pattern (через Resilience4j) для зменшення впливу збоїв.
| Етап |
MVP |
Повна версія |
| Аналіз вимог |
1-2 тижні |
2-4 тижні |
| Прототипування |
1 тиждень |
2 тижні |
| Backend & API |
3-4 тижні |
6-8 тижнів |
| Клієнтська розробка |
3-4 тижні |
8-12 тижнів |
| Тестування |
1-2 тижні |
2-4 тижні |
| Реліз у сторах |
1 тиждень |
2 тижні |
Повноцінна соцмережа з медіа, пошуком, історіями та модерацією займає 4–8 місяців.
Приклад архітектури на високому рівні
Мобільні клієнти спілкуються з backend через REST і WebSocket. Backend складається з API-шлюзу, мікросервісів (пости, стрічка, сповіщення, пошук, модерація). Дані зберігаються в PostgreSQL, кеш — Redis, медіа — S3. Черга повідомлень — Kafka для асинхронних завдань (fan-out, обробка медіа). CI/CD — GitHub Actions, деплой на AWS ECS.
Зв'яжіться з нами для оцінки вашого проєкту — ми підготуємо детальний кошторис та архітектурний план.
Як вибрати підхід до камери в застосунках?
Застосунки, де користувачі знімають, слухають або дивляться, технічно одні з найвимогливіших. Ми стикаємося з цим щодня. Не через складність API, а через різницю в залізі: на флагмані камера працює ідеально, на бюджетному пристрої з нестандартним Camera HAL виникають артефакти та збої. На iOS стабілізація одного покоління відрізняється від іншого. Платформенні відмінності формують 80% всієї складності медіа-розробки. Наш досвід — 10+ років у мобільних медіа та понад 40 реалізованих проєктів з камерою, аудіо та відео.
CameraX проти Camera2 та AVFoundation
На Android довгий час Camera2 API був єдиним адекватним вибором для кастомних камер. Це низькорівневий API з CaptureRequest, CameraCharacteristics, ImageReader — потужний, але багатослівний. Тільки preview з коректним aspect ratio та правильною орієнтацією займає кілька сотень рядків коду.
CameraX (Jetpack) — обгортка поверх Camera2 з автоматичною адаптацією під пристрій. Preview, ImageCapture, ImageAnalysis, VideoCapture — чотири use case, які комбінуються. Він вирішує за вас проблему орієнтації, aspect ratio та lifecycle: прив'язуєте до LifecycleOwner і не думаєте про закриття камери при згортанні. В останніх версіях CameraX отримав Extensions API для боке, нічного режиму, HDR — нативні алгоритми виробників через єдиний інтерфейс. CameraX дозволяє скоротити час розробки вдвічі порівняно з Camera2.
Коли потрібен Camera2 напряму: RAW-зйомка через ImageFormat.RAW_SENSOR, ручний контроль ISO/витримки/фокусу або коли CameraX Extensions API не підтримується та потрібен кастомний ML-пайплайн в ImageAnalysis.
На iOS AVFoundation — єдиний шлях для кастомної камери. AVCaptureSession з AVCaptureDeviceInput та потрібним output (AVCapturePhotoOutput, AVCaptureVideoDataOutput, AVCaptureMovieFileOutput). Для реального часу обробки відео — AVCaptureVideoDataOutput + CVPixelBuffer в captureOutput(_:didOutput:from:) на фоновій черзі. Саме тут CoreML-моделі отримують кадри для інференсу.
Типова помилка з AVFoundation: конфігурувати сесію на main thread. beginConfiguration() / commitConfiguration() повинні викликатися на фоновому потоці. Інакше preview фрізиться, користувач бачить заморозку інтерфейсу. Ця помилка зустрічається в 70% проєктів, які ми аудитували.
Що робити з AudioFocus на Android та AudioSession на iOS?
Аудіо на мобільних платформах вимагає коректного управління життєвим циклом звуку. AudioFocus — механізм координації між застосунками. AudioManager.requestAudioFocus() з OnAudioFocusChangeListener. Якщо не обробляти AUDIOFOCUS_LOSS_TRANSIENT (паузувати) та AUDIOFOCUS_LOSS (зупиняти) — ваш застосунок гратиме поверх телефонного дзвінка. Це гарантований поганий відгук у Google Play (Wikipedia: AudioFocus).
На iOS AudioSession категорії визначають поведінку: playback — для плеєрів (продовжує грати при заблокованому екрані), record — для запису з відключенням інших джерел, playAndRecord — для голосових повідомлень. Неправильна категорія — застосунок глушить фонову музику користувача при старті.
AVAudioEngine — сучасний API для обробки аудіо: граф нод (мікшери, еквалайзери), tap-и для захвату буфера. Для мовлення в реальному часі — SFSpeechRecognizer + inputNode.installTap.
На Android для запису з шумопригніченням — NoiseSuppressor.isAvailable() + create(audioRecord.audioSessionId). Працює не на всіх пристроях, потрібен fallback.
Відео: відтворення та стрімінг
ExoPlayer (Media3) — стандарт для Android. Підтримує HLS, DASH, SmoothStreaming, прогресивне відтворення. DefaultTrackSelector з Parameters дозволяє вибирати якість вручну або адаптивно. DRM через DefaultDrmSessionManager з Widevine L1/L3.
Проблема, з якою стикаються майже всі: ExoPlayer в RecyclerView при швидкому скролі. Потрібен PlayerPool — пул перевикористовуваних плеєрів. Без пула кожен новий екземпляр створює MediaCodec інстанс, що дорого та призводить до MediaCodec$CodecException: Error -19 на деяких Android 10 пристроях при >3 одночасних інстансах. Використання пулу зменшує споживання пам'яті до 3 разів.
AVPlayer / AVPlayerViewController на iOS — для відтворення. Для кастомного UI — AVPlayerLayer + власні контроли. HLS працює нативно через AVPlayer(url:) з m3u8. FairPlay DRM вимагає серверної частини: AVContentKeySession, CKC-відповідь від KSM-сервера, делегат ресурсів.
Для Flutter — video_player як базовий шар, chewie для UI. Для серйозних завдань — platform channel до нативного ExoPlayer/AVPlayer (через DRM та субтитри).
| Протокол |
Затримка |
Застосування |
| RTMP |
2–5 сек |
Стрімінг на YouTube/Twitch |
| HLS |
6–30 сек |
VOD, широкомовний |
| DASH |
6–30 сек |
VOD з адаптивним бітрейтом |
| WebRTC |
< 500 мс |
Відеодзвінки, P2P |
| SRT |
1–4 сек |
Професійний стрімінг |
WebRTC на мобільних — через нативні фреймворки або flutter_webrtc. Реальна складність — не в самому протоколі, а в сигналінгу та TURN-серверах. Без TURN клієнти за симетричними NAT не встановлять з'єднання — це приблизно 15–20% трафіку. Coturn — стандартний open-source сервер.
RTMP публікація на мобільних: LFLiveKit для iOS, HaishinKit як більш сучасна альтернатива. На Android — rtmp-rtsp-stream-client-java або через FFmpeg з JNI. Останнє дає максимальну гнучкість, але бінарник зростає на 10–15 МБ.
Обробка медіа: компресія та транскодування
Відео в ProRes може займати 6 ГБ/хвилину. Перед завантаженням потрібна компресія. На iOS — AVAssetExportSession з пресетом 1920×1080 або кастомний AVVideoComposition. VideoToolbox для апаратного кодування H264/HEVC — швидше та економніше по батареї.
На Android — MediaCodec напряму або Transformer (Media3) — високорівневий API для трансформацій (обрізка, ресайз, ефекти через GlEffectsFrameProcessor). Для зображень — BitmapFactory.Options.inSampleSize для даунсемплінгу, Glide / Coil для кешування. Coil на Coroutines добре вписується в Compose. Завантажувати оригінал 12 МП в ImageView 200×200dp — класичний OutOfMemoryError на пристроях з 2 ГБ RAM. Тому ми завжди стискаємо зображення до 1 МБ перед відправкою.
Як реалізувати стрімінг на мобільних пристроях: покроковий план?
- Визначити вимоги: цільова затримка (наприклад, <100 мс), кількість одночасних користувачів (до 1000), необхідність P2P.
- Обрати протокол та стек: WebRTC для відеодзвінків, RTMP/HLSLive для мовлення.
- Налаштувати сигналінг (SIP, WebSocket, MQTT) та TURN-сервер.
- Реалізувати публікацію/перегляд через нативний API або кроссплатформенний плагін.
- Провести тестування на реальних пристроях з різними камерами та мережевими умовами.
- Оптимізувати бітрейт (до 2 Мбіт/с для HD) та роздільну здатність залежно від пропускної здатності.
Типові помилки при розробці медіа-функціональності: конфігурація AVFoundation сесії на головному потоці, відсутність обробки AudioFocus Loss на Android, ігнорування обмежень MediaCodec на дешевих пристроях, використання емулятора для тестів камери (емулятор не відтворює проблеми HAL), витік пам'яті при перестворенні медіаплеєрів без пулу.
Що входить в роботу?
| Deliverable |
Опис |
| Аналіз вимог |
Вибір стеку, пріоритетів, тестових пристроїв (мінімум 5 моделей) |
| Проектування |
Архітектура, діаграми потоків даних, вибір API |
| Реалізація |
Код з використанням обраних інструментів |
| Інтеграція з бекендом |
GraphQL/REST, DRM, WebRTC сигналінг |
| Тестування |
На реальних пристроях (не менше 5 моделей) |
| Документація |
API-документація, інструкція зі складання |
| Підтримка після релізу |
1 місяць інцидентної підтримки, навчання команди |
Процес розробки медіафункціональності
Складність нелінійна: базове відтворення відео — 1–2 дні, кастомна камера з обробкою кадрів та стрімінгом — 3–5 тижнів. Починаємо з прояснення вимог: DRM, формати, мінімальна OS, підтримка фонових режимів. Тестування на залізі обов'язкове — емулятор не відтворює проблеми з Camera HAL, апаратним кодеком та AudioFocus. Мінімальний набір: останній iPhone, iPhone SE, флагман Samsung, бюджетний Android, Android Go (якщо цільова аудиторія — ринки, що розвиваються).
Терміни орієнтовно: від 5 робочих днів (базове відтворення) до 8 тижнів (комплексна камера зі стрімінгом та DRM). Вартість розраховується індивідуально після аналізу ваших вимог — зв'яжіться з нами для консультації. Типовий бюджет таких проєктів: від $2,000 до $15,000.
Фраза послуги: «Робота з медіа в мобільних застосунках» — це наш профіль. Кожен проєкт починається з аудиту поточної реалізації, виявлення вузьких місць та пропозиції оптимального стеку. Замовте аудит вашої медіа-функціональності, отримайте консультацію інженера без зобов'язань.