@videojs/html 10.1.0 → 10.3.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 (355) hide show
  1. package/dist/default/define/audio/compat-skin.css +116 -65
  2. package/dist/default/define/audio/compat-skin2.js +1 -1
  3. package/dist/default/define/audio/neutral-skin.css +25 -16
  4. package/dist/default/define/audio/neutral-skin2.js +1 -1
  5. package/dist/default/define/audio/scaffold-skin.css +93 -51
  6. package/dist/default/define/audio/scaffold-skin2.js +1 -1
  7. package/dist/default/define/audio/skin.css +21 -6
  8. package/dist/default/define/audio/skin2.js +1 -1
  9. package/dist/default/define/extensions/google-analytics.js +6 -0
  10. package/dist/default/define/live-audio/compat-skin.css +98 -65
  11. package/dist/default/define/live-audio/compat-skin2.js +1 -1
  12. package/dist/default/define/live-audio/neutral-skin.css +8 -5
  13. package/dist/default/define/live-audio/neutral-skin2.js +1 -1
  14. package/dist/default/define/live-audio/scaffold-skin.css +75 -51
  15. package/dist/default/define/live-audio/scaffold-skin2.js +1 -1
  16. package/dist/default/define/live-audio/skin.css +6 -5
  17. package/dist/default/define/live-audio/skin2.js +1 -1
  18. package/dist/default/define/live-video/compat-skin.css +123 -21
  19. package/dist/default/define/live-video/compat-skin2.js +1 -1
  20. package/dist/default/define/live-video/neutral-skin.css +82 -14
  21. package/dist/default/define/live-video/neutral-skin2.js +1 -1
  22. package/dist/default/define/live-video/scaffold-skin.css +107 -26
  23. package/dist/default/define/live-video/scaffold-skin2.js +1 -1
  24. package/dist/default/define/live-video/skin.css +96 -16
  25. package/dist/default/define/live-video/skin2.js +1 -1
  26. package/dist/default/define/media/dailymotion-video.js +11 -0
  27. package/dist/default/define/media/mixcloud-audio.js +11 -0
  28. package/dist/default/define/media/soundcloud-audio.js +11 -0
  29. package/dist/default/define/video/compat-skin.css +123 -21
  30. package/dist/default/define/video/compat-skin2.js +1 -1
  31. package/dist/default/define/video/neutral-skin.css +85 -24
  32. package/dist/default/define/video/neutral-skin2.js +1 -1
  33. package/dist/default/define/video/scaffold-skin.css +107 -26
  34. package/dist/default/define/video/scaffold-skin2.js +1 -1
  35. package/dist/default/define/video/skin.css +94 -16
  36. package/dist/default/define/video/skin2.js +1 -1
  37. package/dist/default/extensions/google-analytics/extension.js +75 -0
  38. package/dist/default/extensions/mux-data/extension.js +7 -2
  39. package/dist/default/internal/skins/compat-audio/register.js +0 -10
  40. package/dist/default/internal/skins/compat-audio/skin.css +116 -65
  41. package/dist/default/internal/skins/compat-audio/template.js +15 -39
  42. package/dist/default/internal/skins/compat-live-audio/register.js +0 -10
  43. package/dist/default/internal/skins/compat-live-audio/skin.css +98 -65
  44. package/dist/default/internal/skins/compat-live-audio/template.js +2 -26
  45. package/dist/default/internal/skins/compat-live-video/skin.css +123 -21
  46. package/dist/default/internal/skins/compat-video/skin.css +123 -21
  47. package/dist/default/internal/skins/default-audio/skin.css +21 -6
  48. package/dist/default/internal/skins/default-live-audio/skin.css +6 -5
  49. package/dist/default/internal/skins/default-live-video/skin.css +96 -16
  50. package/dist/default/internal/skins/default-video/skin.css +94 -16
  51. package/dist/default/internal/skins/neutral-audio/skin.css +25 -16
  52. package/dist/default/internal/skins/neutral-audio/template.js +1 -1
  53. package/dist/default/internal/skins/neutral-live-audio/skin.css +8 -5
  54. package/dist/default/internal/skins/neutral-live-video/skin.css +82 -14
  55. package/dist/default/internal/skins/neutral-video/skin.css +85 -24
  56. package/dist/default/internal/skins/neutral-video/template.js +1 -1
  57. package/dist/default/internal/skins/scaffold-audio/register.js +0 -10
  58. package/dist/default/internal/skins/scaffold-audio/skin.css +93 -51
  59. package/dist/default/internal/skins/scaffold-audio/template.js +15 -39
  60. package/dist/default/internal/skins/scaffold-live-audio/register.js +0 -10
  61. package/dist/default/internal/skins/scaffold-live-audio/skin.css +75 -51
  62. package/dist/default/internal/skins/scaffold-live-audio/template.js +2 -26
  63. package/dist/default/internal/skins/scaffold-live-video/skin.css +107 -26
  64. package/dist/default/internal/skins/scaffold-video/skin.css +107 -26
  65. package/dist/default/media/dailymotion-video/adapter.js +31 -0
  66. package/dist/default/media/hls-audio/adapter.js +1 -1
  67. package/dist/default/media/hls-background-video/adapter.js +8 -1
  68. package/dist/default/media/hls-video/adapter.js +1 -1
  69. package/dist/default/media/mixcloud-audio/adapter.js +16 -0
  70. package/dist/default/media/soundcloud-audio/adapter.js +16 -0
  71. package/dist/default/player/element.js +1 -5
  72. package/dist/default/presets/background/skin.js +2 -2
  73. package/dist/default/presets/skin.js +4 -3
  74. package/dist/default/ui/dialog/element.js +13 -1
  75. package/dist/default/ui/gesture/element.js +3 -0
  76. package/dist/default/ui/media-button-element.js +10 -1
  77. package/dist/default/ui/playback-rate-button/element.js +7 -2
  78. package/dist/default/ui/playback-rate-radio-group/element.js +10 -3
  79. package/dist/default/ui/radio-options/controller.js +18 -5
  80. package/dist/default/ui/slider/element.js +3 -1
  81. package/dist/default/ui/time-slider/element.js +19 -7
  82. package/dist/default/ui/volume-slider/element.js +3 -1
  83. package/dist/default/version.js +1 -1
  84. package/dist/dev/define/audio/compat-skin.css +116 -65
  85. package/dist/dev/define/audio/compat-skin2.js +1 -1
  86. package/dist/dev/define/audio/compat-skin2.js.map +1 -1
  87. package/dist/dev/define/audio/neutral-skin.css +25 -16
  88. package/dist/dev/define/audio/neutral-skin2.js +1 -1
  89. package/dist/dev/define/audio/neutral-skin2.js.map +1 -1
  90. package/dist/dev/define/audio/scaffold-skin.css +93 -51
  91. package/dist/dev/define/audio/scaffold-skin2.js +1 -1
  92. package/dist/dev/define/audio/scaffold-skin2.js.map +1 -1
  93. package/dist/dev/define/audio/skin.css +21 -6
  94. package/dist/dev/define/audio/skin2.js +1 -1
  95. package/dist/dev/define/audio/skin2.js.map +1 -1
  96. package/dist/dev/define/extensions/google-analytics.d.ts +11 -0
  97. package/dist/dev/define/extensions/google-analytics.js +8 -0
  98. package/dist/dev/define/extensions/google-analytics.js.map +1 -0
  99. package/dist/dev/define/live-audio/compat-skin.css +98 -65
  100. package/dist/dev/define/live-audio/compat-skin2.js +1 -1
  101. package/dist/dev/define/live-audio/compat-skin2.js.map +1 -1
  102. package/dist/dev/define/live-audio/neutral-skin.css +8 -5
  103. package/dist/dev/define/live-audio/neutral-skin2.js +1 -1
  104. package/dist/dev/define/live-audio/neutral-skin2.js.map +1 -1
  105. package/dist/dev/define/live-audio/scaffold-skin.css +75 -51
  106. package/dist/dev/define/live-audio/scaffold-skin2.js +1 -1
  107. package/dist/dev/define/live-audio/scaffold-skin2.js.map +1 -1
  108. package/dist/dev/define/live-audio/skin.css +6 -5
  109. package/dist/dev/define/live-audio/skin2.js +1 -1
  110. package/dist/dev/define/live-audio/skin2.js.map +1 -1
  111. package/dist/dev/define/live-video/compat-skin.css +123 -21
  112. package/dist/dev/define/live-video/compat-skin2.js +1 -1
  113. package/dist/dev/define/live-video/compat-skin2.js.map +1 -1
  114. package/dist/dev/define/live-video/neutral-skin.css +82 -14
  115. package/dist/dev/define/live-video/neutral-skin2.js +1 -1
  116. package/dist/dev/define/live-video/neutral-skin2.js.map +1 -1
  117. package/dist/dev/define/live-video/scaffold-skin.css +107 -26
  118. package/dist/dev/define/live-video/scaffold-skin2.js +1 -1
  119. package/dist/dev/define/live-video/scaffold-skin2.js.map +1 -1
  120. package/dist/dev/define/live-video/skin.css +96 -16
  121. package/dist/dev/define/live-video/skin2.js +1 -1
  122. package/dist/dev/define/live-video/skin2.js.map +1 -1
  123. package/dist/dev/define/media/dailymotion-video.d.ts +15 -0
  124. package/dist/dev/define/media/dailymotion-video.js +13 -0
  125. package/dist/dev/define/media/dailymotion-video.js.map +1 -0
  126. package/dist/dev/define/media/mixcloud-audio.d.ts +15 -0
  127. package/dist/dev/define/media/mixcloud-audio.js +13 -0
  128. package/dist/dev/define/media/mixcloud-audio.js.map +1 -0
  129. package/dist/dev/define/media/soundcloud-audio.d.ts +15 -0
  130. package/dist/dev/define/media/soundcloud-audio.js +13 -0
  131. package/dist/dev/define/media/soundcloud-audio.js.map +1 -0
  132. package/dist/dev/define/video/compat-skin.css +123 -21
  133. package/dist/dev/define/video/compat-skin2.js +1 -1
  134. package/dist/dev/define/video/compat-skin2.js.map +1 -1
  135. package/dist/dev/define/video/neutral-skin.css +85 -24
  136. package/dist/dev/define/video/neutral-skin2.js +1 -1
  137. package/dist/dev/define/video/neutral-skin2.js.map +1 -1
  138. package/dist/dev/define/video/scaffold-skin.css +107 -26
  139. package/dist/dev/define/video/scaffold-skin2.js +1 -1
  140. package/dist/dev/define/video/scaffold-skin2.js.map +1 -1
  141. package/dist/dev/define/video/skin.css +94 -16
  142. package/dist/dev/define/video/skin2.js +1 -1
  143. package/dist/dev/define/video/skin2.js.map +1 -1
  144. package/dist/dev/extensions/google-analytics/extension.d.ts +52 -0
  145. package/dist/dev/extensions/google-analytics/extension.js +77 -0
  146. package/dist/dev/extensions/google-analytics/extension.js.map +1 -0
  147. package/dist/dev/extensions/google-analytics/index.d.ts +2 -0
  148. package/dist/dev/extensions/mux-data/extension.d.ts +4 -1
  149. package/dist/dev/extensions/mux-data/extension.js +7 -2
  150. package/dist/dev/extensions/mux-data/extension.js.map +1 -1
  151. package/dist/dev/index.d.ts +3 -3
  152. package/dist/dev/internal/skins/compat-audio/register.d.ts +3 -5
  153. package/dist/dev/internal/skins/compat-audio/register.js +0 -10
  154. package/dist/dev/internal/skins/compat-audio/register.js.map +1 -1
  155. package/dist/dev/internal/skins/compat-audio/skin.css +116 -65
  156. package/dist/dev/internal/skins/compat-audio/template.js +15 -39
  157. package/dist/dev/internal/skins/compat-audio/template.js.map +1 -1
  158. package/dist/dev/internal/skins/compat-live-audio/register.d.ts +0 -2
  159. package/dist/dev/internal/skins/compat-live-audio/register.js +0 -10
  160. package/dist/dev/internal/skins/compat-live-audio/register.js.map +1 -1
  161. package/dist/dev/internal/skins/compat-live-audio/skin.css +98 -65
  162. package/dist/dev/internal/skins/compat-live-audio/template.js +2 -26
  163. package/dist/dev/internal/skins/compat-live-audio/template.js.map +1 -1
  164. package/dist/dev/internal/skins/compat-live-video/register.d.ts +2 -2
  165. package/dist/dev/internal/skins/compat-live-video/skin.css +123 -21
  166. package/dist/dev/internal/skins/compat-video/register.d.ts +5 -5
  167. package/dist/dev/internal/skins/compat-video/skin.css +123 -21
  168. package/dist/dev/internal/skins/default-audio/register.d.ts +1 -1
  169. package/dist/dev/internal/skins/default-audio/skin.css +21 -6
  170. package/dist/dev/internal/skins/default-live-audio/skin.css +6 -5
  171. package/dist/dev/internal/skins/default-live-video/register.d.ts +2 -2
  172. package/dist/dev/internal/skins/default-live-video/skin.css +96 -16
  173. package/dist/dev/internal/skins/default-video/register.d.ts +3 -3
  174. package/dist/dev/internal/skins/default-video/skin.css +94 -16
  175. package/dist/dev/internal/skins/neutral-audio/register.d.ts +3 -3
  176. package/dist/dev/internal/skins/neutral-audio/skin.css +25 -16
  177. package/dist/dev/internal/skins/neutral-audio/template.js +1 -1
  178. package/dist/dev/internal/skins/neutral-audio/template.js.map +1 -1
  179. package/dist/dev/internal/skins/neutral-live-audio/skin.css +8 -5
  180. package/dist/dev/internal/skins/neutral-live-video/register.d.ts +2 -2
  181. package/dist/dev/internal/skins/neutral-live-video/skin.css +82 -14
  182. package/dist/dev/internal/skins/neutral-video/register.d.ts +5 -5
  183. package/dist/dev/internal/skins/neutral-video/skin.css +85 -24
  184. package/dist/dev/internal/skins/neutral-video/template.js +1 -1
  185. package/dist/dev/internal/skins/neutral-video/template.js.map +1 -1
  186. package/dist/dev/internal/skins/scaffold-audio/register.d.ts +3 -5
  187. package/dist/dev/internal/skins/scaffold-audio/register.js +0 -10
  188. package/dist/dev/internal/skins/scaffold-audio/register.js.map +1 -1
  189. package/dist/dev/internal/skins/scaffold-audio/skin.css +93 -51
  190. package/dist/dev/internal/skins/scaffold-audio/template.js +15 -39
  191. package/dist/dev/internal/skins/scaffold-audio/template.js.map +1 -1
  192. package/dist/dev/internal/skins/scaffold-live-audio/register.d.ts +0 -2
  193. package/dist/dev/internal/skins/scaffold-live-audio/register.js +0 -10
  194. package/dist/dev/internal/skins/scaffold-live-audio/register.js.map +1 -1
  195. package/dist/dev/internal/skins/scaffold-live-audio/skin.css +75 -51
  196. package/dist/dev/internal/skins/scaffold-live-audio/template.js +2 -26
  197. package/dist/dev/internal/skins/scaffold-live-audio/template.js.map +1 -1
  198. package/dist/dev/internal/skins/scaffold-live-video/register.d.ts +2 -2
  199. package/dist/dev/internal/skins/scaffold-live-video/skin.css +107 -26
  200. package/dist/dev/internal/skins/scaffold-video/register.d.ts +5 -5
  201. package/dist/dev/internal/skins/scaffold-video/skin.css +107 -26
  202. package/dist/dev/media/dailymotion-video/adapter.d.ts +17 -0
  203. package/dist/dev/media/dailymotion-video/adapter.js +47 -0
  204. package/dist/dev/media/dailymotion-video/adapter.js.map +1 -0
  205. package/dist/dev/media/dailymotion-video/index.d.ts +2 -0
  206. package/dist/dev/media/hls-audio/adapter.d.ts +1 -1
  207. package/dist/dev/media/hls-audio/adapter.js +1 -1
  208. package/dist/dev/media/hls-audio/adapter.js.map +1 -1
  209. package/dist/dev/media/hls-background-video/adapter.d.ts +6 -1
  210. package/dist/dev/media/hls-background-video/adapter.js +8 -1
  211. package/dist/dev/media/hls-background-video/adapter.js.map +1 -1
  212. package/dist/dev/media/hls-video/adapter.d.ts +1 -1
  213. package/dist/dev/media/hls-video/adapter.js +1 -1
  214. package/dist/dev/media/hls-video/adapter.js.map +1 -1
  215. package/dist/dev/media/mixcloud-audio/adapter.d.ts +11 -0
  216. package/dist/dev/media/mixcloud-audio/adapter.js +52 -0
  217. package/dist/dev/media/mixcloud-audio/adapter.js.map +1 -0
  218. package/dist/dev/media/mixcloud-audio/index.d.ts +2 -0
  219. package/dist/dev/media/soundcloud-audio/adapter.d.ts +11 -0
  220. package/dist/dev/media/soundcloud-audio/adapter.js +53 -0
  221. package/dist/dev/media/soundcloud-audio/adapter.js.map +1 -0
  222. package/dist/dev/media/soundcloud-audio/index.d.ts +2 -0
  223. package/dist/dev/player/element.js +1 -5
  224. package/dist/dev/player/element.js.map +1 -1
  225. package/dist/dev/presets/background/skin.d.ts +2 -1
  226. package/dist/dev/presets/background/skin.js +2 -2
  227. package/dist/dev/presets/background/skin.js.map +1 -1
  228. package/dist/dev/presets/skin.d.ts +4 -3
  229. package/dist/dev/presets/skin.js +4 -3
  230. package/dist/dev/presets/skin.js.map +1 -1
  231. package/dist/dev/ui/dialog/element.js +13 -1
  232. package/dist/dev/ui/dialog/element.js.map +1 -1
  233. package/dist/dev/ui/gesture/element.js +3 -0
  234. package/dist/dev/ui/gesture/element.js.map +1 -1
  235. package/dist/dev/ui/media-button-element.d.ts +9 -0
  236. package/dist/dev/ui/media-button-element.js +10 -1
  237. package/dist/dev/ui/media-button-element.js.map +1 -1
  238. package/dist/dev/ui/play-button/element.d.ts +2 -0
  239. package/dist/dev/ui/playback-rate-button/element.d.ts +9 -1
  240. package/dist/dev/ui/playback-rate-button/element.js +7 -2
  241. package/dist/dev/ui/playback-rate-button/element.js.map +1 -1
  242. package/dist/dev/ui/playback-rate-radio-group/element.d.ts +4 -0
  243. package/dist/dev/ui/playback-rate-radio-group/element.js +10 -3
  244. package/dist/dev/ui/playback-rate-radio-group/element.js.map +1 -1
  245. package/dist/dev/ui/radio-options/controller.js +18 -5
  246. package/dist/dev/ui/radio-options/controller.js.map +1 -1
  247. package/dist/dev/ui/slider/element.js +3 -1
  248. package/dist/dev/ui/slider/element.js.map +1 -1
  249. package/dist/dev/ui/time-slider/element.js +19 -7
  250. package/dist/dev/ui/time-slider/element.js.map +1 -1
  251. package/dist/dev/ui/volume-slider/element.js +3 -1
  252. package/dist/dev/ui/volume-slider/element.js.map +1 -1
  253. package/dist/dev/version.js +1 -1
  254. package/docs/README.md +1 -1
  255. package/docs/guides/autoplay.md +1 -1
  256. package/docs/guides/browser-support.md +13 -11
  257. package/docs/guides/build-your-own-skin.md +383 -0
  258. package/docs/guides/cdn.md +10 -9
  259. package/docs/guides/content-security-policy.md +3 -0
  260. package/docs/guides/customize-skins.md +6 -3
  261. package/docs/guides/features.md +1 -1
  262. package/docs/guides/google-analytics.md +199 -0
  263. package/docs/guides/installation-cdn.md +4 -4
  264. package/docs/guides/installation-shadcn.md +3 -3
  265. package/docs/guides/installation-svelte.md +4 -4
  266. package/docs/guides/installation-vue.md +4 -4
  267. package/docs/guides/installation.md +4 -4
  268. package/docs/guides/internationalization.md +5 -5
  269. package/docs/guides/keyboard-shortcuts.md +1 -1
  270. package/docs/guides/llms.txt +3 -1
  271. package/docs/guides/media-sources.md +3 -0
  272. package/docs/guides/migrate-from-media-chrome.md +4 -4
  273. package/docs/guides/migrate-from-mux-player.md +9 -9
  274. package/docs/guides/migrate-from-plyr.md +8 -8
  275. package/docs/guides/migrate-from-video-js-8.md +9 -10
  276. package/docs/guides/migrate-from-vidstack.md +9 -9
  277. package/docs/guides/mux-data.md +22 -0
  278. package/docs/guides/presets.md +1 -1
  279. package/docs/guides/self-hosting.md +9 -6
  280. package/docs/guides/skins.md +17 -1
  281. package/docs/guides/ui-components.md +1 -1
  282. package/docs/llms.txt +12 -6
  283. package/docs/reference/api/feature-playback-rate.md +54 -3
  284. package/docs/reference/api/feature-playback.md +5 -1
  285. package/docs/reference/api/html-create-player.md +2 -2
  286. package/docs/reference/api/llms.txt +1 -1
  287. package/docs/reference/api/media-capabilities.md +1 -1
  288. package/docs/reference/api/player-store.md +6 -3
  289. package/docs/reference/api/preset-audio.md +13 -5
  290. package/docs/reference/api/preset-background.md +2 -2
  291. package/docs/reference/api/preset-live-audio.md +13 -5
  292. package/docs/reference/api/preset-live-video.md +13 -5
  293. package/docs/reference/api/preset-video.md +13 -5
  294. package/docs/reference/api/resolve-adapter-type.md +4 -1
  295. package/docs/reference/api/ui-element.md +2 -2
  296. package/docs/reference/components/alert-dialog.md +21 -16
  297. package/docs/reference/components/audio-compat-skin.md +8 -2
  298. package/docs/reference/components/audio-neutral-skin.md +2 -2
  299. package/docs/reference/components/audio-scaffold-skin.md +2 -2
  300. package/docs/reference/components/audio-skin.md +2 -2
  301. package/docs/reference/components/audio-track-radio-group.md +2 -2
  302. package/docs/reference/components/background-video-skin.md +1 -1
  303. package/docs/reference/components/background-video.md +1 -1
  304. package/docs/reference/components/buffering-indicator.md +2 -2
  305. package/docs/reference/components/captions-radio-group.md +2 -2
  306. package/docs/reference/components/cloudflare-video.md +1 -1
  307. package/docs/reference/components/dailymotion-video.md +192 -0
  308. package/docs/reference/components/dash-video.md +2 -1
  309. package/docs/reference/components/dialog.md +49 -22
  310. package/docs/reference/components/error-dialog.md +13 -10
  311. package/docs/reference/components/gesture.md +2 -2
  312. package/docs/reference/components/google-analytics.md +51 -0
  313. package/docs/reference/components/google-cast.md +1 -1
  314. package/docs/reference/components/hls-audio.md +2 -48
  315. package/docs/reference/components/hls-background-video.md +4 -1
  316. package/docs/reference/components/hls-video.md +2 -66
  317. package/docs/reference/components/hlsjs-video.md +3 -1
  318. package/docs/reference/components/hotkey.md +2 -2
  319. package/docs/reference/components/live-audio-compat-skin.md +8 -2
  320. package/docs/reference/components/live-audio-neutral-skin.md +2 -2
  321. package/docs/reference/components/live-audio-scaffold-skin.md +2 -2
  322. package/docs/reference/components/live-audio-skin.md +2 -2
  323. package/docs/reference/components/live-video-compat-skin.md +8 -2
  324. package/docs/reference/components/live-video-neutral-skin.md +2 -2
  325. package/docs/reference/components/live-video-scaffold-skin.md +2 -2
  326. package/docs/reference/components/live-video-skin.md +2 -2
  327. package/docs/reference/components/llms.txt +9 -5
  328. package/docs/reference/components/mixcloud-audio.md +203 -0
  329. package/docs/reference/components/mux-audio.md +3 -1
  330. package/docs/reference/components/mux-background-video.md +1 -1
  331. package/docs/reference/components/mux-data.md +22 -2
  332. package/docs/reference/components/mux-video.md +3 -1
  333. package/docs/reference/components/native-hls-video.md +2 -1
  334. package/docs/reference/components/play-button.md +7 -5
  335. package/docs/reference/components/playback-rate-button.md +26 -7
  336. package/docs/reference/components/playback-rate-radio-group.md +7 -4
  337. package/docs/reference/components/player.md +3 -3
  338. package/docs/reference/components/playerjs-video.md +1 -1
  339. package/docs/reference/components/quality-radio-group.md +2 -2
  340. package/docs/reference/components/shaka-video.md +2 -1
  341. package/docs/reference/components/slider.md +2 -0
  342. package/docs/reference/components/soundcloud-audio.md +227 -0
  343. package/docs/reference/components/spotify-audio.md +2 -2
  344. package/docs/reference/components/tiktok-video.md +2 -2
  345. package/docs/reference/components/time-slider.md +7 -5
  346. package/docs/reference/components/twitch-video.md +2 -3
  347. package/docs/reference/components/video-compat-skin.md +8 -2
  348. package/docs/reference/components/video-neutral-skin.md +2 -2
  349. package/docs/reference/components/video-scaffold-skin.md +2 -2
  350. package/docs/reference/components/video-skin.md +2 -2
  351. package/docs/reference/components/vimeo-video.md +2 -1
  352. package/docs/reference/components/volume-slider.md +8 -6
  353. package/docs/reference/components/wistia-video.md +1 -1
  354. package/docs/reference/components/youtube-video.md +2 -1
  355. package/package.json +62 -43
