A high-performance VR browser server for Resonite, featuring GPU-accelerated video encoding and hardware-accelerated browser rendering. Stream multiple independent browser sessions to VR with minimal CPU overhead.
you can get the item from my folder here
- π GPU Hardware Acceleration: NVIDIA NVENC encoding + GPU-accelerated video decode
- π¬ 10+ Simultaneous Sessions: Handle 10+ concurrent YouTube streams with hardware acceleration
- πΊ Separate Video/Audio Streams: H.264 (NVENC) video + MP3 audio streams
- π±οΈ Full Browser Control: Mouse, keyboard, scrolling, navigation
- π Session Management: Restart broken sessions, auto-cleanup on timeout
- π Isolated Audio: Per-session PulseAudio virtual sinks
- π URL Tracking: Automatic URL change notifications
βοΈ βΆοΈ Navigation State: Real-time back/forward button state
| Configuration | Sessions | CPU Usage | GPU Usage |
|---|---|---|---|
| Software Only | 4 streams | 99% | 0% |
| GPU Accelerated | 10+ streams | 50-60% | 90-95% |
2.5x capacity increase with GPU acceleration!
- GPU: NVIDIA GPU with NVENC support (GTX 1050 or better recommended)
- CPU: Multi-core CPU (tested on Ryzen 7 5800X3D, 12 cores)
- RAM: 4-8GB minimum, 16GB+ recommended for multiple sessions
- OS: Ubuntu 20.04 LTS or later
- Node.js: v20.x or later
- NVIDIA Driver: 535.x or compatible
- Dependencies: Xvfb, FFmpeg with NVENC, PulseAudio, Playwright
# 1. Install system dependencies
sudo apt update && sudo apt install -y xvfb pulseaudio ffmpeg mesa-utils xdotool
# 2. Install NVIDIA drivers
sudo apt install -y nvidia-driver-535
# 3. Install Node.js 20
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
sudo apt install -y nodejs
# 4. Clone and setup
git clone https://github.com/YourUsername/resonite-browser-server.git
cd resonite-browser-server
npm install
# 5. Start server
npm start- WebSocket:
ws://localhost:3000 - Video Stream:
http://localhost:3000/stream/<SessionID>(H.264 MPEG-TS, 1080p30, 6Mbps) - Audio Stream:
http://localhost:3000/audio/<SessionID>(MP3, 128kbps, 48kHz)
// Session Management
get_session // Create new session β Returns "SessionID RW-XX"
restart <SessionID> // Restart broken session
heartbeat <SessionID> // Keep alive (required every 60s)
// Navigation
setUrl <SessionID> <URL> // Navigate (supports http://, https://, chrome://, about://)
back <SessionID> // Go back β Returns NavState
forward <SessionID> // Go forward β Returns NavState
reload <SessionID> // Reload page β Returns NavState
getNavState <SessionID> // Get current nav state
// Tab Management
newTab <SessionID> [URL] // Create new tab
closeTab <SessionID> <index> // Close tab
switchTab <SessionID> <index> // Switch tab
getTabs <SessionID> // List tabs β Returns tab count and titles
// Interaction
clickPos <SessionID> <x>,<y> // Click at coordinates
doubleclick <SessionID> <x>,<y> // Double click
mousemove <SessionID> <x>,<y> // Move mouse
scroll <SessionID> <x>,<y> // Scroll (0-1 normalized)
keyboard <SessionID> <text> // Type textCoordinate System: Canvas is 1920x1080 centered at origin
- X: -960 to +960
- Y: -540 to +540
The server automatically sends these messages:
URL Changes
URLChanged RW-XX https://youtube.com
Sent whenever the page navigates (clicks, redirects, form submissions, etc.)
Navigation State (bool2 format for Resonite)
NavState RW-XX [true;false]
- First bool: Can go back
- Second bool: Can go forward
- Sent after: setUrl, reload, back, forward, or getNavState commands
Examples:
[true;false]- Can go back, can't go forward[false;true]- Can't go back, can go forward[true;true]- Can go both directions[false;false]- At first page, no history
const ws = new WebSocket('ws://localhost:3000');
// Create session
ws.send('get_session');
// β "SessionID RW-42"
// Navigate
ws.send('setUrl RW-42 https://youtube.com');
// Click
ws.send('clickPos RW-42 100,-200');
// Keep alive
setInterval(() => ws.send('heartbeat RW-42'), 5000);Each session consists of:
- Xvfb: Virtual X display (:100-:199)
- Chromium: Browser with GPU acceleration enabled
- PulseAudio: Virtual audio sink (browser_RW_XX)
- FFmpeg Video: x11grab β NVENC H.264 β MPEG-TS
- FFmpeg Audio: PulseAudio monitor β MP3
Occasional GPU initialization failures cause frozen/white screens (~10-30% of sessions).
Solution: Use Wrench Icon
restart RW-XX
May need 2-3 attempts.
Navigate to GPU status page:
type chrome://gpu in addressbar
Should show "Hardware accelerated" for Canvas, Compositing, Rasterization, Video Decode, WebGL.
High CPU Usage
- Check GPU is being used:
nvidia-smi(should show Chrome processes) - Verify NVENC: Server logs should show
h264_nvenc
No Audio
- Check PulseAudio sinks:
pactl list sinks | grep browser_RW - Verify audio stream URL works in browser
Sessions Not Starting
- Check Xvfb:
ps aux | grep Xvfb - Check GPU devices:
ls /dev/nvidia* /dev/dri/
NVENC Session Limit Consumer NVIDIA GPUs limit 8 concurrent NVENC sessions. Apply nvidia-patch to remove limit.
Adjust Y offset in server-video.js if cursor alignment is off:
const screenY = Math.round(540 - y) - 5; // Default: -5'-b:v', '6M', // Bitrate
'-maxrate', '6M',
'-g', '30', // Keyframe intervalconst HEARTBEAT_TIMEOUT = 60000; // 60 seconds-
White Screen Bug: Random GPU initialization failures
- Workaround: Use the wrench icon on the browser
-
Tab Switching Delay: 1-2 second delay when new tab is created
Built for Resonite VR by alexvermaning0 for the community.
Experimental Software: GPU passthrough and hardware acceleration can be finicky. Expect some troubleshooting!