or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

advanced.mdbrowser-support.mdcore-player.mderror-handling.mdevents.mdindex.mdlive-streaming.mdquality-control.mdtracks.md
tile.json

browser-support.mddocs/

Browser Support Detection

HLS.js provides utilities for detecting browser capabilities and MediaSource Extensions support to ensure compatibility before initializing playback.

Capabilities

Support Detection Functions

Check browser compatibility and feature support.

/**
 * Check complete HLS.js support including MSE and codec support
 * @returns true if HLS.js is fully supported
 */
function isSupported(): boolean;

/**
 * Check MediaSource Extensions support
 * @returns true if MSE is available
 */
function isMSESupported(): boolean;

/**
 * Get MediaSource constructor if available
 * @returns MediaSource constructor or undefined
 */
function getMediaSource(): typeof MediaSource | undefined;

Usage Examples:

import Hls, { isSupported, isMSESupported, getMediaSource } from "hls.js";

// Check full HLS.js support
if (isSupported()) {
  console.log("HLS.js is fully supported");
  const hls = new Hls();
  // Use HLS.js for playback
} else {
  console.log("HLS.js not supported, check for native support");
  
  // Check for native HLS support (Safari)
  const video = document.createElement("video");
  if (video.canPlayType("application/vnd.apple.mpegurl")) {
    console.log("Native HLS support available");
    video.src = "https://example.com/stream.m3u8";
  } else {
    console.error("No HLS support available");
  }
}

// Check MSE support specifically
if (isMSESupported()) {
  console.log("MediaSource Extensions supported");
} else {
  console.log("MSE not supported");
}

// Get MediaSource constructor
const MediaSourceClass = getMediaSource();
if (MediaSourceClass) {
  console.log("MediaSource available:", MediaSourceClass.isTypeSupported("video/mp4"));
}

Static Support Methods

Access support detection through the Hls class.

declare class Hls {
  /**
   * Check complete HLS.js support
   * @returns true if fully supported
   */
  static isSupported(): boolean;
  
  /**
   * Check MediaSource Extensions support
   * @returns true if MSE is available
   */
  static isMSESupported(): boolean;
  
  /**
   * Get MediaSource constructor
   * @returns MediaSource constructor or undefined
   */
  static getMediaSource(): typeof MediaSource | undefined;
}

Usage Examples:

// Using static methods
if (Hls.isSupported()) {
  const hls = new Hls();
  // Initialize HLS.js
} else if (Hls.isMSESupported()) {
  console.log("MSE available but HLS.js not fully supported");
} else {
  console.log("No MSE support");
}

// Check MediaSource capabilities
const MediaSource = Hls.getMediaSource();
if (MediaSource) {
  console.log("MP4 support:", MediaSource.isTypeSupported('video/mp4; codecs="avc1.42E01E,mp4a.40.2"'));
  console.log("WebM support:", MediaSource.isTypeSupported('video/webm; codecs="vp9,opus"'));
}

Codec Support Detection

Check support for specific codecs and formats.

// Check codec support through MediaSource
function checkCodecSupport(): void {
  const MediaSource = getMediaSource();
  if (!MediaSource) return;
  
  // Common HLS codecs
  const codecs = [
    'video/mp4; codecs="avc1.42E01E,mp4a.40.2"', // H.264 + AAC
    'video/mp4; codecs="avc1.4d401f,mp4a.40.2"', // H.264 Main + AAC
    'video/mp4; codecs="hev1.1.6.L93.B0,mp4a.40.2"', // H.265 + AAC
    'audio/mp4; codecs="mp4a.40.2"', // AAC audio
    'audio/mpeg' // MP3 audio
  ];
  
  codecs.forEach(codec => {
    console.log(`${codec}: ${MediaSource.isTypeSupported(codec)}`);
  });
}

Feature Detection

Check for additional browser features used by HLS.js.

/**
 * Check if Fetch API is supported for loading
 * @returns true if fetch is available
 */
function fetchSupported(): boolean;

Usage Examples:

import { fetchSupported } from "hls.js";

// Check loader support
if (fetchSupported()) {
  console.log("Fetch API available - will use FetchLoader");
} else {
  console.log("Fetch API not available - will use XhrLoader");
}

// Configure loader preference
const hls = new Hls({
  // Force specific loader
  loader: fetchSupported() ? FetchLoader : XhrLoader
});

Progressive Enhancement