@@ -18,22 +18,24 @@ import '@videojs/html/ui/play-button';
18
18
 
19
19
  The play button is a three-state button: **play**, **pause**, and **replay**. When media reaches the end (`ended` state), clicking restarts playback from the beginning.
20
20
 
21
+ While media with `autoplay` is trying to start, the button shows **pause**, and clicking it cancels the autoplay. If the browser refuses the autoplay, the button returns to **play**.
22
+
21
23
  ## Styling
22
24
 
23
- Style with the `[data-paused]` and `[data-ended]` attributes to show/hide play/pause/replay icons based on state. For example:
25
+ Style with the `[data-paused]` and `[data-ended]` attributes to show/hide play/pause/replay icons based on state. While autoplay is pending, the button omits `data-paused` and adds `data-started`, so the pause icon shows. For example:
24
26
 
25
27
  ```css
26
28
  /* Paused (but not ended) */
27
29
  media-play-button[data-paused]:not([data-ended]) .play-icon { display: inline; }
28
30
 
29
- /* Playing */
31
+ /* Playing, or autoplay pending */
30
32
  media-play-button:not([data-paused]) .pause-icon { display: inline; }
31
33
 
32
34
  /* Ended */
33
35
  media-play-button[data-ended] .replay-icon { display: inline; }
34
36
  ```
