CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-video-js

An HTML5 video player that supports HLS and DASH with a common API and skin.

Pending
Overview
Eval results
Files

plugins.mddocs/

Plugin System

Video.js provides an extensible plugin architecture that allows developers to add custom functionality to players through both function-based and class-based plugins.

Capabilities

Plugin Registration

Register plugins with Video.js for use across all player instances or specific players.

/**
 * Register a plugin with Video.js
 * @param name - Plugin name (used to invoke plugin)
 * @param plugin - Plugin function or class
 * @returns Registered plugin
 */
videojs.registerPlugin<T = Plugin>(name: string, plugin: PluginFunction<T> | typeof Plugin): PluginFunction<T> | typeof Plugin;

/**
 * Remove registered plugin
 * @param name - Plugin name to deregister
 */
videojs.deregisterPlugin(name: string): void;

/**
 * Get registered plugin by name
 * @param name - Plugin name
 * @returns Plugin function or class
 */
videojs.getPlugin(name: string): PluginFunction | typeof Plugin | undefined;

/**
 * Get all registered plugins
 * @returns Object with all registered plugins
 */
videojs.getPlugins(): Record<string, PluginFunction | typeof Plugin>;

/**
 * Get version of registered plugin
 * @param name - Plugin name
 * @returns Plugin version string
 */
videojs.getPluginVersion(name: string): string;

Usage Examples:

// Register function-based plugin
videojs.registerPlugin('logger', function(options) {
  this.on('play', () => console.log('Player started'));
  this.on('pause', () => console.log('Player paused'));
});

// Register class-based plugin
class AnalyticsPlugin extends videojs.getComponent('Plugin') {
  constructor(player, options) {
    super(player, options);
    this.setupAnalytics();
  }
  
  setupAnalytics() {
    this.player.on('play', this.trackPlay.bind(this));
  }
  
  trackPlay() {
    // Send analytics event
  }
}

videojs.registerPlugin('analytics', AnalyticsPlugin);

// Use plugins
const player = videojs('my-video');
player.logger(); // Initialize logger plugin
player.analytics({ trackingId: 'UA-12345' }); // Initialize with options

Function-Based Plugins

Simple plugins that add functionality through functions attached to player instances.

/**
 * Function-based plugin signature
 * @param options - Plugin options passed during initialization
 */
type PluginFunction<T = any> = (this: Player, options?: T) => void;

Usage Examples:

// Simple function plugin
videojs.registerPlugin('skipIntro', function(options = {}) {
  const skipTime = options.skipTime || 10;
  
  // Add skip button
  const skipButton = this.addChild('button', {
    text: 'Skip Intro'
  });
  
  skipButton.on('click', () => {
    this.currentTime(skipTime);
    skipButton.hide();
  });
  
  // Auto-hide after intro
  this.on('timeupdate', () => {
    if (this.currentTime() > skipTime) {
      skipButton.hide();
    }
  });
});

// Use the plugin
player.skipIntro({ skipTime: 15 });

Class-Based Plugins

Advanced plugins using classes that extend the base Plugin class for complex functionality.

/**
 * Base Plugin class for class-based plugins
 */
class Plugin {
  /**
   * Create plugin instance
   * @param player - Player instance
   * @param options - Plugin options
   */
  constructor(player: Player, options?: object);
  
  /**
   * Associated player instance
   */
  readonly player: Player;
  
  /**
   * Plugin options
   */
  readonly options: object;
  
  /**
   * Dispose plugin and clean up resources
   */
  dispose(): void;
  
  /**
   * Check if plugin has been disposed
   * @returns True if disposed
   */
  isDisposed(): boolean;
  
  /**
   * Execute callback when plugin is ready
   * @param callback - Function to call when ready
   */
  ready(callback: () => void): void;
}

Usage Examples:

// Advanced class-based plugin
class PlaylistPlugin extends videojs.getComponent('Plugin') {
  constructor(player, options) {
    super(player, options);
    
    this.playlist = options.playlist || [];
    this.currentIndex = 0;
    
    this.setupPlaylist();
  }
  
  setupPlaylist() {
    // Add playlist UI
    this.playlistMenu = this.player.addChild('MenuButton', {
      label: 'Playlist'
    });
    
    // Handle video end
    this.player.on('ended', this.playNext.bind(this));
    
    // Load first video
    if (this.playlist.length > 0) {
      this.loadVideo(0);
    }
  }
  
  loadVideo(index) {
    if (index >= 0 && index < this.playlist.length) {
      this.currentIndex = index;
      const video = this.playlist[index];
      this.player.src(video.src);
      this.player.poster(video.poster);
    }
  }
  
