Skip to content

VR360 Video Playback Demo ​

This example plays a 360° video whose view can be moved by mouse or touch. Use a real panoramic source: a monoscopic equirectangular video (ERP), commonly 2:1. erp360 is the SDK setting that turns on VR360 viewing; it cannot turn an ordinary flat video into a panorama.

The current public SDK includes VR360 APIs such as set_projection(). If an older cached bundle does not expose them, update the SDK version. See VR360 Video Playback API for the complete contract.

1. Prepare the files ​

Put the SDK files and your 360° MP4 in this layout, then serve it over HTTP instead of opening file://. For a known source, download the self-generated VR360 H.264 + AAC test video as media/vr360.mp4. Other formats and FFmpeg live-publishing commands are on Test Media and FFmpeg.

text
demo/
├── index.html
├── media/vr360.mp4                 ← replace with your monoscopic 360° video
└── output/
    ├── h265web.js
    ├── h265web_wasm.js
    └── h265web_wasm.wasm

2. Copy index.html ​

html
<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>VR360 playback demo</title>
  <!-- The SDK JS and both WASM files must come from the same build. -->
  <script src="./output/h265web.js"></script>
</head>
<body>
  <div id="player"></div>
  <button id="play" disabled>Play</button>
  <button id="pause">Pause</button>
  <button id="left">Look left</button>
  <button id="right">Look right</button>
  <button id="flat">Flat view</button>
  <button id="vr">VR360 view</button>
  <button id="sound">Enable sound</button>
  <p id="status">Loading…</p>

  <script>
    const status = document.getElementById('status');
    const playButton = document.getElementById('play');
    const player = H265webjsPlayer();

    // Bind callbacks before build() and load_media(). Ready means a frame exists, not that playback started.
    player.on_ready_show_done_callback = () => {
      playButton.disabled = false;
      status.textContent = 'First frame ready. Press Play; the source may start with a black frame.';
    };
    player.on_error_callback = (error) => {
      if (error.domain === 'vr' && error.fatal === false) {
        // A VR-only failure can fall back to flat video; do not rebuild the decoder.
        status.textContent = `VR360 unavailable; flat playback attempted: ${error.code}`;
        return;
      }
      status.textContent = `Playback error: ${error.message || error.code}`;
    };

    // erp360 changes how a panorama is viewed; it does not convert the file.
    const ok = player.build({
      player_id: 'player',
      base_url: './output/',
      wasm_js_uri: 'h265web_wasm.js',
      wasm_wasm_uri: 'h265web_wasm.wasm',
      width: '100%', height: 480,
      auto_play: false, ignore_audio: false,
      projection: 'erp360',
      vr: {yaw: 0, pitch: 0, fov: 75, mouse_control: true, touch_control: true}
    });
    if (ok) {
      player.set_voice(0); // Start muted, but keep audio available for the sound button.
      player.load_media('./media/vr360.mp4'); // Replace with your 360° video URL.
    } else {
      status.textContent = 'Player build failed: check SDK paths and Console.';
    }

    playButton.onclick = () => player.play();
    document.getElementById('pause').onclick = () => player.pause();
    document.getElementById('left').onclick = () => player.rotate_vr_view({yaw: -30});
    document.getElementById('right').onclick = () => player.rotate_vr_view({yaw: 30});
    document.getElementById('flat').onclick = () => player.set_projection('flat');
    document.getElementById('vr').onclick = () => player.set_projection('erp360');
    document.getElementById('sound').onclick = () => player.set_voice(1);
    window.addEventListener('beforeunload', () => player.release());
  </script>
</body>
</html>

3. Open and troubleshoot ​

Run python3 -m http.server 8080 in demo/ and open http://localhost:8080/. With autoplay off, press Play after the first frame is ready; some other sources may have a black first frame, which does not mean loading failed. A cross-origin video needs CORS permission for VR360. If you see VR_SOURCE_CORS, start with QA WIKI.

For a VR360 live stream, keep projection: 'erp360' and replace load_media('./media/vr360.mp4') with a live URL carrying real ERP frames, for example http://127.0.0.1/live/vr360.live.flv. The stream must actually contain 360° panoramic video. See the live playback demo for publishing and the WebRTC playback demo for WebRTC URLs.