Broadcast to a Large Audience with HLS
Turn a stream into HLS so it plays on phones, TVs and browsers for audiences of any size. This guide uses an OBS stream sent over WHIP as the source.
Before you start
- A running room and its
meetingID. - A video source: the
sessionIDof an active WHIP stream.
1. Start the broadcast
From your server:
curl -X POST "https://mediasfu.com/v1/meetings/$MEETING_ID/broadcasts" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $MEDIASFU_API_USERNAME:$MEDIASFU_API_KEY" \
-d "{\"sourceSessionID\":\"$SESSION_ID\"}"
The response includes:
{
"success": true,
"broadcastID": "…",
"state": "…",
"sourceQuality": "…",
"renditions": ["…"],
"playbackUrl": "https://…"
}
Wait until the broadcast reports that it is active before you show the player.
MediaSFU produces the source's quality and lower ones; it doesn't upscale an SD
source to HD, so renditions tells you what viewers can get.
2. Play it
Safari plays HLS natively. Other browsers can use
hls.js:
<video id="live" controls playsinline></video>
<script src="https://cdn.jsdelivr.net/npm/hls.js@1"></script>
<script>
const url = 'PLAYBACK_URL_FROM_YOUR_SERVER';
const video = document.getElementById('live');
if (video.canPlayType('application/vnd.apple.mpegurl')) {
video.src = url;
} else if (Hls.isSupported()) {
const hls = new Hls();
hls.loadSource(url);
hls.attachMedia(video);
}
</script>
Serve playbackUrl to viewers from your own backend. It carries a short-lived
token, so fetch a fresh broadcast or URL when it expires. For large public
audiences, put a CDN in front of the playback origin.
3. End the broadcast
curl -X DELETE "https://mediasfu.com/v1/meetings/$MEETING_ID/broadcasts/$BROADCAST_ID" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $MEDIASFU_API_USERNAME:$MEDIASFU_API_KEY" \
-d '{"reason":"event_finished"}'
Good to know
- HLS runs a few seconds behind the live room. Use WHEP when viewers need to interact in real time.
- Broadcasts use complete CMAF segments, not partial-segment Low-Latency HLS.
- A broadcast request is declined when streaming isn't enabled for the account, the room has ended, or the source has no video.
See the streaming HTTP reference for every field and route.