A broadcast, in a box.
[![License][license-image]][license-url] [![Discord][discord-image]][discord-invite-url]
Broadcast Box lets you broadcast/screen-share to friends in sub-second time. It was designed to be simple to use and easily modifiable. Broadcast Box uses WebRTC, to learn more see the OBS WHIP Streaming Guide
Want to contribute to the development of Broadcast Box? See Contributing.
A public instance of Broadcast Box is hosted at b.siobud.com. Feel free to use this as much as you want. Go to Getting Started for instructions on running it locally.
To use Broadcast Box with OBS you must set your output to WebRTC and set a proper URL + Stream Key. You may use any Stream Key you like. The same stream key is used for broadcasting and playback.
Go to Settings -> Stream and set the following values.
Your settings page should look like this:
OBS by default will have ~2 seconds of latency. If you want sub-second latency you can configure
this in Settings -> Output. Set your encoder to x264 and set tune to zerolatency. Your Output
page will look like this.
When you are ready to broadcast press Start Streaming and now time to watch!
Open /publish/<streamKey> (for example https://b.siobud.com/publish/StreamTest) to publish directly from the browser.
Broadcast Box can capture either your screen or webcam and uses the same stream key for playback.
If the supplied bearer token belongs to a reserved profile, the page also exposes profile settings so you can update the stream MOTD and toggle public/private visibility without leaving the publish flow.
The following simple example broadcasts video-test.mp4 to https://b.siobud.com with a Bearer Token of ffmpeg-test
ffmpeg -re -i video-test.mp4 -bf 0 -f whip -authorization ffmpeg-test https://b.siobud.com/api/whipFor now, FFmpeg WHIP only supports H.264 (libx264) and Opus and will use them by default if the -vcodec and -acodec
options are omitted. However, you can use any H.264 encoder, such as:
ffmpeg -hwaccel vulkan -re -i video-test.mp4 -bf 0 -vcodec h264_vaapi \
-vf 'format=nv12|vulkan,hwupload' -init_hw_device vulkan \
-f whip -authorization ffmpeg-test https://b.siobud.com/api/whipThe following complex example broadcasts a test feed to https://b.siobud.com with a Bearer Token of ffmpeg-test
ffmpeg \
-re \
-f lavfi -i testsrc=size=1280x720 \
-f lavfi -i sine=frequency=440 \
-pix_fmt yuv420p -vcodec libx264 -profile:v baseline -r 25 -g 50 \
-acodec libopus -ar 48000 -ac 2 \
-f whip -authorization "ffmpeg-test" \
"https://b.siobud.com/api/whip"Note that WHIP support and libx264 are required for this example. WHIP was added in version 8 of FFmpeg.
See the example script here.
Can broadcast gstreamer's test sources, or pulsesrc+v4l2src
Expects gstreamer-1.0, with good,bad,ugly plugins and gst-plugins-rs
Use of example scripts:
# testsrcs
./examples/gstreamer-broadcast.sh http://localhost:8080/api/whip testStream1
# v4l2src
./examples/gstreamer-broadcast.sh http://localhost:8080/api/whip testStream1 v4l2If you are broadcasting to the Stream Key StreamTest your video will be available at https://b.siobud.com/StreamTest.
The player page also supports multi-view playback. Use the Add Stream button in the footer to add more active streams
to the same page, and use ?cinemaMode=true to open the player in a chrome-free layout.
You can also go to the home page and enter StreamTest. The following is a screenshot of OBS broadcasting and
the latency of 120 milliseconds observed.
When FRONTEND_ADMIN_TOKEN is set Broadcast Box provides an Admin Portal at /admin. The same token is used to log in.
The current Admin Portal exposes:
Status to inspect active publishers/subscribers and metadataProfiles to create stream profiles, rotate tokens, and remove profilesLogging to read the current server log fileStream Profiles let you reserve a stream key, so only authorized users can stream to that key.
Viewable at /statistics, this page shows stream uptime, track metrics, and WHEP session details.
This page relies on /api/status, so disabling the status API disables statistics.
The repository includes a few small examples and integration helpers:
/api/status and opens viewers for all active streams.ogg and .h264 filesBroadcast Box is made up of two parts. The server is written in Go and is in charge of ingesting and broadcasting WebRTC. The frontend is in react and connects to the Go backend. The Go server can be used to serve the HTML/CSS/JS directly. Use the following instructions to build from source or utilize Docker / Docker Compose.
The backend loads .env.production by default. Set APP_ENV=development to load
.env.development instead.
If you only want the backend API or CLI helpers without serving the built frontend, set DISABLE_FRONTEND=TRUE.
React dependencies are installed by running npm install in the web directory.
npm run build builds production assets into web/buildnpm start runs the Vite dev server and proxies /api to the backendnpm run host runs the same Vite dev server on your local networkIf everything is successful, you should see output similar to:
…Go dependencies are automatically installed.
To run the Go server, run go run . in the root of this project, you should see the following:
2026/02/24 12:00:00 Environment: Loading `.env.production`
2026/02/24 12:00:00 Starting HTTP server at :8080To use Broadcast Box navigate to: http://<YOUR_IP>:8080. In your broadcast tool of choice, you will broadcast to http://<YOUR_IP>:8080/api/whip.
A Docker image is also provided to make it easier to run locally and in production. The arguments you run the Dockerfile with depending on if you are using it locally or a server.
If you want to run locally execute docker run -e UDP_MUX_PORT=8080 -e NAT_1_TO_1_IP=127.0.0.1 -p 8080:8080 -p 8080:8080/udp seaduboi/broadcast-box.
This will make broadcast-box available on http://localhost:8080. The UDPMux is needed because Docker on macOS/Windows runs inside a NAT.
If you are running on AWS (or other cloud providers) execute. docker run --net=host -e INCLUDE_PUBLIC_IP_IN_NAT_1_TO_1_IP=yes seaduboi/broadcast-box
broadcast-box needs to be run in net=host mode. broadcast-box listens on random UDP ports to establish sessions.
A Docker Compose is included that uses LetsEncrypt for automated HTTPS. It also includes Watchtower so your instance of Broadcast Box will be automatically updated every night. If you are running on a VPS/Cloud server this is the quickest/easiest way to get started.
export URL=my-server.com
docker-compose up -dWhen serving the page over a reverse proxy, you must ensure that http://<YOUR_IP>/api/sse is unbuffered as it can otherwise cause a delay in receiving events until the buffer is flushed and cause issues with the video controls.
For example in nginx you would use the following configuration
location /api/sse {
proxy_pass http://<YOUR_IP>:<PORT>;
# ... other configurations
proxy_buffering off;
}The frontend can be configured by passing these URL Parameters.
cinemaMode=true - Forces the player into cinema mode by adding to end of URL like https://b.siobud.com/myStream?cinemaMode=true| Variable | Description |
|---|---|
APP_ENV |
Set to development to load .env.development instead of .env.production. |
HTTP_ADDRESS |
Address for the main server to bind to. Used for HTTP, or HTTPS when certificates are configured. |
ENABLE_HTTP_REDIRECT |
When set, enables automatic redirection from HTTP to HTTPS. |
HTTPS_REDIRECT_PORT |
Port to listen on for the HTTP-to-HTTPS redirect server. |
NETWORK_TEST_ON_START |
If true, checks network connectivity on startup. |
DISABLE_STATUS |
When set, disables /api/status. Stream discovery and /statistics rely on this endpoint. |
ENABLE_PROFILING |
If true, enables PPROF profiling on localhost:6060. |
| Variable | Description |
|---|---|
SSL_CERT |
Path to the SSL certificate file. When set together with SSL_KEY, the Go server serves HTTPS. |
SSL_KEY |
Path to the SSL key file. When set together with SSL_CERT, the Go server serves HTTPS. |
| Variable | Description |
|---|---|
STREAM_PROFILE_PATH |
Path to store stream profile configurations. Default is profiles. |
STREAM_PROFILE_POLICY |
Policy |
No open issues yet, or sync has not completed.