35
37
 
36
- After first play, the `data-started` attribute is added and remains present until a new source is loaded. Use this to hide the play button when media hasn’t started yet:
38
+ The `data-started` attribute is present while the media tries to autoplay, and from first play until a new source is loaded. Use this to hide the play button when media hasn’t started yet:
37
39
 
38
40
  ```css
39
41
  /* Hide play button before first play */
@@ -146,6 +148,6 @@ State is reflected as data attributes for CSS styling.
146
148
 
147
149
  | Attribute | Description |
148
150
  | --- | --- |
149
- | `data-paused` | Present when the media is paused. |
151
+ | `data-paused` | Present when the media is paused and not trying to autoplay. |
150
152
  | `data-ended` | Present when the media has ended. |
151
- | `data-started` | Present when playback has started. |
153
+ | `data-started` | Present when playback has started or the media is trying to autoplay. |
@@ -16,12 +16,20 @@ import '@videojs/html/ui/playback-rate-button';
16
16
 
17
17
  ## Behavior
18
18
 
19
- Cycles through playback rates on click. The default rate list is `[0.2, 0.5, 0.7, 1, 1.2, 1.5, 1.7, 2]`. After the last rate, it wraps back to the first. If the current rate isn’t in the list (e.g., set programmatically), the button jumps to the next rate greater than the current one.
19
+ Cycles through the player’s playback rates on click, in the order they are listed. The default list is `[0.5, 0.75, 1, 1.25, 1.5, 1.75, 2]`; see the [playback rate feature](../api/feature-playback-rate.md) to set your own for the whole player, or set `rates` on the button to give it its own list. After the last rate, it wraps back to the first. If the current rate isn’t in the list (e.g., set programmatically), the button jumps to the next rate greater than the current one.
20
20
 
21
21
  When `commandfor` is set, activation opens the linked playback-rate menu instead of cycling through rates. Use this mode when the button is the trigger for a `<media-menu>` that contains playback-rate options.
22
22
 
23
+ When the media’s playback rate is unavailable or unsupported, such as on an embed that takes no speed command, the element receives the native `hidden` attribute and ignores activation.
24
+
23
25
  ## Styling
24
26
 
27
+ | Attribute | Values | Description |
28
+ | --- | --- | --- |
29
+ | `data-rate` | Number | Current playback rate |
30
+ | `data-availability` | `"available"` \| `"unavailable"` \| `"unsupported"` | Whether the media can change its playback rate |
31
+ | `data-hidden` | Present / absent | Present on the HTML element while playback rate is unavailable or unsupported |
32
+
25
33
  Display the current rate using the `data-rate` attribute:
26
34
 
27
35
  ```css
