@videojs/html 10.0.0-beta.27 → 10.0.0-beta.29

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 (676) hide show
  1. package/cdn/{adapter-XTen-YVQ.js → adapter-CEnNWvii.js} +17 -4
  2. package/cdn/adapter-CEnNWvii.js.map +1 -0
  3. package/cdn/adapter-DaKW8NzI.js +2 -0
  4. package/cdn/adapter-DaKW8NzI.js.map +1 -0
  5. package/cdn/audio-headless.dev.js +1 -1
  6. package/cdn/audio-headless.js +1 -1
  7. package/cdn/audio-minimal-ui.dev.js +2 -2
  8. package/cdn/audio-minimal-ui.js +1 -1
  9. package/cdn/audio-minimal.dev.js +5 -5
  10. package/cdn/audio-minimal.dev.js.map +1 -1
  11. package/cdn/audio-minimal.js +1 -1
  12. package/cdn/audio-minimal.js.map +1 -1
  13. package/cdn/audio-ui.dev.js +2 -2
  14. package/cdn/audio-ui.js +1 -1
  15. package/cdn/audio.dev.js +5 -5
  16. package/cdn/audio.dev.js.map +1 -1
  17. package/cdn/audio.js +1 -1
  18. package/cdn/audio.js.map +1 -1
  19. package/cdn/background-video-WKumpp49.js +59 -0
  20. package/cdn/background-video-WKumpp49.js.map +1 -0
  21. package/cdn/background-video-YHY_3-lX.js +2 -0
  22. package/cdn/background-video-YHY_3-lX.js.map +1 -0
  23. package/cdn/background.dev.js +3 -56
  24. package/cdn/background.dev.js.map +1 -1
  25. package/cdn/background.js +1 -1
  26. package/cdn/background.js.map +1 -1
  27. package/cdn/bn-CcLIScl6.js +108 -0
  28. package/cdn/bn-CcLIScl6.js.map +1 -0
  29. package/cdn/bn-KcCmQhYd.js +2 -0
  30. package/cdn/bn-KcCmQhYd.js.map +1 -0
  31. package/cdn/compounds-C4YYLyL2.js +8 -0
  32. package/cdn/compounds-C4YYLyL2.js.map +1 -0
  33. package/cdn/{compounds-CCvdpvge.js → compounds-C73u1MeO.js} +68 -71
  34. package/cdn/compounds-C73u1MeO.js.map +1 -0
  35. package/cdn/container-element-Dd0ZCdhK.js +14 -0
  36. package/cdn/container-element-Dd0ZCdhK.js.map +1 -0
  37. package/cdn/container-element-HHK_KZOE.js +376 -0
  38. package/cdn/container-element-HHK_KZOE.js.map +1 -0
  39. package/cdn/create-player-BU8LDJDL.js +2 -0
  40. package/cdn/create-player-BU8LDJDL.js.map +1 -0
  41. package/cdn/{create-player-BHFyOnWi.js → create-player-Db1CIvlK.js} +76 -424
  42. package/cdn/create-player-Db1CIvlK.js.map +1 -0
  43. package/cdn/{default-BqQDVloS.js → default-A3aM0skz.js} +2 -2
  44. package/cdn/default-A3aM0skz.js.map +1 -0
  45. package/cdn/default-BDyhiTCm.js +2 -0
  46. package/cdn/default-BDyhiTCm.js.map +1 -0
  47. package/cdn/{default-I2LasfxC.js → default-C1_k1NeB.js} +2 -2
  48. package/cdn/default-C1_k1NeB.js.map +1 -0
  49. package/cdn/default-DHrMd4ie.js +2 -0
  50. package/cdn/default-DHrMd4ie.js.map +1 -0
  51. package/cdn/embed-params-D2e8u0d4.js +2 -0
  52. package/cdn/embed-params-D2e8u0d4.js.map +1 -0
  53. package/cdn/embed-params-W6T88S8x.js +39 -0
  54. package/cdn/embed-params-W6T88S8x.js.map +1 -0
  55. package/cdn/error-surface-BID4D3DW.js +59 -0
  56. package/cdn/error-surface-BID4D3DW.js.map +1 -0
  57. package/cdn/{select-tracks-nRPBa1NC.js → error-surface-D0bo71gD.js} +442 -48
  58. package/cdn/error-surface-D0bo71gD.js.map +1 -0
  59. package/cdn/{gesture-element-BNfMI8eh.js → gesture-element-CeRy1IVs.js} +2 -2
  60. package/cdn/gesture-element-CeRy1IVs.js.map +1 -0
  61. package/cdn/{gesture-element-CG-Sx_5t.js → gesture-element-DB67OYCE.js} +3 -3
  62. package/cdn/gesture-element-DB67OYCE.js.map +1 -0
  63. package/cdn/hls-js-CiE4wOrG.js +2 -0
  64. package/cdn/{hls-js-6lW7L4th.js.map → hls-js-CiE4wOrG.js.map} +1 -1
  65. package/cdn/hls-js-DBKRCbQm.js +2 -0
  66. package/cdn/{hls-js-DCQzjzB5.js.map → hls-js-DBKRCbQm.js.map} +1 -1
  67. package/cdn/{hls-js-g1zdcyvE.js → hls-js-DX2NGCAr.js} +3 -2
  68. package/cdn/{hls-js-g1zdcyvE.js.map → hls-js-DX2NGCAr.js.map} +1 -1
  69. package/cdn/{hls-js-Cwj8UBx9.js → hls-js-JeH8yvsP.js} +3 -2
  70. package/cdn/{hls-js-Cwj8UBx9.js.map → hls-js-JeH8yvsP.js.map} +1 -1
  71. package/cdn/i18n-CE4KxKuj.js +2 -0
  72. package/cdn/i18n-CE4KxKuj.js.map +1 -0
  73. package/cdn/i18n-CpBDXf6M.js +2 -0
  74. package/cdn/{i18n-DfKGl5Rh.js.map → i18n-CpBDXf6M.js.map} +1 -1
  75. package/cdn/{i18n-Mtlmj1AA.js → i18n-D0nhPa0m.js} +2 -2
  76. package/cdn/{i18n-Mtlmj1AA.js.map → i18n-D0nhPa0m.js.map} +1 -1
  77. package/cdn/i18n-DyF_NfCk.js +157 -0
  78. package/cdn/i18n-DyF_NfCk.js.map +1 -0
  79. package/cdn/i18n.dev.js +3 -152
  80. package/cdn/i18n.dev.js.map +1 -1
  81. package/cdn/i18n.js +1 -1
  82. package/cdn/i18n.js.map +1 -1
  83. package/cdn/live-button-element-Co8z2LkI.js +2 -0
  84. package/cdn/{live-button-element-CWfkQUoy.js.map → live-button-element-Co8z2LkI.js.map} +1 -1
  85. package/cdn/{live-button-element-B_y-ZJBy.js → live-button-element-zE-8uoR2.js} +5 -4
  86. package/cdn/live-button-element-zE-8uoR2.js.map +1 -0
  87. package/cdn/live-video-minimal.dev.js +12 -10
  88. package/cdn/live-video-minimal.dev.js.map +1 -1
  89. package/cdn/live-video-minimal.js +1 -1
  90. package/cdn/live-video-minimal.js.map +1 -1
  91. package/cdn/live-video.dev.js +13 -11
  92. package/cdn/live-video.dev.js.map +1 -1
  93. package/cdn/live-video.js +1 -1
  94. package/cdn/live-video.js.map +1 -1
  95. package/cdn/locales/bn.dev.js +1 -1
  96. package/cdn/locales/bn.js +1 -1
  97. package/cdn/media/background-video.dev.d.ts +1 -0
  98. package/cdn/media/background-video.dev.js +3 -0
  99. package/cdn/media/background-video.js +1 -0
  100. package/cdn/media/cloudflare-video.dev.d.ts +1 -0
  101. package/cdn/media/cloudflare-video.dev.js +668 -0
  102. package/cdn/media/cloudflare-video.dev.js.map +1 -0
  103. package/cdn/media/cloudflare-video.js +2 -0
  104. package/cdn/media/cloudflare-video.js.map +1 -0
  105. package/cdn/media/container.dev.d.ts +1 -0
  106. package/cdn/media/container.dev.js +8 -0
  107. package/cdn/media/container.dev.js.map +1 -0
  108. package/cdn/media/container.js +2 -0
  109. package/cdn/media/container.js.map +1 -0
  110. package/cdn/media/dash-video.dev.js +2 -1
  111. package/cdn/media/dash-video.js +2 -2
  112. package/cdn/media/dash-video.js.map +1 -1
  113. package/cdn/media/google-cast.dev.js +2 -31
  114. package/cdn/media/google-cast.dev.js.map +1 -1
  115. package/cdn/media/google-cast.js +3 -3
  116. package/cdn/media/google-cast.js.map +1 -1
  117. package/cdn/media/hls-audio.dev.js +2 -1
  118. package/cdn/media/hls-audio.js +1 -1
  119. package/cdn/media/hls-audio.js.map +1 -1
  120. package/cdn/media/hls-background-video.dev.js +2 -1
  121. package/cdn/media/hls-background-video.js +1 -1
  122. package/cdn/media/hls-background-video.js.map +1 -1
  123. package/cdn/media/hls-video.dev.js +2 -1
  124. package/cdn/media/hls-video.js +1 -1
  125. package/cdn/media/hls-video.js.map +1 -1
  126. package/cdn/media/hlsjs-video.dev.js +2 -1
  127. package/cdn/media/hlsjs-video.js +1 -1
  128. package/cdn/media/hlsjs-video.js.map +1 -1
  129. package/cdn/media/mux-audio/hls-js.dev.js +3 -1
  130. package/cdn/media/mux-audio/hls-js.js +1 -1
  131. package/cdn/media/mux-audio/spf.dev.js +3 -2
  132. package/cdn/media/mux-audio/spf.js +1 -1
  133. package/cdn/media/mux-audio/spf.js.map +1 -1
  134. package/cdn/media/mux-audio.dev.js +3 -1
  135. package/cdn/media/mux-audio.js +1 -1
  136. package/cdn/media/mux-background-video.dev.js +2 -1
  137. package/cdn/media/mux-background-video.js +1 -1
  138. package/cdn/media/mux-background-video.js.map +1 -1
  139. package/cdn/media/mux-data.dev.js +2 -1
  140. package/cdn/media/mux-data.dev.js.map +1 -1
  141. package/cdn/media/mux-data.js +2 -2
  142. package/cdn/media/mux-data.js.map +1 -1
  143. package/cdn/media/mux-video/hls-js.dev.js +3 -1
  144. package/cdn/media/mux-video/hls-js.js +1 -1
  145. package/cdn/media/mux-video/spf.dev.js +3 -2
  146. package/cdn/media/mux-video/spf.js +1 -1
  147. package/cdn/media/mux-video/spf.js.map +1 -1
  148. package/cdn/media/mux-video.dev.js +3 -1
  149. package/cdn/media/mux-video.js +1 -1
  150. package/cdn/media/native-hls-video.dev.js +1 -0
  151. package/cdn/media/native-hls-video.js +1 -1
  152. package/cdn/media/native-hls-video.js.map +1 -1
  153. package/cdn/media/spotify-audio.dev.d.ts +1 -0
  154. package/cdn/media/spotify-audio.dev.js +605 -0
  155. package/cdn/media/spotify-audio.dev.js.map +1 -0
  156. package/cdn/media/spotify-audio.js +2 -0
  157. package/cdn/media/spotify-audio.js.map +1 -0
  158. package/cdn/media/tiktok-video.dev.d.ts +1 -0
  159. package/cdn/media/tiktok-video.dev.js +636 -0
  160. package/cdn/media/tiktok-video.dev.js.map +1 -0
  161. package/cdn/media/tiktok-video.js +2 -0
  162. package/cdn/media/tiktok-video.js.map +1 -0
  163. package/cdn/media/twitch-video.dev.d.ts +1 -0
  164. package/cdn/media/twitch-video.dev.js +627 -0
  165. package/cdn/media/twitch-video.dev.js.map +1 -0
  166. package/cdn/media/twitch-video.js +2 -0
  167. package/cdn/media/twitch-video.js.map +1 -0
  168. package/cdn/media/vimeo-video.dev.d.ts +1 -0
  169. package/cdn/media/vimeo-video.dev.js +3011 -0
  170. package/cdn/media/vimeo-video.dev.js.map +1 -0
  171. package/cdn/media/vimeo-video.js +16 -0
  172. package/cdn/media/vimeo-video.js.map +1 -0
  173. package/cdn/media/youtube-video.dev.d.ts +1 -0
  174. package/cdn/media/youtube-video.dev.js +713 -0
  175. package/cdn/media/youtube-video.dev.js.map +1 -0
  176. package/cdn/media/youtube-video.js +2 -0
  177. package/cdn/media/youtube-video.js.map +1 -0
  178. package/cdn/{media-Uxm0d3Vx.js → media-BI8caj07.js} +3 -3
  179. package/cdn/{media-Uxm0d3Vx.js.map → media-BI8caj07.js.map} +1 -1
  180. package/cdn/{media-B_gQXwri.js → media-BNuI0Im7.js} +30 -8
  181. package/cdn/media-BNuI0Im7.js.map +1 -0
  182. package/cdn/{media-Cp3acYc8.js → media-BavrGKqa.js} +274 -5
  183. package/cdn/media-BavrGKqa.js.map +1 -0
  184. package/cdn/media-CQxFuDcv.js +2 -0
  185. package/cdn/{media-CbWsJJhU.js.map → media-CQxFuDcv.js.map} +1 -1
  186. package/cdn/media-CanBm0Jh.js +41 -0
  187. package/cdn/media-CanBm0Jh.js.map +1 -0
  188. package/cdn/media-D4tG62L5.js +2 -0
  189. package/cdn/{media-BTipOcKo.js.map → media-D4tG62L5.js.map} +1 -1
  190. package/cdn/{media-DRo3n8tM.js → media-DI6DvYm3.js} +4 -4
  191. package/cdn/{media-DRo3n8tM.js.map → media-DI6DvYm3.js.map} +1 -1
  192. package/cdn/media-DU3Xf5XR.js +2 -0
  193. package/cdn/media-DU3Xf5XR.js.map +1 -0
  194. package/cdn/media-mYKOAsk3.js +825 -0
  195. package/cdn/media-mYKOAsk3.js.map +1 -0
  196. package/cdn/media-played-ranges-CM2zeOGr.js +2 -0
  197. package/cdn/media-played-ranges-CM2zeOGr.js.map +1 -0
  198. package/cdn/media-played-ranges-Yd9acuMt.js +156 -0
  199. package/cdn/media-played-ranges-Yd9acuMt.js.map +1 -0
  200. package/cdn/media-zReLnePj.js +2 -0
  201. package/cdn/media-zReLnePj.js.map +1 -0
  202. package/cdn/{minimal-DQCLKRyR.js → minimal-3OmH0xQS.js} +2 -2
  203. package/cdn/minimal-3OmH0xQS.js.map +1 -0
  204. package/cdn/{minimal-DLosvq31.js → minimal-6w_Vyyl9.js} +2 -2
  205. package/cdn/minimal-6w_Vyyl9.js.map +1 -0
  206. package/cdn/minimal-BWLTn7oQ.js +2 -0
  207. package/cdn/minimal-BWLTn7oQ.js.map +1 -0
  208. package/cdn/minimal-DIGrklyh.js +2 -0
  209. package/cdn/minimal-DIGrklyh.js.map +1 -0
  210. package/cdn/{minimal-ui-Bxcpf5Mb.js → minimal-ui-BCIESK8f.js} +9 -9
  211. package/cdn/{minimal-ui-Bxcpf5Mb.js.map → minimal-ui-BCIESK8f.js.map} +1 -1
  212. package/cdn/minimal-ui-BXrq3z4U.js +2 -0
  213. package/cdn/{minimal-ui-BVKu9LWj.js.map → minimal-ui-BXrq3z4U.js.map} +1 -1
  214. package/cdn/{minimal-ui--JsmpU2q.js → minimal-ui-DEalpMk6.js} +5 -5
  215. package/cdn/{minimal-ui--JsmpU2q.js.map → minimal-ui-DEalpMk6.js.map} +1 -1
  216. package/cdn/minimal-ui-vY3QgohH.js +2 -0
  217. package/cdn/{minimal-ui-AFk6Ut5f.js.map → minimal-ui-vY3QgohH.js.map} +1 -1
  218. package/cdn/mixin-BqN0V06a.js +2 -0
  219. package/cdn/{mixin-DiB7dIef.js.map → mixin-BqN0V06a.js.map} +1 -1
  220. package/cdn/{mixin-CkNZwQXF.js → mixin-C193v40v.js} +67 -67
  221. package/cdn/mixin-C193v40v.js.map +1 -0
  222. package/cdn/noop-BxkeRIz9.js +6 -0
  223. package/cdn/noop-BxkeRIz9.js.map +1 -0
  224. package/cdn/noop-Ch0IHcOP.js +2 -0
  225. package/cdn/noop-Ch0IHcOP.js.map +1 -0
  226. package/cdn/{player-C4ix6TQq.js → player-B3GlPF90.js} +3 -2
  227. package/cdn/{player-C4ix6TQq.js.map → player-B3GlPF90.js.map} +1 -1
  228. package/cdn/player-CtTC7qa5.js +2 -0
  229. package/cdn/{player-B0ccW5-n.js.map → player-CtTC7qa5.js.map} +1 -1
  230. package/cdn/player-DKkph8UM.js +2 -0
  231. package/cdn/{player-srq1RGTj.js.map → player-DKkph8UM.js.map} +1 -1
  232. package/cdn/{player-B0qnepD5.js → player-DPDmTRvg.js} +3 -2
  233. package/cdn/{player-B0qnepD5.js.map → player-DPDmTRvg.js.map} +1 -1
  234. package/cdn/player-DrDd7LJi.js +2 -0
  235. package/cdn/{player-iIewo8Y9.js.map → player-DrDd7LJi.js.map} +1 -1
  236. package/cdn/{player-D4fdOLLk.js → player-L5UpZmT4.js} +3 -2
  237. package/cdn/{player-D4fdOLLk.js.map → player-L5UpZmT4.js.map} +1 -1
  238. package/cdn/{poster-element-BP1Ypgbf.js → poster-element-B5tdJ2ub.js} +192 -39
  239. package/cdn/poster-element-B5tdJ2ub.js.map +1 -0
  240. package/cdn/poster-element-B8QwXSU_.js +2 -0
  241. package/cdn/poster-element-B8QwXSU_.js.map +1 -0
  242. package/cdn/{error-surface-drmCvBVW.js → relocation-pipelines-Dh8CcgHw.js} +5 -343
  243. package/cdn/relocation-pipelines-Dh8CcgHw.js.map +1 -0
  244. package/cdn/relocation-pipelines-DunE4gcV.js +2 -0
  245. package/cdn/relocation-pipelines-DunE4gcV.js.map +1 -0
  246. package/cdn/script-D3ZkiqwO.js +2 -0
  247. package/cdn/script-D3ZkiqwO.js.map +1 -0
  248. package/cdn/script-erPJaaTz.js +33 -0
  249. package/cdn/script-erPJaaTz.js.map +1 -0
  250. package/cdn/{seek-button-element-TErrbilI.js → seek-button-element-5co-k0Dx.js} +7 -6
  251. package/cdn/seek-button-element-5co-k0Dx.js.map +1 -0
  252. package/cdn/seek-button-element-B8TkILg-.js +2 -0
  253. package/cdn/seek-button-element-B8TkILg-.js.map +1 -0
  254. package/cdn/shallow-equal-C7S8rj2f.js +16 -0
  255. package/cdn/shallow-equal-C7S8rj2f.js.map +1 -0
  256. package/cdn/shallow-equal-KV1zFqZi.js +2 -0
  257. package/cdn/shallow-equal-KV1zFqZi.js.map +1 -0
  258. package/cdn/{skin-element-wPSb4AAs.js → skin-element-DrkI8xuM.js} +2 -2
  259. package/cdn/{skin-element-wPSb4AAs.js.map → skin-element-DrkI8xuM.js.map} +1 -1
  260. package/cdn/{skin-element-1_MG2zgS.js → skin-element-DvX6Bxsv.js} +2 -2
  261. package/cdn/{skin-element-1_MG2zgS.js.map → skin-element-DvX6Bxsv.js.map} +1 -1
  262. package/cdn/text-element-BoY6AhMn.js +2 -0
  263. package/cdn/{text-element-Bsyglab8.js.map → text-element-BoY6AhMn.js.map} +1 -1
  264. package/cdn/{text-element-DTB9_2HX.js → text-element-cg6l21cd.js} +3 -3
  265. package/cdn/{text-element-DTB9_2HX.js.map → text-element-cg6l21cd.js.map} +1 -1
  266. package/cdn/time-slider-chapters-element-BfLjdnU4.js +2 -0
  267. package/cdn/time-slider-chapters-element-BfLjdnU4.js.map +1 -0
  268. package/cdn/{time-slider-chapters-element-DPgaLdBt.js → time-slider-chapters-element-CznFQWFm.js} +7 -6
  269. package/cdn/time-slider-chapters-element-CznFQWFm.js.map +1 -0
  270. package/cdn/{translate-text-DP0CzUCC.js → translate-text-BWvoW5-r.js} +2 -7
  271. package/cdn/translate-text-BWvoW5-r.js.map +1 -0
  272. package/cdn/translate-text-TzSgu_oe.js +2 -0
  273. package/cdn/translate-text-TzSgu_oe.js.map +1 -0
  274. package/cdn/{ui-D0AokGxw.js → ui-BwzqkJNK.js} +8 -8
  275. package/cdn/{ui-D0AokGxw.js.map → ui-BwzqkJNK.js.map} +1 -1
  276. package/cdn/ui-DayfItun.js +2 -0
  277. package/cdn/{ui-CecDxhTX.js.map → ui-DayfItun.js.map} +1 -1
  278. package/cdn/ui-PSnD-pv8.js +2 -0
  279. package/cdn/{ui-ChWM6Xz2.js.map → ui-PSnD-pv8.js.map} +1 -1
  280. package/cdn/{ui-p36Szn71.js → ui-fnKp94a7.js} +10 -10
  281. package/cdn/{ui-p36Szn71.js.map → ui-fnKp94a7.js.map} +1 -1
  282. package/cdn/video-headless.dev.js +1 -1
  283. package/cdn/video-headless.js +1 -1
  284. package/cdn/video-minimal-ui.dev.js +2 -2
  285. package/cdn/video-minimal-ui.js +1 -1
  286. package/cdn/video-minimal.dev.js +8 -6
  287. package/cdn/video-minimal.dev.js.map +1 -1
  288. package/cdn/video-minimal.js +1 -1
  289. package/cdn/video-minimal.js.map +1 -1
  290. package/cdn/video-ui.dev.js +2 -2
  291. package/cdn/video-ui.js +1 -1
  292. package/cdn/video.dev.js +9 -7
  293. package/cdn/video.dev.js.map +1 -1
  294. package/cdn/video.js +1 -1
  295. package/cdn/video.js.map +1 -1
  296. package/dist/default/__generated__/skins/default-video/styles/buttons.css +132 -18
  297. package/dist/default/__generated__/skins/default-video/styles/captions.css +22 -0
  298. package/dist/default/__generated__/skins/default-video/styles/container.css +121 -8
  299. package/dist/default/__generated__/skins/default-video/styles/controls.css +436 -21
  300. package/dist/default/__generated__/skins/default-video/styles/dialog.css +169 -0
  301. package/dist/default/__generated__/skins/default-video/styles/indicator.css +459 -0
  302. package/dist/default/__generated__/skins/default-video/styles/menus.css +254 -0
  303. package/dist/default/__generated__/skins/default-video/styles/overlays.css +26 -2
  304. package/dist/default/__generated__/skins/default-video/styles/popups.css +338 -12
  305. package/dist/default/__generated__/skins/default-video/styles/poster.css +4 -4
  306. package/dist/default/__generated__/skins/default-video/styles/sliders.css +355 -31
  307. package/dist/default/__generated__/skins/default-video/styles/styles.css +2455 -216
  308. package/dist/default/__generated__/skins/default-video/styles/theme.css +4 -19
  309. package/dist/default/__generated__/skins/default-video/styles/video.css +29 -0
  310. package/dist/default/__generated__/skins/minimal-video/styles/base.css +25 -0
  311. package/dist/default/__generated__/skins/minimal-video/styles/buttons.css +266 -0
  312. package/dist/default/__generated__/skins/minimal-video/styles/captions.css +22 -0
  313. package/dist/default/__generated__/skins/minimal-video/styles/container.css +158 -0
  314. package/dist/default/__generated__/skins/minimal-video/styles/controls.css +182 -0
  315. package/dist/default/__generated__/skins/minimal-video/styles/dialog.css +77 -0
  316. package/dist/default/__generated__/skins/minimal-video/styles/indicator.css +322 -0
  317. package/dist/default/__generated__/skins/minimal-video/styles/menus.css +254 -0
  318. package/dist/default/__generated__/skins/minimal-video/styles/overlays.css +35 -0
  319. package/dist/default/__generated__/skins/minimal-video/styles/popups.css +371 -0
  320. package/dist/default/__generated__/skins/minimal-video/styles/poster.css +47 -0
  321. package/dist/default/__generated__/skins/minimal-video/styles/sliders.css +436 -0
  322. package/dist/default/__generated__/skins/minimal-video/styles/styles.css +2246 -0
  323. package/dist/default/__generated__/skins/minimal-video/styles/theme.css +7 -0
  324. package/dist/default/__generated__/skins/minimal-video/styles/video.css +29 -0
  325. package/dist/default/_virtual/inline-css_src/define/audio/minimal-skin.js +1 -1
  326. package/dist/default/_virtual/inline-css_src/define/audio/minimal-skin.js.map +1 -1
  327. package/dist/default/_virtual/inline-css_src/define/audio/skin.js +1 -1
  328. package/dist/default/_virtual/inline-css_src/define/audio/skin.js.map +1 -1
  329. package/dist/default/_virtual/inline-css_src/define/live-audio/minimal-skin.js +1 -1
  330. package/dist/default/_virtual/inline-css_src/define/live-audio/minimal-skin.js.map +1 -1
  331. package/dist/default/_virtual/inline-css_src/define/live-audio/skin.js +1 -1
  332. package/dist/default/_virtual/inline-css_src/define/live-audio/skin.js.map +1 -1
  333. package/dist/default/_virtual/inline-css_src/define/live-video/minimal-skin.js +1 -1
  334. package/dist/default/_virtual/inline-css_src/define/live-video/minimal-skin.js.map +1 -1
  335. package/dist/default/_virtual/inline-css_src/define/live-video/skin.js +1 -1
  336. package/dist/default/_virtual/inline-css_src/define/live-video/skin.js.map +1 -1
  337. package/dist/default/_virtual/inline-css_src/define/video/minimal-skin.js +1 -1
  338. package/dist/default/_virtual/inline-css_src/define/video/minimal-skin.js.map +1 -1
  339. package/dist/default/_virtual/inline-css_src/define/video/skin.js +1 -1
  340. package/dist/default/_virtual/inline-css_src/define/video/skin.js.map +1 -1
  341. package/dist/default/define/audio/minimal-skin.css +117 -118
  342. package/dist/default/define/audio/skin.css +95 -99
  343. package/dist/default/define/live-audio/minimal-skin.css +117 -118
  344. package/dist/default/define/live-audio/skin.css +95 -99
  345. package/dist/default/define/live-video/minimal-skin.css +158 -137
  346. package/dist/default/define/live-video/minimal-skin.js +1 -1
  347. package/dist/default/define/live-video/minimal-skin.js.map +1 -1
  348. package/dist/default/define/live-video/minimal-skin.tailwind.js +1 -1
  349. package/dist/default/define/live-video/minimal-skin.tailwind.js.map +1 -1
  350. package/dist/default/define/live-video/skin.css +120 -106
  351. package/dist/default/define/live-video/skin.js +1 -1
  352. package/dist/default/define/live-video/skin.js.map +1 -1
  353. package/dist/default/define/live-video/skin.tailwind.js +1 -1
  354. package/dist/default/define/live-video/skin.tailwind.js.map +1 -1
  355. package/dist/default/define/ui/gesture.js +7 -0
  356. package/dist/default/define/ui/gesture.js.map +1 -0
  357. package/dist/default/define/video/minimal-skin.css +158 -137
  358. package/dist/default/define/video/minimal-skin.js +1 -1
  359. package/dist/default/define/video/minimal-skin.js.map +1 -1
  360. package/dist/default/define/video/minimal-skin.tailwind.js +1 -1
  361. package/dist/default/define/video/minimal-skin.tailwind.js.map +1 -1
  362. package/dist/default/define/video/skin.css +120 -106
  363. package/dist/default/define/video/skin.js +1 -1
  364. package/dist/default/define/video/skin.js.map +1 -1
  365. package/dist/default/define/video/skin.tailwind.js +1 -1
  366. package/dist/default/define/video/skin.tailwind.js.map +1 -1
  367. package/dist/default/icons/dist/element/default/icons.js +1 -1
  368. package/dist/default/icons/dist/element/default/icons.js.map +1 -1
  369. package/dist/default/icons/dist/element/minimal/icons.js +1 -1
  370. package/dist/default/icons/dist/element/minimal/icons.js.map +1 -1
  371. package/dist/default/icons/dist/html/default/airplay-exit.js +1 -1
  372. package/dist/default/icons/dist/html/default/airplay-exit.js.map +1 -1
  373. package/dist/default/icons/dist/html/minimal/airplay-exit.js +1 -1
  374. package/dist/default/icons/dist/html/minimal/airplay-exit.js.map +1 -1
  375. package/dist/default/icons/dist/render/default/index.js +1 -1
  376. package/dist/default/icons/dist/render/default/index.js.map +1 -1
  377. package/dist/default/icons/dist/render/minimal/index.js +1 -1
  378. package/dist/default/icons/dist/render/minimal/index.js.map +1 -1
  379. package/dist/default/media/hls-background-video/media.js +18 -0
  380. package/dist/default/media/hls-background-video/media.js.map +1 -1
  381. package/dist/default/media/tiktok-video/media.js +3 -2
  382. package/dist/default/media/tiktok-video/media.js.map +1 -1
  383. package/dist/default/skins/dist/default/default/tailwind/components/button.js +3 -1
  384. package/dist/default/skins/dist/default/default/tailwind/components/button.js.map +1 -1
  385. package/dist/default/skins/dist/default/default/tailwind/components/poster.js +8 -1
  386. package/dist/default/skins/dist/default/default/tailwind/components/poster.js.map +1 -1
  387. package/dist/default/skins/dist/default/default/tailwind/components/slider.js +13 -13
  388. package/dist/default/skins/dist/default/default/tailwind/components/slider.js.map +1 -1
  389. package/dist/default/skins/dist/default/default/tailwind/components/thumbnail.js +1 -1
  390. package/dist/default/skins/dist/default/default/tailwind/components/thumbnail.js.map +1 -1
  391. package/dist/default/skins/dist/default/default/tailwind/video.tailwind.js +3 -3
  392. package/dist/default/skins/dist/default/default/tailwind/video.tailwind.js.map +1 -1
  393. package/dist/default/skins/dist/default/minimal/tailwind/components/poster.js +8 -1
  394. package/dist/default/skins/dist/default/minimal/tailwind/components/poster.js.map +1 -1
  395. package/dist/default/skins/dist/default/minimal/tailwind/components/slider.js +13 -12
  396. package/dist/default/skins/dist/default/minimal/tailwind/components/slider.js.map +1 -1
  397. package/dist/default/skins/dist/default/minimal/tailwind/components/thumbnail.js +1 -1
  398. package/dist/default/skins/dist/default/minimal/tailwind/components/thumbnail.js.map +1 -1
  399. package/dist/default/skins/dist/default/minimal/tailwind/video.tailwind.js +7 -6
  400. package/dist/default/skins/dist/default/minimal/tailwind/video.tailwind.js.map +1 -1
  401. package/dist/default/skins/dist/default/shared/tailwind/icon-state.js +4 -4
  402. package/dist/default/skins/dist/default/shared/tailwind/icon-state.js.map +1 -1
  403. package/dist/default/store/provider-mixin.js +22 -8
  404. package/dist/default/store/provider-mixin.js.map +1 -1
  405. package/dist/default/ui/audio-track-radio-group/audio-track-radio-group-element.js +1 -1
  406. package/dist/default/ui/audio-track-radio-group/audio-track-radio-group-element.js.map +1 -1
  407. package/dist/default/ui/captions-radio-group/captions-radio-group-element.js +1 -1
  408. package/dist/default/ui/captions-radio-group/captions-radio-group-element.js.map +1 -1
  409. package/dist/default/ui/gesture/gesture-element.js.map +1 -1
  410. package/dist/default/ui/hotkey/hotkey-element.js.map +1 -1
  411. package/dist/default/ui/menu/context.js.map +1 -1
  412. package/dist/default/ui/menu/menu-element.js +28 -27
  413. package/dist/default/ui/menu/menu-element.js.map +1 -1
  414. package/dist/default/ui/menu/menu-radio-group-element.js +14 -14
  415. package/dist/default/ui/menu/menu-radio-group-element.js.map +1 -1
  416. package/dist/default/ui/playback-rate-button/playback-rate-button-element.js +1 -2
  417. package/dist/default/ui/playback-rate-button/playback-rate-button-element.js.map +1 -1
  418. package/dist/default/ui/playback-rate-radio-group/playback-rate-radio-group-element.js +1 -1
  419. package/dist/default/ui/playback-rate-radio-group/playback-rate-radio-group-element.js.map +1 -1
  420. package/dist/default/ui/poster/poster-element.js +138 -8
  421. package/dist/default/ui/poster/poster-element.js.map +1 -1
  422. package/dist/default/ui/quality-radio-group/quality-radio-group-element.js +1 -1
  423. package/dist/default/ui/quality-radio-group/quality-radio-group-element.js.map +1 -1
  424. package/dist/default/ui/slider/slider-preview-element.js.map +1 -1
  425. package/dist/dev/__generated__/skins/default-video/styles/buttons.css +132 -18
  426. package/dist/dev/__generated__/skins/default-video/styles/captions.css +22 -0
  427. package/dist/dev/__generated__/skins/default-video/styles/container.css +121 -8
  428. package/dist/dev/__generated__/skins/default-video/styles/controls.css +436 -21
  429. package/dist/dev/__generated__/skins/default-video/styles/dialog.css +169 -0
  430. package/dist/dev/__generated__/skins/default-video/styles/indicator.css +459 -0
  431. package/dist/dev/__generated__/skins/default-video/styles/menus.css +254 -0
  432. package/dist/dev/__generated__/skins/default-video/styles/overlays.css +26 -2
  433. package/dist/dev/__generated__/skins/default-video/styles/popups.css +338 -12
  434. package/dist/dev/__generated__/skins/default-video/styles/poster.css +4 -4
  435. package/dist/dev/__generated__/skins/default-video/styles/sliders.css +355 -31
  436. package/dist/dev/__generated__/skins/default-video/styles/styles.css +2455 -216
  437. package/dist/dev/__generated__/skins/default-video/styles/theme.css +4 -19
  438. package/dist/dev/__generated__/skins/default-video/styles/video.css +29 -0
  439. package/dist/dev/__generated__/skins/minimal-video/styles/base.css +25 -0
  440. package/dist/dev/__generated__/skins/minimal-video/styles/buttons.css +266 -0
  441. package/dist/dev/__generated__/skins/minimal-video/styles/captions.css +22 -0
  442. package/dist/dev/__generated__/skins/minimal-video/styles/container.css +158 -0
  443. package/dist/dev/__generated__/skins/minimal-video/styles/controls.css +182 -0
  444. package/dist/dev/__generated__/skins/minimal-video/styles/dialog.css +77 -0
  445. package/dist/dev/__generated__/skins/minimal-video/styles/indicator.css +322 -0
  446. package/dist/dev/__generated__/skins/minimal-video/styles/menus.css +254 -0
  447. package/dist/dev/__generated__/skins/minimal-video/styles/overlays.css +35 -0
  448. package/dist/dev/__generated__/skins/minimal-video/styles/popups.css +371 -0
  449. package/dist/dev/__generated__/skins/minimal-video/styles/poster.css +47 -0
  450. package/dist/dev/__generated__/skins/minimal-video/styles/sliders.css +436 -0
  451. package/dist/dev/__generated__/skins/minimal-video/styles/styles.css +2246 -0
  452. package/dist/dev/__generated__/skins/minimal-video/styles/theme.css +7 -0
  453. package/dist/dev/__generated__/skins/minimal-video/styles/video.css +29 -0
  454. package/dist/dev/_virtual/inline-css_src/define/audio/minimal-skin.js +1 -1
  455. package/dist/dev/_virtual/inline-css_src/define/audio/minimal-skin.js.map +1 -1
  456. package/dist/dev/_virtual/inline-css_src/define/audio/skin.js +1 -1
  457. package/dist/dev/_virtual/inline-css_src/define/audio/skin.js.map +1 -1
  458. package/dist/dev/_virtual/inline-css_src/define/live-audio/minimal-skin.js +1 -1
  459. package/dist/dev/_virtual/inline-css_src/define/live-audio/minimal-skin.js.map +1 -1
  460. package/dist/dev/_virtual/inline-css_src/define/live-audio/skin.js +1 -1
  461. package/dist/dev/_virtual/inline-css_src/define/live-audio/skin.js.map +1 -1
  462. package/dist/dev/_virtual/inline-css_src/define/live-video/minimal-skin.js +1 -1
  463. package/dist/dev/_virtual/inline-css_src/define/live-video/minimal-skin.js.map +1 -1
  464. package/dist/dev/_virtual/inline-css_src/define/live-video/skin.js +1 -1
  465. package/dist/dev/_virtual/inline-css_src/define/live-video/skin.js.map +1 -1
  466. package/dist/dev/_virtual/inline-css_src/define/video/minimal-skin.js +1 -1
  467. package/dist/dev/_virtual/inline-css_src/define/video/minimal-skin.js.map +1 -1
  468. package/dist/dev/_virtual/inline-css_src/define/video/skin.js +1 -1
  469. package/dist/dev/_virtual/inline-css_src/define/video/skin.js.map +1 -1
  470. package/dist/dev/define/audio/minimal-skin.css +117 -118
  471. package/dist/dev/define/audio/skin.css +95 -99
  472. package/dist/dev/define/live-audio/minimal-skin.css +117 -118
  473. package/dist/dev/define/live-audio/skin.css +95 -99
  474. package/dist/dev/define/live-video/minimal-skin.css +158 -137
  475. package/dist/dev/define/live-video/minimal-skin.d.ts.map +1 -1
  476. package/dist/dev/define/live-video/minimal-skin.js +3 -1
  477. package/dist/dev/define/live-video/minimal-skin.js.map +1 -1
  478. package/dist/dev/define/live-video/minimal-skin.tailwind.d.ts.map +1 -1
  479. package/dist/dev/define/live-video/minimal-skin.tailwind.js +3 -1
  480. package/dist/dev/define/live-video/minimal-skin.tailwind.js.map +1 -1
  481. package/dist/dev/define/live-video/skin.css +120 -106
  482. package/dist/dev/define/live-video/skin.d.ts.map +1 -1
  483. package/dist/dev/define/live-video/skin.js +3 -1
  484. package/dist/dev/define/live-video/skin.js.map +1 -1
  485. package/dist/dev/define/live-video/skin.tailwind.d.ts.map +1 -1
  486. package/dist/dev/define/live-video/skin.tailwind.js +4 -2
  487. package/dist/dev/define/live-video/skin.tailwind.js.map +1 -1
  488. package/dist/dev/define/ui/gesture.d.ts +8 -0
  489. package/dist/dev/define/ui/gesture.d.ts.map +1 -0
  490. package/dist/dev/define/ui/gesture.js +7 -0
  491. package/dist/dev/define/ui/gesture.js.map +1 -0
  492. package/dist/dev/define/video/minimal-skin.css +158 -137
  493. package/dist/dev/define/video/minimal-skin.d.ts.map +1 -1
  494. package/dist/dev/define/video/minimal-skin.js +3 -1
  495. package/dist/dev/define/video/minimal-skin.js.map +1 -1
  496. package/dist/dev/define/video/minimal-skin.tailwind.d.ts.map +1 -1
  497. package/dist/dev/define/video/minimal-skin.tailwind.js +3 -1
  498. package/dist/dev/define/video/minimal-skin.tailwind.js.map +1 -1
  499. package/dist/dev/define/video/skin.css +120 -106
  500. package/dist/dev/define/video/skin.d.ts.map +1 -1
  501. package/dist/dev/define/video/skin.js +3 -1
  502. package/dist/dev/define/video/skin.js.map +1 -1
  503. package/dist/dev/define/video/skin.tailwind.d.ts.map +1 -1
  504. package/dist/dev/define/video/skin.tailwind.js +4 -2
  505. package/dist/dev/define/video/skin.tailwind.js.map +1 -1
  506. package/dist/dev/media/hls-background-video/media.d.ts +16 -0
  507. package/dist/dev/media/hls-background-video/media.d.ts.map +1 -1
  508. package/dist/dev/media/hls-background-video/media.js +18 -0
  509. package/dist/dev/media/hls-background-video/media.js.map +1 -1
  510. package/dist/dev/media/tiktok-video/media.d.ts.map +1 -1
  511. package/dist/dev/media/tiktok-video/media.js +10 -7
  512. package/dist/dev/media/tiktok-video/media.js.map +1 -1
  513. package/dist/dev/packages/icons/dist/element/default/icons.js +1 -1
  514. package/dist/dev/packages/icons/dist/element/default/icons.js.map +1 -1
  515. package/dist/dev/packages/icons/dist/element/minimal/icons.js +1 -1
  516. package/dist/dev/packages/icons/dist/element/minimal/icons.js.map +1 -1
  517. package/dist/dev/packages/icons/dist/html/default/airplay-exit.js +1 -1
  518. package/dist/dev/packages/icons/dist/html/default/airplay-exit.js.map +1 -1
  519. package/dist/dev/packages/icons/dist/html/minimal/airplay-exit.js +1 -1
  520. package/dist/dev/packages/icons/dist/html/minimal/airplay-exit.js.map +1 -1
  521. package/dist/dev/packages/icons/dist/render/default/index.js +1 -1
  522. package/dist/dev/packages/icons/dist/render/default/index.js.map +1 -1
  523. package/dist/dev/packages/icons/dist/render/minimal/index.js +1 -1
  524. package/dist/dev/packages/icons/dist/render/minimal/index.js.map +1 -1
  525. package/dist/dev/packages/skins/dist/default/default/tailwind/components/button.js +3 -1
  526. package/dist/dev/packages/skins/dist/default/default/tailwind/components/button.js.map +1 -1
  527. package/dist/dev/packages/skins/dist/default/default/tailwind/components/poster.js +8 -1
  528. package/dist/dev/packages/skins/dist/default/default/tailwind/components/poster.js.map +1 -1
  529. package/dist/dev/packages/skins/dist/default/default/tailwind/components/slider.js +13 -13
  530. package/dist/dev/packages/skins/dist/default/default/tailwind/components/slider.js.map +1 -1
  531. package/dist/dev/packages/skins/dist/default/default/tailwind/components/thumbnail.js +1 -1
  532. package/dist/dev/packages/skins/dist/default/default/tailwind/components/thumbnail.js.map +1 -1
  533. package/dist/dev/packages/skins/dist/default/default/tailwind/video.tailwind.js +3 -3
  534. package/dist/dev/packages/skins/dist/default/default/tailwind/video.tailwind.js.map +1 -1
  535. package/dist/dev/packages/skins/dist/default/minimal/tailwind/components/poster.js +8 -1
  536. package/dist/dev/packages/skins/dist/default/minimal/tailwind/components/poster.js.map +1 -1
  537. package/dist/dev/packages/skins/dist/default/minimal/tailwind/components/slider.js +13 -12
  538. package/dist/dev/packages/skins/dist/default/minimal/tailwind/components/slider.js.map +1 -1
  539. package/dist/dev/packages/skins/dist/default/minimal/tailwind/components/thumbnail.js +1 -1
  540. package/dist/dev/packages/skins/dist/default/minimal/tailwind/components/thumbnail.js.map +1 -1
  541. package/dist/dev/packages/skins/dist/default/minimal/tailwind/video.tailwind.js +7 -6
  542. package/dist/dev/packages/skins/dist/default/minimal/tailwind/video.tailwind.js.map +1 -1
  543. package/dist/dev/packages/skins/dist/default/shared/tailwind/icon-state.js +4 -4
  544. package/dist/dev/packages/skins/dist/default/shared/tailwind/icon-state.js.map +1 -1
  545. package/dist/dev/store/provider-mixin.d.ts.map +1 -1
  546. package/dist/dev/store/provider-mixin.js +24 -8
  547. package/dist/dev/store/provider-mixin.js.map +1 -1
  548. package/dist/dev/store/types.d.ts +2 -2
  549. package/dist/dev/store/types.d.ts.map +1 -1
  550. package/dist/dev/ui/audio-track-radio-group/audio-track-radio-group-element.js +1 -1
  551. package/dist/dev/ui/audio-track-radio-group/audio-track-radio-group-element.js.map +1 -1
  552. package/dist/dev/ui/captions-radio-group/captions-radio-group-element.js +1 -1
  553. package/dist/dev/ui/captions-radio-group/captions-radio-group-element.js.map +1 -1
  554. package/dist/dev/ui/gesture/gesture-element.d.ts +7 -7
  555. package/dist/dev/ui/gesture/gesture-element.d.ts.map +1 -1
  556. package/dist/dev/ui/gesture/gesture-element.js.map +1 -1
  557. package/dist/dev/ui/hotkey/hotkey-element.d.ts +6 -6
  558. package/dist/dev/ui/hotkey/hotkey-element.d.ts.map +1 -1
  559. package/dist/dev/ui/hotkey/hotkey-element.js.map +1 -1
  560. package/dist/dev/ui/menu/context.d.ts +8 -8
  561. package/dist/dev/ui/menu/context.d.ts.map +1 -1
  562. package/dist/dev/ui/menu/context.js.map +1 -1
  563. package/dist/dev/ui/menu/menu-element.d.ts.map +1 -1
  564. package/dist/dev/ui/menu/menu-element.js +28 -27
  565. package/dist/dev/ui/menu/menu-element.js.map +1 -1
  566. package/dist/dev/ui/menu/menu-radio-group-element.d.ts +1 -1
  567. package/dist/dev/ui/menu/menu-radio-group-element.d.ts.map +1 -1
  568. package/dist/dev/ui/menu/menu-radio-group-element.js +14 -14
  569. package/dist/dev/ui/menu/menu-radio-group-element.js.map +1 -1
  570. package/dist/dev/ui/playback-rate-button/playback-rate-button-element.d.ts.map +1 -1
  571. package/dist/dev/ui/playback-rate-button/playback-rate-button-element.js +1 -2
  572. package/dist/dev/ui/playback-rate-button/playback-rate-button-element.js.map +1 -1
  573. package/dist/dev/ui/playback-rate-radio-group/playback-rate-radio-group-element.js +1 -1
  574. package/dist/dev/ui/playback-rate-radio-group/playback-rate-radio-group-element.js.map +1 -1
  575. package/dist/dev/ui/poster/poster-element.d.ts +20 -18
  576. package/dist/dev/ui/poster/poster-element.d.ts.map +1 -1
  577. package/dist/dev/ui/poster/poster-element.js +145 -8
  578. package/dist/dev/ui/poster/poster-element.js.map +1 -1
  579. package/dist/dev/ui/quality-radio-group/quality-radio-group-element.js +1 -1
  580. package/dist/dev/ui/quality-radio-group/quality-radio-group-element.js.map +1 -1
  581. package/dist/dev/ui/slider/slider-preview-element.d.ts +2 -2
  582. package/dist/dev/ui/slider/slider-preview-element.d.ts.map +1 -1
  583. package/dist/dev/ui/slider/slider-preview-element.js.map +1 -1
  584. package/docs/README.md +1 -1
  585. package/docs/concepts/features.md +2 -2
  586. package/docs/concepts/media-sources.md +79 -1
  587. package/docs/concepts/skins.md +122 -108
  588. package/docs/how-to/build-your-own-component.md +1 -1
  589. package/docs/how-to/customize-skins.md +499 -469
  590. package/docs/how-to/migrate-from-media-chrome.md +359 -0
  591. package/docs/how-to/migrate-from-mux-player.md +535 -0
  592. package/docs/how-to/migrate-from-plyr.md +394 -0
  593. package/docs/how-to/migrate-from-video-js-8.md +594 -0
  594. package/docs/llms.txt +9 -0
  595. package/docs/reference/feature-volume.md +3 -1
  596. package/docs/reference/menu.md +3 -19
  597. package/docs/reference/mute-button.md +34 -0
  598. package/docs/reference/popover.md +2 -2
  599. package/docs/reference/poster.md +211 -21
  600. package/docs/reference/slider.md +1 -1
  601. package/docs/reference/time-slider.md +1 -1
  602. package/docs/reference/tooltip.md +6 -6
  603. package/docs/reference/volume-slider.md +2 -2
  604. package/package.json +15 -9
  605. package/cdn/adapter-Bk03SAxn.js +0 -2
  606. package/cdn/adapter-Bk03SAxn.js.map +0 -1
  607. package/cdn/adapter-XTen-YVQ.js.map +0 -1
  608. package/cdn/bn-DdelKD_n.js +0 -108
  609. package/cdn/bn-DdelKD_n.js.map +0 -1
  610. package/cdn/bn-YS8ruMcO.js +0 -2
  611. package/cdn/bn-YS8ruMcO.js.map +0 -1
  612. package/cdn/compounds-CCvdpvge.js.map +0 -1
  613. package/cdn/compounds-CJ6SbYAh.js +0 -8
  614. package/cdn/compounds-CJ6SbYAh.js.map +0 -1
  615. package/cdn/create-player-BHFyOnWi.js.map +0 -1
  616. package/cdn/create-player-CbpxjDaZ.js +0 -14
  617. package/cdn/create-player-CbpxjDaZ.js.map +0 -1
  618. package/cdn/default-BqQDVloS.js.map +0 -1
  619. package/cdn/default-CXWVp2oG.js +0 -2
  620. package/cdn/default-CXWVp2oG.js.map +0 -1
  621. package/cdn/default-Dw6cIEqT.js +0 -2
  622. package/cdn/default-Dw6cIEqT.js.map +0 -1
  623. package/cdn/default-I2LasfxC.js.map +0 -1
  624. package/cdn/error-surface-DCT1m2p1.js +0 -2
  625. package/cdn/error-surface-DCT1m2p1.js.map +0 -1
  626. package/cdn/error-surface-drmCvBVW.js.map +0 -1
  627. package/cdn/gesture-element-BNfMI8eh.js.map +0 -1
  628. package/cdn/gesture-element-CG-Sx_5t.js.map +0 -1
  629. package/cdn/hls-js-6lW7L4th.js +0 -2
  630. package/cdn/hls-js-DCQzjzB5.js +0 -2
  631. package/cdn/i18n-DfKGl5Rh.js +0 -2
  632. package/cdn/live-button-element-B_y-ZJBy.js.map +0 -1
  633. package/cdn/live-button-element-CWfkQUoy.js +0 -2
  634. package/cdn/media-5ODYtX1-.js +0 -2
  635. package/cdn/media-5ODYtX1-.js.map +0 -1
  636. package/cdn/media-BTipOcKo.js +0 -2
  637. package/cdn/media-B_gQXwri.js.map +0 -1
  638. package/cdn/media-CPWNSZFX.js +0 -41
  639. package/cdn/media-CPWNSZFX.js.map +0 -1
  640. package/cdn/media-CbWsJJhU.js +0 -2
  641. package/cdn/media-Cp3acYc8.js.map +0 -1
  642. package/cdn/media-Dq4zmIJa2.js +0 -2
  643. package/cdn/media-Dq4zmIJa2.js.map +0 -1
  644. package/cdn/media-suYcjCG22.js +0 -445
  645. package/cdn/media-suYcjCG22.js.map +0 -1
  646. package/cdn/minimal-BedCvMBG.js +0 -2
  647. package/cdn/minimal-BedCvMBG.js.map +0 -1
  648. package/cdn/minimal-BoP112ye.js +0 -2
  649. package/cdn/minimal-BoP112ye.js.map +0 -1
  650. package/cdn/minimal-DLosvq31.js.map +0 -1
  651. package/cdn/minimal-DQCLKRyR.js.map +0 -1
  652. package/cdn/minimal-ui-AFk6Ut5f.js +0 -2
  653. package/cdn/minimal-ui-BVKu9LWj.js +0 -2
  654. package/cdn/mixin-CkNZwQXF.js.map +0 -1
  655. package/cdn/mixin-DiB7dIef.js +0 -2
  656. package/cdn/player-B0ccW5-n.js +0 -2
  657. package/cdn/player-iIewo8Y9.js +0 -2
  658. package/cdn/player-srq1RGTj.js +0 -2
  659. package/cdn/poster-element-BP1Ypgbf.js.map +0 -1
  660. package/cdn/poster-element-S-rr412t.js +0 -2
  661. package/cdn/poster-element-S-rr412t.js.map +0 -1
  662. package/cdn/seek-button-element-DxLmm58Y.js +0 -2
  663. package/cdn/seek-button-element-DxLmm58Y.js.map +0 -1
  664. package/cdn/seek-button-element-TErrbilI.js.map +0 -1
  665. package/cdn/select-tracks-nRPBa1NC.js.map +0 -1
  666. package/cdn/select-tracks-xV1s28xD.js +0 -59
  667. package/cdn/select-tracks-xV1s28xD.js.map +0 -1
  668. package/cdn/text-element-Bsyglab8.js +0 -2
  669. package/cdn/time-slider-chapters-element-DPgaLdBt.js.map +0 -1
  670. package/cdn/time-slider-chapters-element-MdlcovBu.js +0 -2
  671. package/cdn/time-slider-chapters-element-MdlcovBu.js.map +0 -1
  672. package/cdn/translate-text-BPMWpzFm.js +0 -2
  673. package/cdn/translate-text-BPMWpzFm.js.map +0 -1
  674. package/cdn/translate-text-DP0CzUCC.js.map +0 -1
  675. package/cdn/ui-CecDxhTX.js +0 -2
  676. package/cdn/ui-ChWM6Xz2.js +0 -2
