HLS.js provides comprehensive live streaming support with DVR functionality, low-latency modes, and advanced latency control.
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());
}
});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;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);
}
}
});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
});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);
}
});
});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);
}
});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;
}