  playNext() {
    const nextIndex = (this.currentIndex + 1) % this.playlist.length;
    this.loadVideo(nextIndex);
    this.player.play();
  }
  
  playPrevious() {
    const prevIndex = this.currentIndex === 0 
      ? this.playlist.length - 1 
      : this.currentIndex - 1;
    this.loadVideo(prevIndex);
    this.player.play();
  }
  
  dispose() {
    this.playlistMenu.dispose();
    super.dispose();
  }
}

// Register and use
videojs.registerPlugin('playlist', PlaylistPlugin);

const player = videojs('my-video');
player.playlist({
  playlist: [
    { src: 'video1.mp4', poster: 'poster1.jpg', title: 'Video 1' },
    { src: 'video2.mp4', poster: 'poster2.jpg', title: 'Video 2' }
  ]
});

Plugin State Management

Plugins have built-in state management and lifecycle hooks.

/**
 * Get plugin state for a player
 * @param player - Player instance
 * @param name - Plugin name
 * @returns Plugin state object
 */
videojs.getPluginState(player: Player, name: string): PluginState;

/**
 * Set plugin state for a player
 * @param player - Player instance  
 * @param name - Plugin name
 * @param state - State to set
 */
videojs.setPluginState(player: Player, name: string, state: PluginState): void;

Plugin Options and Configuration

Plugins can accept configuration options and provide default values.

// Plugin with default options
videojs.registerPlugin('customPlayer', function(options) {
  const settings = videojs.obj.merge({
    theme: 'default',
    showProgress: true,
    autoHide: 3000
  }, options);
  
  // Apply theme
  this.addClass(`vjs-theme-${settings.theme}`);
  
  // Configure progress bar
  if (!settings.showProgress) {
    this.getChild('ControlBar').getChild('ProgressControl').hide();
  }
  
  // Auto-hide controls
  let hideTimeout;
  this.on('mousemove', () => {
    this.removeClass('vjs-user-inactive');
    clearTimeout(hideTimeout);
    hideTimeout = setTimeout(() => {
      this.addClass('vjs-user-inactive');
    }, settings.autoHide);
  });
});

Plugin Inheritance

Plugins can extend other plugins to build upon existing functionality.

// Base analytics plugin
class BaseAnalytics extends videojs.getComponent('Plugin') {
  constructor(player, options) {
    super(player, options);
    this.events = [];
  }
  
  track(event, data) {
    this.events.push({ event, data, timestamp: Date.now() });
    console.log('Tracking:', event, data);
  }
}

// Google Analytics plugin extending base
class GoogleAnalytics extends BaseAnalytics {
  constructor(player, options) {
    super(player, options);
    this.trackingId = options.trackingId;
    this.setupGA();
  }
  
  setupGA() {
    // Initialize Google Analytics
    this.player.on('play', () => this.track('video_play'));
    this.player.on('pause', () => this.track('video_pause'));
    this.player.on('ended', () => this.track('video_complete'));
  }
  
  track(event, data) {
    super.track(event, data);
    // Send to Google Analytics
    if (window.gtag) {
      window.gtag('event', event, {
        video_title: this.player.poster() || 'Unknown',
        ...data
      });
    }
  }
}

videojs.registerPlugin('googleAnalytics', GoogleAnalytics);

Legacy Plugin Support

Video.js maintains backward compatibility with older plugin patterns.

/**
 * Legacy plugin registration method (deprecated)
 * @param name - Plugin name
 * @param plugin - Plugin function or class
 * @returns Registered plugin
 * @deprecated Use videojs.registerPlugin() instead
 */
videojs.plugin(name: string, plugin: PluginFunction | typeof Plugin): PluginFunction | typeof Plugin;

Types

interface Plugin {
  player: Player;
  options: object;
  dispose(): void;
  isDisposed(): boolean;
  ready(callback: () => void): void;
}

type PluginFunction<T = any> = (this: Player, options?: T) => void;

interface PluginState {
  [key: string]: any;
}

interface PluginOptions {
  [key: string]: any;
}

// Plugin lifecycle hooks
interface PluginLifecycle {
  beforePluginSetup?: (player: Player, options: object) => void;
  afterPluginSetup?: (player: Player, plugin: Plugin) => void;
}

Install with Tessl CLI

npx tessl i tessl/npm-video-js

docs

components.md

events.md

index.md

player.md

plugins.md

tech.md

tracks.md

utilities.md

tile.json