CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-hls-js

JavaScript HLS client using MediaSourceExtension for smooth video stream playback

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

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;
}

docs

advanced.md

browser-support.md

core-player.md

error-handling.md

events.md

index.md

live-streaming.md

quality-control.md

tracks.md

tile.json