The chain from OBS to a browser tab
Four pieces sit between the scene in OBS and a viewer's tab. Each one has a single job, and most problems people hit come from expecting one piece to do another's work.
| Piece | Job | Protocol |
|---|---|---|
| OBS Studio | Composites the scene and encodes it once | RTMP, SRT or WHIP out |
| Ingest / origin | Accepts the push and authenticates it | RTMP, SRT or WHIP in |
| Packager and delivery | Cuts the stream into segments plus a playlist and serves them over HTTP | HLS (DASH as an option) |
| Player on your page | Fetches the playlist and segments and decodes them | HTML5 video, with hls.js where needed |
Browsers do not play RTMP or SRT. HLS is what they get instead: a .m3u8 playlist that lists short media segments, fetched over plain HTTPS like any other file. That is also why a CDN can sit in front of it: every segment is a cacheable object.
Pointing OBS at your own server
In OBS the destination lives under Settings → Stream. Pick Custom... in the Service list instead of a platform, then fill in the fields for the protocol your server speaks.
- RTMP: put the server URL in Server and the stream name in Stream Key. If the server signs encoders in with a login, tick Use authentication and fill Username and Password.
- SRT: put
srt://host:portin Server. Leave Stream Key empty unless your server asks for a stream ID, because OBS sends the key as the SRT streamid. For an encrypted channel, tick Use authentication and put the passphrase in Password, or addpassphrase=...to the URL's query string. Other options also go in the query string, and the one that matters islatency, in microseconds. - WHIP (WebRTC): pick WHIP as the Service, then paste the provider's URL into Server and its token into Bearer Token. WHIP is new in OBS; the Ubuntu 24.04 PPA build lacks it, and the OBS docs point Ubuntu users to the Flatpak.
OBS's SRT guide gives a default latency of 120 ms and says it should be at least 2.5 times the round trip between encoder and ingest. From a venue with an 80 ms round trip to the ingest, that means 200 ms or more:
srt://ingest.example.net:9000?latency=200000
Run a few minutes of test stream before the real one. The OBS quick-start guide recommends exactly that, and it is the only way to see a wrong key or a blocked port before an audience does.
Output settings that make HLS segment cleanly
An HLS packager can only start a segment on a keyframe, so the keyframe interval decides segment boundaries. Apple's HLS authoring specification asks for an IDR every 2 s and a 6 s target duration for segments; a 2 s interval divides 6 s evenly, so every segment is cut on schedule.
Simple output mode hides the field. Switch Settings → Output → Output Mode to Advanced; on the Streaming tab the x264 encoder shows Rate Control, Bitrate and Keyframe Interval (0=auto). Set the interval to 2 rather than leaving it on auto, and use CBR so the bitrate the server sees is the one you set. OBS's transcoding notes give the reason for a consistent interval: automatic quality switching can only move between renditions smoothly when keyframes come at a steady rhythm.
| Output | Video bitrate (Apple ladder, kbit/s) | Upload to budget |
|---|---|---|
| 1280×720 | 3,000 or 4,500 | About 4-6 Mbit/s spare |
| 1920×1080 | 6,000 or 7,800 | About 8-10.5 Mbit/s spare |
| Audio, AAC stereo | 32-160 | Included above |
The ladder figures are Apple's example rungs; the upload column applies the starting rule in OBS's connection troubleshooting guide, which puts the video bitrate at about 75% of your total upload speed. If the line is shared or wireless, aim lower: dropped frames in OBS mean the connection to the ingest server could not keep up.
OBS can lower the bitrate by itself when the network chokes: Settings → Advanced → Network → Dynamically change bitrate to manage congestion (Beta). OBS marks it Beta and says it does not solve the root cause of dropped frames, and the picture gets softer while it acts.
Putting the player on your page
Safari plays an HLS playlist natively in a plain video element. Chrome, Firefox and Edge need hls.js, which feeds the segments to the browser through Media Source Extensions; on iOS 17.1 and later it uses Managed Media Source. This minimal embed is adapted from the hls.js README, with your playlist address in place of its example:
<script src="https://cdn.jsdelivr.net/npm/hls.js@1"></script>
<video id="video" controls muted playsinline></video>
<script>
var video = document.getElementById('video');
var videoSrc = 'https://YOUR-PLAYLIST-ADDRESS/playlist.m3u8';
if (Hls.isSupported()) {
var hls = new Hls();
hls.loadSource(videoSrc);
hls.attachMedia(video);
} else if (video.canPlayType('application/vnd.apple.mpegurl')) {
video.src = videoSrc;
}
</script>
For production, pin an exact version (hls.js@1.x.y) and add an integrity attribute, or host the file yourself. The playlist must be served over HTTPS if your site is, and the server must send CORS headers that allow your domain, because hls.js fetches segments with XHR. A hosted channel normally ships its own player, which saves writing any of this; the snippet is for when you want the video element under your own markup and CSS.
Running the origin yourself, or on a service
Self-hosting the chain means an ingest server, a packager, TLS, CORS, an HTTP tier that survives a crowd, and somebody watching it during every broadcast. Every viewer pulls the full bitrate, so delivery grows linearly with the audience: 500 people on a 4.5 Mbit/s stream is about 2.25 Gbit/s leaving the server.
Our live video streaming service is that chain run for you. OBS pushes RTMP to rtmp://ingest.video.serverroom.net/ plus the channel's name, with a stream name, username and password; SRT is on Starter and up, each channel with its own port and passphrase; WHIP works from OBS 30 on every plan and connects directly to the channel's server. RTMP and SRT pushes enter at the nearest of 5 cities and ride our own links to the channel's server in New York or Bucharest. Viewers get HLS and DASH from the city nearest to them, on the video CDN.
- The dashboard prints each channel's encoder settings with a copy button beside every line.
- The Live tab shows whether the encoder is connected, from which address, at what rate, and how many people watch.
- Viewer limits per channel are enforced on the channel itself: 1,000 at once on Free and Starter, 5,000 on Pro, 25,000 on Platinum.
- A new publish password plus a channel restart locks out an encoder you no longer control.
Wanting Wowza, Nimble or your own packager with root access points to the other route, a dedicated streaming server: one physical machine with its own unmetered port, and the operations work is yours.
Your site and YouTube from one OBS push
Encoding twice on the streaming PC costs CPU or GPU time and doubles the upload. Pushing once to your origin and fanning out from there costs neither. On our channels the Live tab sends the same feed to up to 5 destinations, YouTube, Facebook, Twitch or any RTMP address, each switched on or off without touching OBS, while the player on your own site keeps running.
For a one-off conference or concert sized past a normal channel, live event streaming covers the audience without a standing plan.
What goes wrong, and where to look
- Player loads, then stalls every few seconds: the keyframe interval is on auto or too long, so segments come out uneven. Set it to 2.
- Dropped frames climbing in OBS: the upload cannot hold the bitrate. Lower it, use a wired connection, and on a lossy path switch to SRT with a larger latency value.
- Works in Safari, blank elsewhere: hls.js is missing or the segment requests fail CORS. The browser console shows which.
- Blank player with a mixed-content error in the console: the playlist is on http while the page is on https. Serve it over https.
- Encoding overloaded: the machine running OBS is short of CPU or GPU, not the network. Lower the output resolution or frame rate.
Questions
Can OBS stream directly to a website with no server in between?
Not to an audience. OBS pushes a single outgoing stream to one destination; it does not hand out copies to each viewer. Its WHIP output can reach a single browser peer to peer, but serving a crowd needs a server or CDN that packages and delivers the stream.
Which keyframe interval should I set for a website stream?
Two seconds. Apple's HLS specification asks for an IDR every 2 s, and a fixed interval lets the packager cut even segments. In OBS that means Advanced output mode, then Keyframe Interval 2 on the Streaming tab.
RTMP, SRT or WHIP: which should OBS use?
RTMP is the default every server accepts and suits a stable wired line. SRT recovers lost packets, so it holds up on a venue uplink or a long-distance path; set its latency to at least 2.5 times the round trip. WHIP gives the lowest delay on the way in and needs OBS 30 or newer.
How do I embed the live stream on a WordPress or plain HTML page?
Paste the provider's player embed, or a video element driven by hls.js pointing at the HLS playlist, into a custom HTML block. Serve the playlist over HTTPS and make sure its CORS headers allow your domain. Test in Chrome, desktop Safari and an iPhone. hls.js handles most of them, and older iOS versions fall back to native HLS.
Does a Server Room channel need its own server to manage?
No. The channel lives on our streaming servers (New York or Bucharest), which the video CDN delivers from; there is nothing to install or patch. If you want a whole machine with your own software, that is a dedicated streaming server, a separate product.
Can I keep streaming to YouTube while my site gets the feed?
Yes. Send OBS to your channel once and add YouTube, Facebook, Twitch or any RTMP address as a restream target in the Live tab, up to 5 at a time. Your own player keeps playing alongside them.