@blaineam/videojs-vr

中文文档
3.3.0发布于 2026/05/04MITESM + CJS构建来源已验证近 30 天下载 5440

A plugin to add 360, 180, and VR video support to video.js with full WebXR support, VR HUD controls, and in-VR media gallery.

原始使用文档
文档目录29 节
  1. Installation
  2. Features
  3. Browser Support
  4. Desktop
  5. Mobile
  6. VR Headsets (WebXR)
  7. Quick Start
  8. Script Tag
  9. ES Modules / Bundlers
  10. Projection Types
  11. Standard Projections
  12. Side-by-Side (Stereoscopic) Projections
  13. Equi-Angular Cubemap (EAC)
  14. Fisheye Projections (since 3.2.0)
  15. WebXR VR Mode
  16. VR HUD Controls
  17. VR Gallery Panel
  18. Gallery Features
  19. Dynamic Gallery Updates
  20. API Reference
  21. Options
  22. Methods
  23. Events
  24. Custom Buttons
  25. Per-Source Projection
  26. Accessing Three.js Objects
  27. Caveats
  28. Development
  29. License

videojs-vr

A video.js plugin that turns a video element into a HTML5 Panoramic 360 video player. Project video onto different shapes with full WebXR support for immersive VR viewing on devices like Meta Quest, HTC Vive, and other WebXR-compatible headsets.

Maintainer: Blaine Miller

PRs Welcome! Contributions, bug reports, and feature requests are encouraged.

Installation

npm install @blaineam/videojs-vr

Features

  • Full WebXR Support: Modern WebXR API support for immersive VR experiences on Quest, Vive, and other headsets
  • Multiple Projections: Support for 360, 180, side-by-side (SBS), equi-angular cubemap (EAC), and equidistant fisheye (180°/200°/220°/360° with mono and LR stereo variants)
  • Glassmorphic VR UI: Beautiful frosted-glass design with translucent panels and subtle gradients for an immersive, non-intrusive interface
  • VR HUD Controls: In-VR user interface with scrub bar, play/pause, and navigation controls
  • VR Gallery Panel: Browse and select media while in VR mode with scrollable thumbnails and pill-shaped duration badges
  • Controller Support: Full VR controller interaction with pointer rays and grip toggle
  • Orientation Controls: Adjust viewing angle for comfortable viewing in any position
  • Stereo 3D Support: Proper left/right eye rendering for stereoscopic content

Browser Support

The most recent versions of:

Desktop

  • Chrome
  • Firefox
  • Safari

Mobile

  • Chrome on Android
  • Safari on iOS

VR Headsets (WebXR)

  • Meta Quest (Quest 2, Quest 3, Quest Pro)
  • HTC Vive / Vive Pro
  • Valve Index
  • Windows Mixed Reality headsets
  • Any WebXR-compatible device

Quick Start

Script Tag

<script src="//path/to/video.min.js"></script>
<script src="//path/to/videojs-vr.min.js"></script>
<script>
  var player = videojs('my-video');

  player.vr({
    projection: '360',
    enableVRHUD: true,
    enableVRGallery: true
  });
</script>

ES Modules / Bundlers

import videojs from 'video.js';
import '@blaineam/videojs-vr';

const player = videojs('my-video');

player.vr({
  projection: '360',
  enableVRHUD: true,
  enableVRGallery: true,
  onNext: () => console.log('Next video'),
  onPrevious: () => console.log('Previous video'),
  onFavorite: () => console.log('Toggle favorite')
});

Projection Types

Standard Projections

ProjectionDescription
'360' / 'Sphere' / 'equirectangular'Full 360-degree spherical video
'180'180-degree half sphere video
'180_MONO'Monoscopic 180-degree video
'Cube' / '360_CUBE'360-degree cube map video
'NONE'Standard flat video (no VR projection)
'AUTO'Automatically detect from player.mediainfo.projection

Side-by-Side (Stereoscopic) Projections

Side-by-side video contains separate left and right eye views packed into a single video frame. The plugin automatically separates these for proper stereoscopic viewing in VR headsets.

ProjectionDescription
'360_LR'360-degree with left/right eye side-by-side
'360_TB'360-degree with top/bottom eye layout
'180_LR'180-degree with left/right eye side-by-side
'SBS_MONO'Flat screen side-by-side - shows stereo 3D in WebXR, mono in browser

Equi-Angular Cubemap (EAC)

ProjectionDescription
'EAC'YouTube's equi-angular cubemap format
'EAC_LR'EAC with left/right eye side-by-side

Fisheye Projections (since 3.2.0)

Fisheye sources are circular images shot through a wide-angle lens. The plugin reprojects the disc onto a sphere with a custom shader, so the camera can look around naturally inside the captured field of view. Fragments outside the disc are discarded so the letterbox stays clean.

