Testing

HLS: Browser Support, Codecs, Known Issues

HLS works in Safari, Chrome 142+ and Edge 142+ on desktop, Chrome for Android 147+, Firefox for Android 150+, Samsung Internet, and Opera Mobile 80+. Learn HLS browser support and quirks.

Author

Prince Dewani

May 1, 2026

HLS, or HTTP Live Streaming, is an adaptive bitrate protocol that Apple developed and the IETF standardized as RFC 8216. It works in Safari, Chrome 142+ and Edge 142+ on desktop, Chrome for Android 147+, Firefox for Android 150+, Samsung Internet, and Opera Mobile 80+, while desktop Firefox and Internet Explorer never added support.

This guide covers what HLS is, the browsers that support it, key features, how to play HLS without native support, use cases, and known issues.

What is HLS?

HLS, short for HTTP Live Streaming, is an adaptive bitrate streaming protocol Apple created for delivering audio and video over standard HTTP. The IETF standardized it as RFC 8216, and the protocol uses .m3u8 manifest files that point to short MPEG-TS or fragmented MP4 segments encoded at multiple bitrates.

Which browsers does HLS support?

Safari and every iOS browser support HLS natively across all modern versions. Chrome 142+, Edge 142+, Chrome for Android 147+, Firefox for Android 150+, Samsung Internet, and Opera Mobile 80+ also play HLS through a native demuxer, while desktop Firefox, desktop Opera, and Internet Explorer require hls.js with Media Source Extensions or do not support HLS at all.

Loading browser compatibility data...

HLS compatibility in Chrome

Desktop Chrome supports HLS natively from Chrome 142 on Windows, macOS, Linux, and ChromeOS through a Chromium HLS demuxer. Chrome 4 to 141 on desktop did not play .m3u8 URLs without hls.js or a third-party extension. Chrome for Android added native HLS from Chrome 147; earlier Android Chrome relied on the OS media stack on a per-device basis.

HLS compatibility in Edge

Microsoft Edge Legacy 12 to 18 supported HLS through the Windows Media Foundation pipeline. Chromium-based Edge 79 to 141 dropped that path and did not play HLS natively. From Edge 142 on, the browser inherits Chromium's HLS demuxer, so HLS works out of the box on Windows 10 and Windows 11.

HLS compatibility in Firefox

Desktop Firefox does not support HLS natively in any version. Firefox for Android added native HLS playback from Firefox 150 and uses the OS media decoder pipeline. To play HLS in desktop Firefox, load hls.js with Media Source Extensions; Firefox supports the MSE 'video/MP4' MIME type from Firefox 42 on.

HLS compatibility in Safari

Safari for macOS supports HLS from Safari 6 on, and Safari for iOS from version 3.2 on. Apple created the protocol, so both desktop and mobile Safari can play HLS through the standard video element with no extra library. Safari is also the only major desktop browser that supports Apple's Low-Latency HLS extension end-to-end.

HLS compatibility in Opera

Opera desktop does not support HLS natively across versions 9 to 131. Opera Mobile added native HLS playback from Opera Mobile 80 on Android, and Opera Mini does not support HLS at all because the browser routes traffic through Opera's compression proxy. For desktop Opera, use hls.js with Media Source Extensions.

HLS compatibility in Samsung Internet

Samsung Internet supports HLS natively from version 4 through the current 29, using the Android media framework on Samsung Galaxy devices. The browser also handles Apple's fragmented MP4 segments, so DRM-free HLS streams play in the standard video element without any extra library.

HLS compatibility in Android Browser

The stock Android Browser supported HLS in versions 3.0 to 4.4.4, then dropped support before the modern Android Browser entry returned to version 147 with native HLS. Most Android handsets now ship Chrome for Android, which has native HLS from Chrome 147 on. Android WebView inherits the same Chromium HLS pipeline.

HLS compatibility in Internet Explorer

Internet Explorer 5.5 to 11 never supported HLS natively. Microsoft has retired Internet Explorer, and the browser also lacks Media Source Extensions, so hls.js cannot fill the gap either. Sites that still receive IE traffic must redirect those visitors to Microsoft Edge or fall back to a non-HLS format.

Note

Note: HLS support is splintered across desktop Firefox, older Chromium, Internet Explorer, and Opera. Test it on real browsers and OS with TestMu AI. Try TestMu AI free!

What are the key features of HLS?