@@ -1 +1 @@
1
- {"version":3,"file":"playback-rate-radio-group-element.js","names":["#mediaState","#core","#i18n","#options"],"sources":["../../../../src/ui/playback-rate-radio-group/playback-rate-radio-group-element.ts"],"sourcesContent":["import {\n PlaybackRateRadioGroupCore,\n PlaybackRateRadioGroupDataAttrs,\n type PlaybackRateRadioGroupOption,\n} from '@videojs/core';\nimport { applyStateDataAttrs, logMissingFeature, selectPlaybackRate } from '@videojs/core/dom';\nimport { translateText } from '@videojs/core/i18n';\nimport type { PropertyDeclarationMap, PropertyValues } from '@videojs/element';\n\nimport { i18nContext } from '../../i18n/context';\nimport { I18nController } from '../../i18n/controller';\nimport { playerContext } from '../../player/context';\nimport { PlayerController } from '../../player/player-controller';\nimport { MenuRadioGroupElement } from '../menu/menu-radio-group-element';\nimport { RadioOptionsController } from '../radio-options/radio-options-controller';\n\nexport class PlaybackRateRadioGroupElement extends MenuRadioGroupElement {\n static override readonly tagName = 'media-playback-rate-radio-group';\n\n static override properties = {\n ...MenuRadioGroupElement.properties,\n disabled: { type: Boolean },\n } satisfies PropertyDeclarationMap<'value' | 'disabled'>;\n\n disabled = false;\n formatRate = PlaybackRateRadioGroupCore.defaultProps.formatRate;\n\n readonly #core = new PlaybackRateRadioGroupCore();\n readonly #i18n = new I18nController(this, i18nContext);\n readonly #mediaState = new PlayerController(this, playerContext, selectPlaybackRate);\n readonly #options = new RadioOptionsController<PlaybackRateRadioGroupOption>(this, {\n setItemAttributes: (item, option) => item.setAttribute('data-rate', option.value),\n onValueChange: (value) => {\n const media = this.#mediaState.value;\n if (media) this.#core.selectValue(media, value);\n },\n });\n\n override connectedCallback(): void {\n super.connectedCallback();\n if (this.destroyed) return;\n\n if (__DEV__ && !this.#mediaState.value && this.#mediaState.displayName) {\n logMissingFeature(this.localName, this.#mediaState.displayName);\n }\n }\n\n protected override update(changed: PropertyValues): void {\n const media = this.#mediaState.value;\n let state: PlaybackRateRadioGroupCore.State | null = null;\n\n if (media) {\n this.#core.setProps({ formatRate: this.formatRate, disabled: this.disabled });\n this.#core.setMedia(media);\n state = this.#core.getState();\n\n this.applyDefaultAriaLabel(\n translateText(this.#core.getLabel(state), this.#i18n.value, this.#core.getLabelParams(state))\n );\n this.#options.sync(state, this.#i18n.value, this.#i18n.locale);\n this.publishMenuMetadata(state.disabled, state.availability);\n }\n\n super.update(changed);\n\n if (state) applyStateDataAttrs(this, state, PlaybackRateRadioGroupDataAttrs);\n }\n}\n\nexport namespace PlaybackRateRadioGroupElement {\n export type State = PlaybackRateRadioGroupCore.State;\n}\n"],"mappings":";;;;;;;;;;AAgBA,IAAa,gCAAb,cAAmD,sBAAsB;;;EAQ5D,KAAA,WAAA;EACE,KAAA,aAAA,2BAA2B,aAAa;EAEpC,KAAA,QAAA,IAAI,2BAA2B;EAC/B,KAAA,QAAA,IAAI,eAAe,MAAM,WAAW;EAC9B,KAAA,cAAA,IAAI,iBAAiB,MAAM,eAAe,kBAAkB;EAC/D,KAAA,WAAA,IAAI,uBAAqD,MAAM;GACjF,oBAAoB,MAAM,WAAW,KAAK,aAAa,aAAa,OAAO,KAAK;GAChF,gBAAgB,UAAU;IACxB,MAAM,QAAQ,KAAKA,YAAY;IAC/B,IAAI,OAAO,KAAKC,MAAM,YAAY,OAAO,KAAK;GAChD;EACF,CAAC;;;EAnBkC,KAAA,UAAA;;;EAEN,KAAA,aAAA;GAC3B,GAAG,sBAAsB;GACzB,UAAU,EAAE,MAAM,QAAQ;EAC5B;;CAKA;CACA;CACA;CACA;CAQA,oBAAmC;EACjC,MAAM,kBAAkB;EACxB,IAAI,KAAK,WAAW;EAEpB,IAAe,CAAC,KAAKD,YAAY,SAAS,KAAKA,YAAY,aACzD,kBAAkB,KAAK,WAAW,KAAKA,YAAY,WAAW;CAElE;CAEA,OAA0B,SAA+B;EACvD,MAAM,QAAQ,KAAKA,YAAY;EAC/B,IAAI,QAAiD;EAErD,IAAI,OAAO;GACT,KAAKC,MAAM,SAAS;IAAE,YAAY,KAAK;IAAY,UAAU,KAAK;GAAS,CAAC;GAC5E,KAAKA,MAAM,SAAS,KAAK;GACzB,QAAQ,KAAKA,MAAM,SAAS;GAE5B,KAAK,sBACH,cAAc,KAAKA,MAAM,SAAS,KAAK,GAAG,KAAKC,MAAM,OAAO,KAAKD,MAAM,eAAe,KAAK,CAAC,CAC9F;GACA,KAAKE,SAAS,KAAK,OAAO,KAAKD,MAAM,OAAO,KAAKA,MAAM,MAAM;GAC7D,KAAK,oBAAoB,MAAM,UAAU,MAAM,YAAY;EAC7D;EAEA,MAAM,OAAO,OAAO;EAEpB,IAAI,OAAO,oBAAoB,MAAM,OAAO,+BAA+B;CAC7E;AACF"}
1
+ {"version":3,"file":"playback-rate-radio-group-element.js","names":["#mediaState","#core","#i18n","#options"],"sources":["../../../../src/ui/playback-rate-radio-group/playback-rate-radio-group-element.ts"],"sourcesContent":["import {\n PlaybackRateRadioGroupCore,\n PlaybackRateRadioGroupDataAttrs,\n type PlaybackRateRadioGroupOption,\n} from '@videojs/core';\nimport { applyStateDataAttrs, logMissingFeature, selectPlaybackRate } from '@videojs/core/dom';\nimport { translateText } from '@videojs/core/i18n';\nimport type { PropertyDeclarationMap, PropertyValues } from '@videojs/element';\n\nimport { i18nContext } from '../../i18n/context';\nimport { I18nController } from '../../i18n/controller';\nimport { playerContext } from '../../player/context';\nimport { PlayerController } from '../../player/player-controller';\nimport { MenuRadioGroupElement } from '../menu/menu-radio-group-element';\nimport { RadioOptionsController } from '../radio-options/radio-options-controller';\n\nexport class PlaybackRateRadioGroupElement extends MenuRadioGroupElement {\n static override readonly tagName = 'media-playback-rate-radio-group';\n\n static override properties = {\n ...MenuRadioGroupElement.properties,\n disabled: { type: Boolean },\n } satisfies PropertyDeclarationMap<'value' | 'disabled'>;\n\n disabled = false;\n formatRate = PlaybackRateRadioGroupCore.defaultProps.formatRate;\n\n readonly #core = new PlaybackRateRadioGroupCore();\n readonly #i18n = new I18nController(this, i18nContext);\n readonly #mediaState = new PlayerController(this, playerContext, selectPlaybackRate);\n readonly #options = new RadioOptionsController<PlaybackRateRadioGroupOption>(this, {\n setItemAttributes: (item, option) => item.setAttribute('data-rate', option.value),\n onValueChange: (value) => {\n const media = this.#mediaState.value;\n if (media) this.#core.selectValue(media, value);\n },\n });\n\n override connectedCallback(): void {\n super.connectedCallback();\n if (this.destroyed) return;\n\n if (__DEV__ && !this.#mediaState.value && this.#mediaState.displayName) {\n logMissingFeature(this.localName, this.#mediaState.displayName);\n }\n }\n\n protected override update(changed: PropertyValues): void {\n const media = this.#mediaState.value;\n let state: PlaybackRateRadioGroupCore.State | null = null;\n\n if (media) {\n this.#core.setProps({ formatRate: this.formatRate, disabled: this.disabled });\n this.#core.setMedia(media);\n state = this.#core.getState();\n\n this.applyDefaultAriaLabel(\n translateText(this.#core.getLabel(state), this.#i18n.value, this.#core.getLabelParams(state))\n );\n this.#options.sync(state, this.#i18n.value, this.#i18n.locale);\n this.publishMenuTriggerState(state.disabled, state.availability);\n }\n\n super.update(changed);\n\n if (state) applyStateDataAttrs(this, state, PlaybackRateRadioGroupDataAttrs);\n }\n}\n\nexport namespace PlaybackRateRadioGroupElement {\n export type State = PlaybackRateRadioGroupCore.State;\n}\n"],"mappings":";;;;;;;;;;AAgBA,IAAa,gCAAb,cAAmD,sBAAsB;;;EAQ5D,KAAA,WAAA;EACE,KAAA,aAAA,2BAA2B,aAAa;EAEpC,KAAA,QAAA,IAAI,2BAA2B;EAC/B,KAAA,QAAA,IAAI,eAAe,MAAM,WAAW;EAC9B,KAAA,cAAA,IAAI,iBAAiB,MAAM,eAAe,kBAAkB;EAC/D,KAAA,WAAA,IAAI,uBAAqD,MAAM;GACjF,oBAAoB,MAAM,WAAW,KAAK,aAAa,aAAa,OAAO,KAAK;GAChF,gBAAgB,UAAU;IACxB,MAAM,QAAQ,KAAKA,YAAY;IAC/B,IAAI,OAAO,KAAKC,MAAM,YAAY,OAAO,KAAK;GAChD;EACF,CAAC;;;EAnBkC,KAAA,UAAA;;;EAEN,KAAA,aAAA;GAC3B,GAAG,sBAAsB;GACzB,UAAU,EAAE,MAAM,QAAQ;EAC5B;;CAKA;CACA;CACA;CACA;CAQA,oBAAmC;EACjC,MAAM,kBAAkB;EACxB,IAAI,KAAK,WAAW;EAEpB,IAAe,CAAC,KAAKD,YAAY,SAAS,KAAKA,YAAY,aACzD,kBAAkB,KAAK,WAAW,KAAKA,YAAY,WAAW;CAElE;CAEA,OAA0B,SAA+B;EACvD,MAAM,QAAQ,KAAKA,YAAY;EAC/B,IAAI,QAAiD;EAErD,IAAI,OAAO;GACT,KAAKC,MAAM,SAAS;IAAE,YAAY,KAAK;IAAY,UAAU,KAAK;GAAS,CAAC;GAC5E,KAAKA,MAAM,SAAS,KAAK;GACzB,QAAQ,KAAKA,MAAM,SAAS;GAE5B,KAAK,sBACH,cAAc,KAAKA,MAAM,SAAS,KAAK,GAAG,KAAKC,MAAM,OAAO,KAAKD,MAAM,eAAe,KAAK,CAAC,CAC9F;GACA,KAAKE,SAAS,KAAK,OAAO,KAAKD,MAAM,OAAO,KAAKA,MAAM,MAAM;GAC7D,KAAK,wBAAwB,MAAM,UAAU,MAAM,YAAY;EACjE;EAEA,MAAM,OAAO,OAAO;EAEpB,IAAI,OAAO,oBAAoB,MAAM,OAAO,+BAA+B;CAC7E;AACF"}
@@ -1,25 +1,27 @@
1
- import { PlayerController } from "../../player/player-controller.js";
2
- import { MediaUIElement } from "../media-ui-element.js";
3
- import { index_d_exports } from "../../index.js";
4
- import { PosterCore } from "@videojs/core";
1
+ import { MediaElement } from "../media-element.js";
2
+ import { PropertyValues } from "@videojs/element";
5
3
  //#region src/ui/poster/poster-element.d.ts
