An HTML5 video player that supports HLS and DASH with a common API and skin.
—
Video.js provides a comprehensive event system for handling media events, user interactions, and component communication, built on standard DOM events with additional Video.js-specific events.
Global event handling functions for managing events across Video.js components.
/**
* Add event listener to target
* @param target - Event target (element, component, or player)
* @param type - Event type or space-separated types
* @param listener - Event handler function
*/
videojs.on(target: EventTarget, type: string, listener: EventListener): void;
/**
* Add one-time event listener
* @param target - Event target
* @param type - Event type or space-separated types
* @param listener - Event handler function
*/
videojs.one(target: EventTarget, type: string, listener: EventListener): void;
/**
* Remove event listener
* @param target - Event target
* @param type - Event type or space-separated types
* @param listener - Specific handler to remove (optional)
*/
videojs.off(target: EventTarget, type?: string, listener?: EventListener): void;
/**
* Trigger event on target
* @param target - Event target
* @param event - Event type string or Event object
* @param data - Additional event data
*/
videojs.trigger(target: EventTarget, event: string | Event, data?: any): void;
/**
* Listen to event on multiple targets
* @param targets - Array of event targets
* @param type - Event type
* @param listener - Event handler function
*/
videojs.any(targets: EventTarget[], type: string, listener: EventListener): void;Usage Examples:
// Add event listeners
videojs.on(player, 'play', () => {
console.log('Player started playing');
});
// Multiple event types
videojs.on(player, 'play pause', (event) => {
console.log('Playback state changed:', event.type);
});
// One-time listener
videojs.one(player, 'loadedmetadata', () => {
console.log('Metadata loaded - fires once');
});
// Remove listeners
videojs.off(player, 'play'); // Remove all play listeners
videojs.off(player); // Remove all listeners
// Trigger custom events
videojs.trigger(player, 'customEvent', { data: 'value' });
// Listen on multiple players
const players = [player1, player2, player3];
videojs.any(players, 'ended', () => {
console.log('One of the players finished');
});Core player instance methods for event handling.
/**
* Add event listener to player
* @param type - Event type or space-separated types
* @param listener - Event handler function
*/
on(type: string, listener: EventListener): void;
/**
* Add one-time event listener to player
* @param type - Event type or space-separated types
* @param listener - Event handler function
*/
one(type: string, listener: EventListener): void;
/**
* Remove event listener from player
* @param type - Event type or space-separated types
* @param listener - Specific handler to remove (optional)
*/
off(type?: string, listener?: EventListener): void;
/**
* Trigger event on player
* @param event - Event type string or Event object
* @param data - Additional event data
*/
trigger(event: string | Event, data?: any): void;Usage Examples:
// Player event listeners
player.on('play', function() {
console.log('Playing');
});
player.on('timeupdate', function() {
console.log('Current time:', this.currentTime());
});
// Context is the player
player.on('ended', function() {
console.log('Video ended, duration was:', this.duration());
});
// Event object contains additional info
player.on('error', function(event) {
console.error('Player error:', event.target.error());
});Standard HTML5 media events fired by the player during playback.
// Playback events
'loadstart' // Started loading media
'progress' // Downloading media data
'loadedmetadata' // Metadata loaded (duration, dimensions)
'loadeddata' // First frame loaded
'canplay' // Can start playing
'canplaythrough' // Can play without buffering
'playing' // Playback started after being paused
'waiting' // Waiting for data (buffering)
'seeking' // Seeking started
'seeked' // Seeking completed
'ended' // Playback completed
'durationchange' // Duration changed
'timeupdate' // Current time changed
'play' // Play() called
'pause' // Pause() called
'ratechange' // Playback rate changed
'resize' // Video dimensions changed
'volumechange' // Volume or muted state changed
// Loading events
'abort' // Loading aborted
'error' // Loading error occurred
'stalled' // Data loading stalled
'suspend' // Loading suspended
'emptied' // Media element emptied
// Text track events
'texttrackchange' // Text track mode changed
'cuechange' // Active cues changedUsage Examples:
// Track loading progress
player.on('loadstart', () => {
console.log('Started loading');
});
player.on('progress', () => {
const buffered = player.buffered();
if (buffered.length > 0) {
console.log('Buffered:', buffered.end(0), 'seconds');
}
});
player.on('canplay', () => {
console.log('Ready to play');
});
// Monitor playback
player.on('play', () => {
console.log('Playback started');
});
player.on('timeupdate', () => {
const currentTime = player.currentTime();
const duration = player.duration();
const progress = (currentTime / duration) * 100;
console.log('Progress:', progress.toFixed(1) + '%');
});
player.on('ended', () => {
console.log('Video finished');
});
// Handle errors
player.on('error', () => {
const error = player.error();
console.error('Playback error:', error.code, error.message);
});Events specific to UI components and user interactions.
// UI interaction events
'click' // Component clicked
'focus' // Component focused
'blur' // Component lost focus
'keydown' // Key pressed
'keyup' // Key released
'mouseenter' // Mouse entered component
'mouseleave' // Mouse left component
'touchstart' // Touch interaction started
'touchend' // Touch interaction ended
// Component lifecycle events
'componentresize' // Component resized
'ready' // Component ready
'dispose' // Component disposed
// Player-specific UI events
'userinactive' // User inactive (controls auto-hide)
'useractive' // User active (controls shown)
'fullscreenchange' // Fullscreen state changed
'enterFullWindow' // Entered full window mode
'exitFullWindow' // Exited full window modeUsage Examples:
// UI interaction handling
const playButton = player.getChild('ControlBar').getChild('PlayToggle');
playButton.on('click', () => {
console.log('Play button clicked');
});
// User activity monitoring
player.on('useractive', () => {
console.log('User is active - show controls');
});
player.on('userinactive', () => {
console.log('User inactive - hide controls');
});
// Fullscreen events
player.on('fullscreenchange', () => {
if (player.isFullscreen()) {
console.log('Entered fullscreen');
} else {
console.log('Exited fullscreen');
}
});
// Component resize
player.on('componentresize', () => {
console.log('Player resized to:', player.width(), 'x', player.height());
});Create and handle custom events for application-specific functionality.
// Trigger custom events with data
player.trigger('qualitychange', {
oldQuality: '720p',
newQuality: '1080p'
});
player.trigger('adstart', {
duration: 30,
skipTime: 5
});
// Listen for custom events
player.on('qualitychange', (event, data) => {
console.log('Quality changed from', data.oldQuality, 'to', data.newQuality);
});
player.on('adstart', (event, data) => {
console.log('Ad started, duration:', data.duration, 'seconds');
setTimeout(() => {
player.trigger('adskippable');
}, data.skipTime * 1000);
});Handle events from child components through event delegation.
// Listen for button clicks on control bar
const controlBar = player.getChild('ControlBar');
controlBar.on('click', function(event) {
const target = event.target;
console.log('Control bar button clicked:', target.className);
});
// Handle menu item selection
const menuButton = player.getChild('ControlBar').getChild('PlaybackRateMenuButton');
if (menuButton) {
menuButton.on('click', function(event) {
if (event.target.tagName === 'LI') {
console.log('Playback rate selected:', event.target.textContent);
}
});
}Access event information and maintain proper context in event handlers.
// Event handler context
player.on('play', function(event) {
// 'this' refers to the player
console.log('Player ID:', this.id());
console.log('Current source:', this.currentSrc());
// Event object properties
console.log('Event type:', event.type);
console.log('Event target:', event.target);
console.log('Timestamp:', event.timeStamp);
});
// Arrow functions don't bind 'this'
player.on('pause', (event) => {
// Use event.target or direct player reference
console.log('Paused at:', event.target.currentTime());
console.log('Paused at:', player.currentTime());
});
// Event with custom data
player.on('customEvent', function(event, data) {
console.log('Custom event data:', data);
console.log('Player state:', this.paused() ? 'paused' : 'playing');
});Comprehensive error handling with detailed error information.
// Media errors
player.on('error', function() {
const error = this.error();
switch (error.code) {
case 1: // MEDIA_ERR_ABORTED
console.log('Media loading aborted');
break;
case 2: // MEDIA_ERR_NETWORK
console.log('Network error');
break;
case 3: // MEDIA_ERR_DECODE
console.log('Media decode error');
break;
case 4: // MEDIA_ERR_SRC_NOT_SUPPORTED
console.log('Media format not supported');
break;
default:
console.log('Unknown error:', error.message);
}
});
// Custom error handling
player.on('networkerror', function(event, data) {
console.log('Network error details:', data);
// Implement retry logic or fallback source
});Use events to monitor player performance and user engagement.
// Track loading performance
let loadStartTime;
player.on('loadstart', () => {
loadStartTime = Date.now();
});
player.on('canplay', () => {
const loadTime = Date.now() - loadStartTime;
console.log('Load time:', loadTime, 'ms');
});
// Track user engagement
let watchTime = 0;
let lastTime = 0;
player.on('play', () => {
lastTime = player.currentTime();
});
player.on('timeupdate', () => {
if (!player.paused()) {
const currentTime = player.currentTime();
watchTime += Math.max(0, currentTime - lastTime);
lastTime = currentTime;
}
});
player.on('pause ended', () => {
console.log('Total watch time:', watchTime, 'seconds');
});interface EventListener {
(event: Event, ...args: any[]): void;
}
interface Event {
type: string;
target: EventTarget;
currentTarget: EventTarget;
timeStamp: number;
preventDefault(): void;
stopPropagation(): void;
stopImmediatePropagation(): void;
}
interface EventTarget {
addEventListener(type: string, listener: EventListener): void;
removeEventListener(type: string, listener: EventListener): void;
dispatchEvent(event: Event): boolean;
}
// Media error codes
interface MediaError {
code: number;
message: string;
MEDIA_ERR_ABORTED: 1;
MEDIA_ERR_NETWORK: 2;
MEDIA_ERR_DECODE: 3;
MEDIA_ERR_SRC_NOT_SUPPORTED: 4;
}
// Common event types
type MediaEventType =
| 'loadstart' | 'progress' | 'loadedmetadata' | 'loadeddata'
| 'canplay' | 'canplaythrough' | 'playing' | 'waiting'
| 'seeking' | 'seeked' | 'ended' | 'durationchange'
| 'timeupdate' | 'play' | 'pause' | 'ratechange'
| 'resize' | 'volumechange' | 'abort' | 'error'
| 'stalled' | 'suspend' | 'emptied';
type PlayerEventType = MediaEventType
| 'ready' | 'dispose' | 'useractive' | 'userinactive'
| 'fullscreenchange' | 'componentresize';
type ComponentEventType =
| 'click' | 'focus' | 'blur' | 'keydown' | 'keyup'
| 'mouseenter' | 'mouseleave' | 'touchstart' | 'touchend';Install with Tessl CLI
npx tessl i tessl/npm-video-js