Shitty service to proxy data from OBS into an HTTP Live Streaming (HLS) feed VRChat understands. ## Cost - One connection is about 7 Mb/s - GCE charges $0.05 per GiB ($0.05 $/GiB) * (1 byte / 8 bits) = 0.00625 $/Gib (0.00625 $/Gib) * 0.007 Gib/s = $4.375 * 10^-5 $/sec (per connection) [$4.375 * 10^-5 / (sec * connection)] * 100 connections = $0.004375 / sec 7 Mb/s is 3.076 GiB/hr ## Streamer instructions 1. Configure OBS with a custom server pointing at `rtmps://:1935/live` in the stream settings and enter your stream key. 2. Press stream. Check status on bottom right of obs. ## Dev instructions 1. Get ssh perms to yummers.dev. `ssh yummers.dev` should log you in as yum if not, you'll have to update the ssh commands below. 2. Run ./push.sh 3. Add this to your .bashrc: ```bash function check_live { ssh yummers.dev 'sudo journalctl -u obsproxy -f' } function start_live { ssh yummers.dev 'sudo systemctl start obsproxy' } function stop_live { ssh yummers.dev 'sudo systemctl stop obsproxy' } function reset_live { ssh yummers.dev 'sudo systemctl restart obsproxy' get_live_logs } function get_live { live_url=$(ssh yummers.dev "journalctl -u obsproxy -n 10000 | grep 'HLS:' | awk '{print \$NF}'" | tail -n 1) echo $live_url | clip.exe echo "Copied to clipboard: $live_url" } ``` ... and source it with `source ~/.bashrc`. 4. 2. Install runtime dependencies: `pip install -r opt/obsproxy/requirements.txt`. 3. Start the Python service (see `etc/systemd/system/obsproxy.service` for a sample unit). The bundled entrypoint now runs under [Waitress](https://docs.pylonsproject.org/projects/waitress/en/stable/) so you get a production-grade WSGI server out of the box. 4. When the service starts it prints a session-specific playlist URL like `https:///hls//stream.m3u8`; share that exact URL with your VRChat video player. The manifest now advertises AES-128 encryption with a companion key URL in the same session-scoped directory, so the player must support standard HLS key retrieval. Multiple viewers can consume the feed concurrently. RTMPS termination happens at nginx (default port `1935`) via the `ngx_stream_module`, which proxies plain RTMP to the local nginx-rtmp listener on `127.0.0.1:1936`. Update the `INGEST_RTMP_*` settings if you run the backend elsewhere, and make sure the stream module is installed/enabled (on Debian/Ubuntu install `libnginx-mod-stream`). Environmental knobs: - `OBS_STREAM_KEY` / `STREAM_PSK`: required PSK for the single ingest client. - `INGEST_THREAD_QUEUE_SIZE`: RTMP demux queue depth before frames are dropped (defaults to `4096`). - `INGEST_RTMP_HOST`: host FFmpeg pulls RTMP from (defaults to `127.0.0.1`). - `INGEST_RTMP_PORT`: port FFmpeg pulls RTMP from (defaults to `1936`). - `HLS_SEGMENT_TIME`: length (in seconds) of the `.ts` segments emitted by FFmpeg (defaults to `2`). - `HLS_PLAYLIST_SIZE`: number of segments retained in the rolling playlist (defaults to `6`). - `HLS_DELETE_THRESHOLD`: additional historical HLS segments to keep on disk before pruning (defaults to `2`). - `HOST`: interface Waitress binds to (defaults to `0.0.0.0`). - `PORT`: TCP port Waitress listens on (defaults to `5000`). - `FFMPEG_LOGLEVEL`: override the log verbosity passed to FFmpeg (defaults to `info`). The server seeds a fresh 128-bit session ID on every restart and writes HLS artifacts under `/live/`. The playlist and segments are only exposed under `/hls//`, making it infeasible to guess a live session path.