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

live-streaming.mddocs/

Live Streaming & Low Latency

HLS.js provides comprehensive live streaming support with DVR functionality, low-latency modes, and advanced latency control.

Capabilities

Live Stream Detection

Automatically detect and handle live streams.

interface Hls {
  /** Current live sync position in seconds (read-only) */
  readonly liveSyncPosition: number | null;
  
  /** Current program date and time (read-only) */
  readonly playingDate: Date | null;
}

Usage Examples:

const hls = new Hls();

hls.on(Hls.Events.MANIFEST_PARSED, (event, data) => {
  if (data.live) {
    console.log("Live stream detected");
    console.log("Live sync position:", hls.liveSyncPosition);
  } else {
    console.log("VOD stream detected");
  }
});

// Monitor current program date/time
hls.on(Hls.Events.FRAG_CHANGED, () => {
  if (hls.playingDate) {
    console.log("Current program time:", hls.playingDate.toISOString());
  }
});

Latency Management

Monitor and control playback latency for live streams.

interface Hls {
  /** Current estimated latency in seconds (read-only) */
  readonly latency: number;
  
  /** Maximum observed latency (read-only) */
  readonly maxLatency: number;
  
  /** Target latency for live streams */
  targetLatency: number | null;
  
  /** Live edge drift rate (read-only) */
  readonly drift: number | null;
  
  /** Enable low-latency mode */
  lowLatencyMode: boolean;
}

Usage Examples:

const hls = new Hls({
  // Enable low-latency features
  lowLatencyMode: true,
  // Target 3 seconds of latency
  liveMaxLatencyDuration: 3,
  // Enable live back-buffer management
  liveBackBufferLength: 10
});

// Monitor latency
hls.on(Hls.Events.FRAG_LOADED, () => {
  console.log("Current latency:", hls.latency, "seconds");
  console.log("Max latency:", hls.maxLatency, "seconds");
  console.log("Drift rate:", hls.drift);
});

// Adjust target latency dynamically
hls.targetLatency = 2; // Target 2 seconds

// Enable/disable low-latency mode
hls.lowLatencyMode = true;

DVR Functionality

Support for seeking in live streams with DVR capability.

// Check if DVR is available
hls.on(Hls.Events.LEVEL_LOADED, (event, data) => {
  const levelDetails = data.details;
  if (levelDetails.live) {
    const dvrWindow = levelDetails.totalduration;
    console.log("DVR window:", dvrWindow, "seconds");
    
    // Seek to earlier point in live stream
    if (hls.media && dvrWindow > 0) {
      const seekTarget = hls.media.currentTime - 30; // 30 seconds back
      hls.media.currentTime = Math.max(seekTarget, 0);
    }
  }
});

Live Configuration Options

Configure live streaming behavior through HlsConfig.

interface HlsConfig {
  /** Enable low-latency mode */
  lowLatencyMode: boolean;
  
  /** Maximum latency before correcting */
  liveMaxLatencyDuration: number;
  
  /** Target latency for live streams */
  liveTargetLatencyDuration: number | null;
  
  /** Back buffer length for live streams */
  liveBackBufferLength: number;
  
  /** Sync duration count */
  liveSyncDurationCount: number;
  
  /** Enable live sync on stall */
  liveSyncOnStall: boolean;
  
  /** Playlist reload interval for live */
  manifestLoadingRetryDelay: number;
  
  /** Enable partial segment loading */
  enablePartialLoad: boolean;
}

Usage Example:

const hls = new Hls({
  // Low-latency configuration
  lowLatencyMode: true,
  liveMaxLatencyDuration: 3,
  liveTargetLatencyDuration: 1.5,
  liveBackBufferLength: 10,
  liveSyncDurationCount: 3,
  liveSyncOnStall: true,
  
  // Aggressive loading for low latency
  enablePartialLoad: true,
  maxBufferLength: 10,
  maxMaxBufferLength: 20
});

Live Events

Events specific to live stream handling.

// Live sync events
hls.on(Hls.Events.LIVE_BACK_BUFFER_REACHED, (event, data: {
  bufferEnd: number
}) => {
  // Called when live back buffer limit is reached
  console.log("Live back buffer reached at:", data.bufferEnd);
});

// Level updates for live streams
hls.on(Hls.Events.LEVEL_UPDATED, (event, data: {
  level: number,
  details: LevelDetails
}) => {
  // Called when live playlist is refreshed
  console.log("Live playlist updated for level:", data.level);
});

// Program date time events
hls.on(Hls.Events.FRAG_PARSING_METADATA, (event, data: {
  id: string,
  samples: any[]
}) => {
  // Called when parsing timed metadata (ID3 tags)
  data.samples.forEach(sample => {
    if (sample.type === "PRIV") {
      console.log("Program date metadata:", sample.data);
    }
  });
});

Low-Latency Features

Advanced features for ultra-low latency streaming.

// Enable chunked transfer encoding
const hls = new Hls({
  enablePartialLoad: true,
  enableChunkedTransfer: true,
  
  // Reduce buffering for low latency
  maxBufferLength: 4,
  maxBufferSize: 4 * 1000 * 1000,
  
  // Faster manifest refreshes
  manifestLoadingRetryDelay: 500,
  
  // Reduce fragment loading timeout
  fragLoadingTimeOut: 2000
});

// Monitor partial segments
hls.on(Hls.Events.FRAG_LOADING, (event, data) => {
  if (data.part) {
    console.log("Loading partial segment:", data.part.index);
  }
});

Types

interface LevelDetails {
  /** Whether this is a live stream */
  readonly live: boolean;
  
  /** Total duration available for DVR */
  readonly totalduration: number;
  
  /** Target duration for segments */
  readonly targetduration: number;
  
  /** Playlist sequence numbers */
  readonly startSN: number;
  readonly endSN: number;
  
  /** Program date time */
  readonly programDateTime: number | null;
  
  /** Whether playlist has ended (#EXT-X-ENDLIST) */
  readonly endlist: boolean;
  
  /** Partial segments (low-latency) */
  readonly partList: Part[] | null;
}

interface Part {
  /** Part index within segment */
  readonly index: number;
  
  /** Part duration in seconds */
  readonly duration: number;
  
  /** Part URL */
  readonly url: string;
  
  /** Byte range for partial loading */
  readonly byteRange: ByteRange | null;
  
  /** Whether part is independent */
  readonly independent: boolean;
}

interface ByteRange {
  /** Byte offset */
  readonly offset: number;
  
  /** Byte length */
  readonly length: number;
}