Skip to content

Latest commit

 

History

99 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

VRCStreamer

WebSocket-to-RTSP audio/video server for VRChat.

This installation guide has only been tested on Debian 13. All commands below assume that you are using the root user.

1. Install Rust

apt install -y curl build-essential
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
. "$HOME/.cargo/env"

2. Clone and Build

Clone the repository into the directory where you want to keep the server, then build it:

git clone https://github.com/vard88508/VRCStreamer.git
cd VRCStreamer/server
chmod +x build.sh create_service.sh kill_service.sh
./build.sh

The compiled executable is written to VRCStreamer/server/VRCStreamer.

3. Configure the Server

Create your local .env file from the provided example:

cp .env.example .env
nano .env

Before starting the server, check your TLS path settings:

  • TLS_CERT_PATH and TLS_KEY_PATH: paths to the certificate and private key for your API domain. You can make them using Certbot

The complete list of settings is available in the Environment section.

4. Install the Service

./create_service.sh

The script creates /etc/systemd/system/VRCStreamer.service, enables automatic startup, and starts the server.

Useful commands:

systemctl status VRCStreamer
systemctl restart VRCStreamer
journalctl -u VRCStreamer -f

To stop the server and remove its systemd service:

./kill_service.sh

This does not delete the executable, .env, placeholders, or source files.

5. Start Streaming

Open stream.vard.cc, choose Custom Server, and enter your server's API address:

https://example.com

Updating

cd VRCStreamer
git pull
cd server
./build.sh

If the systemd service is installed, build.sh automatically restarts it after a successful build.

Stream Blacklist

To block publishing to specific stream URLs, create blacklist.txt next to the VRCStreamer executable. Add the 32-character stream IDs from the URLs, separated by semicolons or new lines:

a85c0211c512828c4c52dc5716a79e3a;1dd5a1d78b07336b21496ccf7bf79b8a

The server reloads the file every minute. Newly blocked streamers are disconnected, and their IP addresses are blocked from starting new streams. Attempting to publish to an already blocked stream ID also blocks that streamer's IP. Each IP block is linked to the stream IDs that caused it: removing an ID releases its IPs unless another blacklisted ID also blocks them. Removing the file or leaving it empty clears both the stream ID blacklist and its IP blocks. Invalid updates are ignored so the previous valid list remains active.

IP blocks are stored only in RAM and cleared on restart. Other active streams from the same IP and RTSP listeners are unaffected. Logs identify connections with anonymous peer IDs, without exposing IP addresses.

The server stores at most 65,536 stream ID/IP associations. If another association cannot be stored, new streams are rejected until all IDs that overflowed this limit are removed from the blacklist or the server restarts.

Environment

The values below match .env.example and the server's built-in defaults.

Name Meaning
SERVER_NAME Server name shown by the web client
Default value: Self-Hosted Instance
SERVER_DESCRIPTION Optional server description sent to the web client
Default value: empty
POLICIES_LINK Optional policies page
Default value: empty
REPORT_ABUSE_LINK Optional abuse report page
Default value: empty
ROOT_REDIRECT_URL Destination for visitors who open the API root / in a browser
Default value: https://stream.vard.cc
BIND_ADDR Address and port used by the HTTP/HTTPS API and streamer WebSocket
Default value: 0.0.0.0:443
TLS_CERT_PATH Path to the PEM certificate; set both TLS paths to none to disable TLS
Default value: /etc/letsencrypt/live/example.com/fullchain.pem
TLS_KEY_PATH Path to the PEM private key; set both TLS paths to none to disable TLS
Default value: /etc/letsencrypt/live/example.com/privkey.pem
RTSP_BIND_ADDR Address and port used by RTSP listeners
Default value: 0.0.0.0:554
RTSP_PUBLIC_BASE Public RTSPT base URL sent to clients; none derives it from the API hostname and RTSP port
Default value: none
ALLOWED_ORIGINS Comma-separated web client origins allowed to publish streams
Default value: https://stream.vard.cc
ALLOW_ANY_ORIGIN Allow publishing from any website; keep this false unless you specifically need it
Default value: false
PASSWORD Optional comma-separated publishing passwords; listeners do not need a password
Default value: empty
VIDEO Enable H.264 video publishing; false restricts publishers to audio
Default value: true
AVAILABLE_VIDEO_QUALITY Video presets in widthxheight*fps/bitrate-kbps format; each preset's bitrate is also its sustained ingest limit
Default value: 1280x720*30/2000,
1280x720*60/4000,
1920x1080*30/3000,
1920x1080*60/6000
MAX_H264_FRAME_BYTES Maximum size of one H.264 access unit. Values above 8388608 are rejected to bound single-message memory use
Default value: 524288
VIDEO_INGEST_BURST_SECS Video byte/frame token-bucket capacity measured in seconds at the selected preset. Higher values allow longer short-term delivery spikes without changing the encoder target or allocating a media queue
Default value: 2
MAX_CONNECTIONS Maximum concurrent streamer WebSockets and accepted RTSP connections, including pending RTSP handshakes. Set to 0 to disable this limit
Default value: 320
MAX_STREAMERS Maximum active streamers. Set to 0 to disable this limit
Default value: 0
MAX_STREAMERS_PER_IP Maximum active streamers from one IP address. Set to 0 to disable this limit
Default value: 3
MAX_LISTENERS_TOTAL Maximum active RTSP listeners across all streams. Set to 0 to disable this limit
Default value: 0
MAX_LISTENERS_PER_STREAM Maximum RTSP listeners on one stream URL. Set to 0 to disable this limit
Default value: 105
MAX_LISTENERS_PER_IP Maximum accepted RTSP connections from one IP address, including pending handshakes. Set to 0 to disable this limit
Default value: 6
EGRESS_KBPS_PER_LISTENER Per-listener value used only to estimate outgoing bandwidth in server statistics
Default value: 384
MAX_HTTP_REQUESTS_PER_IP Maximum /healthz, /stats, and /ingest handshake requests from one IP per rate-limit window. Set to 0 to disable this limit
Default value: 60
HTTP_RATE_LIMIT_WINDOW_SECS HTTP rate-limit window in seconds
Default value: 60
MAX_RTSP_REQUESTS_PER_CONNECTION Maximum RTSP commands on one TCP connection, including playback setup and keepalives. Set to 0 to disable this limit
Default value: 4096
RTSP_HANDSHAKE_TIMEOUT_SECS Seconds allowed for a new RTSP connection to complete setup and start playback
Default value: 30
CHANNEL_BUFFER Shared frame queue per stream, not per listener; larger values tolerate more listener jitter but retain more media in memory for every active stream
Default value: 128
STREAMER_IDLE_TIMEOUT_SECS Disconnect a streamer after this many seconds without a WebSocket message
Default value: 120
RUST_LOG Server log level, such as error, warn, info, debug, or trace; trace also logs RTSP request headers with sensitive values redacted
Default value: warn

About

Easy low-latency streaming into VRChat

Resources

Stars

40 stars

Watchers

1 watching

Forks

Sponsor this project

Contributors

Languages