HLS combines adaptive bitrate switching, HTTP-only delivery, and standard MPEG containers, which lets the same stream reach desktop browsers, phones, smart TVs, and CDNs without a special server. Six features carry most of the protocol's reach.

  • Adaptive bitrate streaming: The master playlist points to multiple variant streams encoded at different resolutions and bitrates. The player picks a variant based on bandwidth and switches between them mid-playback when the network changes.
  • .m3u8 playlist manifests: HLS uses the Extended M3U format, served with the application/vnd.apple.mpegurl MIME type. The master playlist lists variants; each variant playlist lists the segments in order.
  • Segment containers: HLS originally shipped MPEG-2 Transport Stream (.ts) segments. The protocol now also supports fragmented MP4 (.m4s, .mp4) segments, which is what Apple uses for HEVC, AV1, and Low-Latency HLS streams.
  • Codec coverage: HLS supports H.264, HEVC, and AV1 for video, and AAC, MP3, AC-3, and EAC-3 for audio. Apple's authoring spec also defines Dolby Atmos, Dolby Vision, and HDR10 carriage in fMP4 segments.
  • DRM and encryption: HLS supports AES-128 segment encryption, SAMPLE-AES, and Apple's FairPlay Streaming for premium content. Common Encryption (CMAF CBCS) lets the same fMP4 segments serve both HLS-FairPlay and DASH-Widevine players.
  • Live and on-demand: The same playlist format covers live broadcasts, video-on-demand, and DVR windows. Apple's Low-Latency HLS extension shrinks glass-to-glass delay to about 2 seconds with partial segments and HTTP/2 push.

How do you play HLS in browsers without native support?

Use hls.js, a JavaScript library that parses .m3u8 playlists, transmuxes MPEG-TS to fragmented MP4, and pushes the bytes through Media Source Extensions into a standard video element. The same page can target Safari and Chrome 142+ natively, then fall back to hls.js for desktop Firefox and older Chromium.

  • Add hls.js to your page: Pull it from a CDN with a script tag, or install it through npm and import the default export from your bundler.
  • Add a video element: Drop a standard HTML video tag with an id attribute and any controls or autoplay attributes you need. hls.js attaches to that element and feeds it through MSE.
  • Feature-detect native support first: Check video.canPlayType('application/vnd.apple.mpegurl'). If the browser returns 'probably' or 'maybe', set the video src directly to the .m3u8 URL and skip hls.js.
  • Fall back to hls.js when native is missing: If Hls.isSupported() returns true, create a new Hls() instance, call hls.loadSource(streamUrl), then hls.attachMedia(video). hls.js handles the rest.
  • Listen for MANIFEST_PARSED and ERROR events: Call video.play() inside the MANIFEST_PARSED handler so playback only starts after the manifest is ready. Log fatal errors from the ERROR event to diagnose 404s, codec mismatches, or CORS failures.
  • Verify in DevTools: Open the Network panel and filter for .m3u8 and .ts (or .m4s) requests. A working stream shows the master playlist, one variant playlist, and an ongoing series of segment requests.
// hls.js feature-detect and attach pattern.
// Drop this into a page that loads hls.js from a CDN or your bundler.

const video = document.querySelector("#player");
const streamUrl = "https://example.com/master.m3u8";

if (video.canPlayType("application/vnd.apple.mpegurl")) {
    // Safari, Chrome 142+, Edge 142+, iOS, Chrome for Android.
    // The browser ships its own HLS demuxer, so set the src directly.
    video.src = streamUrl;
} else if (window.Hls && Hls.isSupported()) {
    // Desktop Firefox, older Chromium, desktop Opera.
    // hls.js parses the playlist, transmuxes MPEG-TS to fMP4, feeds MSE.
    const hls = new Hls();
    hls.loadSource(streamUrl);
    hls.attachMedia(video);
    hls.on(Hls.Events.MANIFEST_PARSED, () => {
        console.log("HLS manifest parsed, ready for playback");
    });
    hls.on(Hls.Events.ERROR, (event, data) => {
        if (data.fatal) console.warn("HLS fatal error:", data.type, data.details);
    });
} else {
    console.warn("This browser cannot play HLS, even with hls.js.");
}

If the video element fires no progress events, check that the server returns the playlist with the application/vnd.apple.mpegurl MIME type and that the segment responses include CORS headers when the player and the stream sit on different origins.

...

What are the use cases of HLS?

