Part 9 · Applications

hls.js: HLS engine, not a complete branded player

Learn to: initialize one HLS engine with fallback, failure reporting and cleanup.

Prerequisites: 03-adaptive-streaming

HLS scheduling pipeline

Conceptual controller flow. Actual loading and buffering are asynchronous; ABR influences requests across the pipeline.
Conceptual controller flow. Actual loading and buffering are asynchronous; ABR influences requests across the pipeline. [S21] [S22] [S23]

On a narrow screen, swipe the diagram horizontally to keep its labels readable.

Architecture verified

hls.js loads HLS and uses browser media capabilities for playback. Its controllers handle loading, stream processing and buffering. Transmuxing reorganizes encoded data for the playback path; it does not transcode an unsupported codec into a supported one.

[S21] [S22]

Minimal mounting pattern synthesis

// Illustrative JS module; src must be a real HLS manifest URL.
import Hls from "hls.js";
export function mountHls(video, src, onFailure) {
  if (video.canPlayType("application/vnd.apple.mpegurl")) {
    const onError = () => onFailure(video.error);
    video.addEventListener("error", onError);
    video.src = src;
    return () => {
      video.removeEventListener("error", onError);
      video.pause(); video.removeAttribute("src"); video.load();
    };
  }
  if (!Hls.isSupported()) {
    onFailure(new Error("HLS is unsupported")); return () => {};
  }
  const hls = new Hls();
  hls.on(Hls.Events.ERROR, (_, detail) => {
    if (detail.fatal) onFailure(detail);
  });
  hls.attachMedia(video); hls.loadSource(src);
  return () => hls.destroy();
}
[S21] [S23]

Decision and trade-off synthesis

Choose this engine when you need direct HLS diagnostics and can supply the UI. Native-first is the sample’s policy, not a universal rule: choosing MSE can expose additional engine control at the cost of another code path. Test the target browser/codec combination.

[S21] [S23]

Pitfall → improvement synthesis

CORS must work for all HLS resources, not just the playlist. A fatal error needs a bounded, classified recovery policy; endless retries hide expired authorization. Add metrics and cleanup before advanced ABR tuning.

[S21] [S23]
Keep this: Own initialization, fallback, cleanup and error reporting when using a low-level engine.
Check yourself: Can transmuxing repair a codec unsupported by the browser?

No. Packaging can change while the encoded video codec stays the same; the browser must still be able to decode it.

Sources & further reading

  1. [S21] HLS.js README

    HLS.js maintainers · official documentation · accessed 2026-10-10 · current docs

    Supports: MSE-based HLS, native fallback, browser codec constraints and CORS on all HLS resources.

    Read this page to inspect the API and assumptions behind the cited explanation.

  2. [S22] HLS.js design

    HLS.js maintainers · official documentation · accessed 2026-10-10 · current docs

    Supports: Loading, stream control, demux/transmux and buffer architecture.

    Read this page to inspect the API and assumptions behind the cited explanation.

  3. [S23] Hls class API

    HLS.js maintainers · official documentation · accessed 2026-10-10 · current docs

    Supports: One media element per Hls instance, destroy, level caps, buffer and bandwidth introspection.

    Read this page to inspect the API and assumptions behind the cited explanation.