ProjectionDescription
'FISHEYE_180'Single 180° fisheye disc, mono
'FISHEYE_200'Single 200° fisheye disc, mono (covers MKX200-style lenses)
'FISHEYE_220'Single 220° fisheye disc, mono (VRCA220, etc.)
'FISHEYE_360'Dual fisheye 360° — front hemisphere on the left half of the texture, back hemisphere on the right half (Ricoh Theta-style raw)
'FISHEYE_180_LR'180° fisheye with left/right eye side-by-side (each half is a full disc per eye)
'FISHEYE_200_LR'200° fisheye, LR stereo
'FISHEYE_220_LR'220° fisheye, LR stereo
'FISHEYE_360_LR'Stereoscopic dual fisheye 360°

LR variants render the left eye on Three.js layers 0 and 1 and the right eye on layer 2 only. WebXR routes per-eye rendering through layers 1 and 2 for true stereo, while non-XR (flat browser) viewers see just the left eye instead of a black scene.

WebXR VR Mode

When viewing in a WebXR-compatible browser (like Meta Quest Browser), the plugin provides an immersive VR experience:

  1. Click the Cardboard/VR button in the player controls to enter VR mode
  2. Squeeze the grip on your VR controller to show/hide the VR HUD
  3. Use the thumbstick to:
    • Left/Right: Seek through the video
    • Up/Down: Scroll through the gallery (when open)
  4. Point and click with your controller to interact with buttons
  5. Press A button on controller to toggle play/pause

VR HUD Controls

The VR HUD provides these controls while in VR mode:

ButtonFunction
Exit (X)Exit VR mode
GalleryOpen the media gallery panel
PreviousGo to previous media item
Play/PauseToggle video playback
NextGo to next media item
Reset OrientationReset view to default orientation
Drag HandleDrag to adjust viewing angle (for lying down, etc.)
ProjectionOpen projection mode selector
FavoriteToggle favorite status (if callback provided)

The HUD also includes a scrub bar showing current playback position with a draggable handle for seeking.

The VR Gallery allows users to browse and select media while remaining in VR:

player.vr({
  projection: '360',
  enableVRGallery: true,
  mediaItems: [
    {
      title: 'Beach Sunset',
      thumbnail: '/thumbnails/beach.jpg',
      url: '/videos/beach-360.mp4',
      duration: 180 // seconds (optional)
    },
    {
      title: 'Mountain View',
      thumbnail: '/thumbnails/mountain.jpg',
      url: '/videos/mountain-360.mp4',
      duration: 240
    }
  ],
  onMediaSelect: (item, index) => {
    // Handle media selection
    player.src({ src: item.url, type: 'video/mp4' });
  }
});
  • Scrollable Grid: 4-column thumbnail grid with smooth scrolling
  • Lazy Loading: Thumbnails load as they become visible
  • VR Controller Support: Point and click to select, use thumbstick to scroll
  • Mouse/Touch Support: Works in non-VR mode too
  • Duration Badges: Shows video duration on thumbnails
// Update gallery items at runtime
player.vr().setGalleryItems([
  { title: 'New Video', thumbnail: '/thumb.jpg', url: '/video.mp4' }
]);

// Show/hide gallery programmatically
player.vr().showGallery();
player.vr().hideGallery();
player.vr().toggleGallery();

API Reference

Options

player.vr({
  // Projection mode
  projection: '360',           // See projection types above
  sphereDetail: 32,            // Sphere mesh detail (higher = smoother)

  // VR HUD options
  enableVRHUD: true,           // Enable in-VR controls
  enableVRGallery: true,       // Enable in-VR media gallery
  showHUDOnStart: true,        // Show HUD when entering VR
  hudAutoHideDelay: 5000,      // Auto-hide HUD after ms (0 to disable)
  hudDistance: 1.5,            // Distance of HUD from viewer
  hudHeight: 1.5,              // Height of HUD
  hudScale: 0.015,             // Scale of HUD elements

  // Behavior options
  forceCardboard: false,       // Force cardboard button on all devices
  motionControls: true,        // Enable gyroscope/device orientation
  disableTogglePlay: false,    // Disable click-to-play

  // Spatial audio (requires Omnitone library)
  omnitone: null,              // Pass Omnitone library object
  omnitoneOptions: {},         // Omnitone configuration

  // Media gallery items
  mediaItems: [],              // Array of media items for gallery

  // Callbacks
  onNext: () => {},            // Called when next button pressed
  onPrevious: () => {},        // Called when previous button pressed
  onMediaSelect: (item, index) => {}, // Called when gallery item selected
  onGallery: () => {},         // Called when gallery button pressed
  onExit: () => {},            // Called when exit VR pressed
  onProjectionChange: (projection) => {}, // Called when projection changed
  onFavorite: () => {}         // Called when favorite button pressed (enables button)
});

Methods

const vr = player.vr();

// Projection
vr.setProjection('360_LR');    // Change projection mode