6
- declare class PosterElement extends MediaUIElement<PosterCore> {
4
+ /**
5
+ * `<media-poster>` — sets `src` on a poster image it does not own.
6
+ *
7
+ * The image is a child, as in `<picture>`, but sourcing runs the other way
8
+ * around: `<picture>` treats the `src` on its `<img>` as the fallback, while
9
+ * here an image with no source of its own is the one this element fills in.
10
+ * Give the child a `src`, a `srcset`, or `<source>` candidates and it is yours,
11
+ * left alone.
12
+ *
13
+ * Renders no image of its own, so include one:
14
+ * `<media-poster><img alt=""></media-poster>`. Inside a skin, an
15
+ * `<img slot="poster">` of yours replaces the one the skin carries.
16
+ */
17
+ declare class PosterElement extends MediaElement {
18
+ #private;
7
19
  static readonly tagName = "media-poster";
8
20
  static get observedAttributes(): string[];
9
- protected readonly core: PosterCore;
10
- protected readonly stateAttrMap: {
11
- readonly visible: 'data-visible';
12
- };
13
- protected readonly mediaState: PlayerController<index_d_exports.AnyPlayerStore, {
14
- paused: boolean;
15
- ended: boolean;
16
- started: boolean;
17
- waiting: boolean;
18
- play: () => Promise<void>;
19
- pause: () => void;
20
- togglePaused: () => boolean;
21
- } | undefined>;
21
+ connectedCallback(): void;
22
22
  attributeChangedCallback(attr: string, oldValue: string | null, newValue: string | null): void;
23
+ disconnectedCallback(): void;
24
+ protected update(changed: PropertyValues): void;
23
25
  }
24
26
  //#endregion
25
27
  export { PosterElement };
@@ -1 +1 @@
1
- {"version":3,"file":"poster-element.d.ts","names":[],"sources":["../../../../src/ui/poster/poster-element.ts"],"mappings":";;;;;cAOa,sBAAsB,eAAe;kBAChC;aAEL;qBAKQ,MAAI;qBACJ;;;qBACA,YAAU,iBAFN,gBAEM;;;;;;;;;EAEpB,yBAAyB,cAAc,yBAAyB"}
1
+ {"version":3,"file":"poster-element.d.ts","names":[],"sources":["../../../../src/ui/poster/poster-element.ts"],"mappings":";;;;;;;;;;;;;;;;cAuEa,sBAAsB;;kBACjB;aAEL;EAoBF;EAiBA,yBAAyB,cAAc,yBAAyB;EAYhE;YAcU,OAAO,SAAS"}
@@ -1,27 +1,164 @@
1
1
  import { playerContext } from "../../player/context.js";
2
+ import { MediaElement } from "../media-element.js";
2
3
  import { PlayerController } from "../../player/player-controller.js";
3
- import { MediaUIElement } from "../media-ui-element.js";
4
- import { selectPlayback } from "@videojs/core/dom";
4
+ import { applyStateDataAttrs, logMissingFeature, selectMetadata, selectPlayback } from "@videojs/core/dom";
5
5
  import { PosterCore, PosterDataAttrs } from "@videojs/core";
6
6
  //#region src/ui/poster/poster-element.ts
7
- var PosterElement = class extends MediaUIElement {
8
- constructor(..._args) {
9
- super(..._args);
10
- this.core = new PosterCore();
11
- this.stateAttrMap = PosterDataAttrs;
12
- this.mediaState = new PlayerController(this, playerContext, selectPlayback);
7
+ /** What an element composes: whatever fills a slot, or the element's own children. */
8
+ function composedChildren(element) {
9
+ if (element instanceof HTMLSlotElement) {
10
+ const assigned = element.assignedElements();
11
+ if (assigned.length > 0) return assigned;
13
12
  }
13
+ return [...element.children];
14
+ }
15
+ /**
16
+ * The first image an element composes. A skin forwards its own
17
+ * `<slot name="poster">` in, so the image is a slot or two down and may be
18
+ * wrapped in a `<picture>` or a framework image component.
19
+ */
20
+ function findImage(element) {
21
+ for (const child of composedChildren(element)) {
22
+ if (child instanceof HTMLImageElement) return child;
23
+ const nested = findImage(child);
24
+ if (nested) return nested;
25
+ }
26
+ return null;
27
+ }
28
+ /**
29
+ * Whether anything already points this image somewhere, which answers both
30
+ * whether the author owns the source and whether there is a download to wait
31
+ * for. A `<source>` counts: inside a `<picture>` it can win over the `src`.
32
+ */
33
+ function hasSource(img) {
34
+ if (img.hasAttribute("src") || img.hasAttribute("srcset")) return true;
35
+ const parent = img.parentElement;
36
+ return parent?.localName === "picture" && parent.querySelector("source") !== null;
37
+ }
38
+ /**
39
+ * Whether `complete` on this image describes a request. It is also true for one
40
+ * that omits both `src` and `srcset`, whatever a parent `<picture>` is fetching
41
+ * on its behalf, so only an image sourced from its own attributes can be read.
42
+ */
43
+ function hasOwnSource(img) {
44
+ return !!img.getAttribute("src") || img.hasAttribute("srcset");
45
+ }
46
+ /**
47
+ * `<media-poster>` — sets `src` on a poster image it does not own.
48
+ *
49
+ * The image is a child, as in `<picture>`, but sourcing runs the other way
50
+ * around: `<picture>` treats the `src` on its `<img>` as the fallback, while
51
+ * here an image with no source of its own is the one this element fills in.
52
+ * Give the child a `src`, a `srcset`, or `<source>` candidates and it is yours,
53
+ * left alone.
54
+ *
55
+ * Renders no image of its own, so include one:
56
+ * `<media-poster><img alt=""></media-poster>`. Inside a skin, an
57
+ * `<img slot="poster">` of yours replaces the one the skin carries.
58
+ */
59
+ var PosterElement = class extends MediaElement {
14
60
  static {
15
61
  this.tagName = "media-poster";
16
62
  }
17
63
  static get observedAttributes() {
18
64
  return [...super.observedAttributes, "placeholdersrc"];
19
65
  }
66
+ #core = new PosterCore();
67
+ #children = new MutationObserver(() => this.requestUpdate());
68
+ #playback = new PlayerController(this, playerContext, selectPlayback);
69
+ #metadata = new PlayerController(this, playerContext, selectMetadata);
70
+ #image = null;
71
+ /** Whether `#image` had no source of its own when it became active. */
72
+ #owned = false;
73
+ #imageLoadState = "pending";
74
+ #imageEvents = null;
75
+ #disconnect = null;
76
+ #warnedMissingImage = false;
77
+ connectedCallback() {
78
+ super.connectedCallback();
79
+ if (this.destroyed) return;
80
+ this.#disconnect = new AbortController();
81
+ const { signal } = this.#disconnect;
82
+ this.addEventListener("slotchange", () => this.requestUpdate(), { signal });
83
+ this.#children.observe(this, {
84
+ childList: true,
85
+ subtree: true
86
+ });
87
+ if (!this.#playback.value) logMissingFeature(this.localName, this.#playback.displayName ?? "playback");
88
+ }
20
89
  attributeChangedCallback(attr, oldValue, newValue) {
21
90
  super.attributeChangedCallback(attr, oldValue, newValue);
22
91
  if (attr === "placeholdersrc") if (newValue) this.style.setProperty("--media-poster-placeholder", `url(${newValue})`);
23
92
  else this.style.removeProperty("--media-poster-placeholder");
24
93
  }
94
+ disconnectedCallback() {
95
+ super.disconnectedCallback();
96
+ this.#adopt(null);
97
+ this.#children.disconnect();
98
+ this.#disconnect?.abort();
99
+ this.#disconnect = null;
100
+ }
101
+ get #loadState() {
102
+ if (!this.#image || !hasSource(this.#image)) return "none";
103
+ return this.#imageLoadState === "pending" ? "loading" : this.#imageLoadState;
104
+ }
105
+ update(changed) {
106
+ super.update(changed);
107
+ const playback = this.#playback.value;
108
+ if (!playback) return;
109
+ this.#core.setMedia({
110
+ started: playback.started,
111
+ poster: this.#metadata.value?.poster ?? ""
112
+ });
113
+ const { src } = this.#core.getState();
114
+ this.#adopt(findImage(this));
115
+ this.#applySource(src);
116
+ this.#core.setImageLoadState(this.#loadState);
117
+ applyStateDataAttrs(this, this.#core.getState(), PosterDataAttrs);
118
+ }
119
+ /**
120
+ * Ownership is settled once, when an image becomes active: after the first fill
121
+ * the `src` we set would itself look authored. Re-slot an image with a source
122
+ * to hand it back, the way React decides a field is controlled at mount.
123
+ */
124
+ #adopt(next) {
125
+ if (next === this.#image) return;
126
+ if (this.#owned) this.#image?.removeAttribute("src");
127
+ this.#imageEvents?.abort();
128
+ this.#imageEvents = null;
129
+ this.#image = next;
130
+ this.#owned = next !== null && !hasSource(next);
131
+ this.#imageLoadState = "pending";
132
+ if (!next) return;
133
+ if (next.naturalWidth > 0) this.#imageLoadState = "loaded";
134
+ else if (next.complete && hasOwnSource(next)) this.#imageLoadState = "error";
135
+ this.#imageEvents = new AbortController();
136
+ const { signal } = this.#imageEvents;
137
+ const settle = (loadState) => () => {
138
+ this.#imageLoadState = loadState;
139
+ this.requestUpdate();
140
+ };
141
+ next.addEventListener("load", settle("loaded"), { signal });
142
+ next.addEventListener("error", settle("error"), { signal });
143
+ }
144
+ #applySource(src) {
145
+ const img = this.#image;
146
+ if (!img) {
147
+ if (src && !this.#warnedMissingImage) {
148
+ this.#warnedMissingImage = true;
149
+ console.warn(`<${this.localName}> resolved a poster but has no image to put it in. Add one as a child: <${this.localName}><img alt=""></${this.localName}>`);
150
+ }
151
+ return;
152
+ }
153
+ if (!this.#owned) return;
154
+ if (!src) {
155
+ this.#imageLoadState = "pending";
156
+ img.removeAttribute("src");
157
+ } else if (img.getAttribute("src") !== src) {
158
+ this.#imageLoadState = "pending";
159
+ img.setAttribute("src", src);
160
+ }
161
+ }
25
162
  };
26
163
  //#endregion
27
164
  export { PosterElement };
@@ -1 +1 @@
1
- {"version":3,"file":"poster-element.js","names":[],"sources":["../../../../src/ui/poster/poster-element.ts"],"sourcesContent":["import { PosterCore, PosterDataAttrs } from '@videojs/core';\nimport { selectPlayback } from '@videojs/core/dom';\n\nimport { playerContext } from '../../player/context';\nimport { PlayerController } from '../../player/player-controller';\nimport { MediaUIElement } from '../media-ui-element';\n\nexport class PosterElement extends MediaUIElement<PosterCore> {\n static readonly tagName = 'media-poster';\n\n static get observedAttributes(): string[] {\n // biome-ignore lint/complexity/noThisInStatic: intentional use of super\n return [...super.observedAttributes, 'placeholdersrc'];\n }\n\n protected readonly core = new PosterCore();\n protected readonly stateAttrMap = PosterDataAttrs;\n protected readonly mediaState = new PlayerController(this, playerContext, selectPlayback);\n\n override attributeChangedCallback(attr: string, oldValue: string | null, newValue: string | null): void {\n super.attributeChangedCallback(attr, oldValue, newValue);\n\n if (attr === 'placeholdersrc') {\n if (newValue) {\n this.style.setProperty('--media-poster-placeholder', `url(${newValue})`);\n } else {\n this.style.removeProperty('--media-poster-placeholder');\n }\n }\n }\n}\n"],"mappings":";;;;;;AAOA,IAAa,gBAAb,cAAmC,eAA2B;;;EAQlC,KAAA,OAAA,IAAI,WAAW;EACP,KAAA,eAAA;EACF,KAAA,aAAA,IAAI,iBAAiB,MAAM,eAAe,cAAc;;;EAT9D,KAAA,UAAA;;CAE1B,WAAW,qBAA+B;EAExC,OAAO,CAAC,GAAG,MAAM,oBAAoB,gBAAgB;CACvD;CAMA,yBAAkC,MAAc,UAAyB,UAA+B;EACtG,MAAM,yBAAyB,MAAM,UAAU,QAAQ;EAEvD,IAAI,SAAS,kBACX,IAAI,UACF,KAAK,MAAM,YAAY,8BAA8B,OAAO,SAAS,EAAE;OAEvE,KAAK,MAAM,eAAe,4BAA4B;CAG5D;AACF"}
1
+ {"version":3,"file":"poster-element.js","names":["#core","#children","#playback","#metadata","#disconnect","#adopt","#loadState","#image","#imageLoadState","#applySource","#owned","#imageEvents","#warnedMissingImage"],"sources":["../../../../src/ui/poster/poster-element.ts"],"sourcesContent":["import { PosterCore, PosterDataAttrs, type PosterImageLoadState } from '@videojs/core';\nimport { applyStateDataAttrs, logMissingFeature, selectMetadata, selectPlayback } from '@videojs/core/dom';\nimport type { PropertyValues } from '@videojs/element';\n\nimport { playerContext } from '../../player/context';\nimport { PlayerController } from '../../player/player-controller';\nimport { MediaElement } from '../media-element';\n\n/** What an element composes: whatever fills a slot, or the element's own children. */\nfunction composedChildren(element: Element): Element[] {\n if (element instanceof HTMLSlotElement) {\n const assigned = element.assignedElements();\n if (assigned.length > 0) return assigned;\n }\n\n return [...element.children];\n}\n\n/**\n * The first image an element composes. A skin forwards its own\n * `<slot name=\"poster\">` in, so the image is a slot or two down and may be\n * wrapped in a `<picture>` or a framework image component.\n */\nfunction findImage(element: Element): HTMLImageElement | null {\n for (const child of composedChildren(element)) {\n if (child instanceof HTMLImageElement) return child;\n\n const nested = findImage(child);\n if (nested) return nested;\n }\n\n return null;\n}\n\n/**\n * Whether anything already points this image somewhere, which answers both\n * whether the author owns the source and whether there is a download to wait\n * for. A `<source>` counts: inside a `<picture>` it can win over the `src`.\n */\nfunction hasSource(img: HTMLImageElement): boolean {\n if (img.hasAttribute('src') || img.hasAttribute('srcset')) return true;\n\n const parent = img.parentElement;\n return parent?.localName === 'picture' && parent.querySelector('source') !== null;\n}\n\n/**\n * Whether `complete` on this image describes a request. It is also true for one\n * that omits both `src` and `srcset`, whatever a parent `<picture>` is fetching\n * on its behalf, so only an image sourced from its own attributes can be read.\n */\nfunction hasOwnSource(img: HTMLImageElement): boolean {\n return !!img.getAttribute('src') || img.hasAttribute('srcset');\n}\n\n/** How the current source is faring. */\ntype ImageLoadState = 'pending' | 'loaded' | 'error';\n\n/**\n * `<media-poster>` — sets `src` on a poster image it does not own.\n *\n * The image is a child, as in `<picture>`, but sourcing runs the other way\n * around: `<picture>` treats the `src` on its `<img>` as the fallback, while\n * here an image with no source of its own is the one this element fills in.\n * Give the child a `src`, a `srcset`, or `<source>` candidates and it is yours,\n * left alone.\n *\n * Renders no image of its own, so include one:\n * `<media-poster><img alt=\"\"></media-poster>`. Inside a skin, an\n * `<img slot=\"poster\">` of yours replaces the one the skin carries.\n */\nexport class PosterElement extends MediaElement {\n static readonly tagName = 'media-poster';\n\n static get observedAttributes(): string[] {\n // biome-ignore lint/complexity/noThisInStatic: intentional use of super\n return [...super.observedAttributes, 'placeholdersrc'];\n }\n\n readonly #core = new PosterCore();\n readonly #children = new MutationObserver(() => this.requestUpdate());\n\n readonly #playback = new PlayerController(this, playerContext, selectPlayback);\n readonly #metadata = new PlayerController(this, playerContext, selectMetadata);\n\n #image: HTMLImageElement | null = null;\n /** Whether `#image` had no source of its own when it became active. */\n #owned = false;\n #imageLoadState: ImageLoadState = 'pending';\n\n #imageEvents: AbortController | null = null;\n #disconnect: AbortController | null = null;\n #warnedMissingImage = false;\n\n override connectedCallback(): void {\n super.connectedCallback();\n if (this.destroyed) return;\n\n this.#disconnect = new AbortController();\n const { signal } = this.#disconnect;\n\n // Two ways the image can change: a skin's forwarding slot fills or empties,\n // which bubbles here, or a child is added or removed, which announces nothing.\n this.addEventListener('slotchange', () => this.requestUpdate(), { signal });\n this.#children.observe(this, { childList: true, subtree: true });\n\n if (__DEV__ && !this.#playback.value) {\n logMissingFeature(this.localName, this.#playback.displayName ?? 'playback');\n }\n }\n\n override attributeChangedCallback(attr: string, oldValue: string | null, newValue: string | null): void {\n super.attributeChangedCallback(attr, oldValue, newValue);\n\n if (attr === 'placeholdersrc') {\n if (newValue) {\n this.style.setProperty('--media-poster-placeholder', `url(${newValue})`);\n } else {\n this.style.removeProperty('--media-poster-placeholder');\n }\n }\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n\n this.#adopt(null);\n this.#children.disconnect();\n this.#disconnect?.abort();\n this.#disconnect = null;\n }\n\n get #loadState(): PosterImageLoadState {\n if (!this.#image || !hasSource(this.#image)) return 'none';\n return this.#imageLoadState === 'pending' ? 'loading' : this.#imageLoadState;\n }\n\n protected override update(changed: PropertyValues): void {\n super.update(changed);\n\n const playback = this.#playback.value;\n if (!playback) return;\n\n // `metadata` is optional: without it nothing resolves a URL, and this stays\n // a visibility wrapper around whatever the author supplied.\n this.#core.setMedia({\n started: playback.started,\n poster: this.#metadata.value?.poster ?? '',\n });\n\n const { src } = this.#core.getState();\n\n this.#adopt(findImage(this));\n this.#applySource(src);\n\n this.#core.setImageLoadState(this.#loadState);\n applyStateDataAttrs(this, this.#core.getState(), PosterDataAttrs);\n }\n\n /**\n * Ownership is settled once, when an image becomes active: after the first fill\n * the `src` we set would itself look authored. Re-slot an image with a source\n * to hand it back, the way React decides a field is controlled at mount.\n */\n #adopt(next: HTMLImageElement | null): void {\n if (next === this.#image) return;\n\n // An image that steps aside keeps downloading whatever we pointed it at.\n if (this.#owned) this.#image?.removeAttribute('src');\n this.#imageEvents?.abort();\n this.#imageEvents = null;\n\n this.#image = next;\n this.#owned = next !== null && !hasSource(next);\n this.#imageLoadState = 'pending';\n\n if (!next) return;\n\n // An image that finished before we started listening never fires again, so\n // its load state has to be read off it. Decoded pixels stand on their own;\n // the absence of them only means failure once `complete` can be trusted.\n if (next.naturalWidth > 0) this.#imageLoadState = 'loaded';\n else if (next.complete && hasOwnSource(next)) this.#imageLoadState = 'error';\n\n this.#imageEvents = new AbortController();\n const { signal } = this.#imageEvents;\n const settle = (loadState: ImageLoadState) => () => {\n this.#imageLoadState = loadState;\n this.requestUpdate();\n };\n\n next.addEventListener('load', settle('loaded'), { signal });\n next.addEventListener('error', settle('error'), { signal });\n }\n\n #applySource(src: string): void {\n const img = this.#image;\n\n if (!img) {\n if (__DEV__ && src && !this.#warnedMissingImage) {\n this.#warnedMissingImage = true;\n console.warn(\n `<${this.localName}> resolved a poster but has no image to put it in. ` +\n `Add one as a child: <${this.localName}><img alt=\"\"></${this.localName}>`\n );\n }\n return;\n }\n\n if (!this.#owned) return;\n\n if (!src) {\n this.#imageLoadState = 'pending';\n img.removeAttribute('src');\n } else if (img.getAttribute('src') !== src) {\n // Reset before the write, not after: how the last source fared says\n // nothing about this one, and the write itself can settle it.\n this.#imageLoadState = 'pending';\n img.setAttribute('src', src);\n }\n }\n}\n"],"mappings":";;;;;;;AASA,SAAS,iBAAiB,SAA6B;CACrD,IAAI,mBAAmB,iBAAiB;EACtC,MAAM,WAAW,QAAQ,iBAAiB;EAC1C,IAAI,SAAS,SAAS,GAAG,OAAO;CAClC;CAEA,OAAO,CAAC,GAAG,QAAQ,QAAQ;AAC7B;;;;;;AAOA,SAAS,UAAU,SAA2C;CAC5D,KAAK,MAAM,SAAS,iBAAiB,OAAO,GAAG;EAC7C,IAAI,iBAAiB,kBAAkB,OAAO;EAE9C,MAAM,SAAS,UAAU,KAAK;EAC9B,IAAI,QAAQ,OAAO;CACrB;CAEA,OAAO;AACT;;;;;;AAOA,SAAS,UAAU,KAAgC;CACjD,IAAI,IAAI,aAAa,KAAK,KAAK,IAAI,aAAa,QAAQ,GAAG,OAAO;CAElE,MAAM,SAAS,IAAI;CACnB,OAAO,QAAQ,cAAc,aAAa,OAAO,cAAc,QAAQ,MAAM;AAC/E;;;;;;AAOA,SAAS,aAAa,KAAgC;CACpD,OAAO,CAAC,CAAC,IAAI,aAAa,KAAK,KAAK,IAAI,aAAa,QAAQ;AAC/D;;;;;;;;;;;;;;AAkBA,IAAa,gBAAb,cAAmC,aAAa;;EACpB,KAAA,UAAA;;CAE1B,WAAW,qBAA+B;EAExC,OAAO,CAAC,GAAG,MAAM,oBAAoB,gBAAgB;CACvD;CAEA,QAAiB,IAAI,WAAW;CAChC,YAAqB,IAAI,uBAAuB,KAAK,cAAc,CAAC;CAEpE,YAAqB,IAAI,iBAAiB,MAAM,eAAe,cAAc;CAC7E,YAAqB,IAAI,iBAAiB,MAAM,eAAe,cAAc;CAE7E,SAAkC;;CAElC,SAAS;CACT,kBAAkC;CAElC,eAAuC;CACvC,cAAsC;CACtC,sBAAsB;CAEtB,oBAAmC;EACjC,MAAM,kBAAkB;EACxB,IAAI,KAAK,WAAW;EAEpB,KAAKI,cAAc,IAAI,gBAAgB;EACvC,MAAM,EAAE,WAAW,KAAKA;EAIxB,KAAK,iBAAiB,oBAAoB,KAAK,cAAc,GAAG,EAAE,OAAO,CAAC;EAC1E,KAAKH,UAAU,QAAQ,MAAM;GAAE,WAAW;GAAM,SAAS;EAAK,CAAC;EAE/D,IAAe,CAAC,KAAKC,UAAU,OAC7B,kBAAkB,KAAK,WAAW,KAAKA,UAAU,eAAe,UAAU;CAE9E;CAEA,yBAAkC,MAAc,UAAyB,UAA+B;EACtG,MAAM,yBAAyB,MAAM,UAAU,QAAQ;EAEvD,IAAI,SAAS,kBACX,IAAI,UACF,KAAK,MAAM,YAAY,8BAA8B,OAAO,SAAS,EAAE;OAEvE,KAAK,MAAM,eAAe,4BAA4B;CAG5D;CAEA,uBAAsC;EACpC,MAAM,qBAAqB;EAE3B,KAAKG,OAAO,IAAI;EAChB,KAAKJ,UAAU,WAAW;EAC1B,KAAKG,aAAa,MAAM;EACxB,KAAKA,cAAc;CACrB;CAEA,IAAIE,aAAmC;EACrC,IAAI,CAAC,KAAKC,UAAU,CAAC,UAAU,KAAKA,MAAM,GAAG,OAAO;EACpD,OAAO,KAAKC,oBAAoB,YAAY,YAAY,KAAKA;CAC/D;CAEA,OAA0B,SAA+B;EACvD,MAAM,OAAO,OAAO;EAEpB,MAAM,WAAW,KAAKN,UAAU;EAChC,IAAI,CAAC,UAAU;EAIf,KAAKF,MAAM,SAAS;GAClB,SAAS,SAAS;GAClB,QAAQ,KAAKG,UAAU,OAAO,UAAU;EAC1C,CAAC;EAED,MAAM,EAAE,QAAQ,KAAKH,MAAM,SAAS;EAEpC,KAAKK,OAAO,UAAU,IAAI,CAAC;EAC3B,KAAKI,aAAa,GAAG;EAErB,KAAKT,MAAM,kBAAkB,KAAKM,UAAU;EAC5C,oBAAoB,MAAM,KAAKN,MAAM,SAAS,GAAG,eAAe;CAClE;;;;;;CAOA,OAAO,MAAqC;EAC1C,IAAI,SAAS,KAAKO,QAAQ;EAG1B,IAAI,KAAKG,QAAQ,KAAKH,QAAQ,gBAAgB,KAAK;EACnD,KAAKI,cAAc,MAAM;EACzB,KAAKA,eAAe;EAEpB,KAAKJ,SAAS;EACd,KAAKG,SAAS,SAAS,QAAQ,CAAC,UAAU,IAAI;EAC9C,KAAKF,kBAAkB;EAEvB,IAAI,CAAC,MAAM;EAKX,IAAI,KAAK,eAAe,GAAG,KAAKA,kBAAkB;OAC7C,IAAI,KAAK,YAAY,aAAa,IAAI,GAAG,KAAKA,kBAAkB;EAErE,KAAKG,eAAe,IAAI,gBAAgB;EACxC,MAAM,EAAE,WAAW,KAAKA;EACxB,MAAM,UAAU,oBAAoC;GAClD,KAAKH,kBAAkB;GACvB,KAAK,cAAc;EACrB;EAEA,KAAK,iBAAiB,QAAQ,OAAO,QAAQ,GAAG,EAAE,OAAO,CAAC;EAC1D,KAAK,iBAAiB,SAAS,OAAO,OAAO,GAAG,EAAE,OAAO,CAAC;CAC5D;CAEA,aAAa,KAAmB;EAC9B,MAAM,MAAM,KAAKD;EAEjB,IAAI,CAAC,KAAK;GACR,IAAe,OAAO,CAAC,KAAKK,qBAAqB;IAC/C,KAAKA,sBAAsB;IAC3B,QAAQ,KACN,IAAI,KAAK,UAAU,0EACO,KAAK,UAAU,iBAAiB,KAAK,UAAU,EAC3E;GACF;GACA;EACF;EAEA,IAAI,CAAC,KAAKF,QAAQ;EAElB,IAAI,CAAC,KAAK;GACR,KAAKF,kBAAkB;GACvB,IAAI,gBAAgB,KAAK;EAC3B,OAAO,IAAI,IAAI,aAAa,KAAK,MAAM,KAAK;GAG1C,KAAKA,kBAAkB;GACvB,IAAI,aAAa,OAAO,GAAG;EAC7B;CACF;AACF"}
@@ -59,7 +59,7 @@ var QualityRadioGroupElement = class extends MenuRadioGroupElement {
59
59
  state = this.#core.getState();
60
60
  this.applyDefaultAriaLabel(translateText(this.#core.getLabel(state), this.#i18n.value));
61
61
  this.#options.sync(state, this.#i18n.value, this.#i18n.locale);
62
- this.publishMenuMetadata(state.disabled, state.availability);
62
+ this.publishMenuTriggerState(state.disabled, state.availability);
63
63
  }
64
64
  super.update(changed);
65
65
  if (state) applyStateDataAttrs(this, state, QualityRadioGroupDataAttrs);
@@ -1 +1 @@
1
- {"version":3,"file":"quality-radio-group-element.js","names":["#setContent","#mediaState","#core","#i18n","#options"],"sources":["../../../../src/ui/quality-radio-group/quality-radio-group-element.ts"],"sourcesContent":["import { QualityRadioGroupCore, QualityRadioGroupDataAttrs, type QualityRadioGroupOption } from '@videojs/core';\nimport { applyStateDataAttrs, logMissingFeature, selectQuality } from '@videojs/core/dom';\nimport { type Text, translateText } from '@videojs/core/i18n';\nimport type { PropertyDeclarationMap, PropertyValues } from '@videojs/element';\nimport { i18nContext } from '../../i18n/context';\nimport { I18nController } from '../../i18n/controller';\nimport { playerContext } from '../../player/context';\nimport { PlayerController } from '../../player/player-controller';\nimport { MenuRadioGroupElement } from '../menu/menu-radio-group-element';\nimport type { MenuRadioItemElement } from '../menu/menu-radio-item-element';\nimport { RadioOptionsController } from '../radio-options/radio-options-controller';\n\nexport class QualityRadioGroupElement extends MenuRadioGroupElement {\n static override readonly tagName = 'media-quality-radio-group';\n\n static override properties = {\n ...MenuRadioGroupElement.properties,\n disabled: { type: Boolean },\n label: { type: String },\n } satisfies PropertyDeclarationMap<'value' | 'label' | 'disabled'>;\n\n disabled = false;\n label: Text | string = '';\n formatRendition = QualityRadioGroupCore.defaultProps.formatRendition;\n\n readonly #core = new QualityRadioGroupCore();\n readonly #i18n = new I18nController(this, i18nContext);\n readonly #mediaState = new PlayerController(this, playerContext, selectQuality);\n readonly #options = new RadioOptionsController<QualityRadioGroupOption>(this, {\n renderItem: (item, label, option) => this.#setContent(item, label, option.tier, option.badge),\n setItemAttributes: (item, option) => item.setAttribute('data-rendition', option.value),\n getOptionCacheKey: (option) => `${option.tier ?? ''}:${option.badge ?? ''}`,\n onValueChange: (value) => {\n const media = this.#mediaState.value;\n if (media) this.#core.selectValue(media, value);\n },\n });\n\n override connectedCallback(): void {\n super.connectedCallback();\n if (this.destroyed) return;\n\n if (__DEV__ && !this.#mediaState.value && this.#mediaState.displayName) {\n logMissingFeature(this.localName, this.#mediaState.displayName);\n }\n }\n\n protected override update(changed: PropertyValues): void {\n const media = this.#mediaState.value;\n let state: QualityRadioGroupCore.State | null = null;\n\n if (media) {\n this.#core.setProps({ formatRendition: this.formatRendition, disabled: this.disabled, label: this.label });\n this.#core.setMedia(media);\n state = this.#core.getState();\n\n this.applyDefaultAriaLabel(translateText(this.#core.getLabel(state), this.#i18n.value));\n this.#options.sync(state, this.#i18n.value, this.#i18n.locale);\n this.publishMenuMetadata(state.disabled, state.availability);\n }\n\n super.update(changed);\n\n if (state) applyStateDataAttrs(this, state, QualityRadioGroupDataAttrs);\n }\n\n #setContent(item: MenuRadioItemElement, label: string, tier: string | undefined, badge: string | undefined): void {\n const labelPart = item.querySelector<HTMLElement>('[data-part~=\"label\"]');\n const tierPart = item.querySelector<HTMLElement>('[data-part~=\"tier\"]');\n const badgePart = item.querySelector<HTMLElement>('[data-part~=\"badge\"]');\n\n if (labelPart) {\n labelPart.textContent = label;\n }\n\n if (tierPart) {\n tierPart.textContent = tier ?? '';\n tierPart.hidden = !tier;\n }\n\n if (badgePart) {\n badgePart.textContent = badge ?? '';\n badgePart.hidden = !badge;\n }\n\n if (!labelPart && !tierPart && !badgePart) {\n item.textContent = [label, tier, badge].filter(Boolean).join(' ');\n }\n }\n}\n\nexport namespace QualityRadioGroupElement {\n export type State = QualityRadioGroupCore.State;\n}\n"],"mappings":";;;;;;;;;;AAYA,IAAa,2BAAb,cAA8C,sBAAsB;;;EASvD,KAAA,WAAA;EACY,KAAA,QAAA;EACL,KAAA,kBAAA,sBAAsB,aAAa;EAEpC,KAAA,QAAA,IAAI,sBAAsB;EAC1B,KAAA,QAAA,IAAI,eAAe,MAAM,WAAW;EAC9B,KAAA,cAAA,IAAI,iBAAiB,MAAM,eAAe,aAAa;EAC1D,KAAA,WAAA,IAAI,uBAAgD,MAAM;GAC5E,aAAa,MAAM,OAAO,WAAW,KAAKA,YAAY,MAAM,OAAO,OAAO,MAAM,OAAO,KAAK;GAC5F,oBAAoB,MAAM,WAAW,KAAK,aAAa,kBAAkB,OAAO,KAAK;GACrF,oBAAoB,WAAW,GAAG,OAAO,QAAQ,GAAG,GAAG,OAAO,SAAS;GACvE,gBAAgB,UAAU;IACxB,MAAM,QAAQ,KAAKC,YAAY;IAC/B,IAAI,OAAO,KAAKC,MAAM,YAAY,OAAO,KAAK;GAChD;EACF,CAAC;;;EAvBkC,KAAA,UAAA;;;EAEN,KAAA,aAAA;GAC3B,GAAG,sBAAsB;GACzB,UAAU,EAAE,MAAM,QAAQ;GAC1B,OAAO,EAAE,MAAM,OAAO;EACxB;;CAMA;CACA;CACA;CACA;CAUA,oBAAmC;EACjC,MAAM,kBAAkB;EACxB,IAAI,KAAK,WAAW;EAEpB,IAAe,CAAC,KAAKD,YAAY,SAAS,KAAKA,YAAY,aACzD,kBAAkB,KAAK,WAAW,KAAKA,YAAY,WAAW;CAElE;CAEA,OAA0B,SAA+B;EACvD,MAAM,QAAQ,KAAKA,YAAY;EAC/B,IAAI,QAA4C;EAEhD,IAAI,OAAO;GACT,KAAKC,MAAM,SAAS;IAAE,iBAAiB,KAAK;IAAiB,UAAU,KAAK;IAAU,OAAO,KAAK;GAAM,CAAC;GACzG,KAAKA,MAAM,SAAS,KAAK;GACzB,QAAQ,KAAKA,MAAM,SAAS;GAE5B,KAAK,sBAAsB,cAAc,KAAKA,MAAM,SAAS,KAAK,GAAG,KAAKC,MAAM,KAAK,CAAC;GACtF,KAAKC,SAAS,KAAK,OAAO,KAAKD,MAAM,OAAO,KAAKA,MAAM,MAAM;GAC7D,KAAK,oBAAoB,MAAM,UAAU,MAAM,YAAY;EAC7D;EAEA,MAAM,OAAO,OAAO;EAEpB,IAAI,OAAO,oBAAoB,MAAM,OAAO,0BAA0B;CACxE;CAEA,YAAY,MAA4B,OAAe,MAA0B,OAAiC;EAChH,MAAM,YAAY,KAAK,cAA2B,wBAAsB;EACxE,MAAM,WAAW,KAAK,cAA2B,uBAAqB;EACtE,MAAM,YAAY,KAAK,cAA2B,wBAAsB;EAExE,IAAI,WACF,UAAU,cAAc;EAG1B,IAAI,UAAU;GACZ,SAAS,cAAc,QAAQ;GAC/B,SAAS,SAAS,CAAC;EACrB;EAEA,IAAI,WAAW;GACb,UAAU,cAAc,SAAS;GACjC,UAAU,SAAS,CAAC;EACtB;EAEA,IAAI,CAAC,aAAa,CAAC,YAAY,CAAC,WAC9B,KAAK,cAAc;GAAC;GAAO;GAAM;EAAK,CAAC,CAAC,OAAO,OAAO,CAAC,CAAC,KAAK,GAAG;CAEpE;AACF"}
1
+ {"version":3,"file":"quality-radio-group-element.js","names":["#setContent","#mediaState","#core","#i18n","#options"],"sources":["../../../../src/ui/quality-radio-group/quality-radio-group-element.ts"],"sourcesContent":["import { QualityRadioGroupCore, QualityRadioGroupDataAttrs, type QualityRadioGroupOption } from '@videojs/core';\nimport { applyStateDataAttrs, logMissingFeature, selectQuality } from '@videojs/core/dom';\nimport { type Text, translateText } from '@videojs/core/i18n';\nimport type { PropertyDeclarationMap, PropertyValues } from '@videojs/element';\nimport { i18nContext } from '../../i18n/context';\nimport { I18nController } from '../../i18n/controller';\nimport { playerContext } from '../../player/context';\nimport { PlayerController } from '../../player/player-controller';\nimport { MenuRadioGroupElement } from '../menu/menu-radio-group-element';\nimport type { MenuRadioItemElement } from '../menu/menu-radio-item-element';\nimport { RadioOptionsController } from '../radio-options/radio-options-controller';\n\nexport class QualityRadioGroupElement extends MenuRadioGroupElement {\n static override readonly tagName = 'media-quality-radio-group';\n\n static override properties = {\n ...MenuRadioGroupElement.properties,\n disabled: { type: Boolean },\n label: { type: String },\n } satisfies PropertyDeclarationMap<'value' | 'label' | 'disabled'>;\n\n disabled = false;\n label: Text | string = '';\n formatRendition = QualityRadioGroupCore.defaultProps.formatRendition;\n\n readonly #core = new QualityRadioGroupCore();\n readonly #i18n = new I18nController(this, i18nContext);\n readonly #mediaState = new PlayerController(this, playerContext, selectQuality);\n readonly #options = new RadioOptionsController<QualityRadioGroupOption>(this, {\n renderItem: (item, label, option) => this.#setContent(item, label, option.tier, option.badge),\n setItemAttributes: (item, option) => item.setAttribute('data-rendition', option.value),\n getOptionCacheKey: (option) => `${option.tier ?? ''}:${option.badge ?? ''}`,\n onValueChange: (value) => {\n const media = this.#mediaState.value;\n if (media) this.#core.selectValue(media, value);\n },\n });\n\n override connectedCallback(): void {\n super.connectedCallback();\n if (this.destroyed) return;\n\n if (__DEV__ && !this.#mediaState.value && this.#mediaState.displayName) {\n logMissingFeature(this.localName, this.#mediaState.displayName);\n }\n }\n\n protected override update(changed: PropertyValues): void {\n const media = this.#mediaState.value;\n let state: QualityRadioGroupCore.State | null = null;\n\n if (media) {\n this.#core.setProps({ formatRendition: this.formatRendition, disabled: this.disabled, label: this.label });\n this.#core.setMedia(media);\n state = this.#core.getState();\n\n this.applyDefaultAriaLabel(translateText(this.#core.getLabel(state), this.#i18n.value));\n this.#options.sync(state, this.#i18n.value, this.#i18n.locale);\n this.publishMenuTriggerState(state.disabled, state.availability);\n }\n\n super.update(changed);\n\n if (state) applyStateDataAttrs(this, state, QualityRadioGroupDataAttrs);\n }\n\n #setContent(item: MenuRadioItemElement, label: string, tier: string | undefined, badge: string | undefined): void {\n const labelPart = item.querySelector<HTMLElement>('[data-part~=\"label\"]');\n const tierPart = item.querySelector<HTMLElement>('[data-part~=\"tier\"]');\n const badgePart = item.querySelector<HTMLElement>('[data-part~=\"badge\"]');\n\n if (labelPart) {\n labelPart.textContent = label;\n }\n\n if (tierPart) {\n tierPart.textContent = tier ?? '';\n tierPart.hidden = !tier;\n }\n\n if (badgePart) {\n badgePart.textContent = badge ?? '';\n badgePart.hidden = !badge;\n }\n\n if (!labelPart && !tierPart && !badgePart) {\n item.textContent = [label, tier, badge].filter(Boolean).join(' ');\n }\n }\n}\n\nexport namespace QualityRadioGroupElement {\n export type State = QualityRadioGroupCore.State;\n}\n"],"mappings":";;;;;;;;;;AAYA,IAAa,2BAAb,cAA8C,sBAAsB;;;EASvD,KAAA,WAAA;EACY,KAAA,QAAA;EACL,KAAA,kBAAA,sBAAsB,aAAa;EAEpC,KAAA,QAAA,IAAI,sBAAsB;EAC1B,KAAA,QAAA,IAAI,eAAe,MAAM,WAAW;EAC9B,KAAA,cAAA,IAAI,iBAAiB,MAAM,eAAe,aAAa;EAC1D,KAAA,WAAA,IAAI,uBAAgD,MAAM;GAC5E,aAAa,MAAM,OAAO,WAAW,KAAKA,YAAY,MAAM,OAAO,OAAO,MAAM,OAAO,KAAK;GAC5F,oBAAoB,MAAM,WAAW,KAAK,aAAa,kBAAkB,OAAO,KAAK;GACrF,oBAAoB,WAAW,GAAG,OAAO,QAAQ,GAAG,GAAG,OAAO,SAAS;GACvE,gBAAgB,UAAU;IACxB,MAAM,QAAQ,KAAKC,YAAY;IAC/B,IAAI,OAAO,KAAKC,MAAM,YAAY,OAAO,KAAK;GAChD;EACF,CAAC;;;EAvBkC,KAAA,UAAA;;;EAEN,KAAA,aAAA;GAC3B,GAAG,sBAAsB;GACzB,UAAU,EAAE,MAAM,QAAQ;GAC1B,OAAO,EAAE,MAAM,OAAO;EACxB;;CAMA;CACA;CACA;CACA;CAUA,oBAAmC;EACjC,MAAM,kBAAkB;EACxB,IAAI,KAAK,WAAW;EAEpB,IAAe,CAAC,KAAKD,YAAY,SAAS,KAAKA,YAAY,aACzD,kBAAkB,KAAK,WAAW,KAAKA,YAAY,WAAW;CAElE;CAEA,OAA0B,SAA+B;EACvD,MAAM,QAAQ,KAAKA,YAAY;EAC/B,IAAI,QAA4C;EAEhD,IAAI,OAAO;GACT,KAAKC,MAAM,SAAS;IAAE,iBAAiB,KAAK;IAAiB,UAAU,KAAK;IAAU,OAAO,KAAK;GAAM,CAAC;GACzG,KAAKA,MAAM,SAAS,KAAK;GACzB,QAAQ,KAAKA,MAAM,SAAS;GAE5B,KAAK,sBAAsB,cAAc,KAAKA,MAAM,SAAS,KAAK,GAAG,KAAKC,MAAM,KAAK,CAAC;GACtF,KAAKC,SAAS,KAAK,OAAO,KAAKD,MAAM,OAAO,KAAKA,MAAM,MAAM;GAC7D,KAAK,wBAAwB,MAAM,UAAU,MAAM,YAAY;EACjE;EAEA,MAAM,OAAO,OAAO;EAEpB,IAAI,OAAO,oBAAoB,MAAM,OAAO,0BAA0B;CACxE;CAEA,YAAY,MAA4B,OAAe,MAA0B,OAAiC;EAChH,MAAM,YAAY,KAAK,cAA2B,wBAAsB;EACxE,MAAM,WAAW,KAAK,cAA2B,uBAAqB;EACtE,MAAM,YAAY,KAAK,cAA2B,wBAAsB;EAExE,IAAI,WACF,UAAU,cAAc;EAG1B,IAAI,UAAU;GACZ,SAAS,cAAc,QAAQ;GAC/B,SAAS,SAAS,CAAC;EACrB;EAEA,IAAI,WAAW;GACb,UAAU,cAAc,SAAS;GACjC,UAAU,SAAS,CAAC;EACtB;EAEA,IAAI,CAAC,aAAa,CAAC,YAAY,CAAC,WAC9B,KAAK,cAAc;GAAC;GAAO;GAAM;EAAK,CAAC,CAAC,OAAO,OAAO,CAAC,CAAC,KAAK,GAAG;CAEpE;AACF"}
@@ -1,6 +1,6 @@
1
1
  import { MediaElement } from "../media-element.js";
2
- import { SliderPreviewOverflow } from "@videojs/core/dom";
3
2
  import { PropertyValues } from "@videojs/element";
3
+ import { SliderPreviewProps } from "@videojs/core";
4
4
  //#region src/ui/slider/slider-preview-element.d.ts
5
5
  declare class SliderPreviewElement extends MediaElement {
6
6
  #private;
@@ -10,7 +10,7 @@ declare class SliderPreviewElement extends MediaElement {
10
10
  type: StringConstructor;
11
11
  };
12
12
  };
13
- overflow: SliderPreviewOverflow;
13
+ overflow: NonNullable<SliderPreviewProps['overflow']>;
14
14
  connectedCallback(): void;
15
15
  disconnectedCallback(): void;
16
16
  protected update(_changed: PropertyValues): void;
@@ -1 +1 @@
1
- {"version":3,"file":"slider-preview-element.d.ts","names":[],"sources":["../../../../src/ui/slider/slider-preview-element.ts"],"mappings":";;;;cASa,6BAA6B;;kBACxB;SAEA;;MACF,MAAI;;;EAGlB,UAAU;EAUD;EASA;YAUU,OAAO,UAAU"}
1
+ {"version":3,"file":"slider-preview-element.d.ts","names":[],"sources":["../../../../src/ui/slider/slider-preview-element.ts"],"mappings":";;;;cASa,6BAA6B;;kBACxB;SAEA;;MACF,MAAI;;;EAGlB,UAAU,YAAY;EAUb;EASA;YAUU,OAAO,UAAU"}
@@ -1 +1 @@
1
- {"version":3,"file":"slider-preview-element.js","names":["#ctx","#stopObservingResize","#width","#applyPosition"],"sources":["../../../../src/ui/slider/slider-preview-element.ts"],"sourcesContent":["import type { SliderPreviewOverflow } from '@videojs/core/dom';\nimport { applyStateDataAttrs, getSliderPreviewStyle } from '@videojs/core/dom';\nimport type { PropertyDeclarationMap, PropertyValues } from '@videojs/element';\nimport { ContextConsumer } from '@videojs/element/context';\nimport { applyStyles, observeResize } from '@videojs/utils/dom';\n\nimport { MediaElement } from '../media-element';\nimport { sliderContext } from './context';\n\nexport class SliderPreviewElement extends MediaElement {\n static readonly tagName = 'media-slider-preview';\n\n static override properties = {\n overflow: { type: String },\n } satisfies PropertyDeclarationMap<'overflow'>;\n\n overflow: SliderPreviewOverflow = 'clamp';\n\n readonly #ctx = new ContextConsumer(this, {\n context: sliderContext,\n subscribe: true,\n });\n\n #stopObservingResize: (() => void) | null = null;\n #width = 0;\n\n override connectedCallback(): void {\n super.connectedCallback();\n\n this.#stopObservingResize = observeResize(this, ([entry]) => {\n this.#width = entry!.contentRect.width;\n this.#applyPosition();\n });\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this.#stopObservingResize?.();\n this.#stopObservingResize = null;\n }\n\n #applyPosition(): void {\n applyStyles(this, getSliderPreviewStyle(this.#width, this.overflow));\n }\n\n protected override update(_changed: PropertyValues): void {\n super.update(_changed);\n\n const ctx = this.#ctx.value;\n if (ctx) applyStateDataAttrs(this, ctx.state, ctx.stateAttrMap);\n\n this.#applyPosition();\n }\n}\n"],"mappings":";;;;;;AASA,IAAa,uBAAb,cAA0C,aAAa;;;EAOnB,KAAA,WAAA;EAElB,KAAA,OAAA,IAAI,gBAAgB,MAAM;GACxC,SAAS;GACT,WAAW;EACb,CAAC;EAE2C,KAAA,uBAAA;EACnC,KAAA,SAAA;;;EAdiB,KAAA,UAAA;;;EAEG,KAAA,aAAA,EAC3B,UAAU,EAAE,MAAM,OAAO,EAC3B;;CAIA;CAKA;CACA;CAEA,oBAAmC;EACjC,MAAM,kBAAkB;EAExB,KAAKC,uBAAuB,cAAc,OAAO,CAAC,WAAW;GAC3D,KAAKC,SAAS,MAAO,YAAY;GACjC,KAAKC,eAAe;EACtB,CAAC;CACH;CAEA,uBAAsC;EACpC,MAAM,qBAAqB;EAC3B,KAAKF,uBAAuB;EAC5B,KAAKA,uBAAuB;CAC9B;CAEA,iBAAuB;EACrB,YAAY,MAAM,sBAAsB,KAAKC,QAAQ,KAAK,QAAQ,CAAC;CACrE;CAEA,OAA0B,UAAgC;EACxD,MAAM,OAAO,QAAQ;EAErB,MAAM,MAAM,KAAKF,KAAK;EACtB,IAAI,KAAK,oBAAoB,MAAM,IAAI,OAAO,IAAI,YAAY;EAE9D,KAAKG,eAAe;CACtB;AACF"}
1
+ {"version":3,"file":"slider-preview-element.js","names":["#ctx","#stopObservingResize","#width","#applyPosition"],"sources":["../../../../src/ui/slider/slider-preview-element.ts"],"sourcesContent":["import type { SliderPreviewProps } from '@videojs/core';\nimport { applyStateDataAttrs, getSliderPreviewStyle } from '@videojs/core/dom';\nimport type { PropertyDeclarationMap, PropertyValues } from '@videojs/element';\nimport { ContextConsumer } from '@videojs/element/context';\nimport { applyStyles, observeResize } from '@videojs/utils/dom';\n\nimport { MediaElement } from '../media-element';\nimport { sliderContext } from './context';\n\nexport class SliderPreviewElement extends MediaElement {\n static readonly tagName = 'media-slider-preview';\n\n static override properties = {\n overflow: { type: String },\n } satisfies PropertyDeclarationMap<'overflow'>;\n\n overflow: NonNullable<SliderPreviewProps['overflow']> = 'clamp';\n\n readonly #ctx = new ContextConsumer(this, {\n context: sliderContext,\n subscribe: true,\n });\n\n #stopObservingResize: (() => void) | null = null;\n #width = 0;\n\n override connectedCallback(): void {\n super.connectedCallback();\n\n this.#stopObservingResize = observeResize(this, ([entry]) => {\n this.#width = entry!.contentRect.width;\n this.#applyPosition();\n });\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this.#stopObservingResize?.();\n this.#stopObservingResize = null;\n }\n\n #applyPosition(): void {\n applyStyles(this, getSliderPreviewStyle(this.#width, this.overflow));\n }\n\n protected override update(_changed: PropertyValues): void {\n super.update(_changed);\n\n const ctx = this.#ctx.value;\n if (ctx) applyStateDataAttrs(this, ctx.state, ctx.stateAttrMap);\n\n this.#applyPosition();\n }\n}\n"],"mappings":";;;;;;AASA,IAAa,uBAAb,cAA0C,aAAa;;;EAOG,KAAA,WAAA;EAExC,KAAA,OAAA,IAAI,gBAAgB,MAAM;GACxC,SAAS;GACT,WAAW;EACb,CAAC;EAE2C,KAAA,uBAAA;EACnC,KAAA,SAAA;;;EAdiB,KAAA,UAAA;;;EAEG,KAAA,aAAA,EAC3B,UAAU,EAAE,MAAM,OAAO,EAC3B;;CAIA;CAKA;CACA;CAEA,oBAAmC;EACjC,MAAM,kBAAkB;EAExB,KAAKC,uBAAuB,cAAc,OAAO,CAAC,WAAW;GAC3D,KAAKC,SAAS,MAAO,YAAY;GACjC,KAAKC,eAAe;EACtB,CAAC;CACH;CAEA,uBAAsC;EACpC,MAAM,qBAAqB;EAC3B,KAAKF,uBAAuB;EAC5B,KAAKA,uBAAuB;CAC9B;CAEA,iBAAuB;EACrB,YAAY,MAAM,sBAAsB,KAAKC,QAAQ,KAAK,QAAQ,CAAC;CACrE;CAEA,OAA0B,UAAgC;EACxD,MAAM,OAAO,QAAQ;EAErB,MAAM,MAAM,KAAKF,KAAK;EACtB,IAAI,KAAK,oBAAoB,MAAM,IAAI,OAAO,IAAI,YAAY;EAE9D,KAAKG,eAAe;CACtB;AACF"}
package/docs/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @videojs/html documentation
2
2
 
3
- Bundled markdown documentation for `@videojs/html` v10.0.0-beta.27.
3
+ Bundled markdown documentation for `@videojs/html` v10.0.0-beta.29.
4
4
 
5
5
  Start at [`./llms.txt`](./llms.txt) — it's the structured index of every page in this directory.
6
6
 
@@ -88,7 +88,7 @@ if (media?.paused) media.play();
88
88
 
89
89
  ### Checking for feature support
90
90
 
91
- Volume, fullscreen, and picture-in-picture expose an `*Availability` property because platform support varies. For example, iOS Safari doesn’t allow programmatic volume control.
91
+ Volume, fullscreen, and picture-in-picture expose availability properties because platform support varies. Volume has two independent properties: `volumeAvailability` for changing the volume level and `mutedAvailability` for toggling mute. For example, iOS Safari allows muting but doesn’t allow programmatic volume control.
92
92
 
93
93
  Value
94
94
 
@@ -106,7 +106,7 @@ Could work, not ready yet
106
106
 
107
107
  Platform can never do this
108
108
 
109
- Components that depend on availability (like [`PiPButton`](../reference/pip-button.md) and [`FullscreenButton`](../reference/fullscreen-button.md)) handle the three states for you:
109
+ Components that depend on availability (like [`MuteButton`](../reference/mute-button.md), [`PiPButton`](../reference/pip-button.md), and [`FullscreenButton`](../reference/fullscreen-button.md)) handle the three states for you:
110
110
 
111
111
  * **`unsupported`** — the HTML custom element receives the native `hidden` attribute (and `data-hidden`); React buttons return `null`. No CSS needed.
112
112
  * **`unavailable`** — the presentation controls stay hidden while capability detection is unresolved. Cast remains visible but disabled when its API is supported and no device is reachable.
@@ -42,7 +42,7 @@ How Video.js plays it
42
42
 
43
43
  `source`, at the top level
44
44
 
45
- `preferPlayback`
45
+ `preferPlayback`, `maxAutoResolution`, `capRenditionToPlayerSize`
46
46
 
47
47
  How a specific engine behaves
48
48
 
@@ -193,6 +193,80 @@ video.source = { src: 'https://example.com/stream.m3u8', preferPlayback: 'native
193
193
 
194
194
  It’s a preference, not a demand — Video.js falls back to whichever path can actually play the source. `HlsJsVideo`, `MuxVideo`, and `MuxAudio` accept it; DASH and Vimeo have no second playback path.
195
195
 
196
+ `maxAutoResolution` caps the highest rendition adaptive bitrate selection reaches for on its own:
197
+
198
+ ts
199
+
200
+ ```
201
+ video.source = { src: 'https://example.com/stream.m3u8', maxAutoResolution: '720p' };
202
+ ```
203
+
204
+ The cap limits automatic selection without hiding anything. Renditions above it stay in `videoRenditions`, so a viewer can still choose 1080p by hand. Reach for it to hold down bandwidth on a stream that would otherwise climb to 4K, or to keep a background or thumbnail player cheap.
205
+
206
+ Renditions are matched on pixel area rather than height, which keeps unusual aspect ratios honest: an ultrawide 2560×1080 rendition carries more pixels than 16:9 1080p, so a `'1080p'` cap leaves it out. When every rendition sits above the cap, the smallest one plays.
207
+
208
+ Changing the cap applies to the running engine, so playback continues uninterrupted. It needs the hls.js engine — native HLS playback ignores it, and audio-only streams have no video renditions to cap.
209
+
210
+ ### Capping to the player’s size
211
+
212
+ A 400px-wide player has no use for a 4K rendition, so `capRenditionToPlayerSize` holds automatic selection to the smallest rendition that still covers the element. It defaults to `true`, and the cap follows the element as it’s resized:
213
+
214
+ ts
215
+
216
+ ```
217
+ video.source = { src: 'https://example.com/stream.m3u8', capRenditionToPlayerSize: false };
218
+ ```
219
+
220
+ The element is measured in device pixels, so a `2` device pixel ratio asks for twice the rendition a CSS measurement would — a 640px-wide player on a retina screen still gets 720p. Switch the cap off for a player whose layout size understates what it needs, such as one that goes fullscreen without a resize.
221
+
222
+ `minAutoResolution` bounds how far down that cap can reach, and defaults to `'720p'`:
223
+
224
+ ts
225
+
226
+ ```
227
+ video.source = { src: 'https://example.com/stream.m3u8', minAutoResolution: '480p' };
228
+ ```
229
+
230
+ **It is not a quality floor.** It bounds the size-derived cap and nothing else. When bandwidth is poor, adaptive selection still drops below it — the cap is a ceiling, and selection stays free underneath. It also never raises an explicit `maxAutoResolution`: ask for at most `'360p'` alongside a `'720p'` floor and you get `'360p'`.
231
+
232
+ The default is there because the low rungs of a ladder exist for poor network conditions, and capping a small player down to them looks worse than its size suggests. Name a lower rung to weaken the floor, or `'270p'` to lift it for any real ladder.
233
+
234
+ ### Four things that sound alike
235
+
236
+ Four separate mechanisms bound which rendition plays, and they’re easy to mistake for each other:
237
+
238
+ Option
239
+
240
+ Side
241
+
242
+ What it does
243
+
244
+ `source.playback.maxResolution`
245
+
246
+ Server
247
+
248
+ A Mux query param. Trims the manifest, so higher renditions never arrive — not even by hand.
249
+
250
+ `source.maxAutoResolution`
251
+
252
+ Client
253
+
254
+ A ceiling on automatic selection. Everything still arrives and stays selectable by hand.
255
+
256
+ `source.capRenditionToPlayerSize`
257
+
258
+ Client
259
+
260
+ The same kind of ceiling, derived from the element’s rendered size and moving with it.
261
+
262
+ `source.minAutoResolution`
263
+
264
+ Client
265
+
266
+ A bound on the one above. Not a quality minimum, and not related to `playback.minResolution`.
267
+
268
+ `playback.maxResolution` and `playback.minResolution` are the server-side pair: they decide what the manifest carries. The other three only bound what adaptive selection picks from whatever does arrive.
269
+
196
270
  ## DRM protected sources
197
271
 
198
272
  Protected content is licensed through `source.drm`, keyed by EME key system id — alongside the URL rather than inside an engine’s namespace, because which engine plays the manifest is decided later and both paths read it:
@@ -276,6 +350,10 @@ video.source = {
276
350
  };
277
351
  ```
278
352
 
353
+ `playback` params ride along in the URL, so `playback.maxResolution` decides which renditions the manifest carries in the first place. `maxAutoResolution` is the other half of that pair: it caps what adaptive selection picks from the renditions that do arrive. Use `playback.maxResolution` when a viewer should never get 4K, and `maxAutoResolution` when they should be able to ask for it.
354
+
355
+ The same split applies at the bottom of the ladder, and the names are close enough to be worth restating: `playback.minResolution` asks Mux to leave the lowest renditions out of the manifest, while `minAutoResolution` is a client-side bound on the player-size cap. They are unrelated.
356
+
279
357
  Setting a Mux stream URL as `src` works too — the element parses the playback ID and query params back out into `source`. To play something Mux doesn’t host, name it with `src` inside `source`; engine options still apply.
280
358
 
281
359
  Two more source params describe images rather than playback. `source.storyboard` and `source.poster` carry the modifiers for the storyboard VTT and the poster still — both belong to the source, since a signed token scopes them to one playback ID: