0
# Plugin System
1
2
Video.js provides an extensible plugin architecture that allows developers to add custom functionality to players through both function-based and class-based plugins.
3
4
## Capabilities
5
6
### Plugin Registration
7
8
Register plugins with Video.js for use across all player instances or specific players.
9
10
```javascript { .api }
11
/**
12
* Register a plugin with Video.js
13
* @param name - Plugin name (used to invoke plugin)
14
* @param plugin - Plugin function or class
15
* @returns Registered plugin
16
*/
17
videojs.registerPlugin<T = Plugin>(name: string, plugin: PluginFunction<T> | typeof Plugin): PluginFunction<T> | typeof Plugin;
18
19
/**
20
* Remove registered plugin
21
* @param name - Plugin name to deregister
22
*/
23
videojs.deregisterPlugin(name: string): void;
24
25
/**
26
* Get registered plugin by name
27
* @param name - Plugin name
28
* @returns Plugin function or class
29
*/
30
videojs.getPlugin(name: string): PluginFunction | typeof Plugin | undefined;
31
32
/**
33
* Get all registered plugins
34
* @returns Object with all registered plugins
35
*/
36
videojs.getPlugins(): Record<string, PluginFunction | typeof Plugin>;
37
38
/**
39
* Get version of registered plugin
40
* @param name - Plugin name
41
* @returns Plugin version string
42
*/
43
videojs.getPluginVersion(name: string): string;
44
```
45
46
**Usage Examples:**
47
48
```javascript
49
// Register function-based plugin
50
videojs.registerPlugin('logger', function(options) {
51
this.on('play', () => console.log('Player started'));
52
this.on('pause', () => console.log('Player paused'));
53
});
54
55
// Register class-based plugin
56
class AnalyticsPlugin extends videojs.getComponent('Plugin') {
57
constructor(player, options) {
58
super(player, options);
59
this.setupAnalytics();
60
}
61
62
setupAnalytics() {
63
this.player.on('play', this.trackPlay.bind(this));
64
}
65
66
trackPlay() {
67
// Send analytics event
68
}
69
}
70
71
videojs.registerPlugin('analytics', AnalyticsPlugin);
72
73
// Use plugins
74
const player = videojs('my-video');
75
player.logger(); // Initialize logger plugin
76
player.analytics({ trackingId: 'UA-12345' }); // Initialize with options
77
```
78
79
### Function-Based Plugins
80
81
Simple plugins that add functionality through functions attached to player instances.
82
83
```javascript { .api }
84
/**
85
* Function-based plugin signature
86
* @param options - Plugin options passed during initialization
87
*/
88
type PluginFunction<T = any> = (this: Player, options?: T) => void;
89
```
90
91
**Usage Examples:**
92
93
```javascript
94
// Simple function plugin
95
videojs.registerPlugin('skipIntro', function(options = {}) {
96
const skipTime = options.skipTime || 10;
97
98
// Add skip button
99
const skipButton = this.addChild('button', {
100
text: 'Skip Intro'
101
});
102
103
skipButton.on('click', () => {
104
this.currentTime(skipTime);
105
skipButton.hide();
106
});
107
108
// Auto-hide after intro
109
this.on('timeupdate', () => {
110
if (this.currentTime() > skipTime) {
111
skipButton.hide();
112
}
113
});
114
});
115
116
// Use the plugin
117
player.skipIntro({ skipTime: 15 });
118
```
119
120
### Class-Based Plugins
121
122
Advanced plugins using classes that extend the base Plugin class for complex functionality.
123
124
```javascript { .api }
125
/**
126
* Base Plugin class for class-based plugins
127
*/
128
class Plugin {
129
/**
130
* Create plugin instance
131
* @param player - Player instance
132
* @param options - Plugin options
133
*/
134
constructor(player: Player, options?: object);
135
136
/**
137
* Associated player instance
138
*/
139
readonly player: Player;
140
141
/**
142
* Plugin options
143
*/
144
readonly options: object;
145
146
/**
147
* Dispose plugin and clean up resources
148
*/
149
dispose(): void;
150
151
/**
152
* Check if plugin has been disposed
153
* @returns True if disposed
154
*/
155
isDisposed(): boolean;
156
157
/**
158
* Execute callback when plugin is ready
159
* @param callback - Function to call when ready
160
*/
161
ready(callback: () => void): void;
162
}
163
```
164
165
**Usage Examples:**
166
167
```javascript
168
// Advanced class-based plugin
169
class PlaylistPlugin extends videojs.getComponent('Plugin') {
170
constructor(player, options) {
171
super(player, options);
172
173
this.playlist = options.playlist || [];
174
this.currentIndex = 0;
175
176
this.setupPlaylist();
177
}
178
179
setupPlaylist() {
180
// Add playlist UI
181
this.playlistMenu = this.player.addChild('MenuButton', {
182
label: 'Playlist'
183
});
184
185
// Handle video end
186
this.player.on('ended', this.playNext.bind(this));
187
188
// Load first video
189
if (this.playlist.length > 0) {
190
this.loadVideo(0);
191
}
192
}
193
194
loadVideo(index) {
195
if (index >= 0 && index < this.playlist.length) {
196
this.currentIndex = index;
197
const video = this.playlist[index];
198
this.player.src(video.src);
199
this.player.poster(video.poster);
200
}
201
}
202
203
playNext() {
204
const nextIndex = (this.currentIndex + 1) % this.playlist.length;
205
this.loadVideo(nextIndex);
206
this.player.play();
207
}
208
209
playPrevious() {
210
const prevIndex = this.currentIndex === 0
211
? this.playlist.length - 1
212
: this.currentIndex - 1;
213
this.loadVideo(prevIndex);
214
this.player.play();
215
}
216
217
dispose() {
218
this.playlistMenu.dispose();
219
super.dispose();
220
}
221
}
222
223
// Register and use
224
videojs.registerPlugin('playlist', PlaylistPlugin);
225
226
const player = videojs('my-video');
227
player.playlist({
228
playlist: [
229
{ src: 'video1.mp4', poster: 'poster1.jpg', title: 'Video 1' },
230
{ src: 'video2.mp4', poster: 'poster2.jpg', title: 'Video 2' }
231
]
232
});
233
```
234
235
### Plugin State Management
236
237
Plugins have built-in state management and lifecycle hooks.
238
239
```javascript { .api }
240
/**
241
* Get plugin state for a player
242
* @param player - Player instance
243
* @param name - Plugin name
244
* @returns Plugin state object
245
*/
246
videojs.getPluginState(player: Player, name: string): PluginState;
247
248
/**
249
* Set plugin state for a player
250
* @param player - Player instance
251
* @param name - Plugin name
252
* @param state - State to set
253
*/
254
videojs.setPluginState(player: Player, name: string, state: PluginState): void;
255
```
256
257
### Plugin Options and Configuration
258
259
Plugins can accept configuration options and provide default values.
260
261
```javascript { .api }
262
// Plugin with default options
263
videojs.registerPlugin('customPlayer', function(options) {
264
const settings = videojs.obj.merge({
265
theme: 'default',
266
showProgress: true,
267
autoHide: 3000
268
}, options);
269
270
// Apply theme
271
this.addClass(`vjs-theme-${settings.theme}`);
272
273
// Configure progress bar
274
if (!settings.showProgress) {
275
this.getChild('ControlBar').getChild('ProgressControl').hide();
276
}
277
278
// Auto-hide controls
279
let hideTimeout;
280
this.on('mousemove', () => {
281
this.removeClass('vjs-user-inactive');
282
clearTimeout(hideTimeout);
283
hideTimeout = setTimeout(() => {
284
this.addClass('vjs-user-inactive');
285
}, settings.autoHide);
286
});
287
});
288
```
289
290
### Plugin Inheritance
291
292
Plugins can extend other plugins to build upon existing functionality.
293
294
```javascript { .api }
295
// Base analytics plugin
296
class BaseAnalytics extends videojs.getComponent('Plugin') {
297
constructor(player, options) {
298
super(player, options);
299
this.events = [];
300
}
301
302
track(event, data) {
303
this.events.push({ event, data, timestamp: Date.now() });
304
console.log('Tracking:', event, data);
305
}
306
}
307
308
// Google Analytics plugin extending base
309
class GoogleAnalytics extends BaseAnalytics {
310
constructor(player, options) {
311
super(player, options);
312
this.trackingId = options.trackingId;
313
this.setupGA();
314
}
315
316
setupGA() {
317
// Initialize Google Analytics
318
this.player.on('play', () => this.track('video_play'));
319
this.player.on('pause', () => this.track('video_pause'));
320
this.player.on('ended', () => this.track('video_complete'));
321
}
322
323
track(event, data) {
324
super.track(event, data);
325
// Send to Google Analytics
326
if (window.gtag) {
327
window.gtag('event', event, {
328
video_title: this.player.poster() || 'Unknown',
329
...data
330
});
331
}
332
}
333
}
334
335
videojs.registerPlugin('googleAnalytics', GoogleAnalytics);
336
```
337
338
### Legacy Plugin Support
339
340
Video.js maintains backward compatibility with older plugin patterns.
341
342
```javascript { .api }
343
/**
344
* Legacy plugin registration method (deprecated)
345
* @param name - Plugin name
346
* @param plugin - Plugin function or class
347
* @returns Registered plugin
348
* @deprecated Use videojs.registerPlugin() instead
349
*/
350
videojs.plugin(name: string, plugin: PluginFunction | typeof Plugin): PluginFunction | typeof Plugin;
351
```
352
353
## Types
354
355
```javascript { .api }
356
interface Plugin {
357
player: Player;
358
options: object;
359
dispose(): void;
360
isDisposed(): boolean;
361
ready(callback: () => void): void;
362
}
363
364
type PluginFunction<T = any> = (this: Player, options?: T) => void;
365
366
interface PluginState {
367
[key: string]: any;
368
}
369
370
interface PluginOptions {
371
[key: string]: any;
372
}
373
374
// Plugin lifecycle hooks
375
interface PluginLifecycle {
376
beforePluginSetup?: (player: Player, options: object) => void;
377
afterPluginSetup?: (player: Player, plugin: Plugin) => void;
378
}
379
```