// VR HUD
vr.showHUD();                  // Show the VR HUD
vr.hideHUD();                  // Hide the VR HUD
vr.toggleHUD();                // Toggle HUD visibility

// VR Gallery
vr.showGallery();              // Show the gallery panel
vr.hideGallery();              // Hide the gallery panel
vr.toggleGallery();            // Toggle gallery visibility
vr.setGalleryItems(items);     // Update gallery media items

// Favorite state
vr.setFavoriteState(true);     // Set favorite button state
vr.getFavoriteState();         // Get current favorite state

// Orientation
vr.setOrientationOffset({ x: 0.5, y: 0, z: 0 }); // Tilt view
vr.resetOrientationOffset();   // Reset to default orientation
vr.recenter();                 // Recenter VR view

// Status
vr.isPresenting();             // Check if currently in VR mode

// Three.js access
vr.camera;                     // THREE.PerspectiveCamera
vr.scene;                      // THREE.Scene
vr.renderer;                   // THREE.WebGLRenderer
vr.cameraVector;               // Camera direction vector

Events

// VR-specific events
player.on('vr-next', () => {});
player.on('vr-previous', () => {});
player.on('vr-gallery', () => {});
player.on('vr-exit', () => {});
player.on('vr-favorite', () => {});
player.on('vr-media-select', (e, { item, index }) => {});
player.on('vr-projection-change', (e, { projection }) => {});
player.on('vr-orientation-change', (e, euler) => {});
player.on('initialized', () => {});

Custom Buttons

The favorite button is an example of how custom functionality can be added. When the onFavorite callback is provided, the favorite button appears in the VR HUD:

player.vr({
  projection: '360',
  onFavorite: () => {
    const isFavorited = !player.vr().getFavoriteState();
    player.vr().setFavoriteState(isFavorited);

    // Save to your backend
    saveFavoriteStatus(currentVideoId, isFavorited);
  }
});

// Update favorite state when loading a new video
player.on('loadedmetadata', () => {
  const isFavorited = checkIfFavorited(currentVideoId);
  player.vr().setFavoriteState(isFavorited);
});

Per-Source Projection

Set projection on a source-by-source basis using player.mediainfo:

player.mediainfo = {
  projection: '360_LR'  // This video is side-by-side 360
};

player.vr({ projection: 'AUTO' }); // Will use mediainfo.projection

Accessing Three.js Objects

For advanced customization, Three.js objects are exposed:

const vr = player.vr();

// Add custom objects to the scene
const geometry = new THREE.BoxGeometry(1, 1, 1);
const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
const cube = new THREE.Mesh(geometry, material);
cube.position.set(0, 0, -5);
vr.scene.add(cube);

// Access camera for custom positioning
console.log(vr.camera.position);
console.log(vr.cameraVector); // Direction camera is facing

Caveats

  • HLS captions on Safari will not be visible as they are located inside the shadowRoot in the video element
  • Some older mobile browsers may have limited WebXR support
  • CORS headers are required for cross-origin video sources

Development

# Install dependencies
npm install

# Start development server
npm start

# Run tests
npm test

# Build for production
npm run build-prod

License

MIT

版本与发布记录

@blaineam/videojs-vr 共发布 7 个版本,首次发布于 2025/12/23;过去 12 个月发布了 7 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
3.3.0latest2026/05/046 个月前
3.2.02026/05/036 个月前
3.1.42026/04/087 个月前
3.1.32026/04/077 个月前
3.1.12026/01/0610 个月前
3.1.02026/01/0510 个月前

关于 @blaineam/videojs-vr 的常见问题

@blaineam/videojs-vr 是什么?

A plugin to add 360, 180, and VR video support to video.js with full WebXR support, VR HUD controls, and in-VR media gallery.

如何安装 @blaineam/videojs-vr?

在项目目录运行 npm install @blaineam/videojs-vr,或使用 pnpm add / yarn add / bun add。

@blaineam/videojs-vr 支持 TypeScript 吗?

该包的 package.json 没有声明类型入口。需要类型提示时,可以在 npm 上查找社区维护的 @types/blaineam__videojs-vr 是否存在。

@blaineam/videojs-vr 支持 ESM 还是 CommonJS?

同时提供 ES Module 与 CommonJS 入口,import 和 require() 都可以使用,打包工具会自动选择合适的版本。

@blaineam/videojs-vr 可以商用吗?

@blaineam/videojs-vr 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@blaineam/videojs-vr 的下载量有多少?

根据 npm 官方下载统计,@blaineam/videojs-vr 在 2026/10/09 – 2026/11/07 这 30 天内被下载 5,440 次,日均约 181 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@blaineam/videojs-vr 还在维护吗?

最新版本 3.3.0 发布于 2026/05/04(6 个月前);至今共发布 7 个版本,其中过去 12 个月发布了 7 个;首次发布于 2025/12/23。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。