Mobile VR App Development for 360-Degree Video
Building a mobile VR player for 360-degree video goes beyond a standard video player. The equirectangular projection must be mapped onto a sphere around the user, synchronized with head movement, and stitched without artifacts—all at a frame rate that prevents discomfort. Mistakes in rendering lead to motion sickness. Loading a 10-minute 4K video via CDN can be expensive at peak loads. According to the MPEG-OMAF specification, viewport-dependent transmission reduces bitrate by 3–5 times—an approach that performs 5 times better than full-streaming. Typical CDN savings range from $2000 to $10000 per month depending on traffic.
We use proven technologies: Unity LTS, Swift, Kotlin, and adaptive streaming protocols. With 7+ years of experience and 15+ VR projects, we guarantee quality and performance. Contact us for a consultation.
Technical Side: Sphere Mapping
Equirectangular video (2:1 aspect ratio, standard for YouTube and Facebook 360) is mapped onto an inverted sphere—the user looks from inside. Comfortable viewing requires at least 4K (3840×2160), preferably 5.7K or 8K. At 4K, each eye gets ~30 pixels per degree—the threshold below which pixelation becomes visible.
On Unity, we create an inverted sphere with inward-pointing normals:
// Standard Unity Sphere + special material
// Or via package com.unity.xr.management
// Shader for 360 video
// vert: pass UV as is
// frag: sample _MainTex with UV, horizontal flip for correct orientation
On native Android using MediaPlayer + OpenGL ES:
// Create Surface for MediaPlayer, render as texture on sphere
SurfaceTexture surfaceTexture = new SurfaceTexture(textureId);
Surface surface = new Surface(surfaceTexture);
mediaPlayer.setSurface(surface);
mediaPlayer.prepareAsync();
On iOS — AVPlayer + SCNSphere in SceneKit or RealityKit:
let sphere = SCNSphere(radius: 10)
sphere.firstMaterial?.isDoubleSided = true // or inverted normals
sphere.firstMaterial?.diffuse.contents = avPlayer
let sphereNode = SCNNode(geometry: sphere)
sphereNode.scale = SCNVector3(-1, 1, 1) // flip X for correct direction
sceneView.scene.rootNode.addChildNode(sphereNode)
Stereoscopic 360: Top-Bottom vs Side-by-Side
Two main formats exist for stereoscopic 360: top-bottom (TB) and side-by-side (SBS). In TB, the top half of the frame is for the left eye, bottom for the right—resulting in a 1:1 aspect ratio and simpler shader implementation. However, vertical resolution per eye is halved. SBS splits the frame vertically—left eye left, right eye right—aspect ratio 4:1. This format distorts less at low bitrates but requires a more complex shader. For most projects, we recommend TB due to better compatibility and simpler integration.
Comparison of Stereoscopic Formats
| Format | Resolution per eye | Shader complexity | Compatibility | Distortion at low bitrate |
|---|---|---|---|---|
| TB | 3840×1080 (50% height) | Low | High | Moderate |
| SBS | 1920×2160 (50% width) | Medium | Medium | Minimal |
TB gives half the vertical pixels per eye but is easier to implement. SBS preserves vertical resolution but requires a narrower field of view.
Streaming Playback: HLS/DASH for 360
360 video files are 2–8 GB for 10 minutes of content at 4K–8K. Full preloading is impractical. The solution is adaptive streaming.
For 360 HLS, segments must be prepared with spherical projection metadata—ideally using Google's Spatial Media spec, which embeds projection type directly into the file. Use ffmpeg with the --spherical flag when creating the manifest.
Adaptive bitrate switching is critical: when turning your head, the whole sphere is visible, but the highest load is in the gaze direction. Viewport-dependent streaming (or tile-based streaming) delivers high resolution only for the current viewport. This cuts traffic by 3–5 times, leading to significant cost savings. It is implemented via MPEG-OMAF or a custom DASH server with viewport information.
Spatial Audio
360 video without positional audio is only half the experience. Ambisonics (B-format or AmbiX) is a spatial format where sound automatically orients to head direction.
On Android — AndroidMediaPlayer + Resonance Audio SDK from Google (included in Google Cardboard SDK). On iOS — AVAudioEngine with AVAudioEnvironmentNode for spatial positioning of sources.
Unity: package com.google.resonance-audio or built-in Unity Spatial Audio with Ambisonics support in Audio Settings.
Caching and Offline
Users want to watch 360 tours without the internet. Preloading: background DownloadManager (Android) / URLSessionDownloadTask (iOS), storing HLS segments locally. For a catalog of tours, use SQLite with metadata (preview frame, duration, description) and paths to local files.
Why High-Quality 360 Rendering Matters
Rendering quality directly affects VR immersion. Below 4K, the eye perceives a pixel grid—breaking the sense of presence. Our engineers optimize shaders for each device: on iOS we use Metal API, on Android—Vulkan. This yields up to 40% performance gain over standard OpenGL ES. We also integrate adaptive texture compression (ASTC/ETC2) and multisampling for anti-aliasing. Result: smooth playback even on three-year-old devices.
How We Deliver a Seamless VR Experience
Our development covers all aspects: from rendering to input/output. We guarantee:
- Adaptive streaming with bitrate switching based on connection speed. We use HLS and DASH with MPEG-OMAF support.
- Viewport-dependent streaming—high resolution only in the gaze direction, reducing traffic by 3–5 times.
- Spatial audio via Resonance Audio (Android) and AVAudioEnvironmentNode (iOS)—sound rotates with head movement.
- Offline mode—preload HLS segments to device with SQLite caching.
What’s Included in the Work
- Architectural documentation (component descriptions, flow diagrams)
- CI/CD setup for automatic builds and store submission
- Integration with App Store Connect and Google Play Console (including certificates and provisioning profiles)
- One month of post-release support (bug fixing, crash monitoring via Firebase Crashlytics)
- Training for your team on using the player (2–3 sessions)
Process
- Analysis — study content, choose format (mono/stereo), target devices.
- Design — player architecture, SDK and tool selection.
- Development — rendering, streaming, spatial audio, caching.
- Testing — on real devices (Cardboard, Google Daydream, Gear VR) with latency and motion sickness measurement.
- Deploy — publish to stores, set up crash reporting (Firebase Crashlytics).
| Step | Duration | Result |
|---|---|---|
| Analysis | 2–3 days | Technical specification |
| Design | 3–5 days | Architecture and prototype |
| Development | 2–4 weeks | Working player |
| Testing | 1 week | Bug report and optimization |
| Deploy | 2 days | App in stores |
Timeline Estimates
Basic player for monoscopic 360 with local playback: from 1 week. Full-featured player with streaming, spatial audio, stereoscopic format, and offline: from 3 to 6 weeks. Cost is calculated individually after analyzing your content and requirements. Development starts at $10,000 for a basic player. Order VR app development—and your users will see 360 content with no compromises. Get a consultation for a project assessment.