Implement progressive enhancement based on capabilities.

function setupVideoPlayer(videoElement: HTMLVideoElement, manifestUrl: string): void {
  if (Hls.isSupported()) {
    // Use HLS.js with full features
    const hls = new Hls({
      // Enable advanced features for supported browsers
      enableWorker: true,
      enableSoftwareAES: true,
      lowLatencyMode: true
    });
    
    hls.attachMedia(videoElement);
    hls.loadSource(manifestUrl);
    
    console.log("Using HLS.js with advanced features");
    
  } else if (videoElement.canPlayType("application/vnd.apple.mpegurl")) {
    // Native HLS support (Safari)
    videoElement.src = manifestUrl;
    console.log("Using native HLS support");
    
  } else {
    // No HLS support - show error or fallback
    console.error("HLS not supported");
    videoElement.innerHTML = `
      <p>Your browser does not support HLS video playback.</p>
      <p>Please use a modern browser or try a different video format.</p>
    `;
  }
}

Browser-Specific Handling

Handle browser-specific behaviors and limitations.

function getBrowserCapabilities(): {
  hasNativeHLS: boolean;
  hasMSE: boolean;
  hasWorkerSupport: boolean;
  hasWasm: boolean;
} {
  const video = document.createElement("video");
  
  return {
    hasNativeHLS: video.canPlayType("application/vnd.apple.mpegurl") !== "",
    hasMSE: isMSESupported(),
    hasWorkerSupport: typeof Worker !== "undefined",
    hasWasm: typeof WebAssembly !== "undefined"
  };
}

// Use capabilities for configuration
const capabilities = getBrowserCapabilities();
const hls = new Hls({
  enableWorker: capabilities.hasWorkerSupport,
  enableSoftwareAES: !capabilities.hasWasm, // Use SW AES if no WASM
  
  // Safari-specific adjustments
  ...(capabilities.hasNativeHLS && {
    manifestLoadingTimeOut: 30000,
    fragLoadingTimeOut: 60000
  })
});

Error Handling for Unsupported Features

Handle graceful degradation when features aren't supported.

function createHlsWithFallbacks(config?: Partial<HlsConfig>): Hls | null {
  if (!isSupported()) {
    console.warn("HLS.js not supported");
    return null;
  }
  
  const capabilities = getBrowserCapabilities();
  
  const safeConfig: Partial<HlsConfig> = {
    ...config,
    
    // Disable features that may not be supported
    enableWorker: capabilities.hasWorkerSupport && (config?.enableWorker ?? true),
    enableSoftwareAES: config?.enableSoftwareAES ?? true,
    
    // Conservative settings for older browsers
    maxBufferLength: capabilities.hasMSE ? (config?.maxBufferLength ?? 30) : 10,
    maxBufferSize: capabilities.hasMSE ? (config?.maxBufferSize ?? 60 * 1000 * 1000) : 10 * 1000 * 1000
  };
  
  try {
    return new Hls(safeConfig);
  } catch (error) {
    console.error("Failed to create HLS instance:", error);
    return null;
  }
}

Compatibility Information

Supported Browsers

HLS.js supports modern browsers with MediaSource Extensions:

  • Chrome: 23+
  • Firefox: 42+
  • Safari: 8+ (with MSE, native HLS preferred)
  • Edge: 12+
  • Internet Explorer: 11+ (with polyfills)
  • Mobile Safari: iOS 17.1+ (MSE), all versions (native HLS)
  • Chrome Mobile: 25+

Required Features

  • MediaSource Extensions (MSE)
  • Typed Arrays
  • Web Workers (optional, for performance)
  • WebAssembly (optional, for encryption)

Optional Enhancements

  • Fetch API (preferred over XMLHttpRequest)
  • WebAssembly (for hardware-accelerated decryption)
  • Intersection Observer (for viewport-based optimizations)
  • Media Capabilities API (for codec support detection)

Types

interface MediaCapabilitiesInfo {
  supported: boolean;
  smooth: boolean;
  powerEfficient: boolean;
}

interface MediaDecodingConfiguration {
  type: "media-source" | "file";
  video?: VideoConfiguration;
  audio?: AudioConfiguration;
}

interface VideoConfiguration {
  contentType: string;
  width: number;
  height: number;
  bitrate: number;
  framerate: number;
}

interface AudioConfiguration {
  contentType: string;
  channels?: string;
  bitrate?: number;
  samplerate?: number;
}