JavaScript HLS client using MediaSourceExtension for smooth video stream playback
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
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;
}