@videojs/html 10.3.0 → 10.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (272) hide show
  1. package/dist/default/define/audio/compat-skin.css +91 -38
  2. package/dist/default/define/audio/compat-skin2.js +1 -1
  3. package/dist/default/define/audio/neutral-skin.css +52 -31
  4. package/dist/default/define/audio/neutral-skin2.js +1 -1
  5. package/dist/default/define/audio/scaffold-skin.css +105 -40
  6. package/dist/default/define/audio/scaffold-skin2.js +1 -1
  7. package/dist/default/define/audio/skin.css +53 -31
  8. package/dist/default/define/audio/skin2.js +1 -1
  9. package/dist/default/define/live-audio/compat-skin.css +91 -38
  10. package/dist/default/define/live-audio/compat-skin2.js +1 -1
  11. package/dist/default/define/live-audio/neutral-skin.css +50 -29
  12. package/dist/default/define/live-audio/neutral-skin2.js +1 -1
  13. package/dist/default/define/live-audio/scaffold-skin.css +105 -40
  14. package/dist/default/define/live-audio/scaffold-skin2.js +1 -1
  15. package/dist/default/define/live-audio/skin.css +51 -29
  16. package/dist/default/define/live-audio/skin2.js +1 -1
  17. package/dist/default/define/live-video/compat-skin.css +142 -61
  18. package/dist/default/define/live-video/compat-skin2.js +1 -1
  19. package/dist/default/define/live-video/neutral-skin.css +241 -55
  20. package/dist/default/define/live-video/neutral-skin2.js +1 -1
  21. package/dist/default/define/live-video/scaffold-skin.css +159 -63
  22. package/dist/default/define/live-video/scaffold-skin2.js +1 -1
  23. package/dist/default/define/live-video/skin.css +245 -60
  24. package/dist/default/define/live-video/skin2.js +1 -1
  25. package/dist/default/define/ui/time-slider-markers.js +5 -0
  26. package/dist/default/define/video/compat-skin.css +150 -61
  27. package/dist/default/define/video/compat-skin2.js +1 -1
  28. package/dist/default/define/video/neutral-skin.css +322 -66
  29. package/dist/default/define/video/neutral-skin2.js +1 -1
  30. package/dist/default/define/video/scaffold-skin.css +168 -63
  31. package/dist/default/define/video/scaffold-skin2.js +1 -1
  32. package/dist/default/define/video/skin.css +348 -66
  33. package/dist/default/define/video/skin2.js +1 -1
  34. package/dist/default/index.js +3 -1
  35. package/dist/default/internal/skins/compat-audio/skin.css +91 -38
  36. package/dist/default/internal/skins/compat-live-audio/skin.css +91 -38
  37. package/dist/default/internal/skins/compat-live-video/skin.css +142 -61
  38. package/dist/default/internal/skins/compat-live-video/template.js +2 -0
  39. package/dist/default/internal/skins/compat-video/skin.css +150 -61
  40. package/dist/default/internal/skins/compat-video/template.js +2 -0
  41. package/dist/default/internal/skins/default-audio/skin.css +53 -31
  42. package/dist/default/internal/skins/default-live-audio/skin.css +51 -29
  43. package/dist/default/internal/skins/default-live-video/skin.css +245 -60
  44. package/dist/default/internal/skins/default-live-video/template.js +14 -0
  45. package/dist/default/internal/skins/default-video/register.js +3 -0
  46. package/dist/default/internal/skins/default-video/skin.css +348 -66
  47. package/dist/default/internal/skins/default-video/template.js +33 -5
  48. package/dist/default/internal/skins/neutral-audio/skin.css +52 -31
  49. package/dist/default/internal/skins/neutral-live-audio/skin.css +50 -29
  50. package/dist/default/internal/skins/neutral-live-video/skin.css +241 -55
  51. package/dist/default/internal/skins/neutral-live-video/template.js +14 -0
  52. package/dist/default/internal/skins/neutral-video/skin.css +322 -66
  53. package/dist/default/internal/skins/neutral-video/template.js +25 -11
  54. package/dist/default/internal/skins/scaffold-audio/skin.css +105 -40
  55. package/dist/default/internal/skins/scaffold-live-audio/skin.css +105 -40
  56. package/dist/default/internal/skins/scaffold-live-video/skin.css +159 -63
  57. package/dist/default/internal/skins/scaffold-live-video/template.js +2 -0
  58. package/dist/default/internal/skins/scaffold-video/skin.css +168 -63
  59. package/dist/default/internal/skins/scaffold-video/template.js +3 -1
  60. package/dist/default/media/background-video/adapter.js +13 -35
  61. package/dist/default/media/background-video/base.js +95 -0
  62. package/dist/default/media/background-video/template.js +13 -20
  63. package/dist/default/media/hls-background-video/adapter.js +16 -35
  64. package/dist/default/ui/captions-radio-group/element.js +14 -1
  65. package/dist/default/ui/controls/element.js +6 -3
  66. package/dist/default/ui/time-slider/markers.js +160 -0
  67. package/dist/default/version.js +1 -1
  68. package/dist/dev/define/audio/compat-skin.css +91 -38
  69. package/dist/dev/define/audio/compat-skin2.js +1 -1
  70. package/dist/dev/define/audio/compat-skin2.js.map +1 -1
  71. package/dist/dev/define/audio/neutral-skin.css +52 -31
  72. package/dist/dev/define/audio/neutral-skin2.js +1 -1
  73. package/dist/dev/define/audio/neutral-skin2.js.map +1 -1
  74. package/dist/dev/define/audio/scaffold-skin.css +105 -40
  75. package/dist/dev/define/audio/scaffold-skin2.js +1 -1
  76. package/dist/dev/define/audio/scaffold-skin2.js.map +1 -1
  77. package/dist/dev/define/audio/skin.css +53 -31
  78. package/dist/dev/define/audio/skin2.js +1 -1
  79. package/dist/dev/define/audio/skin2.js.map +1 -1
  80. package/dist/dev/define/live-audio/compat-skin.css +91 -38
  81. package/dist/dev/define/live-audio/compat-skin2.js +1 -1
  82. package/dist/dev/define/live-audio/compat-skin2.js.map +1 -1
  83. package/dist/dev/define/live-audio/neutral-skin.css +50 -29
  84. package/dist/dev/define/live-audio/neutral-skin2.js +1 -1
  85. package/dist/dev/define/live-audio/neutral-skin2.js.map +1 -1
  86. package/dist/dev/define/live-audio/scaffold-skin.css +105 -40
  87. package/dist/dev/define/live-audio/scaffold-skin2.js +1 -1
  88. package/dist/dev/define/live-audio/scaffold-skin2.js.map +1 -1
  89. package/dist/dev/define/live-audio/skin.css +51 -29
  90. package/dist/dev/define/live-audio/skin2.js +1 -1
  91. package/dist/dev/define/live-audio/skin2.js.map +1 -1
  92. package/dist/dev/define/live-video/compat-skin.css +142 -61
  93. package/dist/dev/define/live-video/compat-skin2.js +1 -1
  94. package/dist/dev/define/live-video/compat-skin2.js.map +1 -1
  95. package/dist/dev/define/live-video/neutral-skin.css +241 -55
  96. package/dist/dev/define/live-video/neutral-skin2.js +1 -1
  97. package/dist/dev/define/live-video/neutral-skin2.js.map +1 -1
  98. package/dist/dev/define/live-video/scaffold-skin.css +159 -63
  99. package/dist/dev/define/live-video/scaffold-skin2.js +1 -1
  100. package/dist/dev/define/live-video/scaffold-skin2.js.map +1 -1
  101. package/dist/dev/define/live-video/skin.css +245 -60
  102. package/dist/dev/define/live-video/skin2.js +1 -1
  103. package/dist/dev/define/live-video/skin2.js.map +1 -1
  104. package/dist/dev/define/ui/time-slider-markers.d.ts +8 -0
  105. package/dist/dev/define/ui/time-slider-markers.js +7 -0
  106. package/dist/dev/define/ui/time-slider-markers.js.map +1 -0
  107. package/dist/dev/define/video/compat-skin.css +150 -61
  108. package/dist/dev/define/video/compat-skin2.js +1 -1
  109. package/dist/dev/define/video/compat-skin2.js.map +1 -1
  110. package/dist/dev/define/video/neutral-skin.css +322 -66
  111. package/dist/dev/define/video/neutral-skin2.js +1 -1
  112. package/dist/dev/define/video/neutral-skin2.js.map +1 -1
  113. package/dist/dev/define/video/scaffold-skin.css +168 -63
  114. package/dist/dev/define/video/scaffold-skin2.js +1 -1
  115. package/dist/dev/define/video/scaffold-skin2.js.map +1 -1
  116. package/dist/dev/define/video/skin.css +348 -66
  117. package/dist/dev/define/video/skin2.js +1 -1
  118. package/dist/dev/define/video/skin2.js.map +1 -1
  119. package/dist/dev/index.d.ts +5 -4
  120. package/dist/dev/index.js +3 -1
  121. package/dist/dev/internal/skins/compat-audio/skin.css +91 -38
  122. package/dist/dev/internal/skins/compat-live-audio/skin.css +91 -38
  123. package/dist/dev/internal/skins/compat-live-video/skin.css +142 -61
  124. package/dist/dev/internal/skins/compat-live-video/template.js +2 -0
  125. package/dist/dev/internal/skins/compat-live-video/template.js.map +1 -1
  126. package/dist/dev/internal/skins/compat-video/skin.css +150 -61
  127. package/dist/dev/internal/skins/compat-video/template.js +2 -0
  128. package/dist/dev/internal/skins/compat-video/template.js.map +1 -1
  129. package/dist/dev/internal/skins/default-audio/skin.css +53 -31
  130. package/dist/dev/internal/skins/default-live-audio/skin.css +51 -29
  131. package/dist/dev/internal/skins/default-live-video/register.js.map +1 -1
  132. package/dist/dev/internal/skins/default-live-video/skin.css +245 -60
  133. package/dist/dev/internal/skins/default-live-video/template.js +14 -0
  134. package/dist/dev/internal/skins/default-live-video/template.js.map +1 -1
  135. package/dist/dev/internal/skins/default-video/register.d.ts +1 -0
  136. package/dist/dev/internal/skins/default-video/register.js +3 -0
  137. package/dist/dev/internal/skins/default-video/register.js.map +1 -1
  138. package/dist/dev/internal/skins/default-video/skin.css +348 -66
  139. package/dist/dev/internal/skins/default-video/template.js +33 -5
  140. package/dist/dev/internal/skins/default-video/template.js.map +1 -1
  141. package/dist/dev/internal/skins/neutral-audio/skin.css +52 -31
  142. package/dist/dev/internal/skins/neutral-live-audio/skin.css +50 -29
  143. package/dist/dev/internal/skins/neutral-live-video/register.js.map +1 -1
  144. package/dist/dev/internal/skins/neutral-live-video/skin.css +241 -55
  145. package/dist/dev/internal/skins/neutral-live-video/template.js +14 -0
  146. package/dist/dev/internal/skins/neutral-live-video/template.js.map +1 -1
  147. package/dist/dev/internal/skins/neutral-video/register.js.map +1 -1
  148. package/dist/dev/internal/skins/neutral-video/skin.css +322 -66
  149. package/dist/dev/internal/skins/neutral-video/template.js +25 -11
  150. package/dist/dev/internal/skins/neutral-video/template.js.map +1 -1
  151. package/dist/dev/internal/skins/scaffold-audio/skin.css +105 -40
  152. package/dist/dev/internal/skins/scaffold-live-audio/skin.css +105 -40
  153. package/dist/dev/internal/skins/scaffold-live-video/skin.css +159 -63
  154. package/dist/dev/internal/skins/scaffold-live-video/template.js +2 -0
  155. package/dist/dev/internal/skins/scaffold-live-video/template.js.map +1 -1
  156. package/dist/dev/internal/skins/scaffold-video/skin.css +168 -63
  157. package/dist/dev/internal/skins/scaffold-video/template.js +3 -1
  158. package/dist/dev/internal/skins/scaffold-video/template.js.map +1 -1
  159. package/dist/dev/media/background-video/adapter.d.ts +7 -13
  160. package/dist/dev/media/background-video/adapter.js +13 -35
  161. package/dist/dev/media/background-video/adapter.js.map +1 -1
  162. package/dist/dev/media/background-video/base.d.ts +44 -0
  163. package/dist/dev/media/background-video/base.js +97 -0
  164. package/dist/dev/media/background-video/base.js.map +1 -0
  165. package/dist/dev/media/background-video/template.d.ts +3 -0
  166. package/dist/dev/media/background-video/template.js +13 -20
  167. package/dist/dev/media/background-video/template.js.map +1 -1
  168. package/dist/dev/media/hls-background-video/adapter.d.ts +8 -18
  169. package/dist/dev/media/hls-background-video/adapter.js +16 -35
  170. package/dist/dev/media/hls-background-video/adapter.js.map +1 -1
  171. package/dist/dev/ui/captions-button/element.d.ts +2 -0
  172. package/dist/dev/ui/captions-radio-group/element.d.ts +2 -1
  173. package/dist/dev/ui/captions-radio-group/element.js +14 -1
  174. package/dist/dev/ui/captions-radio-group/element.js.map +1 -1
  175. package/dist/dev/ui/controls/element.d.ts +2 -2
  176. package/dist/dev/ui/controls/element.js +6 -3
  177. package/dist/dev/ui/controls/element.js.map +1 -1
  178. package/dist/dev/ui/time-slider/markers.d.ts +48 -0
  179. package/dist/dev/ui/time-slider/markers.js +165 -0
  180. package/dist/dev/ui/time-slider/markers.js.map +1 -0
  181. package/dist/dev/version.js +1 -1
  182. package/docs/README.md +1 -1
  183. package/docs/guides/autoplay.md +1 -1
  184. package/docs/guides/background-video.md +2 -4
  185. package/docs/guides/browser-support.md +22 -16
  186. package/docs/guides/cdn.md +9 -9
  187. package/docs/guides/customize-skins.md +3 -0
  188. package/docs/guides/installation-cdn.md +2 -2
  189. package/docs/guides/installation-shadcn.md +1 -1
  190. package/docs/guides/installation-svelte.md +2 -2
  191. package/docs/guides/installation-vue.md +2 -2
  192. package/docs/guides/installation.md +2 -2
  193. package/docs/guides/internationalization.md +5 -5
  194. package/docs/guides/keyboard-shortcuts.md +10 -0
  195. package/docs/guides/llms.txt +2 -1
  196. package/docs/guides/migrate-from-media-chrome.md +4 -4
  197. package/docs/guides/migrate-from-mux-player.md +6 -6
  198. package/docs/guides/migrate-from-plyr.md +7 -7
  199. package/docs/guides/migrate-from-video-js-8.md +6 -6
  200. package/docs/guides/migrate-from-vidstack.md +4 -4
  201. package/docs/guides/presets.md +4 -4
  202. package/docs/guides/self-hosting.md +5 -5
  203. package/docs/guides/skins.md +8 -7
  204. package/docs/guides/timed-metadata.md +318 -0
  205. package/docs/llms.txt +16 -2
  206. package/docs/reference/api/chapters-track.md +71 -0
  207. package/docs/reference/api/define-text-track.md +113 -0
  208. package/docs/reference/api/feature-text-cues.md +133 -0
  209. package/docs/reference/api/feature-text-tracks.md +11 -5
  210. package/docs/reference/api/get-active-text-cues.md +69 -0
  211. package/docs/reference/api/get-text-cues.md +69 -0
  212. package/docs/reference/api/get-text-tracks.md +41 -0
  213. package/docs/reference/api/hls-metadata-track.md +48 -0
  214. package/docs/reference/api/html-create-player.md +2 -2
  215. package/docs/reference/api/llms.txt +13 -1
  216. package/docs/reference/api/media-capabilities.md +4 -4
  217. package/docs/reference/api/player-store.md +9 -4
  218. package/docs/reference/api/preset-audio.md +3 -1
  219. package/docs/reference/api/preset-background.md +1 -1
  220. package/docs/reference/api/preset-live-audio.md +3 -1
  221. package/docs/reference/api/preset-live-video.md +2 -1
  222. package/docs/reference/api/preset-video.md +2 -1
  223. package/docs/reference/components/audio-compat-skin.md +1 -1
  224. package/docs/reference/components/audio-neutral-skin.md +1 -1
  225. package/docs/reference/components/audio-scaffold-skin.md +1 -1
  226. package/docs/reference/components/audio-skin.md +1 -1
  227. package/docs/reference/components/audio.md +19 -1
  228. package/docs/reference/components/background-video-skin.md +1 -1
  229. package/docs/reference/components/background-video.md +26 -11
  230. package/docs/reference/components/captions-radio-group.md +1 -1
  231. package/docs/reference/components/cloudflare-video.md +1 -1
  232. package/docs/reference/components/controls.md +16 -3
  233. package/docs/reference/components/dailymotion-video.md +2 -2
  234. package/docs/reference/components/dash-video.md +20 -3
  235. package/docs/reference/components/google-analytics.md +1 -1
  236. package/docs/reference/components/google-cast.md +1 -1
  237. package/docs/reference/components/hls-audio.md +56 -2
  238. package/docs/reference/components/hls-background-video.md +22 -5
  239. package/docs/reference/components/hls-video.md +99 -7
  240. package/docs/reference/components/hlsjs-video.md +52 -13
  241. package/docs/reference/components/live-audio-compat-skin.md +1 -1
  242. package/docs/reference/components/live-audio-neutral-skin.md +1 -1
  243. package/docs/reference/components/live-audio-scaffold-skin.md +1 -1
  244. package/docs/reference/components/live-audio-skin.md +1 -1
  245. package/docs/reference/components/live-video-compat-skin.md +5 -1
  246. package/docs/reference/components/live-video-neutral-skin.md +5 -1
  247. package/docs/reference/components/live-video-scaffold-skin.md +5 -1
  248. package/docs/reference/components/live-video-skin.md +5 -1
  249. package/docs/reference/components/llms.txt +2 -1
  250. package/docs/reference/components/mixcloud-audio.md +2 -2
  251. package/docs/reference/components/mux-audio.md +34 -3
  252. package/docs/reference/components/mux-background-video.md +1 -1
  253. package/docs/reference/components/mux-data.md +1 -1
  254. package/docs/reference/components/mux-video.md +17 -3
  255. package/docs/reference/components/native-hls-video.md +32 -3
  256. package/docs/reference/components/playerjs-video.md +2 -2
  257. package/docs/reference/components/shaka-video.md +2 -3
  258. package/docs/reference/components/soundcloud-audio.md +2 -2
  259. package/docs/reference/components/spotify-audio.md +2 -2
  260. package/docs/reference/components/tiktok-video.md +2 -2
  261. package/docs/reference/components/time-slider-markers.md +194 -0
  262. package/docs/reference/components/time-slider.md +14 -0
  263. package/docs/reference/components/twitch-video.md +1 -1
  264. package/docs/reference/components/video-compat-skin.md +5 -1
  265. package/docs/reference/components/video-neutral-skin.md +5 -1
  266. package/docs/reference/components/video-scaffold-skin.md +5 -1
  267. package/docs/reference/components/video-skin.md +5 -1
  268. package/docs/reference/components/video.md +19 -1
  269. package/docs/reference/components/vimeo-video.md +1 -2
  270. package/docs/reference/components/wistia-video.md +1 -1
  271. package/docs/reference/components/youtube-video.md +1 -2
  272. package/package.json +48 -48
