Understanding HLS in the Browser
HTTP Live Streaming (HLS) delivers video as a sequence of small MPEG-TS segment files described by an M3U8 playlist. Native HLS playback is supported on Safari and iOS, but Chrome, Firefox, and Edge require a JavaScript bridge — HLS.js — to parse and play M3U8 content.
Setting Up HLS.js in APG vNext
Add the HLS.js script to APG vNext's custom header (Admin → Appearance → Custom Header HTML):
<script src="https://cdn.jsdelivr.net/npm/hls.js@latest" defer></script>
Then add the initialisation function to your custom footer script:
function initHLS(videoId, src) {
var video = document.getElementById(videoId);
if (Hls.isSupported()) {
var hls = new Hls({ maxBufferLength: 30 });
hls.loadSource(src);
hls.attachMedia(video);
} else if (video.canPlayType('application/vnd.apple.mpegurl')) {
video.src = src; // native Safari/iOS
}
}
Custom BBCode Tag: [hls]
APG vNext allows custom BBCode tags via Admin → BBCode Manager. Create a [hls] tag that transforms:
[hls]https://example.com/stream.m3u8[/hls]
Into:
<div class="hls-wrap">
<video id="hls-{unique}" controls playsinline
poster="/assets/images/stream-poster.webp"></video>
<script>initHLS('hls-{unique}','https://example.com/stream.m3u8')</script>
</div>
The 56.25% padding-bottom creates a 16:9 aspect ratio container that fills the post width.
Moderator-Only Posting
Restrict the [hls] BBCode tag to moderators and trusted members to prevent abuse. In APG vNext BBCode Manager, set the minimum role required to use the tag.
Mobile Playback
Mobile browsers require the playsinline attribute to prevent automatic fullscreen takeover on iOS. Always include it. Also test that your M3U8 segments are served with proper CORS headers (Access-Control-Allow-Origin: *) if your stream CDN is on a different domain.
Quality Levels Selector
If your HLS stream has multiple quality levels (adaptive bitrate), expose them to the user:
hls.on(Hls.Events.MANIFEST_PARSED, function() {
var levels = hls.levels.map((l, i) =>
'<option value="' + i + '">' + l.height + 'p</option>'
).join('');
document.getElementById('quality-select-' + videoId).innerHTML = levels;
});
For a complete streaming application combining all these techniques, see the Yalla Shoot streaming guide and the live stream hub guide.
See it in practice
We applied these techniques to build the Yalla Shoot streaming app guide — a real-world ASP.NET web application serving live sports content.
View Yalla Shoot Technical Guide →