HLS.js provides a comprehensive event system for monitoring playback state, handling errors, and responding to stream changes.
Add, remove, and manage event listeners.
interface HlsEventEmitter {
/**
* Add an event listener
* @param event - Event name
* @param listener - Event handler function
* @param context - Optional context for the listener
*/
on<E extends keyof HlsListeners>(
event: E,
listener: HlsListeners[E],
context?: any
): void;
/**
* Add a one-time event listener
* @param event - Event name
* @param listener - Event handler function
* @param context - Optional context for the listener
*/
once<E extends keyof HlsListeners>(
event: E,
listener: HlsListeners[E],
context?: any
): void;
/**
* Remove event listener(s)
* @param event - Event name
* @param listener - Specific listener to remove (optional)
* @param context - Context to match (optional)
*/
off<E extends keyof HlsListeners>(
event: E,
listener?: HlsListeners[E],
context?: any
): void;
/**
* Remove all listeners for an event or all events
* @param event - Event name (optional, removes all if not specified)
*/
removeAllListeners<E extends keyof HlsListeners>(event?: E): void;
/**
* Emit an event
* @param event - Event name
* @param name - Event name (duplicate for consistency)
* @param eventObject - Event data
*/
emit<E extends keyof HlsListeners>(
event: E,
name: E,
eventObject: Parameters<HlsListeners[E]>[1]
): boolean;
/**
* Get all listeners for an event
* @param event - Event name
*/
listeners<E extends keyof HlsListeners>(event: E): HlsListeners[E][];
/**
* Get listener count for an event
* @param event - Event name
*/
listenerCount<E extends keyof HlsListeners>(event: E): number;
}Usage Examples:
const hls = new Hls();
// Add event listeners
hls.on(Hls.Events.MANIFEST_LOADED, (event, data) => {
console.log("Manifest loaded:", data.url);
});
// One-time listener
hls.once(Hls.Events.FIRST_FRAG_CHANGED, (event, data) => {
console.log("First fragment changed:", data.frag.url);
});
// Remove specific listener
const errorHandler = (event, data) => {
console.error("HLS Error:", data);
};
hls.on(Hls.Events.ERROR, errorHandler);
hls.off(Hls.Events.ERROR, errorHandler);
// Remove all error listeners
hls.removeAllListeners(Hls.Events.ERROR);
// Check listener count
console.log("Error listeners:", hls.listenerCount(Hls.Events.ERROR));All events available in HLS.js for comprehensive monitoring.
enum Events {
// Media lifecycle events
MEDIA_ATTACHING = "hlsMediaAttaching",
MEDIA_ATTACHED = "hlsMediaAttached",
MEDIA_DETACHING = "hlsMediaDetaching",
MEDIA_DETACHED = "hlsMediaDetached",
MEDIA_ENDED = "hlsMediaEnded",
// Stall and buffer events
STALL_RESOLVED = "hlsStallResolved",
BUFFER_RESET = "hlsBufferReset",
BUFFER_CODECS = "hlsBufferCodecs",
BUFFER_CREATED = "hlsBufferCreated",
BUFFER_APPENDING = "hlsBufferAppending",
BUFFER_APPENDED = "hlsBufferAppended",
BUFFER_EOS = "hlsBufferEos",
BUFFERED_TO_END = "hlsBufferedToEnd",
BUFFER_FLUSHING = "hlsBufferFlushing",
BUFFER_FLUSHED = "hlsBufferFlushed",
// Manifest events
MANIFEST_LOADING = "hlsManifestLoading",
MANIFEST_LOADED = "hlsManifestLoaded",
MANIFEST_PARSED = "hlsManifestParsed",
// Level/quality events
LEVEL_SWITCHING = "hlsLevelSwitching",
LEVEL_SWITCHED = "hlsLevelSwitched",
LEVEL_LOADING = "hlsLevelLoading",
LEVEL_LOADED = "hlsLevelLoaded",
LEVEL_UPDATED = "hlsLevelUpdated",
LEVEL_PTS_UPDATED = "hlsLevelPtsUpdated",
LEVELS_UPDATED = "hlsLevelsUpdated",
MAX_AUTO_LEVEL_UPDATED = "hlsMaxAutoLevelUpdated",
// Audio track events
AUDIO_TRACKS_UPDATED = "hlsAudioTracksUpdated",
AUDIO_TRACK_SWITCHING = "hlsAudioTrackSwitching",
AUDIO_TRACK_SWITCHED = "hlsAudioTrackSwitched",
AUDIO_TRACK_LOADING = "hlsAudioTrackLoading",
AUDIO_TRACK_LOADED = "hlsAudioTrackLoaded",
AUDIO_TRACK_UPDATED = "hlsAudioTrackUpdated",
// Subtitle track events
SUBTITLE_TRACKS_UPDATED = "hlsSubtitleTracksUpdated",
SUBTITLE_TRACKS_CLEARED = "hlsSubtitleTracksCleared",
SUBTITLE_TRACK_SWITCH = "hlsSubtitleTrackSwitch",
SUBTITLE_TRACK_LOADING = "hlsSubtitleTrackLoading",
SUBTITLE_TRACK_LOADED = "hlsSubtitleTrackLoaded",
SUBTITLE_TRACK_UPDATED = "hlsSubtitleTrackUpdated",
SUBTITLE_FRAG_PROCESSED = "hlsSubtitleFragProcessed",
// Cue and text track events
CUES_PARSED = "hlsCuesParsed",
NON_NATIVE_TEXT_TRACKS_FOUND = "hlsNonNativeTextTracksFound",
// Fragment events
INIT_PTS_FOUND = "hlsInitPtsFound",
FRAG_LOADING = "hlsFragLoading",
FRAG_LOAD_EMERGENCY_ABORTED = "hlsFragLoadEmergencyAborted",
FRAG_LOADED = "hlsFragLoaded",
FRAG_DECRYPTED = "hlsFragDecrypted",
FRAG_PARSING_INIT_SEGMENT = "hlsFragParsingInitSegment",
FRAG_PARSING_USERDATA = "hlsFragParsingUserdata",
FRAG_PARSING_METADATA = "hlsFragParsingMetadata",
FRAG_PARSED = "hlsFragParsed",
FRAG_BUFFERED = "hlsFragBuffered",
FRAG_CHANGED = "hlsFragChanged",
// Performance events
FPS_DROP = "hlsFpsDrop",
FPS_DROP_LEVEL_CAPPING = "hlsFpsDropLevelCapping",
// Encryption key events
KEY_LOADING = "hlsKeyLoading",
KEY_LOADED = "hlsKeyLoaded",
// Back buffer events
LIVE_BACK_BUFFER_REACHED = "hlsLiveBackBufferReached", // deprecated
BACK_BUFFER_REACHED = "hlsBackBufferReached",
// Content steering events
STEERING_MANIFEST_LOADED = "hlsSteeringManifestLoaded",
// Interstitial events (ads/mid-rolls)
ASSET_LIST_LOADING = "hlsAssetListLoading",
ASSET_LIST_LOADED = "hlsAssetListLoaded",
INTERSTITIALS_UPDATED = "hlsInterstitialsUpdated",
INTERSTITIALS_BUFFERED_TO_BOUNDARY = "hlsInterstitialsBufferedToBoundary",
INTERSTITIAL_ASSET_PLAYER_CREATED = "hlsInterstitialAssetPlayerCreated",
INTERSTITIAL_STARTED = "hlsInterstitialStarted",
INTERSTITIAL_ASSET_STARTED = "hlsInterstitialAssetStarted",
INTERSTITIAL_ASSET_ENDED = "hlsInterstitialAssetEnded",
INTERSTITIAL_ASSET_ERROR = "hlsInterstitialAssetError",
INTERSTITIAL_ENDED = "hlsInterstitialEnded",
INTERSTITIALS_PRIMARY_RESUMED = "hlsInterstitialsPrimaryResumed",
PLAYOUT_LIMIT_REACHED = "hlsPlayoutLimitReached",
// Special events
EVENT_CUE_ENTER = "hlsEventCueEnter",
ERROR = "hlsError",
DESTROYING = "hlsDestroying"
}Usage Examples:
const hls = new Hls();
// Media attachment
hls.on(Hls.Events.MEDIA_ATTACHED, () => {
console.log("Media element attached");
});
// Manifest parsing
hls.on(Hls.Events.MANIFEST_PARSED, (event, data) => {
console.log(`Manifest parsed with ${data.levels.length} levels`);
console.log(`Audio tracks: ${data.audioTracks.length}`);
console.log(`Subtitle tracks: ${data.subtitleTracks.length}`);
});
// Quality level changes
hls.on(Hls.Events.LEVEL_SWITCHED, (event, data) => {
const level = hls.levels[data.level];
console.log(`Switched to ${level.width}x${level.height} @ ${level.bitrate}bps`);
});
// Fragment loading
hls.on(Hls.Events.FRAG_LOADED, (event, data) => {
console.log(`Fragment loaded: ${data.frag.url}`);
console.log(`Load time: ${data.stats.loading.end - data.stats.loading.start}ms`);
});Events related to buffer management and operations.
enum Events {
BUFFER_APPENDING = "hlsBufferAppending",
BUFFER_APPENDED = "hlsBufferAppended",
BUFFER_EOS = "hlsBufferEos",
BUFFER_FLUSHING = "hlsBufferFlushing",
BUFFER_FLUSHED = "hlsBufferFlushed",
BUFFER_RESET = "hlsBufferReset",
BUFFER_CODECS = "hlsBufferCodecs"
}Usage Examples:
// Monitor buffer operations
hls.on(Hls.Events.BUFFER_APPENDING, (event, data) => {
console.log(`Appending ${data.type} buffer`);
});
hls.on(Hls.Events.BUFFER_APPENDED, (event, data) => {
console.log(`${data.type} buffer appended`);
});
hls.on(Hls.Events.BUFFER_FLUSHED, (event, data) => {
console.log(`Buffer flushed from ${data.startOffset} to ${data.endOffset}`);
});Events for audio and subtitle track management.
enum Events {
// Audio tracks
AUDIO_TRACKS_UPDATED = "hlsAudioTracksUpdated",
AUDIO_TRACK_SWITCHING = "hlsAudioTrackSwitching",
AUDIO_TRACK_SWITCHED = "hlsAudioTrackSwitched",
AUDIO_TRACK_LOADING = "hlsAudioTrackLoading",
AUDIO_TRACK_LOADED = "hlsAudioTrackLoaded",
// Subtitle tracks
SUBTITLE_TRACKS_UPDATED = "hlsSubtitleTracksUpdated",
SUBTITLE_TRACK_SWITCH = "hlsSubtitleTrackSwitch",
SUBTITLE_TRACK_LOADING = "hlsSubtitleTrackLoading",
SUBTITLE_TRACK_LOADED = "hlsSubtitleTrackLoaded",
CUES_PARSED = "hlsCuesParsed"
}Usage Examples:
// Audio track events
hls.on(Hls.Events.AUDIO_TRACKS_UPDATED, (event, data) => {
console.log("Audio tracks updated:", data.audioTracks.length);
});
hls.on(Hls.Events.AUDIO_TRACK_SWITCHED, (event, data) => {
const track = hls.audioTracks[data.id];
console.log(`Audio switched to: ${track?.name} (${track?.lang})`);
});
// Subtitle events
hls.on(Hls.Events.CUES_PARSED, (event, data) => {
console.log(`${data.cues.length} subtitle cues parsed`);
});Events for advanced features and debugging.
enum Events {
// Fragment parsing
FRAG_PARSING_INIT_SEGMENT = "hlsFragParsingInitSegment",
FRAG_PARSING_USERDATA = "hlsFragParsingUserdata",
FRAG_PARSING_METADATA = "hlsFragParsingMetadata",
// Init segment
INIT_PTS_FOUND = "hlsInitPtsFound",
// Key loading
KEY_LOADING = "hlsKeyLoading",
KEY_LOADED = "hlsKeyLoaded",
// FPS monitoring
FPS_DROP = "hlsFpsDrop",
FPS_DROP_LEVEL_CAPPING = "hlsFpsDropLevelCapping",
// DRM
KEY_SYSTEM_STATUS_CHANGED = "hlsKeySystemStatusChanged",
// Steering
STEERING_MANIFEST_LOADED = "hlsSteeringManifestLoaded"
}Usage Examples:
// Monitor FPS drops
hls.on(Hls.Events.FPS_DROP, (event, data) => {
console.log(`FPS drop detected: ${data.currentDropped}/${data.currentDecoded}`);
});
// Key loading for encrypted content
hls.on(Hls.Events.KEY_LOADED, (event, data) => {
console.log("Decryption key loaded for:", data.frag.url);
});
// Metadata parsing
hls.on(Hls.Events.FRAG_PARSING_METADATA, (event, data) => {
console.log("Metadata samples:", data.samples.length);
});interface ManifestParsedData {
levels: Level[];
audioTracks: MediaPlaylist[];
subtitleTracks: MediaPlaylist[];
sessionData: any[];
sessionKeys: any[];
firstLevel: number;
stats: LoadStats;
audio: boolean;
video: boolean;
altAudio: boolean;
}
interface LevelSwitchingData {
level: number;
attrs: AttrList;
url: string;
bitrate: number;
width: number;
height: number;
codecSet: string;
}
interface FragLoadedData {
frag: Fragment;
payload: ArrayBuffer;
stats: LoadStats;
networkDetails?: any;
}
interface ErrorData {
type: ErrorTypes;
details: ErrorDetails;
fatal: boolean;
reason?: string;
level?: number;
frag?: Fragment;
url?: string;
response?: Response;
context?: any;
}
interface BufferAppendedData {
type: string;
frag: Fragment;
part?: Part;
chunkMeta: ChunkMetadata;
parent: string;
timeRanges: {
video?: TimeRanges;
audio?: TimeRanges;
audiovideo?: TimeRanges;
};
}