@@ -32,7 +40,7 @@ media-playback-rate-button::after {
32
40
 
33
41
  ## Accessibility
34
42
 
35
- Renders a `<button>` with an automatic `aria-label` of `"Playback rate {rate}"` (e.g., `"Playback rate 1.5"`). Override with the `label` prop. Keyboard activation: Enter / Space.
43
+ Renders a `<button>` with an automatic `aria-label` of `"Playback rate, {rate}"` (e.g., `"Playback rate, 1.5"`). Its tooltip shows `"Playback rate"` without the value. Override both with the `label` prop. Keyboard activation: Enter / Space.
36
44
 
37
45
  In menu-trigger mode, the button behaves as a menu trigger and reflects menu state through the trigger attributes.
38
46
 
@@ -97,18 +105,29 @@ import '@videojs/html/ui/playback-rate-button';
97
105
  | --- | --- | --- | --- |
98
106
  | `disabled` | `boolean` | `false` | Whether the button is disabled. |
99
107
  | `label` | `{ key: string; text: string } \| string \| ((state: PlaybackRateButtonState) => Text \| string)` | `''` | Custom label for the button. |
108
+ | `rates` | `readonly number[] \| string` | `[]` | Rates to cycle through, in order, in place of the player's `defaultPlaybackRates`. HTML takes a space-separated list, such as `rates="1 1.5 2"`. |
100
109
 
101
110
  ### State
102
111
 
103
112
  State is reflected as data attributes for CSS styling.
104
113
 
105
- | Property | Type |
106
- | --- | --- |
107
- | `label` | `{ key: string; text: string } \| string` |
108
- | `rate` | `number` |
114
+ | Property | Type | Description |
115
+ | --- | --- | --- |
116
+ | `label` | `{ key: string; text: string } \| string` | |
117
+ | `rate` | `number` | |
118
+ | `availability` | `'available' \| 'unavailable' \| 'unsupported'` | Whether the media can change its playback rate. |
119
+ | `hidden` | `boolean` | Whether the button is hidden because the media has no playback rate to change. |
109
120
 
110
121
  ### Data attributes
111
122
 
112
123
  | Attribute | Type | Description |
113
124
  | --- | --- | --- |
114
- | `data-rate` | `number` | Current playback rate. |
125
+ | `data-rate` | `number` | Current playback rate. |
126
+ | `data-availability` | `'available' \| 'unavailable' \| 'unsupported'` | Indicates playback rate availability (`available`, `unavailable`, `unsupported`). |
127
+ | `data-hidden` | — | Present when the button is hidden because the media has no playback rate to change. |
128
+
129
+ ### CSS custom properties
130
+
131
+ | Variable | Description |
132
+ | --- | --- |
133
+ | `--media-playback-rate-length` | Characters in the current rate as text, such as `4` for `1.75`. Lets a skin size the label to fit the button. |
@@ -27,7 +27,9 @@ import '@videojs/html/ui/menu-item-indicator';
27
27
 
28
28
  ## Behavior
29
29
 
30
- The group is available when the configured media exposes playback rates. Option labels default to the rate followed by a multiplication sign (e.g. `1.5×`); pass `formatRate` to customize them.
30
+ The group is available when the configured media exposes playback rates. It offers the player’s playback rates, or its own when you set `rates`. Option labels default to the rate followed by a multiplication sign (e.g. `1.5×`); pass `formatRate` to customize them.
31
+
32
+ When the current rate isn’t one the group offers, such as `1.1` set through the media API, the group adds it as an extra item before the next faster rate. That item carries `data-custom`, and its accessible name is “Custom, 1.1×” while its visible label stays `1.1×`. It goes away once the rate is back on the list.
31
33
 
32
34
  `<media-playback-rate-radio-group>` generates `<media-menu-radio-item>` children. Add an optional `<template>` with a single `<media-menu-radio-item>` to customize each generated item.
33
35
 
@@ -40,7 +42,7 @@ The group is available when the configured media exposes playback rates. Option
40
42
  | `data-hidden` | Present / absent | Present when playback-rate selection is unavailable. |
41
43
  | `data-availability` | `"available"` / `"unavailable"` | Whether playback rates are available. |
42
44
 
43
- Unavailable groups receive the native `hidden` attribute.
45
+ Unavailable groups receive the native `hidden` attribute. Each item carries `data-rate`, and an item for a current rate the group doesn’t offer also carries `data-custom`.
44
46
 
45
47
  ## Accessibility
46
48
 
@@ -180,6 +182,7 @@ Menu radio group that generates a `<media-menu-radio-item>` per available playba
180
182
  | --- | --- | --- | --- |
181
183
  | `disabled` | `boolean` | `false` | Whether playback rate selection is disabled. |
182
184
  | `formatRate` (attribute `format-rate`) | `((rate: number) => string)` | `formatPlaybackRate` | Custom formatter for visible playback rate labels. |
185
+ | `rates` | `readonly number[] \| string` | `[]` | Rates to offer, in order, in place of the player's `defaultPlaybackRates`. HTML takes a space-separated list, such as `rates="1 1.5 2"`. |
183
186
 
184
187
  #### State
185
188
 
@@ -192,7 +195,7 @@ State is reflected as data attributes for CSS styling.
192
195
  | `options` | `readonly Option[]` | Ordered options displayed by platform adapters. |
193
196
  | `disabled` | `boolean` | Whether the entire option group is disabled. |
194
197
  | `hidden` | `boolean` | Whether the option group is hidden because no meaningful selection is available. |
195
- | `availability` | `'available' \| 'unavailable'` | Whether the media exposes a meaningful selection. |
198
+ | `availability` | `'available' \| 'unavailable' \| 'unsupported'` | Whether the media exposes a meaningful selection. `unsupported` when the media has no such capability at all. |
196
199
  | `rate` | `number` | |
197
200
 
198
201
  #### Data attributes
@@ -202,7 +205,7 @@ State is reflected as data attributes for CSS styling.
202
205
  | `data-rate` | `number` | Current playback rate. |
203
206
  | `data-disabled` | — | Present when playback rate selection is disabled. |
204
207
  | `data-hidden` | — | Present when playback rate selection is unavailable. |
205
- | `data-availability` | `'available' \| 'unavailable'` | Indicates playback rate availability (`available` or `unavailable`). |
208
+ | `data-availability` | `'available' \| 'unavailable' \| 'unsupported'` | Indicates playback rate availability (`available`, `unavailable`, `unsupported`). |
206
209
 
207
210
  #### Events
208
211
 
@@ -124,14 +124,14 @@ Video.js elements clean up after themselves when you remove them from the page:
124
124
  - `<video-player>` and the UI elements destroy themselves two animation frames after they’re removed. Destroying the player also destroys its store.
125
125
  - Media components such as `<hlsjs-video>` tear down their playback engine in a microtask after they’re removed.
126
126
 
127
- Moving an element synchronously, removing it and inserting it elsewhere with no `await` in between, triggers neither. To keep an element through a longer move, add the `keep-alive` attribute:
127
+ Moving an element synchronously, removing it and inserting it elsewhere with no `await` in between, triggers neither. To keep the player through a longer move, add the `keep-alive` attribute to it and to its media component:
128
128
 
129
129
  ```html
130
130
  <video-player keep-alive>
131
- <media-container keep-alive>
131
+ <media-container>
132
132
  <hlsjs-video src="/stream.m3u8" keep-alive></hlsjs-video>
133
133
  </media-container>
134
134
  </video-player>
135
135
  ```
136
136
 
137
- `keep-alive` applies only to the element that carries it; descendants don’t inherit it. Set it on every Video.js element in the tree you move. Packaged skins don’t pass it to the controls inside them, so move a player that uses a packaged skin synchronously. An element with `keep-alive` is never destroyed automatically. When you’re finished with it, call `destroy()` on the player and UI elements, and `adapter.destroy()` on media components, which release their engine that way. A destroyed element can’t be reconnected; create a new one instead.
137
+ On the player, `keep-alive` covers the player and every UI element inside it, including the controls inside a packaged skin. Media components don’t inherit it, because destroying the player doesn’t release their engine: give each one its own `keep-alive`, or it tears down its engine as usual. An element you remove on its own from a kept-alive tree still destroys itself. `keep-alive` only stops an element from destroying itself: destroying an element, automatically or with `destroy()`, also destroys the UI elements inside it, including ones that carry `keep-alive`. When you’re finished, call `destroy()` on the player and `adapter.destroy()` on each media component to release its engine. A destroyed element can’t be reconnected; create a new one instead.
@@ -17,7 +17,7 @@ import '@videojs/html/media/playerjs-video';
17
17
  Or load it from the [CDN](../../guides/cdn.md):
18
18
 
19
19
  ```html
20
- <script type="module" src="https://cdn.jsdelivr.net/npm/@videojs/cdn@10.1.0/media/playerjs-video.js"></script>
20
+ <script type="module" src="https://cdn.jsdelivr.net/npm/@videojs/cdn@10.3.0/media/playerjs-video.js"></script>
21
21
  ```
22
22
 
23
23
  ## Load a source
@@ -220,7 +220,7 @@ State is reflected as data attributes for CSS styling.
220
220
  | `options` | `readonly Option[]` | Ordered options displayed by platform adapters. |
221
221
  | `disabled` | `boolean` | Whether the entire option group is disabled. |
222
222
  | `hidden` | `boolean` | Whether the option group is hidden because no meaningful selection is available. |
223
- | `availability` | `'available' \| 'unavailable'` | Whether the media exposes a meaningful selection. |
223
+ | `availability` | `'available' \| 'unavailable' \| 'unsupported'` | Whether the media exposes a meaningful selection. `unsupported` when the media has no such capability at all. |
224
224
 
225
225
  #### Data attributes
226
226
 
@@ -229,7 +229,7 @@ State is reflected as data attributes for CSS styling.
229
229
  | `data-quality` | `string` | Current quality value. |
230
230
  | `data-disabled` | — | Present when quality selection is disabled. |
231
231
  | `data-hidden` | — | Present when quality selection is unavailable. |
232
- | `data-availability` | `'available' \| 'unavailable'` | Indicates quality availability (`available` or `unavailable`). |
232
+ | `data-availability` | `'available' \| 'unavailable' \| 'unsupported'` | Indicates quality availability (`available` or `unavailable`). |
233
233
 
234
234
  #### Events
235
235
 
@@ -21,7 +21,7 @@ import '@videojs/html/media/shaka-video';
21
21
  Or load it from the [CDN](../../guides/cdn.md):
22
22
 
23
23
  ```html
24
- <script type="module" src="https://cdn.jsdelivr.net/npm/@videojs/cdn@10.1.0/media/shaka-video.js"></script>
24
+ <script type="module" src="https://cdn.jsdelivr.net/npm/@videojs/cdn@10.3.0/media/shaka-video.js"></script>
25
25
  ```
26
26
 
27
27
  ## Load a source
@@ -121,6 +121,7 @@ These Video.js-specific attributes configure media behavior:
121
121
  | `isFullscreen` | `boolean` | — | Read-only. |
122
122
  | `isPictureInPicture` | `boolean` | — | Read-only. |
123
123
  | `liveEdgeStart` | `number` | — | Read-only. |
124
+ | `playbackRateRange` | `{ min: number; max: number } \| undefined` | — | Read-only. The target's narrower rate range, when it reports one; native media accept the browser's range. |
124
125
  | `preload` | `'' \| 'none' \| 'metadata' \| 'auto'` | `'metadata'` | How much to fetch before playback is asked for, mirroring the media element's own `preload`. Shaka has no split between "know the source" and "buffer it", so this maps onto when and how `engine.load()` runs:<br>- `'auto'` — load immediately with the configured buffering goals.<br>- `'metadata'` — load immediately, holding buffering to about a segment; the configured goals come back on the first play intent.<br>- `'none'` / `''` — hold the load entirely until the first play intent. A play intent is a `play` event, a target that is already playing, or `autoplay` — which the spec lets override `preload` for good reason: with nothing fetched there is nothing whose readiness could ever fire it. Widening (`none` → `auto`) takes effect immediately; narrowing after a load began cannot un-fetch and leaves it alone. |
125
126
  | `source` | `{ src?: string; type?: string; drm?: Partial<Record<KeySystem, DrmSystemConfig>>; engine?: ShakaEngineConfig } \| null` | `null` | Structured source: what to play (`src`, an optional `type`) plus how to play it (`drm`, `engine.shaka`). Replacing it re-derives `src`. Shaka takes configuration on a live player, so changing `engine.shaka` re-applies it in place instead of recreating the engine. |
126
127
  | `src` | `string` | `''` | |
@@ -73,6 +73,8 @@ Renders with `role="slider"` and automatic ARIA attributes (`aria-valuemin`, `ar
73
73
  - Home: jump to minimum
74
74
  - End: jump to maximum
75
75
 
76
+ Before each keyboard step, the value snaps to the nearest multiple of `step`.
77
+
76
78
  ## Examples
77
79
 
78
80
  ### Basic
@@ -0,0 +1,227 @@
1
+ # soundcloud-audio
2
+
3
+ Audio component that plays SoundCloud tracks and sets through the SoundCloud Widget
4
+
5
+ The [SoundCloud Widget](https://developers.soundcloud.com/docs/api/html5-widget) plays public and private SoundCloud tracks and sets. This component drives the widget and reports its state like a native `<audio>` element, so a [player skin](../../guides/skins.md) can control it.
6
+
7
+ ## Import
8
+
9
+ ```bash
10
+ pnpm add @videojs/soundcloud-audio
11
+ ```
12
+
13
+ ```ts
14
+ import '@videojs/html/media/soundcloud-audio';
15
+ ```
16
+
17
+ Or load it from the [CDN](../../guides/cdn.md):
18
+
19
+ ```html
20
+ <script type="module" src="https://cdn.jsdelivr.net/npm/@videojs/cdn@10.3.0/media/soundcloud-audio.js"></script>
21
+ ```
22
+
23
+ ## Load a source
24
+
25
+ `src` takes any of these SoundCloud URLs:
26
+
27
+ - A track: `soundcloud.com/<user>/<track>`
28
+ - A set: `soundcloud.com/<user>/sets/<set>`
29
+ - A private track or set, with its secret token: `soundcloud.com/<user>/<track>/s-<token>`
30
+ - An API resource: `api.soundcloud.com/tracks/<id>` or `api.soundcloud.com/playlists/<id>`, with an optional `secret_token`. The id can also be a URN such as `soundcloud:tracks:<id>`
31
+ - A widget embed URL: `w.soundcloud.com/player/?url=...`, as SoundCloud’s own embed code gives it
32
+
33
+ `m.soundcloud.com` links work too. Add `#t=` to start at a given time, in seconds (`#t=90`), clock time (`#t=1:30`), or units (`#t=1m30s`). Profiles, likes, and other pages that list sounds are not supported.
34
+
35
+ ```html
36
+ <soundcloud-audio src="https://soundcloud.com/forss/flickermood#t=1:30"></soundcloud-audio>
37
+ ```
38
+
39
+ ## Controls
40
+
41
+ The widget is the only UI SoundCloud offers, so `controls` decides whether the component is visible at all. Without `controls`, the component hides itself and plays as an invisible transport: a hidden iframe still loads and plays, so a [player skin](../../guides/skins.md) drives playback while the widget takes no room on the page.
42
+
43
+ ```html
44
+ <audio-player>
45
+ <audio-skin>
46
+ <soundcloud-audio src="https://soundcloud.com/forss/flickermood"></soundcloud-audio>
47
+ </audio-skin>
48
+ </audio-player>
49
+ ```
50
+
51
+ With `controls`, the component shows the widget, and the audio skin draws its controls below it, so the two do not overlap. Anything the listener does in the widget shows in the skin: play, pause, seeking on the waveform, and picking another track of a set. The widget is also the part of the page that credits the uploader and links back to the sound on SoundCloud (see [SoundCloud’s terms of use](#soundclouds-terms-of-use)).
52
+
53
+ ```html
54
+ <soundcloud-audio src="https://soundcloud.com/forss/flickermood" controls></soundcloud-audio>
55
+ ```
56
+
57
+ With `controls`, the component is 166 pixels tall by default, SoundCloud’s classic layout. Set a height to change it. From about 300 pixels, a set also shows its track list, and 450 pixels shows most of it. The large artwork layout of `visual: true` (see [widget parameters](#widget-parameters)) needs 300 pixels or more. At the default height, the artwork shows only behind the waveform.
58
+
59
+ ```css
60
+ soundcloud-audio {
61
+ height: 300px;
62
+ }
63
+ ```
64
+
65
+ ## Widget parameters
66
+
67
+ By default, the component hides the parts of the widget a skin has no use for: the buy, share, and download buttons, comments, reposts, the teaser, the related tracks shown after a track ends, and the large artwork layout. The uploader, the title, the artwork, and the SoundCloud logo stay whenever the widget shows.
68
+
69
+ Change any of these, or set `color`, under `source.engine.soundcloud`, spelled as SoundCloud spells them:
70
+
71
+ ```ts
72
+ const audio = document.querySelector('soundcloud-audio');
73
+ audio.source = {
74
+ src: 'https://soundcloud.com/forss/sets/soulhack',
75
+ engine: { soundcloud: { color: '#ff5500', start_track: 2, sharing: true } },
76
+ };
77
+ ```
78
+
79
+ Without JavaScript, put the parameters on a widget embed URL instead:
80
+
81
+ ```html
82
+ <soundcloud-audio
83
+ src="https://w.soundcloud.com/player/?url=https%3A%2F%2Fsoundcloud.com%2Fforss%2Fsets%2Fsoulhack&color=%23ff5500&start_track=2"
84
+ ></soundcloud-audio>
85
+ ```
86
+
87
+ Engine options win over the parameters of a widget embed URL, which win over the defaults. Set an option to `null` to drop a default.
88
+
89
+ ## Behavior
90
+
91
+ - A set plays as one source. When the widget moves on to the next track, `duration` changes, `currentTime` starts again from `0`, and `durationchange` fires. `ended` fires only after the last track. `play()` after the end starts the set again from its first track.
92
+ - `loop` replays the track, or the set from its first track. If the widget does not start again, `ended` still fires.
93
+ - Volume and mute both work. The widget has no separate mute, so muting sets its volume to `0` and unmuting restores the previous level. Mute applies before autoplay starts, so a muted autoplay starts muted.
94
+ - `autoplay` starts playback once the widget is ready. Browsers can still refuse it, as they do for any embed. The widget’s own `auto_play` parameter does the same and is never written to the widget URL, so the volume always applies first.
95
+ - `buffered` is the stretch the widget reports as loaded, from where playback last started or landed.
96
+ - The widget does not support playback rate, picture-in-picture, fullscreen, or text tracks, so the component offers none of them, and a player skin hides those controls.
97
+ - `preload`, `playsinline`, and `poster` are accepted for parity with `<audio>` but have no effect.
98
+ - A track that is private without its secret token, removed, or not available in the listener’s region reports a `MEDIA_ERR_SRC_NOT_SUPPORTED` error, and so does a URL the component does not recognize. A widget that has not finished loading after 5 seconds reports a `MEDIA_ERR_NETWORK` error. An error the widget reports during playback fires a non-fatal `error` event but leaves `error` empty, because a set moves on to its next track by itself.
99
+
100
+ ## SoundCloud’s terms of use
101
+
102
+ The widget is covered by the [SoundCloud Terms of Use](https://soundcloud.com/terms-of-use#use-of-soundcloud-players-and-widget), in the section about players and widgets. Without written consent from SoundCloud, you may not use the widget to:
103
+
104
+ - Aggregate SoundCloud content into a separate destination that substantially replicates what SoundCloud offers, or into a content service where SoundCloud content is a material part.
105
+ - Embed content on a site dedicated to one artist, unless the content is yours and you are that artist or represent them, or on a site dedicated to one genre.
106
+
107
+ These limits apply to commercial and non-commercial use. You also may not use the widget in a way that suggests that SoundCloud, an artist, or anyone else endorses or supports your site. SoundCloud can block your use of the widget at any time, for any reason.
108
+
109
+ The [SoundCloud API terms](https://developers.soundcloud.com/docs/api/terms-of-use), which ask you to credit the uploader and SoundCloud with links back to the sound, apply when you use the SoundCloud API, for example to play stream URLs in a player of your own. This component uses the widget, which [SoundCloud says handles that credit itself](https://developers.soundcloud.com/docs/api/buttons-logos). The widget gives that credit only while it shows, which is with `controls`. Without `controls`, we recommend that your page give the credit itself: name the uploader, name SoundCloud as the source, and link to the sound on SoundCloud. The Terms of Use also say you must not remove trademark, copyright, or other proprietary or legal notices that appear on content from SoundCloud.
110
+
111
+ ## Privacy
112
+
113
+ The widget loads from SoundCloud as soon as the component renders. The [SoundCloud Privacy Policy](https://soundcloud.com/pages/privacy) says that SoundCloud may receive personal data when a visitor opens a page with an embedded widget, including which site they are on, and may recognize the visitor. The widget also stores data in the visitor’s browser. SoundCloud does not document an embed mode that avoids this, so if your site needs consent before it loads third-party content, render the component only after the visitor agrees.
114
+
115
+ ## Examples
116
+
117
+ ### Basic Usage
118
+
119
+ **index.html**
120
+
121
+ ```html
122
+ <soundcloud-audio class="soundcloud-audio" src="https://soundcloud.com/forss/flickermood" controls></soundcloud-audio>
123
+ ```
124
+
125
+ **index.css**
126
+
127
+ ```css
128
+ .soundcloud-audio {
129
+ width: 100%;
130
+ }
131
+ ```
132
+
133
+ **index.ts**
134
+
135
+ ```ts
136
+ import '@videojs/html/media/soundcloud-audio';
137
+ ```
138
+
139
+ ## API Reference
140
+
141
+ ### Attributes
142
+
143
+ These attributes configure the embedded media adapter:
144
+
145
+ | Attribute | Type | Default | Description |
146
+ | --- | --- | --- | --- |
147
+ | `autoplay` | `boolean` | `false` | Starts playback once the widget is ready, after the volume and start position apply. Browsers may refuse it. |
148
+ | `controls` | `boolean` | `false` | |
149
+ | `loop` | `boolean` | `false` | Replays the track, or a set from its first track, when the last one ends. |
150
+ | `muted` | `boolean` | `false` | |
151
+ | `playsinline` | `boolean` | `true` | |
152
+ | `poster` | `string` | `''` | |
153
+ | `preload` | `MediaPreloadType` | `'metadata'` | |
154
+ | `src` | `string` | `''` | |
155
+
156
+ ### Properties
157
+
158
+ | Property | Type | Default | Description |
159
+ | --- | --- | --- | --- |
160
+ | `autoplay` | `boolean` | `false` | Starts playback once the widget is ready, after the volume and start position apply. Browsers may refuse it. |
161
+ | `buffered` | `TimeRangeLike` | — | Read-only. The stretch the widget reports loaded, from where playback last started or landed. |
162
+ | `contentData` | `{ title?: string \| null; poster?: string \| null; storyboard?: string \| null; readonly [key: string]: MediaContentValue }` | — | Read-only. The `title` and `poster` of the track playing, which change with each track of a set. Empty until the widget reports them, and again across a source change. `contentdatachange` announces both. |
163
+ | `controls` | `boolean` | `false` | |
164
+ | `currentSrc` | `string` | — | Read-only. |
165
+ | `currentTime` | `number` | — | |
166
+ | `defaultMuted` | `boolean` | `false` | |
167
+ | `duration` | `number` | — | Read-only. |
168
+ | `ended` | `boolean` | — | Read-only. |
169
+ | `engine` | `Window \| null` | — | Read-only. The widget's window, which commands are posted to. Null until rendered. |
170
+ | `error` | `MediaError \| null` | — | Read-only. |
171
+ | `loop` | `boolean` | `false` | Replays the track, or a set from its first track, when the last one ends. |
172
+ | `muted` | `boolean` | `false` | |
173
+ | `paused` | `boolean` | — | Read-only. |
174
+ | `played` | `{ length: number; start(index: number): number; end(index: number): number }` | — | Read-only. |
175
+ | `playsInline` | `boolean` | `true` | |
176
+ | `poster` | `string` | `''` | |
177
+ | `preload` | `MediaPreloadType` | `'metadata'` | |
178
+ | `readyState` | `number` | — | Read-only. |
179
+ | `seekable` | `TimeRangeLike` | — | Read-only. |
180
+ | `seeking` | `boolean` | — | Read-only. |
181
+ | `source` | `{ src?: string; engine?: SoundCloudSourceEngineConfig } \| null` | `null` | SoundCloud URL in `src`, widget parameters under `engine.soundcloud`. Replacing it re-derives `src`. |
182
+ | `src` | `string` | `''` | |
183
+ | `textTracks` | `TextTrackListLike` | — | Read-only. Always empty: SoundCloud has no captions or other text tracks. |
184
+ | `volume` | `number` | — | |
185
+
186
+ ### Engine options
187
+
188
+ #### `source.engine.soundcloud`
189
+
190
+ Pass [SoundCloud Widget parameters](https://developers.soundcloud.com/docs/api/html5-widget#parameters) under `source.engine.soundcloud`, spelled exactly as SoundCloud spells them, plus anything SoundCloud adds next. [Media Sources](../../guides/media-sources.md) covers how engine options fit into a structured source.
191
+
192
+ The sound comes from `src`, so `url` has no `engine.soundcloud` spelling. `referrerPolicy` sets the `referrerpolicy` of the widget iframe rather than a widget parameter.
193
+
194
+ | Option | Type | Description |
195
+ | --- | --- | --- |
196
+ | `auto_play` | `boolean \| null \| undefined` | Start playback once the widget is ready, as `autoplay` does. Never written to the URL. |
197
+ | `buying` | `boolean \| null \| undefined` | Show the buy button. Defaults to `false`. |
198
+ | `color` | `string \| null \| undefined` | Hex color of the play button and other accents, such as `'#ff5500'`. |
199
+ | `download` | `boolean \| null \| undefined` | Show the download button. Defaults to `false`. |
200
+ | `hide_related` | `boolean \| null \| undefined` | Hide the related tracks the widget offers once a track ends. Defaults to `true`. |
201
+ | `referrerPolicy` | `ReferrerPolicy \| undefined` | `referrerpolicy` for the widget iframe. Not a widget parameter. |
202
+ | `sharing` | `boolean \| null \| undefined` | Show the share button. Defaults to `false`. |
203
+ | `show_artwork` | `boolean \| null \| undefined` | Show the artwork. |
204
+ | `show_comments` | `boolean \| null \| undefined` | Show listener comments on the waveform. Defaults to `false`. |
205
+ | `show_playcount` | `boolean \| null \| undefined` | Show the play count. |
206
+ | `show_reposts` | `boolean \| null \| undefined` | Show reposts. Defaults to `false`. |
207
+ | `show_teaser` | `boolean \| null \| undefined` | Show SoundCloud's promotional teaser. Defaults to `false`. |
208
+ | `show_user` | `boolean \| null \| undefined` | Show the uploader's name. The widget is what credits the uploader, so keep it unless the page does that elsewhere. |
209
+ | `single_active` | `boolean \| null \| undefined` | When `false`, playing this widget does not pause the other SoundCloud widgets on the page. |
210
+ | `start_track` | `number \| null \| undefined` | Index of the track in a set to start from. |
211
+ | `visual` | `boolean \| null \| undefined` | The large artwork layout. Defaults to `false`. |
212
+
213
+ ### Methods
214
+
215
+ Supports these media methods: `load`, `pause`, `play`.
216
+
217
+ ### Events
218
+
219
+ Implements these standard media events through the embedded player: `canplay`, `canplaythrough`, `durationchange`, `emptied`, `ended`, `error`, `loadeddata`, `loadedmetadata`, `loadstart`, `pause`, `play`, `playing`, `progress`, `seeked`, `seeking`, `timeupdate`, `volumechange`, `waiting`.
220
+
221
+ Also emits these Video.js-specific events:
222
+
223
+ | Event | Description |
224
+ | --- | --- |
225
+ | `contentdatachange` | Fired when the widget reports the title and artwork of a track, and when they are cleared. Read `contentData` for them. |
226
+ | `loadcomplete` | |
227
+ | `sourcechange` | Fired when `source` changes, either directly or by resolving a new `src`. Read `source` for the new value. |
@@ -17,7 +17,7 @@ import '@videojs/html/media/spotify-audio';
17
17
  Or load it from the [CDN](../../guides/cdn.md):
18
18
 
19
19
  ```html
20
- <script type="module" src="https://cdn.jsdelivr.net/npm/@videojs/cdn@10.1.0/media/spotify-audio.js"></script>
20
+ <script type="module" src="https://cdn.jsdelivr.net/npm/@videojs/cdn@10.3.0/media/spotify-audio.js"></script>
21
21
  ```
22
22
 
23
23
  ## Load a source
@@ -134,7 +134,7 @@ Supports these media methods: `load`, `pause`, `play`.
134
134
 
135
135
  ### Events
136
136
 
137
- Implements these standard media events through the embedded player: `durationchange`, `emptied`, `ended`, `error`, `loadedmetadata`, `loadstart`, `pause`, `play`, `playing`, `seeked`, `seeking`, `timeupdate`, `waiting`.
137
+ Implements these standard media events through the embedded player: `durationchange`, `emptied`, `ended`, `error`, `loadedmetadata`, `loadstart`, `pause`, `play`, `playing`, `progress`, `seeked`, `seeking`, `timeupdate`, `waiting`.
138
138
 
139
139
  Also emits these Video.js-specific events:
140
140
 
@@ -17,7 +17,7 @@ import '@videojs/html/media/tiktok-video';
17
17
  Or load it from the [CDN](../../guides/cdn.md):
18
18
 
19
19
  ```html
20
- <script type="module" src="https://cdn.jsdelivr.net/npm/@videojs/cdn@10.1.0/media/tiktok-video.js"></script>
20
+ <script type="module" src="https://cdn.jsdelivr.net/npm/@videojs/cdn@10.3.0/media/tiktok-video.js"></script>
21
21
  ```
22
22
 
23
23
  ## Load a source
@@ -155,7 +155,7 @@ Supports these media methods: `exitFullscreen`, `load`, `pause`, `play`, `reques
155
155
 
156
156
  ### Events
157
157
 
158
- Implements these standard media events through the embedded player: `durationchange`, `emptied`, `ended`, `error`, `loadedmetadata`, `loadstart`, `pause`, `play`, `playing`, `seeked`, `seeking`, `timeupdate`, `volumechange`, `waiting`.
158
+ Implements these standard media events through the embedded player: `durationchange`, `emptied`, `ended`, `error`, `loadedmetadata`, `loadstart`, `pause`, `play`, `playing`, `progress`, `seeked`, `seeking`, `timeupdate`, `volumechange`, `waiting`.
159
159
 
160
160
  Also emits these Video.js-specific events:
161
161
 
@@ -95,6 +95,8 @@ Renders with `role="slider"` and an automatic `aria-label` that resolves to “S
95
95
  - Home: seek to start
96
96
  - End: seek to end
97
97
 
98
+ Before each keyboard seek, the current time snaps to the nearest multiple of `step`. With the default `step` of `1`, pressing Arrow Right at 12.4 seconds seeks to 13 seconds.
99
+
98
100
  `<media-time-slider-chapter-title>` follows the pointer during pointer interaction. While the slider has keyboard focus, it follows the current playback position and announces chapter changes.
99
101
 
100
102
  ## Examples
@@ -422,13 +424,13 @@ import '@videojs/html/ui/slider-value';
422
424
  | Prop | Type | Default | Description |
423
425
  | --- | --- | --- | --- |
424
426
  | `changeThrottle` (attribute `change-throttle`) | `number` | `100` | Leading+trailing throttle (ms) for `onValueChange` during drag. |
425
- | `disabled` | `boolean` | — | Whether the slider is non-interactive. |
427
+ | `disabled` | `boolean` | `false` | Whether the slider is non-interactive. |
426
428
  | `label` | `{ key: string; text: string } \| string \| ((state: SliderState) => Text \| string)` | `''` | Custom label for the slider. |
427
- | `largeStep` (attribute `large-step`) | `number` | — | Large step increment (Page Up/Down keys). |
428
- | `orientation` | `'horizontal' \| 'vertical'` | — | Axis of slider movement. |
429
+ | `largeStep` (attribute `large-step`) | `number` | `10` | Large step increment in seconds (Page Up/Down keys). |
430
+ | `orientation` | `'horizontal' \| 'vertical'` | `'horizontal'` | Axis of slider movement. |
429
431
  | `pauseOnDrag` (attribute `pause-on-drag`) | `boolean` | `false` | When true, pause playback while the user is dragging the thumb, resuming on release if it was playing before. |
430
- | `step` | `number` | — | Step increment for value changes (arrow keys). |
431
- | `thumbAlignment` (attribute `thumb-alignment`) | `'center' \| 'edge'` | — | How the thumb aligns at the track edges. `edge` constrains the thumb within track bounds. |
432
+ | `step` | `number` | `1` | Step increment in seconds for value changes (arrow keys). |
433
+ | `thumbAlignment` (attribute `thumb-alignment`) | `'center' \| 'edge'` | `'center'` | How the thumb aligns at the track edges. `edge` constrains the thumb within track bounds. |
432
434
 
433
435
  #### State
434
436
 
@@ -17,7 +17,7 @@ import '@videojs/html/media/twitch-video';
17
17
  Or load it from the [CDN](../../guides/cdn.md):
18
18
 
19
19
  ```html
20
- <script type="module" src="https://cdn.jsdelivr.net/npm/@videojs/cdn@10.1.0/media/twitch-video.js"></script>
20
+ <script type="module" src="https://cdn.jsdelivr.net/npm/@videojs/cdn@10.3.0/media/twitch-video.js"></script>
21
21
  ```
22
22
 
23
23
  ## Load a source
@@ -52,7 +52,7 @@ video.source = {
52
52
  ## Behavior
53
53
 
54
54
  - Volume and mute both work, like a native `<video>`.
55
- - `playbackRate` is reported but never applied: the embed has no rate command.
55
+ - No playback rate: the embed has no rate command, so the player hides its rate controls.
56
56
  - `loop` restarts a finished video from the top; the embed has no loop parameter.
57
57
  - `controls` is read when the embed is built; changing it later doesn’t take effect, since rebuilding the iframe would lose the playback session.
58
58
  - Fullscreen targets the iframe, so Twitch’s own chrome shows in fullscreen.
@@ -117,7 +117,6 @@ These attributes configure the embedded media adapter:
117
117
  | `loop` | `boolean` | `false` | |
118
118
  | `muted` | `boolean` | `false` | |
119
119
  | `paused` | `boolean` | — | Read-only. |
120
- | `playbackRate` | `number` | — | |
121
120
  | `played` | `{ length: number; start(index: number): number; end(index: number): number }` | — | Read-only. |
122
121
  | `playsInline` | `boolean` | `true` | |
123
122
  | `poster` | `string` | `''` | |
@@ -1,8 +1,8 @@
1
1
  # video-compat-skin
2
2
 
3
- A video skin designed for broader browser compatibility
3
+ The video preset's plain, unbranded skin, a polished step above native controls
4
4
 
5
- The Compat skin of the video preset provides basic controls and plain surfaces, with broader browser compatibility as its design goal. Its time slider supports chapter segments and thumbnail previews. See [Customize skins](../../guides/customize-skins.md) to install and edit its source.
5
+ The Compat skin of the video preset: the same core controls with plain, unbranded surfaces that avoid newer visual effects such as backdrop blur. It puts large play and seek buttons in the center, fullscreen, picture-in-picture, Cast, and AirPlay in a top corner, and chapter segments and thumbnail previews on its time slider. The preset also provides [VideoSkin](./video-skin.md), [NeutralVideoSkin](./video-neutral-skin.md), and [ScaffoldVideoSkin](./video-scaffold-skin.md). See [Skins](../../guides/skins.md#choose-a-skin) to choose between them and [Customize skins](../../guides/customize-skins.md) to install and edit its source.
6
6
 
7
7
  ## Import
8
8
 
@@ -10,6 +10,12 @@ The Compat skin of the video preset provides basic controls and plain surfaces,
10
10
  import '@videojs/html/video/compat-skin';
11
11
  ```
12
12
 
13
+ The import registers the skin and every UI element it composes. The [CDN](../../guides/cdn.md) player bundle registers this skin together with its player:
14
+
15
+ ```html
16
+ <script type="module" src="https://cdn.jsdelivr.net/npm/@videojs/cdn@10.3.0/video-compat.js"></script>
17
+ ```
18
+
13
19
  ## Anatomy
14
20
 
15
21
  The skin goes between the player and the media component. It renders its controls around the media.
@@ -2,7 +2,7 @@
2
2
 
3
3
  The video preset's visually lighter skin, closer to a classic control bar
4
4
 
5
- The neutral skin of the video preset: the same player and the same controls in a visually lighter design, closer to a classic control bar. The [default video skin](./video-skin.md) is the same preset’s other variant. See [Skins](../../guides/skins.md) for how packaged skins work and [Presets](../../guides/presets.md) for what the video preset ships.
5
+ The neutral skin of the video preset: the same player and the same controls in a visually lighter design, closer to a classic control bar. The preset also provides [VideoSkin](./video-skin.md), [CompatVideoSkin](./video-compat-skin.md), and [ScaffoldVideoSkin](./video-scaffold-skin.md). See [Skins](../../guides/skins.md#choose-a-skin) to choose between them and [Presets](../../guides/presets.md) for what the video preset ships.
6
6
 
7
7
  ## Import
8
8
 
@@ -13,7 +13,7 @@ import '@videojs/html/video/neutral-skin';
13
13
  The import registers the skin and every UI element it composes. The [CDN](../../guides/cdn.md) player bundle registers this skin together with its player:
14
14
 
15
15
  ```html
16
- <script type="module" src="https://cdn.jsdelivr.net/npm/@videojs/cdn@10.1.0/video-neutral.js"></script>
16
+ <script type="module" src="https://cdn.jsdelivr.net/npm/@videojs/cdn@10.3.0/video-neutral.js"></script>
17
17
  ```
18
18
 
19
19
  ## Anatomy
@@ -2,7 +2,7 @@
2
2
 
3
3
  A video skin with minimal styling for custom skins
4
4
 
5
- The Scaffold skin of the video preset provides functional controls with minimal styling and no transitions. It is a starting point for a custom skin, intended to be restyled before use. Its time slider supports chapter segments and thumbnail previews. See [Customize skins](../../guides/customize-skins.md) to install and edit its source.
5
+ The Scaffold skin of the video preset provides functional controls with minimal styling and no transitions. It is a starting point for a custom skin, intended to be restyled before use. Its time slider supports chapter segments and thumbnail previews. The preset also provides [VideoSkin](./video-skin.md), [NeutralVideoSkin](./video-neutral-skin.md), and [CompatVideoSkin](./video-compat-skin.md). See [Skins](../../guides/skins.md#choose-a-skin) to choose between them and [Customize skins](../../guides/customize-skins.md) to install and edit its source.
6
6
 
7
7
  ## Import
8
8
 
@@ -13,7 +13,7 @@ import '@videojs/html/video/scaffold-skin';
13
13
  The import registers the skin and every UI element it composes. The [CDN](../../guides/cdn.md) player bundle registers this skin together with its player:
14
14
 
15
15
  ```html
16
- <script type="module" src="https://cdn.jsdelivr.net/npm/@videojs/cdn@10.1.0/video-scaffold.js"></script>
16
+ <script type="module" src="https://cdn.jsdelivr.net/npm/@videojs/cdn@10.3.0/video-scaffold.js"></script>
17
17
  ```
18
18
 
19
19
  ## Usage