Розробка мобільного VR-застосунку для перегляду 360°-відео
Створення мобільного VR-плеєра для 360-градусного відео — завдання, яке виходить за рамки звичайного відеоплеєра. Equirectangular-проєкцію потрібно розгорнути на сфері навколо користувача, синхронізувати з рухом голови та виключити артефакти на зшивці — все при частоті кадрів, достатній для комфортного VR. Помилки на етапі рендерингу призводять до дискомфорту та motion sickness. Завантаження 10-хвилинного 4K відео через CDN може коштувати 500 рублів за сесію — при пікових навантаженнях це мільйони. Наш підхід з viewport-залежним стрімінгом економить до 80% трафіку, а отже і грошей.
Ми використовуємо перевірені технології: Unity LTS, Swift, Kotlin, а також адаптивні протоколи стрімінгу. Наш досвід — 7+ років і 15+ VR-проєктів — дозволяє гарантувати якість та продуктивність. Зв'яжіться з нами для консультації.
Згідно специфікації MPEG-OMAF, viewport-залежна передача знижує бітрейт у 3-5 разів. Для проєкту з 1 млн сесій це дає значну економію.
Технічна сторона: sphere mapping
Equirectangular-відео (2:1 співвідношення сторін, стандарт YouTube та Facebook 360) відображається на інвертовану сферу — користувач дивиться зсередини. Роздільна здатність для комфортного перегляду: мінімум 4K (3840×2160), бажано 5.7K або 8K. При 4K на кожне око припадає ~30 пікселів на градус — це межа, нижче якої видно «сітку» пікселів.
На Unity створюємо інвертовану сферу з оберненими нормалями всередину:
// Стандартна Unity Sphere + спеціальний матеріал
// Або через пакет com.unity.xr.management
// Шейдер для 360-відео
// vert: передаємо UV як є
// frag: семплюємо _MainTex з UV, горизонтальний flip для правильної орієнтації
На нативному Android через MediaPlayer + OpenGL ES:
// Створюємо Surface для MediaPlayer, рендеримо як texture на сферу
SurfaceTexture surfaceTexture = new SurfaceTexture(textureId);
Surface surface = new Surface(surfaceTexture);
mediaPlayer.setSurface(surface);
mediaPlayer.prepareAsync();
На iOS — AVPlayer + SCNSphere в SceneKit або RealityKit:
let sphere = SCNSphere(radius: 10)
sphere.firstMaterial?.isDoubleSided = true // або інвертовані нормалі
sphere.firstMaterial?.diffuse.contents = avPlayer
let sphereNode = SCNNode(geometry: sphere)
sphereNode.scale = SCNVector3(-1, 1, 1) // flip X для правильного direction
sceneView.scene.rootNode.addChildNode(sphereNode)
Стереоскопічне 360: top-bottom vs side-by-side
Для стереоскопічного 360-відео використовуються два основні формати: top-bottom (TB) та side-by-side (SBS). У TB верхня половина кадру відводиться для лівого ока, нижня — для правого, що дає співвідношення сторін 1:1 і більш просту реалізацію шейдера. Однак при цьому втрачається корисна роздільна здатність по вертикалі. SBS ділить кадр по вертикалі — ліве око зліва, праве справа, співвідношення сторін 4:1. Цей формат менше спотворюється при низькому бітрейті, але потребує складнішого шейдера для розділення. Для більшості проєктів ми рекомендуємо TB через кращу сумісність і простоту інтеграції.
| Формат | Роздільна здатність на око | Складність шейдера | Сумісність | Спотворення при низькому бітрейті |
|---|---|---|---|---|
| TB | 3840×1080 (50% висоти) | Низька | Висока | Помірні |
| SBS | 1920×2160 (50% ширини) | Середня | Середня | Мінімальні |
TB дає вдвічі менше вертикальних пікселів на око, але простіше в реалізації. SBS зберігає вертикальну роздільну здатність, але потребує вужчого поля зору.
Потокове відтворення: HLS/DASH для 360
360-відео — це файли 2–8 GB для 10-хвилинного контенту при 4K–8K. Завантажувати цілком перед відтворенням неприйнятно. Рішення — адаптивний стрімінг.
Для 360 HLS потрібна особлива нарізка на сегменти з урахуванням spherical projection — ідеально використовувати Spatial Media spec від Google, яка вбудовує метадані про тип проєкції прямо у файл. ffmpeg з прапором --spherical при створенні маніфесту.
Адаптивне перемикання бітрейту критичне: при поворотах голови вся сфера видна, але основне навантаження — на зоні перед поглядом. Viewport-dependent streaming (або Tile-based streaming) віддає високу роздільну здатність тільки для поточного напрямку погляду. Це знижує трафік у 3–5 разів — для проєкту з 1 млн сесій це дає значну економію. Реалізується через MPEG-OMAF або кастомний DASH-сервер з інформацією про Viewport.
Spatial audio
360-відео без позиційного звуку — це пів враження. Ambisonics (формат B-format або AmbiX) — просторовий формат, в якому звук автоматично орієнтується під напрямок погляду.
На Android — AndroidMediaPlayer + Resonance Audio SDK від Google (вбудований в Google Cardboard SDK). На iOS — AVAudioEngine з AVAudioEnvironmentNode для просторового позиціонування джерел.
Unity: пакет com.google.resonance-audio або вбудований Unity Spatial Audio з підтримкою Ambisonics з Audio Settings.
Кешування та offline
Користувач хоче дивитися 360-тури без інтернету. Попереднє завантаження: фоновий DownloadManager (Android) / URLSessionDownloadTask (iOS), зберігання сегментів HLS на пристрої. Для каталогу турів — SQLite з метаданими (preview-frame, тривалість, опис) та шляхами до локальних файлів.
Чому важливе якісне відображення 360-відео?
Якість відображення безпосередньо впливає на сприйняття VR. При роздільній здатності нижче 4K око розрізняє «сітку» пікселів — це руйнує ілюзію присутності. Наші інженери оптимізують шейдери для кожного пристрою: для iOS використовуємо Metal API, для Android — Vulkan. Це дає приріст продуктивності до 40% порівняно зі стандартним OpenGL ES. Крім того, ми інтегруємо адаптивне стиснення текстур (ASTC/ETC2) та мультисемплінг для згладжування артефактів. Результат — плавне відтворення навіть на пристроях трирічної давності.
Як ми забезпечуємо безшовний VR-досвід?
Розробка ведеться з урахуванням усіх аспектів: від рендерингу до вводу/виводу. Ми гарантуємо:
- Адаптивний стрімінг з перемиканням бітрейту залежно від швидкості з'єднання. Використовуємо HLS та DASH з підтримкою MPEG-OMAF.
- Viewport-dependent streaming — висока роздільна здатність тільки в напрямку погляду, що знижує трафік у 3–5 разів.
- Spatial audio за допомогою Resonance Audio (Android) та AVAudioEnvironmentNode (iOS) — звук автоматично повертається за рухом голови.
- Офлайн-режим — попереднє завантаження сегментів HLS на пристрій з кешуванням в SQLite.
Що входить у роботу
- Архітектурна документація (опис компонентів, діаграми потоків)
- Налаштування CI/CD для автоматичних збірок та викладки в стори
- Інтеграція з App Store Connect та Google Play Console (включаючи сертифікати та provisioning profiles)
- Пост-релізна підтримка протягом місяця (баг-фіксинг, моніторинг крашів через Firebase Crashlytics)
- Навчання вашої команди роботі з плеєром (2-3 сесії)
Процес роботи
- Аналітика — вивчення контенту, вибір формату (монокуляр/стерео), цільові пристрої.
- Проектування — архітектура плеєра, вибір SDK та інструментів.
- Розробка — рендеринг, стрімінг, spatial audio, кешування.
- Тестування — на реальних пристроях (Cardboard, Google Daydream, Gear VR) з вимірюванням latency та motion sickness.
- Деплой — публікація в сторах, налаштування краш-репортингу (Firebase Crashlytics).
| Етап | Тривалість | Результат |
|---|---|---|
| Аналітика | 2–3 дні | Технічне завдання |
| Проектування | 3–5 днів | Архітектура та прототип |
| Розробка | 2–4 тижні | Робочий плеєр |
| Тестування | 1 тиждень | Звіт про баги та оптимізація |
| Деплой | 2 дні | Застосунок у сторах |
Орієнтири за термінами
Базовий плеєр для монокулярного 360-відео з локальним відтворенням — від 1 тижня. Повнофункціональний плеєр зі стрімінгом, spatial audio, стереоскопічним форматом та offline — від 3 до 6 тижнів. Вартість розраховується індивідуально після аналізу вашого контенту та вимог. Замовте розробку VR-застосунку — і ваші користувачі побачать 360-контент без компромісів. Отримайте консультацію для оцінки проєкту.