@@ -0,0 +1,318 @@
1
+ # Sync content with timed metadata
2
+
3
+ Show quizzes, product cards, ad markers, chapters, and transcripts in time with playback, from cues in the media or cues your app adds.
4
+
5
+ Timed metadata is data tied to a span of playback: a quiz question, a product card, an ad break, or a chapter. Video.js reads it as text tracks and cues, the platform objects captions use, whether the cues come from the media or from your app.
6
+
7
+ ## Recommended approach
8
+
9
+ Define the track with `defineTextTrack()`, add your cues to the player with `player.store.addTextTrack()`, and render the cue `getActiveTextCues()` returns each time the store changes.
10
+
11
+ **index.html**
12
+
13
+ ```html
14
+ <video-player class="html-timed-metadata-basic">
15
+ <media-container class="html-timed-metadata-basic__container">
16
+ <video src="https://stream.mux.com/BV3YZtogl89mg9VcNBhhnHm02Y34zI1nlMuMQfAbl3dM/highest.mp4" autoplay muted playsinline loop></video>
17
+ <p class="html-timed-metadata-basic__note">
18
+ <strong class="html-timed-metadata-basic__title"></strong>
19
+ <span class="html-timed-metadata-basic__body"></span>
20
+ </p>
21
+ </media-container>
22
+ </video-player>
23
+ ```
24
+
25
+ **index.css**
26
+
27
+ ```css
28
+ .html-timed-metadata-basic__container {
29
+ position: relative;
30
+ }
31
+
32
+ .html-timed-metadata-basic__container video {
33
+ width: 100%;
34
+ aspect-ratio: 16 / 9;
35
+ }
36
+
37
+ .html-timed-metadata-basic__note {
38
+ position: absolute;
39
+ top: 12px;
40
+ left: 12px;
41
+ max-width: calc(100% - 24px);
42
+ padding: 10px 14px;
43
+ margin: 0;
44
+ font-size: 0.875rem;
45
+ line-height: 1.4;
46
+ color: black;
47
+ background: rgba(255, 255, 255, 0.85);
48
+ border-radius: 12px;
49
+ backdrop-filter: blur(10px);
50
+ }
51
+
52
+ .html-timed-metadata-basic__note:not([data-active]) {
53
+ display: none;
54
+ }
55
+
56
+ .html-timed-metadata-basic__title {
57
+ display: block;
58
+ }
59
+ ```
60
+
61
+ **index.ts**
62
+
63
+ ```ts
64
+ import '@videojs/html/video/player';
65
+ import '@videojs/html/ui/container';
66
+ import { defineTextTrack, getActiveTextCues } from '@videojs/html';
67
+
68
+ interface Note {
69
+ title: string;
70
+ body: string;
71
+ }
72
+
73
+ const notesTrack = defineTextTrack<Note>({ kind: 'metadata', label: 'notes' });
74
+
75
+ const player = document.querySelector('video-player');
76
+ const note = document.querySelector<HTMLElement>('.html-timed-metadata-basic__note');
77
+ const title = note?.querySelector('.html-timed-metadata-basic__title');
78
+ const body = note?.querySelector('.html-timed-metadata-basic__body');
79
+
80
+ if (player && note && title && body) {
81
+ player.store.addTextTrack(notesTrack, {
82
+ cues: [
83
+ { startTime: 1, endTime: 8, value: { title: 'Timed metadata', body: 'This note is a cue the app added.' } },
84
+ { startTime: 12, endTime: 19, value: { title: 'Any data', body: 'Each cue carries a value you render.' } },
85
+ { startTime: 23, endTime: 30, value: { title: 'Any media', body: 'The player holds the track, not the video.' } },
86
+ ],
87
+ });
88
+
89
+ player.store.subscribe(() => {
90
+ const [cue] = getActiveTextCues(player.store, notesTrack);
91
+
92
+ note.toggleAttribute('data-active', Boolean(cue?.value));
93
+ title.textContent = cue?.value?.title ?? '';
94
+ body.textContent = cue?.value?.body ?? '';
95
+ });
96
+ }
97
+ ```
98
+
99
+ In your app, the cues usually come from your API or CMS. Fetch them and pass them as `cues`, or pass the file’s URL as `src` and the player loads it.
100
+
101
+ ## How it works
102
+
103
+ A text track has a `kind`, `label`, and `language`, and a list of cues. Each cue spans `startTime` to `endTime`, in seconds, and carries `text`, structured data in `value`, or both. `value` and `type` are named after the platform’s `DataCue`. A cue without an `endTime` is a point, active for one second, except in a chapters track your app adds, where it runs to the next chapter.
104
+
105
+ `addTextTrack()` adds the track to the player, not the media, so it works with any media, including YouTube and other embeds. The track sits next to the media’s tracks in `textTrackList` with `source: 'app'`.
106
+
107
+ The [text cues feature](../reference/api/feature-text-cues.md), included in the video, audio, and live presets, reads cues from the media’s `metadata` and `chapters` tracks and from the tracks your app adds, and tracks which cues are active at the current time. Tracks from either place are read the same way.
108
+
109
+ `defineTextTrack<Note>()` types each cue’s `value`, and works as a filter: reading through it picks the tracks with the same kind, label, and language. A plain filter, such as `{ label: 'notes' }`, works too, but its cues’ `value` is `unknown`.
110
+
111
+ `player.store.subscribe()` calls back whenever player state changes, and `getActiveTextCues()` returns the cues active at that moment.
112
+
113
+ Browsers never draw metadata or chapters cues, so the overlay, its styles, and its accessibility are up to your UI.
114
+
115
+ ## Availability and constraints
116
+
117
+ - Active cues follow `currentTime`, which updates up to about four times a second. Don’t rely on them for frame-accurate timing. A cue that playback passes between two updates still shows up as active once; a cue a seek jumps over doesn’t.
118
+ - `cues` are plain, JSON-serializable data, so a server-rendered page can pass them in. A `src` is fetched only once the player runs on the client, and a cross-origin file needs CORS headers.
119
+ - Browsers load a `<track>` element’s cues only while the track is `showing` or `hidden`. `default` makes a `<track kind="metadata">` `hidden`; without it, the track stays `disabled` and its cues never load.
120
+ - `value` isn’t checked at runtime unless the definition has a schema. See [Check values with a schema](#check-values-with-a-schema).
121
+
122
+ Like a `<track>` element, an app track stays through source changes until you remove it. When you play a different video, remove its tracks and add the new video’s.
123
+
124
+ ## Common variations
125
+
126
+ The examples below assume `player` is the `<video-player>` element, as in the recommended approach, and that the elements they update, such as `adBadge`, are queried from your page.
127
+
128
+ ### Read cues from a WebVTT file
129
+
130
+ Add a `<track kind="metadata">` to the media. Cue text that parses as a JSON object or array becomes the cue’s `value`; any other text stays in `text`.
131
+
132
+ **notes.vtt**
133
+
134
+ ```text
135
+ WEBVTT
136
+
137
+ 00:00:01.000 --> 00:00:08.000
138
+ { "title": "Timed metadata", "body": "This note came from a WebVTT file." }
139
+ ```
140
+
141
+ ```html
142
+ <video src="video.mp4" playsinline>
143
+ <track kind="metadata" label="notes" src="/notes.vtt" default />
144
+ </video>
145
+ ```
146
+
147
+ A definition with the same kind and label reads it, so the rendering code from the recommended approach works unchanged. To use the file with media that has no `<track>` support, such as an embed, pass it as `src` when you add the track instead.
148
+
149
+ ### Read metadata from an HLS stream
150
+
151
+ When hls.js plays a stream, in [`HlsJsVideo`](../reference/components/hlsjs-video.md) and media built on it such as [`MuxVideo`](../reference/components/mux-video.md), it publishes ID3 frames and `EXT-X-DATERANGE` tags as cues on a metadata track. Read them with [`hlsMetadataTrack`](../reference/api/hls-metadata-track.md). Each cue’s `type` tells an ID3 frame from a date range attribute, and narrows its `value`.
152
+
153
+ ```ts
154
+ import { getActiveTextCues, hlsMetadataTrack } from '@videojs/html';
155
+
156
+ player.store.subscribe(() => {
157
+ const cues = getActiveTextCues(player.store, hlsMetadataTrack);
158
+ const inAd = cues.some((cue) => cue.type === 'com.apple.quicktime.HLS' && cue.value?.key === 'X-AD-ID');
159
+
160
+ adBadge.hidden = !inAd;
161
+ });
162
+ ```
163
+
164
+ Where the browser plays HLS natively, as Safari does, in-band metadata arrives as `DataCue`s on the browser’s own metadata tracks. Read those with a `{ kind: 'metadata' }` filter.
165
+
166
+ ### Mark cues on the time slider
167
+
168
+ Add `<media-time-slider-markers>` to the time slider to draw a marker for each cue on the tracks its attributes match, such as the notes from the recommended approach.
169
+
170
+ ```html
171
+ <media-time-slider>
172
+ <media-slider-track>
173
+ <media-slider-fill></media-slider-fill>
174
+ </media-slider-track>
175
+ <media-time-slider-markers kind="metadata" label="notes"></media-time-slider-markers>
176
+ <media-slider-thumb></media-slider-thumb>
177
+ </media-time-slider>
178
+ ```
179
+
180
+ A point is a marker with no width, a range spans its cue, and a marker has `data-active` while its cue is active. Markers are unstyled: position each one with its `--media-slider-marker-*` custom properties. See [the markers reference](../reference/components/time-slider-markers.md) for the full styling contract.
181
+
182
+ ### Check values with a schema
183
+
184
+ Cues from a file or a stream can carry anything. Pass a `schema` to `defineTextTrack()` to check each value where it’s read. Any [Standard Schema](https://standardschema.dev) works, such as one from zod or valibot, and the value type comes from the schema.
185
+
186
+ ```ts
187
+ import { z } from 'zod';
188
+
189
+ const NoteSchema = z.object({ title: z.string(), body: z.string() });
190
+
191
+ const notesTrack = defineTextTrack({ kind: 'metadata', label: 'notes', schema: NoteSchema });
192
+ ```
193
+
194
+ Readers skip cues whose value fails the schema, and warn in development. The schema must be synchronous.
195
+
196
+ ### Add chapters
197
+
198
+ Add a `chapters` track the same way. A chapter’s title is its cue `text`, and a chapter without an `endTime` runs to the next one. When the media has no chapters track of its own, the [time slider](../reference/components/time-slider.md) shows these chapters.
199
+
200
+ ```ts
201
+ player.store.addTextTrack({
202
+ kind: 'chapters',
203
+ cues: [
204
+ { startTime: 0, text: 'Introduction' },
205
+ { startTime: 95, text: 'Setup' },
206
+ { startTime: 410, text: 'Wrap-up' },
207
+ ],
208
+ });
209
+ ```
210
+
211
+ To load a Podcasting 2.0, Apple HLS, or JSON-LD chapters file, pass its converter as `format`, such as `podcastChapters`. Read the current chapter, with any artwork the file gives it, through [`chaptersTrack`](../reference/api/chapters-track.md).
212
+
213
+ ```ts
214
+ import { chaptersTrack, getActiveTextCues, podcastChapters } from '@videojs/html';
215
+
216
+ player.store.addTextTrack({ kind: 'chapters', src: '/episodes/42/chapters.json', format: podcastChapters });
217
+
218
+ player.store.subscribe(() => {
219
+ const [chapter] = getActiveTextCues(player.store, chaptersTrack);
220
+ currentChapter.textContent = chapter?.text ?? '';
221
+ });
222
+ ```
223
+
224
+ ### Show an interactive transcript
225
+
226
+ A transcript reads captions cues, which the text cues feature skips unless something asks for them.
227
+
228
+ Call `watchTextCues()` to read them, then render with `getTextCues()` and `getActiveTextCues()`.
229
+
230
+ ```ts
231
+ import { getActiveTextCues, getTextCues } from '@videojs/html';
232
+
233
+ const captions = { kind: 'captions', language: 'en' } as const;
234
+ // A cue that hasn't changed stays the same object, so it keeps its line.
235
+ const lines = new WeakMap<object, HTMLLIElement>();
236
+
237
+ player.store.watchTextCues(captions);
238
+
239
+ player.store.subscribe(() => {
240
+ const [active] = getActiveTextCues(player.store, captions);
241
+ const next = getTextCues(player.store, captions).map((cue) => {
242
+ let line = lines.get(cue);
243
+
244
+ if (!line) {
245
+ const button = document.createElement('button');
246
+
247
+ button.type = 'button';
248
+ button.textContent = cue.text;
249
+ button.addEventListener('click', () => player.store.seek(cue.startTime));
250
+
251
+ line = document.createElement('li');
252
+ line.append(button);
253
+ lines.set(cue, line);
254
+ }
255
+
256
+ if (cue.id === active?.id) line.setAttribute('aria-current', 'true');
257
+ else line.removeAttribute('aria-current');
258
+
259
+ return line;
260
+ });
261
+
262
+ // Replace the lines only when they change, so a focused button keeps focus.
263
+ const current = [...transcript.children];
264
+
265
+ if (next.length !== current.length || next.some((line, index) => line !== current[index])) {
266
+ transcript.replaceChildren(...next);
267
+ }
268
+ });
269
+ ```
270
+
271
+ The browser loads a `<track>` element’s cues only while captions are on. To show the transcript either way, add the captions track from your app instead of a `<track>` element. The player copies it into the media, so the browser still draws the captions when a viewer turns them on.
272
+
273
+ ```ts
274
+ player.store.addTextTrack({ kind: 'captions', label: 'English', language: 'en', src: '/captions.vtt' });
275
+ ```
276
+
277
+ ## Troubleshooting
278
+
279
+ ### No cue is ever active
280
+
281
+ Confirm that:
282
+
283
+ - The track is one the text cues feature reads: a `metadata` or `chapters` track that isn’t `disabled`. Give a `<track kind="metadata">` the `default` attribute. For other kinds, read through the hooks or call `watchTextCues()`.
284
+ - Your filter or definition matches the track’s `kind`, `label`, and `language` exactly. `getTextTracks()` lists the tracks the player has.
285
+ - Cue times are in seconds.
286
+
287
+ ### A cue’s value is undefined
288
+
289
+ Only `metadata` cue text that parses as a JSON object or array becomes `value`; other text stays in `text`. With a schema, cues whose value fails it are skipped, with a warning in development.
290
+
291
+ ### An app track outlives its video
292
+
293
+ App tracks stay until they’re removed, through source changes. Call the handle’s `remove()`, or the store’s `removeTextTrack()`, before adding the next video’s tracks.
294
+
295
+ ### Cues from a src never load
296
+
297
+ The file failed to load, often because of a missing CORS header or a wrong URL. The track keeps any cues it already had, and a warning shows in development.
298
+
299
+ ## Related pages
300
+
301
+ ### Components
302
+
303
+ - [media-time-slider](../reference/components/time-slider.md): A slider component for seeking through media playback time
304
+ - [media-time-slider-markers](../reference/components/time-slider-markers.md): Draws a marker on the time slider for each cue on the text tracks a filter matches, such as ad breaks
305
+
306
+ ### API
307
+
308
+ - [Text cues](../reference/api/feature-text-cues.md): Cues and active cues from metadata, chapters, and app text tracks
309
+ - [defineTextTrack](../reference/api/define-text-track.md): Define a text track once, with the type of its cue values, to add and read it with
310
+ - [getActiveTextCues](../reference/api/get-active-text-cues.md): The cues active now on the text tracks a filter or track definition matches
311
+ - [getTextCues](../reference/api/get-text-cues.md): Every cue on the text tracks a filter or track definition matches
312
+ - [chaptersTrack](../reference/api/chapters-track.md): A track definition for chapters, and converters that turn chapter JSON formats into cues
313
+ - [hlsMetadataTrack](../reference/api/hls-metadata-track.md): A track definition for the ID3 and EXT-X-DATERANGE metadata hls.js publishes
314
+
315
+ ### Guides
316
+
317
+ - [Show captions and subtitles](./captions.md): Show captions and subtitles, and let users turn them on and pick a language.
318
+ - [Media sources](./media-sources.md): Set what a media component plays and how its engine plays it with the structured source property
package/docs/llms.txt CHANGED
@@ -1,6 +1,6 @@
1
1
  # Video.js v10 — HTML Documentation
2
2
 
3
- > Bundled with `@videojs/html` v10.3.0. Links are relative paths to files in this directory.
3
+ > Bundled with `@videojs/html` v10.4.0. Links are relative paths to files in this directory.
4
4
 
5
5
  > Install the [Video.js skill](https://github.com/videojs/skills) to help AI coding agents find version-matched pages from this index.
6
6
 
@@ -71,6 +71,7 @@ Guides for one player capability each: the recommended setup, how it works, brow
71
71
  - [Automatically show and hide controls](./guides/controls.md): Show controls while the user is active, hide them during playback, and toggle them by touch.
72
72
  - [Add a poster and loading placeholder](./guides/poster.md): Set the image shown before playback, then add a lightweight placeholder while it loads
73
73
  - [Show captions and subtitles](./guides/captions.md): Show captions and subtitles, and let users turn them on and pick a language.
74
+ - [Sync content with timed metadata](./guides/timed-metadata.md): Show quizzes, product cards, ad markers, chapters, and transcripts in time with playback, from cues in the media or cues your app adds.
74
75
  - [Add keyboard shortcuts and gestures](./guides/keyboard-shortcuts.md): Add keyboard shortcuts, tap and double-tap gestures, and on-screen feedback for input actions.
75
76
  - [Play live streams](./guides/live-streams.md): Play live streams with live-edge tracking, DVR windows, and stream-type detection.
76
77
  - [Add a quality selector](./guides/quality.md): Read available renditions, let the engine adapt automatically, and offer manual quality selection.
@@ -190,6 +191,7 @@ API reference for the slider components that scrub time and adjust volume.
190
191
 
191
192
  - [media-slider](./reference/components/slider.md): A composable slider component with track, fill, thumb, preview, and value parts
192
193
  - [media-time-slider](./reference/components/time-slider.md): A slider component for seeking through media playback time
194
+ - [media-time-slider-markers](./reference/components/time-slider-markers.md): Draws a marker on the time slider for each cue on the text tracks a filter matches, such as ad breaks
193
195
  - [media-volume-slider](./reference/components/volume-slider.md): A slider component for controlling media playback volume
194
196
 
195
197
  ### Menus
@@ -242,7 +244,7 @@ API reference for the icon sets the skins use, available for your own controls.
242
244
 
243
245
  ## API
244
246
 
245
- API reference for the player factory, presets, store controllers, features, translation tools, and utilities.
247
+ API reference for the player factory, presets, store controllers, features, text tracks, translation tools, and utilities.
246
248
 
247
249
  Section index: [reference/api/llms.txt](./reference/api/llms.txt).
248
250
 
@@ -294,10 +296,22 @@ API reference for the feature modules passed to createPlayer, which provide play
294
296
  - [Remote Playback](./reference/api/feature-remote-playback.md): Remote playback state and actions for the player store
295
297
  - [Source](./reference/api/feature-source.md): Media source state and actions for the player store
296
298
  - [Stream type](./reference/api/feature-stream-type.md): Stream delivery type (live / on-demand) state for the player store
299
+ - [Text cues](./reference/api/feature-text-cues.md): Cues and active cues from metadata, chapters, and app text tracks
297
300
  - [Text tracks](./reference/api/feature-text-tracks.md): Subtitles, captions, and chapter track state for the player store
298
301
  - [Time](./reference/api/feature-time.md): Playback position and duration state for the player store
299
302
  - [Volume](./reference/api/feature-volume.md): Volume level and mute state for the player store
300
303
 
304
+ ### Text tracks
305
+
306
+ API reference for reading text tracks and their cues: track definitions and readers.
307
+
308
+ - [defineTextTrack](./reference/api/define-text-track.md): Define a text track once, with the type of its cue values, to add and read it with
309
+ - [getTextTracks](./reference/api/get-text-tracks.md): The text tracks a filter or track definition matches, from the media or the app
310
+ - [getTextCues](./reference/api/get-text-cues.md): Every cue on the text tracks a filter or track definition matches
311
+ - [getActiveTextCues](./reference/api/get-active-text-cues.md): The cues active now on the text tracks a filter or track definition matches
312
+ - [chaptersTrack](./reference/api/chapters-track.md): A track definition for chapters, and converters that turn chapter JSON formats into cues
313
+ - [hlsMetadataTrack](./reference/api/hls-metadata-track.md): A track definition for the ID3 and EXT-X-DATERANGE metadata hls.js publishes
314
+
301
315
  ### i18n
302
316
 
303
317
  API reference for translating the player: the i18n elements, controller, and the phrase registry.
@@ -0,0 +1,71 @@
1
+ # chaptersTrack
2
+
3
+ A track definition for chapters, and converters that turn chapter JSON formats into cues
4
+
5
+ ## Import
6
+
7
+ ```ts
8
+ import { appleHlsChapters, chaptersTrack, jsonLdChapters, podcastChapters } from '@videojs/html';
9
+ ```
10
+
11
+ `chaptersTrack` is a [track definition](./define-text-track.md) for `{ kind: 'chapters' }`. It has no `label`, so it matches every chapters track, from the media and the app alike. A chapter’s title is its cue’s `text`, and its `value` is typed as `ChapterCueValue`, which holds what chapter formats carry beyond a title.
12
+
13
+ WebVTT chapters carry only a title, so their cues have no `value`. Chapters converted from JSON with the functions below carry one.
14
+
15
+ | `ChapterCueValue` field | Description |
16
+ | --- | --- |
17
+ | `description` | The chapter’s description. |
18
+ | `url` | A web page for the chapter. |
19
+ | `images` | Images for the chapter, such as artwork or a thumbnail. Each has a `url`, and optionally a `width` and `height` in pixels. |
20
+ | `titles` | The chapter’s titles by language, when the source has several. |
21
+
22
+ ## Usage
23
+
24
+ **current-chapter.ts**
25
+
26
+ ```ts
27
+ import { chaptersTrack, getActiveTextCues } from '@videojs/html';
28
+
29
+ const player = document.querySelector('video-player')!;
30
+ const label = document.querySelector('.current-chapter')!;
31
+
32
+ player.store.subscribe(() => {
33
+ const [chapter] = getActiveTextCues(player.store, chaptersTrack);
34
+ label.textContent = chapter?.text ?? '';
35
+ });
36
+ ```
37
+
38
+ ## Chapter formats
39
+
40
+ Each converter takes a file’s text, or JSON you already parsed, and returns cues for a chapters track. Pass one as the `format` of a track with a `src`, and the player converts the file once it loads. Or call it yourself and pass the result as `cues`. Converters skip entries they can’t read; only text that isn’t JSON throws.
41
+
42
+ ```ts
43
+ player.store.addTextTrack({ kind: 'chapters', src: '/episodes/42/chapters.json', format: podcastChapters });
44
+ ```
45
+
46
+ A chapter without an end runs to the next chapter, and the last one to the end of the media.
47
+
48
+ ### `podcastChapters`
49
+
50
+ Reads a [Podcasting 2.0 JSON chapters](https://github.com/Podcastindex-org/podcast-namespace) file. Each chapter’s `title` becomes the cue text, `startTime` and `endTime` its times, `url` its `url`, and `img` its first image. Chapters marked `toc: false` are left out, since they aren’t meant to be shown.
51
+
52
+ ### `appleHlsChapters`
53
+
54
+ Reads an Apple HLS chapters file: the JSON an `EXT-X-SESSION-DATA` tag with `DATA-ID="com.apple.hls.chapters"` points to. Each chapter starts at its `start-time` and ends after its `duration`. Its first title becomes the cue text, and every title is kept in `titles` by language. Its `images` keep their `pixel-width` and `pixel-height` as `width` and `height`.
55
+
56
+ ### `jsonLdChapters`
57
+
58
+ Reads schema.org JSON-LD: a `VideoObject` whose `hasPart` lists `Clip`s, a list of `Clip`s, or one `Clip`. These are the clips Google shows as key moments. Each clip’s `name` becomes the cue text, `startOffset` and `endOffset` its times in seconds, and its `description`, `url`, and first `thumbnailUrl` its value.
59
+
60
+ ```ts
61
+ const jsonLd = document.querySelector('script[type="application/ld+json"]')!.textContent!;
62
+
63
+ player.store.addTextTrack({ kind: 'chapters', cues: jsonLdChapters(jsonLd) });
64
+ ```
65
+
66
+ ## Exports
67
+
68
+ | Export | Description |
69
+ | --- | --- |
70
+ | `ChapterCueValue` | What a chapter can carry beyond its title. |
71
+ | `ChapterImage` | An image for a chapter: a `url`, and optionally a `width` and `height`. |
@@ -0,0 +1,113 @@
1
+ # defineTextTrack
2
+
3
+ Define a text track once, with the type of its cue values, to add and read it with
4
+
5
+ ## Import
6
+
7
+ ```ts
8
+ import { defineTextTrack } from '@videojs/html';
9
+ ```
10
+
11
+ `defineTextTrack` returns a track definition: a track’s `kind`, and optionally its `label` and `language`, typed with the `value` its cues carry. A definition works anywhere a text track filter does, matching tracks by kind, label, and language. Reading through it types each cue’s `value`, and adding a track from it checks the cues you pass against that type.
12
+
13
+ ## Usage
14
+
15
+ Pass the value type as a type parameter. The type isn’t checked at runtime.
16
+
17
+ ```ts
18
+ import { defineTextTrack, getActiveTextCues, type TextCueInit } from '@videojs/html';
19
+
20
+ interface Quiz {
21
+ question: string;
22
+ }
23
+
24
+ const quizTrack = defineTextTrack<Quiz>({ kind: 'metadata', label: 'quiz' });
25
+
26
+ const player = document.querySelector('video-player')!;
27
+ const cues: TextCueInit<Quiz>[] = await fetch('/api/quiz').then((res) => res.json());
28
+
29
+ player.store.addTextTrack(quizTrack, { cues });
30
+
31
+ player.store.subscribe(() => {
32
+ const [cue] = getActiveTextCues(player.store, quizTrack);
33
+ console.log(cue?.value?.question);
34
+ });
35
+ ```
36
+
37
+ ### Schemas
38
+
39
+ Pass a `schema` to check values where they’re read. It takes any [Standard Schema](https://standardschema.dev), the validation interface zod, valibot, ArkType, and other libraries implement, and the value type comes from the schema’s output.
40
+
41
+ ```ts
42
+ import { z } from 'zod';
43
+
44
+ const QuizSchema = z.object({ question: z.string() });
45
+
46
+ const quizTrack = defineTextTrack({ kind: 'metadata', label: 'quiz', schema: QuizSchema });
47
+ ```
48
+
49
+ Readers skip a cue whose value fails the schema, and warn in development. Each cue is checked once per schema. Schemas must be synchronous; an asynchronous schema fails every value. Adding a track doesn’t run the schema.
50
+
51
+ ### Built-in definitions
52
+
53
+ [`chaptersTrack`](./chapters-track.md) matches every chapters track and types the values chapter formats carry. [`hlsMetadataTrack`](./hls-metadata-track.md) matches the metadata track hls.js publishes ID3 and `EXT-X-DATERANGE` metadata on.
54
+
55
+ ## Exports
56
+
57
+ | Export | Description |
58
+ | --- | --- |
59
+ | `TextTrackDefinition` | A track definition. Its type parameter is the cue type it reads. |
60
+ | `TextTrackIdentity` | What identifies a track: `kind`, `label`, and `language`. |
61
+ | `InferTextTrackCue` | The cue type a definition reads, as in `InferTextTrackCue<typeof quizTrack>`. |
62
+ | `InferSchemaOutput` | The value type a schema produces. |
63
+ | `StandardSchemaV1` | The Standard Schema interface a `schema` implements. |
64
+ | `StandardSchemaV1Props` | The properties a Standard Schema carries under its `~standard` key. |
65
+ | `StandardSchemaV1Result` | What a Standard Schema’s `validate` returns. |
66
+
67
+ ## API Reference
68
+
69
+ ### With Schema
70
+
71
+ `defineTextTrack<Schema extends StandardSchemaV1>(init): TextTrackDefinition<MediaTextCue<InferSchemaOutput<Schema>>>`
72
+
73
+ Define a text track whose cues carry a `value` checked by a schema, such as one from zod or valibot. Cues whose value fails it are skipped where they're read.
74
+
75
+ `const quizTrack = defineTextTrack({ kind: 'metadata', label: 'quiz', schema: QuizSchema });`
76
+
77
+ #### Parameters
78
+
79
+ | Parameter | Type | Default | Description |
80
+ | --- | --- | --- | --- |
81
+ | `init` (required) | `{ kind: 'subtitles' \| 'captions' \| 'descriptions' \| 'chapters' \| 'metadata'; label?: string; language?: string } & { schema: Schema }` | — | The track's kind, and optionally its label and language, with a [Standard Schema](https://standardschema.dev) for its cue values. |
82
+
83
+ #### Return Value
84
+
85
+ | Property | Type | Description |
86
+ | --- | --- | --- |
87
+ | `kind` | `'subtitles' \| 'captions' \| 'descriptions' \| 'chapters' \| 'metadata'` | |
88
+ | `label` | `string \| undefined` | |
89
+ | `language` | `string \| undefined` | |
90
+ | `schema` | `{ ~standard: StandardSchemaV1Props<unknown, Input> } \| undefined` | Checks each cue's `value` where it's read. Cues whose value fails are skipped. |
91
+
92
+ ### With Type
93
+
94
+ `defineTextTrack<Value = unknown>(init): TextTrackDefinition<MediaTextCue<Value>>`
95
+
96
+ Define a text track whose cues carry a `value` of a given type. The type is not checked at runtime; pass a `schema` for that.
97
+
98
+ `const quizTrack = defineTextTrack<Quiz>({ kind: 'metadata', label: 'quiz' });`
99
+
100
+ #### Parameters
101
+
102
+ | Parameter | Type | Default | Description |
103
+ | --- | --- | --- | --- |
104
+ | `init` (required) | `{ kind: 'subtitles' \| 'captions' \| 'descriptions' \| 'chapters' \| 'metadata'; label?: string; language?: string }` | — | The track's kind, and optionally its label and language. |
105
+
106
+ #### Return Value
107
+
108
+ | Property | Type | Description |
109
+ | --- | --- | --- |
110
+ | `kind` | `'subtitles' \| 'captions' \| 'descriptions' \| 'chapters' \| 'metadata'` | |
111
+ | `label` | `string \| undefined` | |
112
+ | `language` | `string \| undefined` | |
113
+ | `schema` | `{ ~standard: StandardSchemaV1Props<unknown, Input> } \| undefined` | Checks each cue's `value` where it's read. Cues whose value fails are skipped. |