0
# Track Management
1
2
Video.js provides comprehensive track management for video, audio, and text tracks with full accessibility support and standardized APIs following HTML5 specifications.
3
4
## Capabilities
5
6
### Text Tracks
7
8
Manage subtitles, captions, descriptions, chapters, and metadata tracks.
9
10
```javascript { .api }
11
/**
12
* Text track for subtitles, captions, descriptions, chapters, and metadata
13
*/
14
class TextTrack {
15
/**
16
* Text track kind
17
*/
18
readonly kind: TextTrackKind;
19
20
/**
21
* Text track label
22
*/
23
readonly label: string;
24
25
/**
26
* Text track language code
27
*/
28
readonly language: string;
29
30
/**
31
* Text track display mode
32
*/
33
mode: TextTrackMode;
34
35
/**
36
* List of track cues
37
*/
38
readonly cues: TextTrackCueList;
39
40
/**
41
* Active cues at current playback time
42
*/
43
readonly activeCues: TextTrackCueList;
44
45
/**
46
* Add cue to track
47
* @param cue - Cue to add
48
*/
49
addCue(cue: VTTCue): void;
50
51
/**
52
* Remove cue from track
53
* @param cue - Cue to remove
54
*/
55
removeCue(cue: VTTCue): void;
56
}
57
58
/**
59
* List of text tracks
60
*/
61
class TextTrackList {
62
/**
63
* Number of tracks
64
*/
65
readonly length: number;
66
67
/**
68
* Get track by index
69
* @param index - Track index
70
* @returns Text track
71
*/
72
[index: number]: TextTrack;
73
74
/**
75
* Get track by ID
76
* @param id - Track ID
77
* @returns Text track or null
78
*/
79
getTrackById(id: string): TextTrack | null;
80
}
81
```
82
83
**Usage Examples:**
84
85
```javascript
86
// Access text tracks
87
const textTracks = player.textTracks();
88
console.log('Number of text tracks:', textTracks.length);
89
90
// Find subtitle track
91
for (let i = 0; i < textTracks.length; i++) {
92
const track = textTracks[i];
93
if (track.kind === 'subtitles' && track.language === 'en') {
94
track.mode = 'showing'; // Show English subtitles
95
break;
96
}
97
}
98
99
// Add programmatic text track
100
const track = player.addTextTrack('subtitles', 'English', 'en');
101
track.addCue(new VTTCue(0, 5, 'Hello World'));
102
track.addCue(new VTTCue(5, 10, 'This is a subtitle'));
103
track.mode = 'showing';
104
105
// Listen for cue changes
106
track.addEventListener('cuechange', () => {
107
const activeCues = track.activeCues;
108
if (activeCues.length > 0) {
109
console.log('Active cue:', activeCues[0].text);
110
}
111
});
112
```
113
114
### Audio Tracks
115
116
Manage multiple audio tracks for language selection and audio descriptions.
117
118
```javascript { .api }
119
/**
120
* Audio track representation
121
*/
122
class AudioTrack {
123
/**
124
* Unique track identifier
125
*/
126
readonly id: string;
127
128
/**
129
* Track kind (main, alternative, commentary, etc.)
130
*/
131
readonly kind: string;
132
133
/**
134
* Human-readable track label
135
*/
136
readonly label: string;
137
138
/**
139
* Track language code
140
*/
141
readonly language: string;
142
143
/**
144
* Whether track is enabled (only one can be enabled at a time)
145
*/
146
enabled: boolean;
147
}
148
149
/**
150
* List of audio tracks
151
*/
152
class AudioTrackList {
153
/**
154
* Number of tracks
155
*/
156
readonly length: number;
157
158
/**
159
* Get track by index
160
* @param index - Track index
161
* @returns Audio track
162
*/
163
[index: number]: AudioTrack;
164
165
/**
166
* Get track by ID
167
* @param id - Track ID
168
* @returns Audio track or null
169
*/
170
getTrackById(id: string): AudioTrack | null;
171
}
172
```
173
174
**Usage Examples:**
175
176
```javascript
177
// Access audio tracks
178
const audioTracks = player.audioTracks();
179
console.log('Available audio tracks:', audioTracks.length);
180
181
// Switch to Spanish audio
182
for (let i = 0; i < audioTracks.length; i++) {
183
const track = audioTracks[i];
184
if (track.language === 'es') {
185
track.enabled = true; // Enable Spanish audio
186
} else {
187
track.enabled = false; // Disable other audio tracks
188
}
189
}
190
191
// Listen for audio track changes
192
audioTracks.addEventListener('change', () => {
193
const enabledTrack = Array.from(audioTracks).find(track => track.enabled);
194
console.log('Audio track changed to:', enabledTrack?.label);
195
});
196
```
197
198
### Video Tracks
199
200
Manage multiple video tracks for different camera angles or video qualities.
201
202
```javascript { .api }
203
/**
204
* Video track representation
205
*/
206
class VideoTrack {
207
/**
208
* Unique track identifier
209
*/
210
readonly id: string;
211
212
/**
213
* Track kind (main, alternative, sign, etc.)
214
*/
215
readonly kind: string;
216
217
/**
218
* Human-readable track label
219
*/
220
readonly label: string;
221
222
/**
223
* Track language code
224
*/
225
readonly language: string;
226
227
/**
228
* Whether track is selected (only one can be selected at a time)
229
*/
230
selected: boolean;
231
}
232
233
/**
234
* List of video tracks
235
*/
236
class VideoTrackList {
237
/**
238
* Number of tracks
239
*/
240
readonly length: number;
241
242
/**
243
* Get track by index
244
* @param index - Track index
245
* @returns Video track
246
*/
247
[index: number]: VideoTrack;
248
249
/**
250
* Get track by ID
251
* @param id - Track ID
252
* @returns Video track or null
253
*/
254
getTrackById(id: string): VideoTrack | null;
255
256
/**
257
* Get currently selected track
258
* @returns Selected video track or null
259
*/
260
getSelectedTrack(): VideoTrack | null;
261
}
262
```
263
264
**Usage Examples:**
265
266
```javascript
267
// Access video tracks
268
const videoTracks = player.videoTracks();
269
270
// Switch to alternate camera angle
271
for (let i = 0; i < videoTracks.length; i++) {
272
const track = videoTracks[i];
273
if (track.kind === 'alternative' && track.label.includes('Angle 2')) {
274
track.selected = true; // Select alternate angle
275
} else {
276
track.selected = false; // Deselect other tracks
277
}
278
}
279
280
// Get currently selected track
281
const selectedTrack = videoTracks.getSelectedTrack();
282
console.log('Current video track:', selectedTrack?.label);
283
```
284
285
### Player Track Methods
286
287
Player-level methods for managing tracks.
288
289
```javascript { .api }
290
/**
291
* Get text tracks list
292
* @returns Text tracks list
293
*/
294
textTracks(): TextTrackList;
295
296
/**
297
* Get audio tracks list
298
* @returns Audio tracks list
299
*/
300
audioTracks(): AudioTrackList;
301
302
/**
303
* Get video tracks list
304
* @returns Video tracks list
305
*/
306
videoTracks(): VideoTrackList;
307
308
/**
309
* Add text track programmatically
310
* @param kind - Track kind
311
* @param label - Track label
312
* @param language - Language code
313
* @returns Created text track
314
*/
315
addTextTrack(kind: TextTrackKind, label?: string, language?: string): TextTrack;
316
317
/**
318
* Add remote text track from URL
319
* @param options - Track options including src URL
320
* @param manualCleanup - Whether to handle cleanup manually
321
* @returns HTML track element
322
*/
323
addRemoteTextTrack(options: RemoteTextTrackOptions, manualCleanup?: boolean): HTMLTrackElement;
324
325
/**
326
* Remove remote text track
327
* @param track - Track or track element to remove
328
*/
329
removeRemoteTextTrack(track: TextTrack | HTMLTrackElement): void;
330
```
331
332
### Text Track Cues
333
334
Manage individual cues within text tracks.
335
336
```javascript { .api }
337
/**
338
* VTT cue representing timed text
339
*/
340
class VTTCue {
341
/**
342
* Create VTT cue
343
* @param startTime - Start time in seconds
344
* @param endTime - End time in seconds
345
* @param text - Cue text content
346
*/
347
constructor(startTime: number, endTime: number, text: string);
348
349
/**
350
* Cue start time in seconds
351
*/
352
startTime: number;
353
354
/**
355
* Cue end time in seconds
356
*/
357
endTime: number;
358
359
/**
360
* Cue text content
361
*/
362
text: string;
363
364
/**
365
* Cue identifier
366
*/
367
id: string;
368
369
/**
370
* Cue positioning and styling
371
*/
372
position: number;
373
line: number;
374
size: number;
375
align: string;
376
vertical: string;
377
}
378
379
/**
380
* List of cues
381
*/
382
class TextTrackCueList {
383
/**
384
* Number of cues
385
*/
386
readonly length: number;
387
388
/**
389
* Get cue by index
390
* @param index - Cue index
391
* @returns VTT cue
392
*/
393
[index: number]: VTTCue;
394
395
/**
396
* Get cue by ID
397
* @param id - Cue ID
398
* @returns VTT cue or null
399
*/
400
getCueById(id: string): VTTCue | null;
401
}
402
```
403
404
**Usage Examples:**
405
406
```javascript
407
// Create cues with styling
408
const cue1 = new VTTCue(0, 3, 'Welcome to our video');
409
cue1.line = 1;
410
cue1.position = 50;
411
cue1.align = 'center';
412
413
const cue2 = new VTTCue(3, 6, '<c.highlight>Important information</c>');
414
cue2.line = -1; // Bottom line
415
416
// Add to track
417
const track = player.addTextTrack('captions', 'English Captions', 'en');
418
track.addCue(cue1);
419
track.addCue(cue2);
420
track.mode = 'showing';
421
```
422
423
### Remote Text Tracks
424
425
Load text tracks from external files.
426
427
```javascript { .api }
428
// Add remote text track
429
const trackElement = player.addRemoteTextTrack({
430
kind: 'subtitles',
431
src: 'path/to/subtitles.vtt',
432
srclang: 'en',
433
label: 'English Subtitles',
434
default: true
435
});
436
437
// Access the track
438
const track = trackElement.track;
439
track.addEventListener('load', () => {
440
console.log('Track loaded with', track.cues.length, 'cues');
441
});
442
443
// Remove when done
444
player.removeRemoteTextTrack(trackElement);
445
```
446
447
### Track Events
448
449
Text tracks support various events for monitoring state changes.
450
451
```javascript { .api }
452
// Track list events
453
textTracks.addEventListener('addtrack', (event) => {
454
console.log('Track added:', event.track);
455
});
456
457
textTracks.addEventListener('removetrack', (event) => {
458
console.log('Track removed:', event.track);
459
});
460
461
textTracks.addEventListener('change', () => {
462
console.log('Track modes changed');
463
});
464
465
// Individual track events
466
track.addEventListener('cuechange', () => {
467
const activeCues = track.activeCues;
468
for (let i = 0; i < activeCues.length; i++) {
469
console.log('Active cue:', activeCues[i].text);
470
}
471
});
472
473
track.addEventListener('load', () => {
474
console.log('Track cues loaded');
475
});
476
477
track.addEventListener('error', (event) => {
478
console.error('Track error:', event);
479
});
480
```
481
482
### Accessibility Features
483
484
Video.js provides built-in accessibility support for text tracks.
485
486
```javascript { .api }
487
// Configure accessibility options
488
const player = videojs('my-video', {
489
tracks: [
490
{
491
kind: 'captions',
492
src: 'captions.vtt',
493
srclang: 'en',
494
label: 'English Captions',
495
default: true
496
},
497
{
498
kind: 'descriptions',
499
src: 'descriptions.vtt',
500
srclang: 'en',
501
label: 'Audio Descriptions'
502
}
503
]
504
});
505
506
// Enable keyboard navigation for tracks
507
player.ready(() => {
508
// Tracks menu is automatically accessible via keyboard
509
const trackMenuButton = player.getChild('ControlBar').getChild('SubtitlesButton');
510
if (trackMenuButton) {
511
trackMenuButton.focus(); // Can be focused with keyboard
512
}
513
});
514
```
515
516
## Types
517
518
```javascript { .api }
519
type TextTrackKind = 'subtitles' | 'captions' | 'descriptions' | 'chapters' | 'metadata';
520
type TextTrackMode = 'disabled' | 'hidden' | 'showing';
521
522
interface RemoteTextTrackOptions {
523
kind: TextTrackKind;
524
src: string;
525
srclang?: string;
526
label?: string;
527
default?: boolean;
528
}
529
530
interface TextTrackOptions {
531
kind: TextTrackKind;
532
src?: string;
533
srclang?: string;
534
label?: string;
535
default?: boolean;
536
[key: string]: any;
537
}
538
539
interface TextTrack {
540
kind: TextTrackKind;
541
label: string;
542
language: string;
543
mode: TextTrackMode;
544
cues: TextTrackCueList;
545
activeCues: TextTrackCueList;
546
addCue(cue: VTTCue): void;
547
removeCue(cue: VTTCue): void;
548
}
549
550
interface AudioTrack {
551
id: string;
552
kind: string;
553
label: string;
554
language: string;
555
enabled: boolean;
556
}
557
558
interface VideoTrack {
559
id: string;
560
kind: string;
561
label: string;
562
language: string;
563
selected: boolean;
564
}
565
566
interface VTTCue {
567
startTime: number;
568
endTime: number;
569
text: string;
570
id: string;
571
position: number;
572
line: number;
573
size: number;
574
align: string;
575
vertical: string;
576
}
577
```