HLS is the default streaming protocol for most consumer video on the web. The protocol's HTTP-only delivery model makes it easy to cache through any CDN, which is why every major streaming platform ships HLS as a primary or fallback format.

  • Live broadcasting: News, sports, and concert streams use HLS for the same reason CDNs do, since each segment is a static HTTP file. Twitch, YouTube Live, and most pay-TV streaming services ship HLS to web and mobile players.
  • Video on demand: Netflix, Disney+, Hulu, and Apple TV+ all ship HLS to Safari and iOS, often alongside DASH for non-Apple platforms. The same fMP4 segments serve both protocols when sites use CMAF.
  • Mobile app video: Apple's App Store guidelines require HLS for any streaming video over cellular longer than 10 minutes, which makes HLS the default in any iOS app that ships video.
  • User-generated video: Platforms like Vimeo, Wistia, and Mux package uploads as HLS so the same asset adapts to any device. Adaptive bitrate matters most on phones with patchy 4G or 5G coverage.
  • Low-latency live commerce and sports: Apple's Low-Latency HLS extension drops delay to about 2 seconds, which is good enough for live shopping, betting, and most live sports broadcasts that previously needed proprietary protocols.
  • Smart TV and OTT apps: tvOS, Roku, Fire TV, and the Tizen and webOS smart-TV stacks all ship native HLS players, so the same backend that feeds Safari can feed living-room devices.
...

What are the known issues with HLS?

HLS is mature and broadly deployed, but the protocol still has rough edges that affect production playback. Plan for these before you treat HLS as a finished problem.

  • Standard latency is high: Default HLS adds 6 to 30 seconds of glass-to-glass delay because each segment must finish encoding before the player can fetch it. Low-Latency HLS drops the floor to about 2 seconds, but only Safari ships full LL-HLS support across desktop and mobile today.
  • Cross-browser fragmentation: Native support arrived in Chrome and Edge only at version 142, and desktop Firefox still has none. A page that targets every browser must ship hls.js as a fallback and test the .m3u8 URL on at least Safari, Chrome, Edge, and Firefox.
  • Codec gaps between browsers: Safari plays HEVC HLS streams natively. Chrome and Edge can play HEVC only when the OS or hardware supports it. Firefox for Android often drops HEVC altogether, so authors usually ship an H.264 variant alongside HEVC for safety.
  • DRM is not portable: FairPlay Streaming protects HLS on Apple platforms, but every other platform needs Widevine (Chrome, Firefox, Edge) or PlayReady (older Edge, smart TVs). Sites that ship premium video must encode CMAF CBCS and run a multi-DRM license server.
  • Server pushes for LL-HLS need HTTP/2: Apple's Low-Latency HLS extension relies on HTTP/2 server push and partial segment delivery. CDNs that have not turned on HTTP/2 push or that strip preload hints will not deliver the latency the spec promises.
  • In my experience: the loudest HLS production issue is CORS plus the application/vnd.apple.mpegurl MIME type. A CDN that serves the playlist as text/plain or that omits Access-Control-Allow-Origin breaks playback on Safari and on hls.js the same way, even though the network tab shows a 200. Always test the playlist response headers, not just the segments, on a real browser.

Citations

All HLS version numbers and platform notes in this guide come from these primary sources:

Author

Prince Dewani is a Community Contributor at TestMu AI, where he manages content strategies around software testing, QA, and test automation. He is certified in Selenium, Cypress, Playwright, Appium, Automation Testing, and KaneAI. Prince has also presented academic research at the international conference PBCON-01. He further specializes in on-page SEO, bridging marketing with core testing technologies. On LinkedIn, he is followed by 4,300+ QA engineers, developers, DevOps experts, tech leaders, and AI-focused practitioners in the global testing community.

Open in ChatGPT Icon

Open in ChatGPT

Open in Claude Icon

Open in Claude

Open in Perplexity Icon

Open in Perplexity

Open in Grok Icon

Open in Grok

Open in Gemini AI Icon

Open in Gemini AI

Copied to Clipboard!
...

3000+ Browsers. One Platform.

See exactly how your site performs everywhere.

Try it free
...

Write Tests in Plain English with KaneAI

Create, debug, and evolve tests using natural language.

Try for free

Frequently asked questions

Did you find this page helpful?

More Related Hubs

TestMu AI forEnterprise

Get access to solutions built on Enterprise
grade security, privacy, & compliance

  • Advanced access controls
  • Advanced data retention rules
  • Advanced Local Testing
  • Premium Support options
  • Early access to beta features
  • Private Slack Channel
  • Unlimited Manual Accessibility DevTools Tests