@videojs/spf 10.0.0-beta.30 → 10.0.0-beta.32

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 (520) hide show
  1. package/dist/default/core/actors/create-machine-actor.js +23 -25
  2. package/dist/default/core/actors/create-machine-actor.js.map +1 -1
  3. package/dist/default/core/actors/create-transition-actor.js +7 -9
  4. package/dist/default/core/actors/create-transition-actor.js.map +1 -1
  5. package/dist/default/core/composition/create-composition.js +26 -29
  6. package/dist/default/core/composition/create-composition.js.map +1 -1
  7. package/dist/default/core/composition/share-signals.js +12 -17
  8. package/dist/default/core/composition/share-signals.js.map +1 -1
  9. package/dist/default/core/machine.js +3 -4
  10. package/dist/default/core/machine.js.map +1 -1
  11. package/dist/default/core/reactors/create-machine-reactor.js +20 -19
  12. package/dist/default/core/reactors/create-machine-reactor.js.map +1 -1
  13. package/dist/default/core/signals/effect.js +24 -4
  14. package/dist/default/core/signals/effect.js.map +1 -1
  15. package/dist/default/core/signals/primitives.js +10 -14
  16. package/dist/default/core/signals/primitives.js.map +1 -1
  17. package/dist/default/core/signals/when.js +6 -8
  18. package/dist/default/core/signals/when.js.map +1 -1
  19. package/dist/default/core/tasks/delayed-reschedule.js +7 -11
  20. package/dist/default/core/tasks/delayed-reschedule.js.map +1 -1
  21. package/dist/default/core/tasks/task.js +59 -82
  22. package/dist/default/core/tasks/task.js.map +1 -1
  23. package/dist/default/hls.js +3 -1
  24. package/dist/default/index.js +2 -3
  25. package/dist/default/index.js.map +1 -1
  26. package/dist/default/media/abr/quality-selection.js +3 -7
  27. package/dist/default/media/abr/quality-selection.js.map +1 -1
  28. package/dist/default/media/buffer/back-buffer.js +15 -19
  29. package/dist/default/media/buffer/back-buffer.js.map +1 -1
  30. package/dist/default/media/buffer/forward-buffer.js +32 -41
  31. package/dist/default/media/buffer/forward-buffer.js.map +1 -1
  32. package/dist/default/media/dom/capabilities.js +26 -37
  33. package/dist/default/media/dom/capabilities.js.map +1 -1
  34. package/dist/default/media/dom/mse/append-segment.js +3 -5
  35. package/dist/default/media/dom/mse/append-segment.js.map +1 -1
  36. package/dist/default/media/dom/mse/buffer-flusher.js +5 -5
  37. package/dist/default/media/dom/mse/buffer-flusher.js.map +1 -1
  38. package/dist/default/media/dom/mse/duration.js +23 -31
  39. package/dist/default/media/dom/mse/duration.js.map +1 -1
  40. package/dist/default/media/dom/mse/end-of-stream.js +3 -6
  41. package/dist/default/media/dom/mse/end-of-stream.js.map +1 -1
  42. package/dist/default/media/dom/mse/mediasource-setup.js +65 -81
  43. package/dist/default/media/dom/mse/mediasource-setup.js.map +1 -1
  44. package/dist/default/media/dom/screen.js +37 -54
  45. package/dist/default/media/dom/screen.js.map +1 -1
  46. package/dist/default/media/dom/text/resolve-vtt-segment.js.map +1 -1
  47. package/dist/default/media/dom/text/text-track-slots.js +15 -23
  48. package/dist/default/media/dom/text/text-track-slots.js.map +1 -1
  49. package/dist/default/media/errors.js +25 -34
  50. package/dist/default/media/errors.js.map +1 -1
  51. package/dist/default/media/hls/parse-attributes.js +9 -26
  52. package/dist/default/media/hls/parse-attributes.js.map +1 -1
  53. package/dist/default/media/hls/parse-media-playlist.js +25 -33
  54. package/dist/default/media/hls/parse-media-playlist.js.map +1 -1
  55. package/dist/default/media/hls/parse-multivariant.js +3 -3
  56. package/dist/default/media/hls/parse-multivariant.js.map +1 -1
  57. package/dist/default/media/hls/reload-policy.js +19 -27
  58. package/dist/default/media/hls/reload-policy.js.map +1 -1
  59. package/dist/default/media/hls/resolve-url.js +1 -3
  60. package/dist/default/media/hls/resolve-url.js.map +1 -1
  61. package/dist/default/media/live-window.js +9 -13
  62. package/dist/default/media/live-window.js.map +1 -1
  63. package/dist/default/media/media-tracks/media-tracks.js +12 -17
  64. package/dist/default/media/media-tracks/media-tracks.js.map +1 -1
  65. package/dist/default/media/mp4/box.js +4 -5
  66. package/dist/default/media/mp4/box.js.map +1 -1
  67. package/dist/default/media/mp4/timestamp-origin.js +30 -42
  68. package/dist/default/media/mp4/timestamp-origin.js.map +1 -1
  69. package/dist/default/media/primitives/resolution.js +5 -8
  70. package/dist/default/media/primitives/resolution.js.map +1 -1
  71. package/dist/default/media/primitives/select-tracks.js +24 -34
  72. package/dist/default/media/primitives/select-tracks.js.map +1 -1
  73. package/dist/default/media/text/parse-vtt-timestamp-map.js +6 -8
  74. package/dist/default/media/text/parse-vtt-timestamp-map.js.map +1 -1
  75. package/dist/default/media/text/resolve-vtt-metadata.js +8 -9
  76. package/dist/default/media/text/resolve-vtt-metadata.js.map +1 -1
  77. package/dist/default/media/types/index.js +10 -18
  78. package/dist/default/media/types/index.js.map +1 -1
  79. package/dist/default/media/utils/cdn.js +10 -16
  80. package/dist/default/media/utils/cdn.js.map +1 -1
  81. package/dist/default/media/utils/preload.js +4 -6
  82. package/dist/default/media/utils/preload.js.map +1 -1
  83. package/dist/default/media/utils/track-selection.js +10 -14
  84. package/dist/default/media/utils/track-selection.js.map +1 -1
  85. package/dist/default/media/utils/tracks.js +56 -54
  86. package/dist/default/media/utils/tracks.js.map +1 -1
  87. package/dist/default/network/bandwidth-estimator.js +18 -19
  88. package/dist/default/network/bandwidth-estimator.js.map +1 -1
  89. package/dist/default/network/chunked-stream-iterable.js +4 -6
  90. package/dist/default/network/chunked-stream-iterable.js.map +1 -1
  91. package/dist/default/network/ewma.js +22 -25
  92. package/dist/default/network/ewma.js.map +1 -1
  93. package/dist/default/network/fetch.js +30 -37
  94. package/dist/default/network/fetch.js.map +1 -1
  95. package/dist/default/playback/actors/dom/segment-loader.js +28 -44
  96. package/dist/default/playback/actors/dom/segment-loader.js.map +1 -1
  97. package/dist/default/playback/actors/dom/source-buffer.js.map +1 -1
  98. package/dist/default/playback/actors/dom/text-tracks.js.map +1 -1
  99. package/dist/default/playback/actors/text-track-segment-loader.js +24 -35
  100. package/dist/default/playback/actors/text-track-segment-loader.js.map +1 -1
  101. package/dist/default/playback/adapters/hls-audio/adapter.js +23 -31
  102. package/dist/default/playback/adapters/hls-audio/adapter.js.map +1 -1
  103. package/dist/default/playback/adapters/hls-audio/media.js.map +1 -1
  104. package/dist/default/playback/adapters/hls-background-video/adapter.js +50 -70
  105. package/dist/default/playback/adapters/hls-background-video/adapter.js.map +1 -1
  106. package/dist/default/playback/adapters/hls-background-video/host.js +12 -16
  107. package/dist/default/playback/adapters/hls-background-video/host.js.map +1 -1
  108. package/dist/default/playback/adapters/hls-background-video/media.js +5 -8
  109. package/dist/default/playback/adapters/hls-background-video/media.js.map +1 -1
  110. package/dist/default/playback/adapters/hls-video/adapter.js +43 -60
  111. package/dist/default/playback/adapters/hls-video/adapter.js.map +1 -1
  112. package/dist/default/playback/adapters/hls-video/error-surface.js +13 -18
  113. package/dist/default/playback/adapters/hls-video/error-surface.js.map +1 -1
  114. package/dist/default/playback/adapters/hls-video/media-tracks.js +4 -5
  115. package/dist/default/playback/adapters/hls-video/media-tracks.js.map +1 -1
  116. package/dist/default/playback/adapters/hls-video/media.js.map +1 -1
  117. package/dist/default/playback/adapters/mux-audio/media.js +8 -12
  118. package/dist/default/playback/adapters/mux-audio/media.js.map +1 -1
  119. package/dist/default/playback/adapters/mux-video/adapter.js +25 -33
  120. package/dist/default/playback/adapters/mux-video/adapter.js.map +1 -1
  121. package/dist/default/playback/adapters/mux-video/media.js +7 -9
  122. package/dist/default/playback/adapters/mux-video/media.js.map +1 -1
  123. package/dist/default/playback/behaviors/calculate-presentation-duration.js +5 -8
  124. package/dist/default/playback/behaviors/calculate-presentation-duration.js.map +1 -1
  125. package/dist/default/playback/behaviors/collect-errors.js +39 -52
  126. package/dist/default/playback/behaviors/collect-errors.js.map +1 -1
  127. package/dist/default/playback/behaviors/derive-cdn-priority.js +16 -23
  128. package/dist/default/playback/behaviors/derive-cdn-priority.js.map +1 -1
  129. package/dist/default/playback/behaviors/dom/airplay.js +38 -61
  130. package/dist/default/playback/behaviors/dom/airplay.js.map +1 -1
  131. package/dist/default/playback/behaviors/dom/apply-start-position.js +23 -35
  132. package/dist/default/playback/behaviors/dom/apply-start-position.js.map +1 -1
  133. package/dist/default/playback/behaviors/dom/end-of-stream.js +11 -16
  134. package/dist/default/playback/behaviors/dom/end-of-stream.js.map +1 -1
  135. package/dist/default/playback/behaviors/dom/load-segments.js +27 -39
  136. package/dist/default/playback/behaviors/dom/load-segments.js.map +1 -1
  137. package/dist/default/playback/behaviors/dom/recover-end-stall.js +21 -26
  138. package/dist/default/playback/behaviors/dom/recover-end-stall.js.map +1 -1
  139. package/dist/default/playback/behaviors/dom/seek-to-live-edge.js +41 -60
  140. package/dist/default/playback/behaviors/dom/seek-to-live-edge.js.map +1 -1
  141. package/dist/default/playback/behaviors/dom/setup-buffer-actors.js +50 -74
  142. package/dist/default/playback/behaviors/dom/setup-buffer-actors.js.map +1 -1
  143. package/dist/default/playback/behaviors/dom/setup-mediasource.js +29 -43
  144. package/dist/default/playback/behaviors/dom/setup-mediasource.js.map +1 -1
  145. package/dist/default/playback/behaviors/dom/setup-text-track-actors.js.map +1 -1
  146. package/dist/default/playback/behaviors/dom/sync-live-seekable-range.js +3 -4
  147. package/dist/default/playback/behaviors/dom/sync-live-seekable-range.js.map +1 -1
  148. package/dist/default/playback/behaviors/dom/sync-text-tracks.js +30 -45
  149. package/dist/default/playback/behaviors/dom/sync-text-tracks.js.map +1 -1
  150. package/dist/default/playback/behaviors/dom/track-current-time.js +9 -11
  151. package/dist/default/playback/behaviors/dom/track-current-time.js.map +1 -1
  152. package/dist/default/playback/behaviors/dom/track-load-triggers.js +24 -32
  153. package/dist/default/playback/behaviors/dom/track-load-triggers.js.map +1 -1
  154. package/dist/default/playback/behaviors/dom/track-playback-rate.js +6 -8
  155. package/dist/default/playback/behaviors/dom/track-playback-rate.js.map +1 -1
  156. package/dist/default/playback/behaviors/dom/track-player-resolution.js +10 -14
  157. package/dist/default/playback/behaviors/dom/track-player-resolution.js.map +1 -1
  158. package/dist/default/playback/behaviors/dom/track-screen-resolution.js +8 -9
  159. package/dist/default/playback/behaviors/dom/track-screen-resolution.js.map +1 -1
  160. package/dist/default/playback/behaviors/dom/update-mediasource-duration.js +28 -43
  161. package/dist/default/playback/behaviors/dom/update-mediasource-duration.js.map +1 -1
  162. package/dist/default/playback/behaviors/establish-start-media-time.js +32 -42
  163. package/dist/default/playback/behaviors/establish-start-media-time.js.map +1 -1
  164. package/dist/default/playback/behaviors/resolve-presentation.js +13 -22
  165. package/dist/default/playback/behaviors/resolve-presentation.js.map +1 -1
  166. package/dist/default/playback/behaviors/resolve-track.js +5 -12
  167. package/dist/default/playback/behaviors/resolve-track.js.map +1 -1
  168. package/dist/default/playback/behaviors/select-tracks.js +77 -104
  169. package/dist/default/playback/behaviors/select-tracks.js.map +1 -1
  170. package/dist/default/playback/behaviors/setup-failover-monitor.js +11 -16
  171. package/dist/default/playback/behaviors/setup-failover-monitor.js.map +1 -1
  172. package/dist/default/playback/behaviors/sync-preload.js +9 -13
  173. package/dist/default/playback/behaviors/sync-preload.js.map +1 -1
  174. package/dist/default/playback/behaviors/track-switching.js +189 -173
  175. package/dist/default/playback/behaviors/track-switching.js.map +1 -1
  176. package/dist/default/playback/engines/hls/engine-audio-only.js +20 -24
  177. package/dist/default/playback/engines/hls/engine-audio-only.js.map +1 -1
  178. package/dist/default/playback/engines/hls/engine-background-video.js +22 -27
  179. package/dist/default/playback/engines/hls/engine-background-video.js.map +1 -1
  180. package/dist/default/playback/engines/hls/engine.js +22 -25
  181. package/dist/default/playback/engines/hls/engine.js.map +1 -1
  182. package/dist/default/playback/primitives/error-messages.js +16 -25
  183. package/dist/default/playback/primitives/error-messages.js.map +1 -1
  184. package/dist/default/playback/primitives/failover-fetch.js +9 -14
  185. package/dist/default/playback/primitives/failover-fetch.js.map +1 -1
  186. package/dist/default/playback/primitives/head-peek.js +7 -10
  187. package/dist/default/playback/primitives/head-peek.js.map +1 -1
  188. package/dist/default/playback/primitives/live-window.js +12 -15
  189. package/dist/default/playback/primitives/live-window.js.map +1 -1
  190. package/dist/default/playback/primitives/relocation-pipelines.js +34 -46
  191. package/dist/default/playback/primitives/relocation-pipelines.js.map +1 -1
  192. package/dist/default/playback/primitives/report-track-conditions.js +26 -38
  193. package/dist/default/playback/primitives/report-track-conditions.js.map +1 -1
  194. package/dist/default/playback/primitives/segment-load-pipeline.js +15 -15
  195. package/dist/default/playback/primitives/segment-load-pipeline.js.map +1 -1
  196. package/dist/default/playback/primitives/selection-rules.js +65 -36
  197. package/dist/default/playback/primitives/selection-rules.js.map +1 -1
  198. package/dist/default/playback/primitives/text-segment-load-pipeline.js +4 -5
  199. package/dist/default/playback/primitives/text-segment-load-pipeline.js.map +1 -1
  200. package/dist/default/playback/primitives/track-types.js +10 -18
  201. package/dist/default/playback/primitives/track-types.js.map +1 -1
  202. package/dist/dev/core/actors/actor.d.ts +4 -4
  203. package/dist/dev/core/actors/actor.d.ts.map +1 -1
  204. package/dist/dev/core/actors/create-machine-actor.d.ts +38 -47
  205. package/dist/dev/core/actors/create-machine-actor.d.ts.map +1 -1
  206. package/dist/dev/core/actors/create-machine-actor.js +23 -25
  207. package/dist/dev/core/actors/create-machine-actor.js.map +1 -1
  208. package/dist/dev/core/actors/create-transition-actor.d.ts +11 -15
  209. package/dist/dev/core/actors/create-transition-actor.d.ts.map +1 -1
  210. package/dist/dev/core/actors/create-transition-actor.js +7 -9
  211. package/dist/dev/core/actors/create-transition-actor.js.map +1 -1
  212. package/dist/dev/core/composition/create-composition.d.ts +70 -102
  213. package/dist/dev/core/composition/create-composition.d.ts.map +1 -1
  214. package/dist/dev/core/composition/create-composition.js +26 -29
  215. package/dist/dev/core/composition/create-composition.js.map +1 -1
  216. package/dist/dev/core/composition/share-signals.d.ts +17 -24
  217. package/dist/dev/core/composition/share-signals.d.ts.map +1 -1
  218. package/dist/dev/core/composition/share-signals.js +12 -17
  219. package/dist/dev/core/composition/share-signals.js.map +1 -1
  220. package/dist/dev/core/machine.d.ts +4 -4
  221. package/dist/dev/core/machine.js +3 -4
  222. package/dist/dev/core/machine.js.map +1 -1
  223. package/dist/dev/core/reactors/create-machine-reactor.d.ts +33 -39
  224. package/dist/dev/core/reactors/create-machine-reactor.d.ts.map +1 -1
  225. package/dist/dev/core/reactors/create-machine-reactor.js +20 -19
  226. package/dist/dev/core/reactors/create-machine-reactor.js.map +1 -1
  227. package/dist/dev/core/signals/effect.d.ts +3 -4
  228. package/dist/dev/core/signals/effect.d.ts.map +1 -1
  229. package/dist/dev/core/signals/effect.js +24 -4
  230. package/dist/dev/core/signals/effect.js.map +1 -1
  231. package/dist/dev/core/signals/primitives.d.ts +10 -12
  232. package/dist/dev/core/signals/primitives.d.ts.map +1 -1
  233. package/dist/dev/core/signals/primitives.js +10 -14
  234. package/dist/dev/core/signals/primitives.js.map +1 -1
  235. package/dist/dev/core/signals/when.js +6 -8
  236. package/dist/dev/core/signals/when.js.map +1 -1
  237. package/dist/dev/core/tasks/delayed-reschedule.js +7 -11
  238. package/dist/dev/core/tasks/delayed-reschedule.js.map +1 -1
  239. package/dist/dev/core/tasks/task.d.ts +51 -73
  240. package/dist/dev/core/tasks/task.d.ts.map +1 -1
  241. package/dist/dev/core/tasks/task.js +59 -82
  242. package/dist/dev/core/tasks/task.js.map +1 -1
  243. package/dist/dev/hls.d.ts +3 -1
  244. package/dist/dev/hls.js +3 -1
  245. package/dist/dev/index.d.ts +2 -3
  246. package/dist/dev/index.d.ts.map +1 -1
  247. package/dist/dev/index.js +2 -3
  248. package/dist/dev/index.js.map +1 -1
  249. package/dist/dev/media/abr/quality-selection.d.ts +7 -10
  250. package/dist/dev/media/abr/quality-selection.d.ts.map +1 -1
  251. package/dist/dev/media/abr/quality-selection.js +3 -7
  252. package/dist/dev/media/abr/quality-selection.js.map +1 -1
  253. package/dist/dev/media/buffer/back-buffer.d.ts +2 -7
  254. package/dist/dev/media/buffer/back-buffer.d.ts.map +1 -1
  255. package/dist/dev/media/buffer/back-buffer.js +15 -19
  256. package/dist/dev/media/buffer/back-buffer.js.map +1 -1
  257. package/dist/dev/media/buffer/forward-buffer.d.ts +2 -7
  258. package/dist/dev/media/buffer/forward-buffer.d.ts.map +1 -1
  259. package/dist/dev/media/buffer/forward-buffer.js +32 -41
  260. package/dist/dev/media/buffer/forward-buffer.js.map +1 -1
  261. package/dist/dev/media/dom/capabilities.js +26 -37
  262. package/dist/dev/media/dom/capabilities.js.map +1 -1
  263. package/dist/dev/media/dom/mse/append-segment.d.ts +3 -5
  264. package/dist/dev/media/dom/mse/append-segment.d.ts.map +1 -1
  265. package/dist/dev/media/dom/mse/append-segment.js +3 -5
  266. package/dist/dev/media/dom/mse/append-segment.js.map +1 -1
  267. package/dist/dev/media/dom/mse/buffer-flusher.d.ts +5 -5
  268. package/dist/dev/media/dom/mse/buffer-flusher.js +5 -5
  269. package/dist/dev/media/dom/mse/buffer-flusher.js.map +1 -1
  270. package/dist/dev/media/dom/mse/duration.js +23 -31
  271. package/dist/dev/media/dom/mse/duration.js.map +1 -1
  272. package/dist/dev/media/dom/mse/end-of-stream.js +3 -6
  273. package/dist/dev/media/dom/mse/end-of-stream.js.map +1 -1
  274. package/dist/dev/media/dom/mse/mediasource-setup.js +65 -81
  275. package/dist/dev/media/dom/mse/mediasource-setup.js.map +1 -1
  276. package/dist/dev/media/dom/screen.d.ts.map +1 -1
  277. package/dist/dev/media/dom/screen.js +37 -54
  278. package/dist/dev/media/dom/screen.js.map +1 -1
  279. package/dist/dev/media/dom/text/resolve-vtt-segment.d.ts.map +1 -1
  280. package/dist/dev/media/dom/text/resolve-vtt-segment.js.map +1 -1
  281. package/dist/dev/media/dom/text/text-track-slots.d.ts +10 -16
  282. package/dist/dev/media/dom/text/text-track-slots.d.ts.map +1 -1
  283. package/dist/dev/media/dom/text/text-track-slots.js +15 -23
  284. package/dist/dev/media/dom/text/text-track-slots.js.map +1 -1
  285. package/dist/dev/media/errors.d.ts +32 -46
  286. package/dist/dev/media/errors.d.ts.map +1 -1
  287. package/dist/dev/media/errors.js +25 -34
  288. package/dist/dev/media/errors.js.map +1 -1
  289. package/dist/dev/media/hls/parse-attributes.js +9 -26
  290. package/dist/dev/media/hls/parse-attributes.js.map +1 -1
  291. package/dist/dev/media/hls/parse-media-playlist.js +25 -33
  292. package/dist/dev/media/hls/parse-media-playlist.js.map +1 -1
  293. package/dist/dev/media/hls/parse-multivariant.js +3 -3
  294. package/dist/dev/media/hls/parse-multivariant.js.map +1 -1
  295. package/dist/dev/media/hls/reload-policy.js +19 -27
  296. package/dist/dev/media/hls/reload-policy.js.map +1 -1
  297. package/dist/dev/media/hls/resolve-url.js +1 -3
  298. package/dist/dev/media/hls/resolve-url.js.map +1 -1
  299. package/dist/dev/media/live-window.js +9 -13
  300. package/dist/dev/media/live-window.js.map +1 -1
  301. package/dist/dev/media/media-tracks/media-tracks.d.ts +8 -13
  302. package/dist/dev/media/media-tracks/media-tracks.d.ts.map +1 -1
  303. package/dist/dev/media/media-tracks/media-tracks.js +12 -17
  304. package/dist/dev/media/media-tracks/media-tracks.js.map +1 -1
  305. package/dist/dev/media/mp4/box.js +4 -5
  306. package/dist/dev/media/mp4/box.js.map +1 -1
  307. package/dist/dev/media/mp4/timestamp-origin.js +30 -42
  308. package/dist/dev/media/mp4/timestamp-origin.js.map +1 -1
  309. package/dist/dev/media/primitives/resolution.d.ts +6 -8
  310. package/dist/dev/media/primitives/resolution.d.ts.map +1 -1
  311. package/dist/dev/media/primitives/resolution.js +5 -8
  312. package/dist/dev/media/primitives/resolution.js.map +1 -1
  313. package/dist/dev/media/primitives/select-tracks.js +24 -34
  314. package/dist/dev/media/primitives/select-tracks.js.map +1 -1
  315. package/dist/dev/media/text/parse-vtt-timestamp-map.js +6 -8
  316. package/dist/dev/media/text/parse-vtt-timestamp-map.js.map +1 -1
  317. package/dist/dev/media/text/resolve-vtt-metadata.js +8 -9
  318. package/dist/dev/media/text/resolve-vtt-metadata.js.map +1 -1
  319. package/dist/dev/media/types/index.d.ts +106 -177
  320. package/dist/dev/media/types/index.d.ts.map +1 -1
  321. package/dist/dev/media/types/index.js +10 -18
  322. package/dist/dev/media/types/index.js.map +1 -1
  323. package/dist/dev/media/utils/cdn.d.ts +4 -6
  324. package/dist/dev/media/utils/cdn.d.ts.map +1 -1
  325. package/dist/dev/media/utils/cdn.js +10 -16
  326. package/dist/dev/media/utils/cdn.js.map +1 -1
  327. package/dist/dev/media/utils/preload.js +4 -6
  328. package/dist/dev/media/utils/preload.js.map +1 -1
  329. package/dist/dev/media/utils/track-selection.js +10 -14
  330. package/dist/dev/media/utils/track-selection.js.map +1 -1
  331. package/dist/dev/media/utils/tracks.js +56 -54
  332. package/dist/dev/media/utils/tracks.js.map +1 -1
  333. package/dist/dev/network/bandwidth-estimator.d.ts +7 -9
  334. package/dist/dev/network/bandwidth-estimator.d.ts.map +1 -1
  335. package/dist/dev/network/bandwidth-estimator.js +18 -19
  336. package/dist/dev/network/bandwidth-estimator.js.map +1 -1
  337. package/dist/dev/network/chunked-stream-iterable.js +4 -6
  338. package/dist/dev/network/chunked-stream-iterable.js.map +1 -1
  339. package/dist/dev/network/ewma.js +22 -25
  340. package/dist/dev/network/ewma.js.map +1 -1
  341. package/dist/dev/network/fetch.js +30 -37
  342. package/dist/dev/network/fetch.js.map +1 -1
  343. package/dist/dev/playback/actors/dom/segment-loader.d.ts +7 -11
  344. package/dist/dev/playback/actors/dom/segment-loader.d.ts.map +1 -1
  345. package/dist/dev/playback/actors/dom/segment-loader.js +28 -44
  346. package/dist/dev/playback/actors/dom/segment-loader.js.map +1 -1
  347. package/dist/dev/playback/actors/dom/source-buffer.d.ts +5 -7
  348. package/dist/dev/playback/actors/dom/source-buffer.d.ts.map +1 -1
  349. package/dist/dev/playback/actors/dom/source-buffer.js.map +1 -1
  350. package/dist/dev/playback/actors/dom/text-tracks.js.map +1 -1
  351. package/dist/dev/playback/actors/text-track-segment-loader.d.ts +10 -16
  352. package/dist/dev/playback/actors/text-track-segment-loader.d.ts.map +1 -1
  353. package/dist/dev/playback/actors/text-track-segment-loader.js +24 -35
  354. package/dist/dev/playback/actors/text-track-segment-loader.js.map +1 -1
  355. package/dist/dev/playback/actors/text-tracks.d.ts +5 -8
  356. package/dist/dev/playback/actors/text-tracks.d.ts.map +1 -1
  357. package/dist/dev/playback/adapters/hls-audio/adapter.d.ts +11 -14
  358. package/dist/dev/playback/adapters/hls-audio/adapter.d.ts.map +1 -1
  359. package/dist/dev/playback/adapters/hls-audio/adapter.js +23 -31
  360. package/dist/dev/playback/adapters/hls-audio/adapter.js.map +1 -1
  361. package/dist/dev/playback/adapters/hls-audio/media.d.ts.map +1 -1
  362. package/dist/dev/playback/adapters/hls-audio/media.js.map +1 -1
  363. package/dist/dev/playback/adapters/hls-background-video/adapter.d.ts +28 -39
  364. package/dist/dev/playback/adapters/hls-background-video/adapter.d.ts.map +1 -1
  365. package/dist/dev/playback/adapters/hls-background-video/adapter.js +50 -70
  366. package/dist/dev/playback/adapters/hls-background-video/adapter.js.map +1 -1
  367. package/dist/dev/playback/adapters/hls-background-video/host.d.ts +12 -16
  368. package/dist/dev/playback/adapters/hls-background-video/host.d.ts.map +1 -1
  369. package/dist/dev/playback/adapters/hls-background-video/host.js +12 -16
  370. package/dist/dev/playback/adapters/hls-background-video/host.js.map +1 -1
  371. package/dist/dev/playback/adapters/hls-background-video/media.d.ts +5 -8
  372. package/dist/dev/playback/adapters/hls-background-video/media.d.ts.map +1 -1
  373. package/dist/dev/playback/adapters/hls-background-video/media.js +5 -8
  374. package/dist/dev/playback/adapters/hls-background-video/media.js.map +1 -1
  375. package/dist/dev/playback/adapters/hls-video/adapter.d.ts +12 -14
  376. package/dist/dev/playback/adapters/hls-video/adapter.d.ts.map +1 -1
  377. package/dist/dev/playback/adapters/hls-video/adapter.js +43 -60
  378. package/dist/dev/playback/adapters/hls-video/adapter.js.map +1 -1
  379. package/dist/dev/playback/adapters/hls-video/error-surface.d.ts +4 -5
  380. package/dist/dev/playback/adapters/hls-video/error-surface.d.ts.map +1 -1
  381. package/dist/dev/playback/adapters/hls-video/error-surface.js +13 -18
  382. package/dist/dev/playback/adapters/hls-video/error-surface.js.map +1 -1
  383. package/dist/dev/playback/adapters/hls-video/media-tracks.d.ts +4 -5
  384. package/dist/dev/playback/adapters/hls-video/media-tracks.d.ts.map +1 -1
  385. package/dist/dev/playback/adapters/hls-video/media-tracks.js +4 -5
  386. package/dist/dev/playback/adapters/hls-video/media-tracks.js.map +1 -1
  387. package/dist/dev/playback/adapters/hls-video/media.d.ts.map +1 -1
  388. package/dist/dev/playback/adapters/hls-video/media.js.map +1 -1
  389. package/dist/dev/playback/adapters/mux-audio/media.d.ts +8 -12
  390. package/dist/dev/playback/adapters/mux-audio/media.d.ts.map +1 -1
  391. package/dist/dev/playback/adapters/mux-audio/media.js +8 -12
  392. package/dist/dev/playback/adapters/mux-audio/media.js.map +1 -1
  393. package/dist/dev/playback/adapters/mux-video/adapter.d.ts +9 -11
  394. package/dist/dev/playback/adapters/mux-video/adapter.d.ts.map +1 -1
  395. package/dist/dev/playback/adapters/mux-video/adapter.js +25 -33
  396. package/dist/dev/playback/adapters/mux-video/adapter.js.map +1 -1
  397. package/dist/dev/playback/adapters/mux-video/media.d.ts +7 -9
  398. package/dist/dev/playback/adapters/mux-video/media.d.ts.map +1 -1
  399. package/dist/dev/playback/adapters/mux-video/media.js +7 -9
  400. package/dist/dev/playback/adapters/mux-video/media.js.map +1 -1
  401. package/dist/dev/playback/behaviors/calculate-presentation-duration.d.ts +5 -8
  402. package/dist/dev/playback/behaviors/calculate-presentation-duration.d.ts.map +1 -1
  403. package/dist/dev/playback/behaviors/calculate-presentation-duration.js +5 -8
  404. package/dist/dev/playback/behaviors/calculate-presentation-duration.js.map +1 -1
  405. package/dist/dev/playback/behaviors/collect-errors.d.ts +2 -0
  406. package/dist/dev/playback/behaviors/collect-errors.js +39 -52
  407. package/dist/dev/playback/behaviors/collect-errors.js.map +1 -1
  408. package/dist/dev/playback/behaviors/derive-cdn-priority.js +16 -23
  409. package/dist/dev/playback/behaviors/derive-cdn-priority.js.map +1 -1
  410. package/dist/dev/playback/behaviors/dom/airplay.js +38 -61
  411. package/dist/dev/playback/behaviors/dom/airplay.js.map +1 -1
  412. package/dist/dev/playback/behaviors/dom/apply-start-position.js +23 -35
  413. package/dist/dev/playback/behaviors/dom/apply-start-position.js.map +1 -1
  414. package/dist/dev/playback/behaviors/dom/end-of-stream.js +11 -16
  415. package/dist/dev/playback/behaviors/dom/end-of-stream.js.map +1 -1
  416. package/dist/dev/playback/behaviors/dom/load-segments.d.ts +5 -8
  417. package/dist/dev/playback/behaviors/dom/load-segments.d.ts.map +1 -1
  418. package/dist/dev/playback/behaviors/dom/load-segments.js +27 -39
  419. package/dist/dev/playback/behaviors/dom/load-segments.js.map +1 -1
  420. package/dist/dev/playback/behaviors/dom/recover-end-stall.js +21 -26
  421. package/dist/dev/playback/behaviors/dom/recover-end-stall.js.map +1 -1
  422. package/dist/dev/playback/behaviors/dom/seek-to-live-edge.js +41 -60
  423. package/dist/dev/playback/behaviors/dom/seek-to-live-edge.js.map +1 -1
  424. package/dist/dev/playback/behaviors/dom/setup-buffer-actors.js +50 -74
  425. package/dist/dev/playback/behaviors/dom/setup-buffer-actors.js.map +1 -1
  426. package/dist/dev/playback/behaviors/dom/setup-mediasource.js +29 -43
  427. package/dist/dev/playback/behaviors/dom/setup-mediasource.js.map +1 -1
  428. package/dist/dev/playback/behaviors/dom/setup-text-track-actors.d.ts +3 -3
  429. package/dist/dev/playback/behaviors/dom/setup-text-track-actors.d.ts.map +1 -1
  430. package/dist/dev/playback/behaviors/dom/setup-text-track-actors.js.map +1 -1
  431. package/dist/dev/playback/behaviors/dom/sync-live-seekable-range.js +3 -4
  432. package/dist/dev/playback/behaviors/dom/sync-live-seekable-range.js.map +1 -1
  433. package/dist/dev/playback/behaviors/dom/sync-text-tracks.js +30 -45
  434. package/dist/dev/playback/behaviors/dom/sync-text-tracks.js.map +1 -1
  435. package/dist/dev/playback/behaviors/dom/track-current-time.d.ts +2 -2
  436. package/dist/dev/playback/behaviors/dom/track-current-time.d.ts.map +1 -1
  437. package/dist/dev/playback/behaviors/dom/track-current-time.js +9 -11
  438. package/dist/dev/playback/behaviors/dom/track-current-time.js.map +1 -1
  439. package/dist/dev/playback/behaviors/dom/track-load-triggers.d.ts +6 -12
  440. package/dist/dev/playback/behaviors/dom/track-load-triggers.d.ts.map +1 -1
  441. package/dist/dev/playback/behaviors/dom/track-load-triggers.js +24 -32
  442. package/dist/dev/playback/behaviors/dom/track-load-triggers.js.map +1 -1
  443. package/dist/dev/playback/behaviors/dom/track-playback-rate.d.ts +2 -2
  444. package/dist/dev/playback/behaviors/dom/track-playback-rate.d.ts.map +1 -1
  445. package/dist/dev/playback/behaviors/dom/track-playback-rate.js +6 -8
  446. package/dist/dev/playback/behaviors/dom/track-playback-rate.js.map +1 -1
  447. package/dist/dev/playback/behaviors/dom/track-player-resolution.d.ts.map +1 -1
  448. package/dist/dev/playback/behaviors/dom/track-player-resolution.js +10 -14
  449. package/dist/dev/playback/behaviors/dom/track-player-resolution.js.map +1 -1
  450. package/dist/dev/playback/behaviors/dom/track-screen-resolution.js +8 -9
  451. package/dist/dev/playback/behaviors/dom/track-screen-resolution.js.map +1 -1
  452. package/dist/dev/playback/behaviors/dom/update-mediasource-duration.js +28 -43
  453. package/dist/dev/playback/behaviors/dom/update-mediasource-duration.js.map +1 -1
  454. package/dist/dev/playback/behaviors/establish-start-media-time.d.ts +15 -19
  455. package/dist/dev/playback/behaviors/establish-start-media-time.d.ts.map +1 -1
  456. package/dist/dev/playback/behaviors/establish-start-media-time.js +32 -42
  457. package/dist/dev/playback/behaviors/establish-start-media-time.js.map +1 -1
  458. package/dist/dev/playback/behaviors/resolve-presentation.d.ts.map +1 -1
  459. package/dist/dev/playback/behaviors/resolve-presentation.js +13 -22
  460. package/dist/dev/playback/behaviors/resolve-presentation.js.map +1 -1
  461. package/dist/dev/playback/behaviors/resolve-track.js +5 -12
  462. package/dist/dev/playback/behaviors/resolve-track.js.map +1 -1
  463. package/dist/dev/playback/behaviors/select-tracks.d.ts +28 -39
  464. package/dist/dev/playback/behaviors/select-tracks.d.ts.map +1 -1
  465. package/dist/dev/playback/behaviors/select-tracks.js +77 -104
  466. package/dist/dev/playback/behaviors/select-tracks.js.map +1 -1
  467. package/dist/dev/playback/behaviors/setup-failover-monitor.d.ts +1 -4
  468. package/dist/dev/playback/behaviors/setup-failover-monitor.d.ts.map +1 -1
  469. package/dist/dev/playback/behaviors/setup-failover-monitor.js +11 -16
  470. package/dist/dev/playback/behaviors/setup-failover-monitor.js.map +1 -1
  471. package/dist/dev/playback/behaviors/sync-preload.js +9 -13
  472. package/dist/dev/playback/behaviors/sync-preload.js.map +1 -1
  473. package/dist/dev/playback/behaviors/track-switching.d.ts +110 -0
  474. package/dist/dev/playback/behaviors/track-switching.d.ts.map +1 -0
  475. package/dist/dev/playback/behaviors/track-switching.js +189 -173
  476. package/dist/dev/playback/behaviors/track-switching.js.map +1 -1
  477. package/dist/dev/playback/engines/hls/engine-audio-only.d.ts +59 -72
  478. package/dist/dev/playback/engines/hls/engine-audio-only.d.ts.map +1 -1
  479. package/dist/dev/playback/engines/hls/engine-audio-only.js +20 -24
  480. package/dist/dev/playback/engines/hls/engine-audio-only.js.map +1 -1
  481. package/dist/dev/playback/engines/hls/engine-background-video.d.ts +51 -78
  482. package/dist/dev/playback/engines/hls/engine-background-video.d.ts.map +1 -1
  483. package/dist/dev/playback/engines/hls/engine-background-video.js +22 -27
  484. package/dist/dev/playback/engines/hls/engine-background-video.js.map +1 -1
  485. package/dist/dev/playback/engines/hls/engine.d.ts +115 -155
  486. package/dist/dev/playback/engines/hls/engine.d.ts.map +1 -1
  487. package/dist/dev/playback/engines/hls/engine.js +22 -25
  488. package/dist/dev/playback/engines/hls/engine.js.map +1 -1
  489. package/dist/dev/playback/primitives/derive-start-media-time.d.ts +3 -3
  490. package/dist/dev/playback/primitives/derive-start-media-time.d.ts.map +1 -1
  491. package/dist/dev/playback/primitives/error-messages.js +16 -25
  492. package/dist/dev/playback/primitives/error-messages.js.map +1 -1
  493. package/dist/dev/playback/primitives/failover-fetch.js +9 -14
  494. package/dist/dev/playback/primitives/failover-fetch.js.map +1 -1
  495. package/dist/dev/playback/primitives/head-peek.js +7 -10
  496. package/dist/dev/playback/primitives/head-peek.js.map +1 -1
  497. package/dist/dev/playback/primitives/live-window.js +12 -15
  498. package/dist/dev/playback/primitives/live-window.js.map +1 -1
  499. package/dist/dev/playback/primitives/relocation-pipelines.js +34 -46
  500. package/dist/dev/playback/primitives/relocation-pipelines.js.map +1 -1
  501. package/dist/dev/playback/primitives/report-track-conditions.d.ts +1 -4
  502. package/dist/dev/playback/primitives/report-track-conditions.d.ts.map +1 -1
  503. package/dist/dev/playback/primitives/report-track-conditions.js +26 -38
  504. package/dist/dev/playback/primitives/report-track-conditions.js.map +1 -1
  505. package/dist/dev/playback/primitives/segment-load-pipeline.js +15 -15
  506. package/dist/dev/playback/primitives/segment-load-pipeline.js.map +1 -1
  507. package/dist/dev/playback/primitives/selection-rules.d.ts +45 -17
  508. package/dist/dev/playback/primitives/selection-rules.d.ts.map +1 -1
  509. package/dist/dev/playback/primitives/selection-rules.js +65 -36
  510. package/dist/dev/playback/primitives/selection-rules.js.map +1 -1
  511. package/dist/dev/playback/primitives/source-buffer-messages.d.ts +6 -9
  512. package/dist/dev/playback/primitives/source-buffer-messages.d.ts.map +1 -1
  513. package/dist/dev/playback/primitives/text-segment-load-pipeline.d.ts +20 -29
  514. package/dist/dev/playback/primitives/text-segment-load-pipeline.d.ts.map +1 -1
  515. package/dist/dev/playback/primitives/text-segment-load-pipeline.js +4 -5
  516. package/dist/dev/playback/primitives/text-segment-load-pipeline.js.map +1 -1
  517. package/dist/dev/playback/primitives/text-track-messages.d.ts.map +1 -1
  518. package/dist/dev/playback/primitives/track-types.js +10 -18
  519. package/dist/dev/playback/primitives/track-types.js.map +1 -1
  520. package/package.json +25 -28
@@ -1,24 +1,20 @@
1
1
  //#region src/playback/adapters/hls-background-video/host.ts
2
2
  /**
3
- * The `<video>` binding a background video uses: somewhere to keep the attached
4
- * element, and the four properties the Media fixes on it.
3
+ * The `<video>` binding a background video uses: somewhere to keep the attached element, and the four properties the
4
+ * Media fixes on it.
5
5
  *
6
- * That is the whole surface anything here reaches. The engine drives playback,
7
- * the element exposes `src` and nothing else, and the background player
8
- * subscribes to no store features, so nothing asks a background video for
9
- * `currentTime`, `play()`, picture-in-picture, fullscreen, forwarded events, or
10
- * media components. Holding the host to what is reachable is what keeps this
11
- * entry free of `@videojs/media`, and small enough to suit a component whose
12
- * whole pitch is its size.
6
+ * That is the whole surface anything here reaches. The engine drives playback, the element exposes `src` and nothing
7
+ * else, and the background player subscribes to no store features, so nothing asks a background video for
8
+ * `currentTime`, `play()`, picture-in-picture, fullscreen, forwarded events, or media components. Holding the host to
9
+ * what is reachable is what keeps this entry free of `@videojs/media`, and small enough to suit a component whose whole
10
+ * pitch is its size.
13
11
  *
14
- * An `EventTarget`, because a Media is one: the store and the element layers
15
- * take anything they attach as an event source, and inheriting the three methods
16
- * satisfies that for free rather than by stubbing them.
12
+ * An `EventTarget`, because a Media is one: the store and the element layers take anything they attach as an event
13
+ * source, and inheriting the three methods satisfies that for free rather than by stubbing them.
17
14
  *
18
- * ⚠️ It still implements too little to carry the rest of the media surface, which
19
- * bounds what may consume it: a store feature reading a property outside this set
20
- * gets `undefined` rather than an error. A Media needing more of that surface
21
- * belongs on a host that provides it.
15
+ * ⚠️ It still implements too little to carry the rest of the media surface, which bounds what may consume it: a store
16
+ * feature reading a property outside this set gets `undefined` rather than an error. A Media needing more of that
17
+ * surface belongs on a host that provides it.
22
18
  */
23
19
  var BackgroundVideoHost = class extends EventTarget {
24
20
  #target = null;
@@ -1 +1 @@
1
- {"version":3,"file":"host.js","names":["#target"],"sources":["../../../../../src/playback/adapters/hls-background-video/host.ts"],"sourcesContent":["/**\n * The `<video>` binding a background video uses: somewhere to keep the attached\n * element, and the four properties the Media fixes on it.\n *\n * That is the whole surface anything here reaches. The engine drives playback,\n * the element exposes `src` and nothing else, and the background player\n * subscribes to no store features, so nothing asks a background video for\n * `currentTime`, `play()`, picture-in-picture, fullscreen, forwarded events, or\n * media components. Holding the host to what is reachable is what keeps this\n * entry free of `@videojs/media`, and small enough to suit a component whose\n * whole pitch is its size.\n *\n * An `EventTarget`, because a Media is one: the store and the element layers\n * take anything they attach as an event source, and inheriting the three methods\n * satisfies that for free rather than by stubbing them.\n *\n * ⚠️ It still implements too little to carry the rest of the media surface, which\n * bounds what may consume it: a store feature reading a property outside this set\n * gets `undefined` rather than an error. A Media needing more of that surface\n * belongs on a host that provides it.\n */\nexport class BackgroundVideoHost extends EventTarget {\n #target: HTMLVideoElement | null = null;\n\n attach(target: HTMLVideoElement): void {\n if (!target || this.#target === target) return;\n this.#target = target;\n }\n\n detach(): void {\n this.#target = null;\n }\n\n // Read back off the element rather than stored, so they describe what is\n // playing instead of what was asked for — see the adapter's note on why the\n // Media declares none of these itself.\n get loop(): boolean {\n return this.#target?.loop ?? false;\n }\n\n set loop(value: boolean) {\n if (this.#target) this.#target.loop = value;\n }\n\n get muted(): boolean {\n return this.#target?.muted ?? false;\n }\n\n set muted(value: boolean) {\n if (this.#target) this.#target.muted = value;\n }\n\n get autoplay(): boolean {\n return this.#target?.autoplay ?? false;\n }\n\n set autoplay(value: boolean) {\n if (this.#target) this.#target.autoplay = value;\n }\n\n get preload(): HTMLVideoElement['preload'] {\n return this.#target?.preload ?? 'metadata';\n }\n\n set preload(value: HTMLVideoElement['preload']) {\n if (this.#target) this.#target.preload = value;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAqBA,IAAa,sBAAb,cAAyC,YAAY;CACnD,UAAmC;CAEnC,OAAO,QAAgC;EACrC,IAAI,CAAC,UAAU,KAAKA,YAAY,QAAQ;EACxC,KAAKA,UAAU;CACjB;CAEA,SAAe;EACb,KAAKA,UAAU;CACjB;CAKA,IAAI,OAAgB;EAClB,OAAO,KAAKA,SAAS,QAAQ;CAC/B;CAEA,IAAI,KAAK,OAAgB;EACvB,IAAI,KAAKA,SAAS,KAAKA,QAAQ,OAAO;CACxC;CAEA,IAAI,QAAiB;EACnB,OAAO,KAAKA,SAAS,SAAS;CAChC;CAEA,IAAI,MAAM,OAAgB;EACxB,IAAI,KAAKA,SAAS,KAAKA,QAAQ,QAAQ;CACzC;CAEA,IAAI,WAAoB;EACtB,OAAO,KAAKA,SAAS,YAAY;CACnC;CAEA,IAAI,SAAS,OAAgB;EAC3B,IAAI,KAAKA,SAAS,KAAKA,QAAQ,WAAW;CAC5C;CAEA,IAAI,UAAuC;EACzC,OAAO,KAAKA,SAAS,WAAW;CAClC;CAEA,IAAI,QAAQ,OAAoC;EAC9C,IAAI,KAAKA,SAAS,KAAKA,QAAQ,UAAU;CAC3C;AACF"}
1
+ {"version":3,"file":"host.js","names":["#target"],"sources":["../../../../../src/playback/adapters/hls-background-video/host.ts"],"sourcesContent":["/**\n * The `<video>` binding a background video uses: somewhere to keep the attached element, and the four properties the\n * Media fixes on it.\n *\n * That is the whole surface anything here reaches. The engine drives playback, the element exposes `src` and nothing\n * else, and the background player subscribes to no store features, so nothing asks a background video for\n * `currentTime`, `play()`, picture-in-picture, fullscreen, forwarded events, or media components. Holding the host to\n * what is reachable is what keeps this entry free of `@videojs/media`, and small enough to suit a component whose whole\n * pitch is its size.\n *\n * An `EventTarget`, because a Media is one: the store and the element layers take anything they attach as an event\n * source, and inheriting the three methods satisfies that for free rather than by stubbing them.\n *\n * ⚠️ It still implements too little to carry the rest of the media surface, which bounds what may consume it: a store\n * feature reading a property outside this set gets `undefined` rather than an error. A Media needing more of that\n * surface belongs on a host that provides it.\n */\nexport class BackgroundVideoHost extends EventTarget {\n #target: HTMLVideoElement | null = null;\n\n attach(target: HTMLVideoElement): void {\n if (!target || this.#target === target) return;\n\n this.#target = target;\n }\n\n detach(): void {\n this.#target = null;\n }\n\n // Read back off the element rather than stored, so they describe what is\n // playing instead of what was asked for — see the adapter's note on why the\n // Media declares none of these itself.\n get loop(): boolean {\n return this.#target?.loop ?? false;\n }\n\n set loop(value: boolean) {\n if (this.#target) this.#target.loop = value;\n }\n\n get muted(): boolean {\n return this.#target?.muted ?? false;\n }\n\n set muted(value: boolean) {\n if (this.#target) this.#target.muted = value;\n }\n\n get autoplay(): boolean {\n return this.#target?.autoplay ?? false;\n }\n\n set autoplay(value: boolean) {\n if (this.#target) this.#target.autoplay = value;\n }\n\n get preload(): HTMLVideoElement['preload'] {\n return this.#target?.preload ?? 'metadata';\n }\n\n set preload(value: HTMLVideoElement['preload']) {\n if (this.#target) this.#target.preload = value;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAiBA,IAAa,sBAAb,cAAyC,YAAY;CACnD,UAAmC;CAEnC,OAAO,QAAgC;EACrC,IAAI,CAAC,UAAU,KAAKA,YAAY,QAAQ;EAExC,KAAKA,UAAU;CACjB;CAEA,SAAe;EACb,KAAKA,UAAU;CACjB;CAKA,IAAI,OAAgB;EAClB,OAAO,KAAKA,SAAS,QAAQ;CAC/B;CAEA,IAAI,KAAK,OAAgB;EACvB,IAAI,KAAKA,SAAS,KAAKA,QAAQ,OAAO;CACxC;CAEA,IAAI,QAAiB;EACnB,OAAO,KAAKA,SAAS,SAAS;CAChC;CAEA,IAAI,MAAM,OAAgB;EACxB,IAAI,KAAKA,SAAS,KAAKA,QAAQ,QAAQ;CACzC;CAEA,IAAI,WAAoB;EACtB,OAAO,KAAKA,SAAS,YAAY;CACnC;CAEA,IAAI,SAAS,OAAgB;EAC3B,IAAI,KAAKA,SAAS,KAAKA,QAAQ,WAAW;CAC5C;CAEA,IAAI,UAAuC;EACzC,OAAO,KAAKA,SAAS,WAAW;CAClC;CAEA,IAAI,QAAQ,OAAoC;EAC9C,IAAI,KAAKA,SAAS,KAAKA,QAAQ,UAAU;CAC3C;AACF"}
@@ -3,16 +3,13 @@ import { BackgroundVideoHost } from "./host.js";
3
3
  //#region src/playback/adapters/hls-background-video/media.d.ts
4
4
  declare const HlsBackgroundVideoMediaBase: import("@videojs/utils/types").MixinReturn<typeof BackgroundVideoHost, HlsBackgroundVideoMediaAPI>;
5
5
  /**
6
- * The background-video Media, bound to a `<video>` through
7
- * {@link BackgroundVideoHost}.
6
+ * The background-video Media, bound to a `<video>` through {@link BackgroundVideoHost}.
8
7
  *
9
- * That host carries the attached element and the four properties `attach` fixes,
10
- * which is all this Media's surface needs, and it is local — so this entry has
11
- * no `@videojs/media` dependency.
8
+ * That host carries the attached element and the four properties `attach` fixes, which is all this Media's surface
9
+ * needs, and it is local — so this entry has no `@videojs/media` dependency.
12
10
  *
13
- * No `MediaTracksMixin`, unlike `HlsVideoMedia`: the engine subtracts audio and
14
- * text entirely and pins one video rendition for the session, so there are no
15
- * track lists for a consumer to project or switch between.
11
+ * No `MediaTracksMixin`, unlike `HlsVideoMedia`: the engine subtracts audio and text entirely and pins one video
12
+ * rendition for the session, so there are no track lists for a consumer to project or switch between.
16
13
  */
17
14
  declare class HlsBackgroundVideoMedia extends HlsBackgroundVideoMediaBase {}
18
15
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"media.d.ts","names":[],"sources":["../../../../../src/playback/adapters/hls-background-video/media.ts"],"mappings":";;;cAGM,4DAA2B,mBAAA,qBAAA;;;;;;;;;;;;;cAcpB,gCAAgC"}
1
+ {"version":3,"file":"media.d.ts","names":[],"sources":["../../../../../src/playback/adapters/hls-background-video/media.ts"],"mappings":";;;cAGM,4DAA2B,mBAAA,qBAAA;;;;;;;;;;cAWpB,gCAAgC"}
@@ -3,16 +3,13 @@ import { BackgroundVideoHost } from "./host.js";
3
3
  //#region src/playback/adapters/hls-background-video/media.ts
4
4
  const HlsBackgroundVideoMediaBase = HlsBackgroundVideoMediaMixin(BackgroundVideoHost);
5
5
  /**
6
- * The background-video Media, bound to a `<video>` through
7
- * {@link BackgroundVideoHost}.
6
+ * The background-video Media, bound to a `<video>` through {@link BackgroundVideoHost}.
8
7
  *
9
- * That host carries the attached element and the four properties `attach` fixes,
10
- * which is all this Media's surface needs, and it is local — so this entry has
11
- * no `@videojs/media` dependency.
8
+ * That host carries the attached element and the four properties `attach` fixes, which is all this Media's surface
9
+ * needs, and it is local — so this entry has no `@videojs/media` dependency.
12
10
  *
13
- * No `MediaTracksMixin`, unlike `HlsVideoMedia`: the engine subtracts audio and
14
- * text entirely and pins one video rendition for the session, so there are no
15
- * track lists for a consumer to project or switch between.
11
+ * No `MediaTracksMixin`, unlike `HlsVideoMedia`: the engine subtracts audio and text entirely and pins one video
12
+ * rendition for the session, so there are no track lists for a consumer to project or switch between.
16
13
  */
17
14
  var HlsBackgroundVideoMedia = class extends HlsBackgroundVideoMediaBase {};
18
15
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"media.js","names":[],"sources":["../../../../../src/playback/adapters/hls-background-video/media.ts"],"sourcesContent":["import { HlsBackgroundVideoMediaMixin } from './adapter';\nimport { BackgroundVideoHost } from './host';\n\nconst HlsBackgroundVideoMediaBase = HlsBackgroundVideoMediaMixin(BackgroundVideoHost);\n\n/**\n * The background-video Media, bound to a `<video>` through\n * {@link BackgroundVideoHost}.\n *\n * That host carries the attached element and the four properties `attach` fixes,\n * which is all this Media's surface needs, and it is local — so this entry has\n * no `@videojs/media` dependency.\n *\n * No `MediaTracksMixin`, unlike `HlsVideoMedia`: the engine subtracts audio and\n * text entirely and pins one video rendition for the session, so there are no\n * track lists for a consumer to project or switch between.\n */\nexport class HlsBackgroundVideoMedia extends HlsBackgroundVideoMediaBase {}\n"],"mappings":";;;AAGA,MAAM,8BAA8B,6BAA6B,mBAAmB;;;;;;;;;;;;;AAcpF,IAAa,0BAAb,cAA6C,4BAA4B,CAAC"}
1
+ {"version":3,"file":"media.js","names":[],"sources":["../../../../../src/playback/adapters/hls-background-video/media.ts"],"sourcesContent":["import { HlsBackgroundVideoMediaMixin } from './adapter';\nimport { BackgroundVideoHost } from './host';\n\nconst HlsBackgroundVideoMediaBase = HlsBackgroundVideoMediaMixin(BackgroundVideoHost);\n\n/**\n * The background-video Media, bound to a `<video>` through {@link BackgroundVideoHost}.\n *\n * That host carries the attached element and the four properties `attach` fixes, which is all this Media's surface\n * needs, and it is local — so this entry has no `@videojs/media` dependency.\n *\n * No `MediaTracksMixin`, unlike `HlsVideoMedia`: the engine subtracts audio and text entirely and pins one video\n * rendition for the session, so there are no track lists for a consumer to project or switch between.\n */\nexport class HlsBackgroundVideoMedia extends HlsBackgroundVideoMediaBase {}\n"],"mappings":";;;AAGA,MAAM,8BAA8B,6BAA6B,mBAAmB;;;;;;;;;;AAWpF,IAAa,0BAAb,cAA6C,4BAA4B,CAAC"}
@@ -5,9 +5,8 @@ import { MediaStreamType } from "@videojs/media";
5
5
  import { Constructor, MixinReturn } from "@videojs/utils/types";
6
6
  //#region src/playback/adapters/hls-video/adapter.d.ts
7
7
  /**
8
- * The media-level stream type: the engine's detected stream type (`'live'` /
9
- * `'on-demand'`) plus `'unknown'` for "no playlist parsed yet." `@videojs/media`'s
10
- * {@link MediaStreamType} itself, kept under its own name because that is what
8
+ * The media-level stream type: the engine's detected stream type (`'live'` / `'on-demand'`) plus `'unknown'` for "no
9
+ * playlist parsed yet." `@videojs/media`'s {@link MediaStreamType} itself, kept under its own name because that is what
11
10
  * this adapter's `streamType` property is documented against.
12
11
  */
13
12
  type HlsVideoMediaStreamType = MediaStreamType;
@@ -31,22 +30,21 @@ interface HlsVideoMediaAPI extends HlsVideoMediaProps {
31
30
  /**
32
31
  * Mixin that adds SPF playback engine behavior to any base class.
33
32
  *
34
- * Implements the src/play() contract per the WHATWG HTML spec so that SPF can
35
- * be used anywhere a media element API is expected.
33
+ * Implements the src/play() contract per the WHATWG HTML spec so that SPF can be used anywhere a media element API is
34
+ * expected.
36
35
  *
37
- * A single engine instance is created at construction and recycled across src
38
- * changes.
36
+ * A single engine instance is created at construction and recycled across src changes.
37
+ *
38
+ * @example
39
+ * class HlsVideoMedia extends HlsVideoMediaMixin(HTMLVideoElementHost) {}
40
+ *
41
+ * const media = new HlsVideoMedia();
42
+ * media.attach(document.querySelector('video'));
43
+ * media.src = 'https://stream.mux.com/abc123.m3u8';
39
44
  *
40
45
  * @fires streamtypechange - Fired when the detected stream type changes. Read `streamType` for the new value.
41
46
  * @fires targetlivewindowchange - Fired when the target live window changes. Read `targetLiveWindow` for the new value.
42
47
  * @fires error - Fired when a fatal condition is reported. Read `error` for it.
43
- *
44
- * @example
45
- * class HlsVideoMedia extends HlsVideoMediaMixin(HTMLVideoElementHost) {}
46
- *
47
- * const media = new HlsVideoMedia();
48
- * media.attach(document.querySelector('video'));
49
- * media.src = 'https://stream.mux.com/abc123.m3u8';
50
48
  */
51
49
  declare function HlsVideoMediaMixin<Base extends Constructor<any>>(BaseClass: Base): MixinReturn<Base, HlsVideoMediaAPI> & {
52
50
  readonly alternativeMediaSuggestion: string | undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"adapter.d.ts","names":[],"sources":["../../../../../src/playback/adapters/hls-video/adapter.ts"],"mappings":";;;;;;;;;;;;KA6CY,0BAA0B;UAIrB;EACf;EACA;EACA;EACA,YAAY;;cAGD,2BAA2B;UAOvB,yBAAyB;WAC/B,QAAQ,YAAY,qBAAqB;WACzC,OAAO;WACP;WACA;EACT,OAAO,cAAc;EACrB;EACA;EACA,QAAQ;;;;;;;;;;;;;;;;;;;;;;iBA+DM,mBAAmB,aAAa,kBAAkB,WAAW,OAuXpC,YAAY,MAAM;WAC9C;;;;;WAA4B;;;cAK5B,6BAA6B"}
1
+ {"version":3,"file":"adapter.d.ts","names":[],"sources":["../../../../../src/playback/adapters/hls-video/adapter.ts"],"mappings":";;;;;;;;;;;KA6CY,0BAA0B;UAIrB;EACf;EACA;EACA;EACA,YAAY;;cAGD,2BAA2B;UAOvB,yBAAyB;WAC/B,QAAQ,YAAY,qBAAqB;WACzC,OAAO;WACP;WACA;EACT,OAAO,cAAc;EACrB;EACA;EACA,QAAQ;;;;;;;;;;;;;;;;;;;;;iBA8DM,mBAAmB,aAAa,kBAAkB,WAAW,OA2XpC,YAAY,MAAM;WAC9C;;;;;WAA4B;;;cAK5B,6BAA6B"}
@@ -16,9 +16,8 @@ const hlsVideoMediaDefaultProps = {
16
16
  streamType: MediaStreamTypes.UNKNOWN
17
17
  };
18
18
  /**
19
- * `targetLiveWindow` per the media-ui-extensions live-edge proposal: `NaN` for
20
- * on-demand (or nothing resolved yet), `0` for standard sliding-window live,
21
- * `Infinity` for DVR (`#EXT-X-PLAYLIST-TYPE:EVENT` — the window grows from the
19
+ * `targetLiveWindow` per the media-ui-extensions live-edge proposal: `NaN` for on-demand (or nothing resolved yet), `0`
20
+ * for standard sliding-window live, `Infinity` for DVR (`#EXT-X-PLAYLIST-TYPE:EVENT` — the window grows from the
22
21
  * start). Read from the timeline-bearing track's playlist metadata.
23
22
  */
24
23
  function deriveTargetLiveWindow(presentation, trackId) {
@@ -31,51 +30,45 @@ function deriveTargetLiveWindow(presentation, trackId) {
31
30
  return deriveStreamType(metadata) === "live" ? 0 : NaN;
32
31
  }
33
32
  /**
34
- * Which reported conditions this composition treats as **fatal** — the ones that
35
- * reach `error` and fire `'error'`. Severity isn't part of an SVTA code
36
- * (§Approach: "impact varies with player implementation"), and here it also
37
- * varies by composition, so it's decided at this boundary rather than by the
38
- * reporter.
33
+ * Which reported conditions this composition treats as **fatal** — the ones that reach `error` and fire `'error'`.
34
+ * Severity isn't part of an SVTA code (§Approach: "impact varies with player implementation"), and here it also varies
35
+ * by composition, so it's decided at this boundary rather than by the reporter.
39
36
  *
40
- * An allow-list, deliberately: only *verdicts* are here. The per-rendition causes
41
- * `resolve-track` reports (unsupported format, unsupported DRM) stay in the
42
- * sequence as context — one unplayable rendition doesn't fail the source, and
37
+ * An allow-list, deliberately: only _verdicts_ are here. The per-rendition causes `resolve-track` reports (unsupported
38
+ * format, unsupported DRM) stay in the sequence as context — one unplayable rendition doesn't fail the source, and
43
39
  * promoting a cause would put a dialog over a mixed source that goes on to play.
44
40
  */
45
41
  const FATAL_SVTA_CODES = /* @__PURE__ */ new Set([SVTA_NO_SUPPORTED_VIDEO_TRACK, SVTA_NO_SUPPORTED_AUDIO_TRACK]);
46
42
  /**
47
43
  * Mixin that adds SPF playback engine behavior to any base class.
48
44
  *
49
- * Implements the src/play() contract per the WHATWG HTML spec so that SPF can
50
- * be used anywhere a media element API is expected.
45
+ * Implements the src/play() contract per the WHATWG HTML spec so that SPF can be used anywhere a media element API is
46
+ * expected.
51
47
  *
52
- * A single engine instance is created at construction and recycled across src
53
- * changes.
48
+ * A single engine instance is created at construction and recycled across src changes.
49
+ *
50
+ * @example
51
+ * class HlsVideoMedia extends HlsVideoMediaMixin(HTMLVideoElementHost) {}
52
+ *
53
+ * const media = new HlsVideoMedia();
54
+ * media.attach(document.querySelector('video'));
55
+ * media.src = 'https://stream.mux.com/abc123.m3u8';
54
56
  *
55
57
  * @fires streamtypechange - Fired when the detected stream type changes. Read `streamType` for the new value.
56
58
  * @fires targetlivewindowchange - Fired when the target live window changes. Read `targetLiveWindow` for the new value.
57
59
  * @fires error - Fired when a fatal condition is reported. Read `error` for it.
58
- *
59
- * @example
60
- * class HlsVideoMedia extends HlsVideoMediaMixin(HTMLVideoElementHost) {}
61
- *
62
- * const media = new HlsVideoMedia();
63
- * media.attach(document.querySelector('video'));
64
- * media.src = 'https://stream.mux.com/abc123.m3u8';
65
60
  */
66
61
  function HlsVideoMediaMixin(BaseClass) {
67
62
  class HlsVideoMediaImpl extends BaseClass {
68
63
  /**
69
- * A complete sentence naming the Media to reach for when this one can't play
70
- * a source `Try the hls.js-backed Mux media instead: import the hls-js
71
- * flavor in place of the spf one.` Appended to the copy this adapter
72
- * surfaces, and to the notices it logs. Name the flavor, not an import path:
73
- * a Media is reached through several packages, each with its own counterpart.
64
+ * A complete sentence naming the Media to reach for when this one can't play a source — `Try the hls.js-backed Mux
65
+ * media instead: import the hls-js flavor in place of the spf one.` Appended to the copy this adapter surfaces, and
66
+ * to the notices it logs. Name the flavor, not an import path: a Media is reached through several packages, each
67
+ * with its own counterpart.
74
68
  *
75
- * Empty here: `hls-video` has no better-equipped sibling to point at.
76
- * A Media that does (a Mux Video built on this engine, whose hls.js-backed
77
- * counterpart plays MPEG-TS and DRM) overrides this static, and its copy gains
78
- * the second sentence with no other change.
69
+ * Empty here: `hls-video` has no better-equipped sibling to point at. A Media that does (a Mux Video built on this
70
+ * engine, whose hls.js-backed counterpart plays MPEG-TS and DRM) overrides this static, and its copy gains the
71
+ * second sentence with no other change.
79
72
  */
80
73
  static get alternativeMediaSuggestion() {}
81
74
  #engine;
@@ -88,9 +81,8 @@ function HlsVideoMediaMixin(BaseClass) {
88
81
  #targetLiveWindow = NaN;
89
82
  #error = null;
90
83
  /**
91
- * The *reported* condition currently surfaced, which is what the re-fire
92
- * latch keys on. Not `#error.code`: that's the code this adapter chose to
93
- * surface, and a later cause can change the choice for a condition already
84
+ * The _reported_ condition currently surfaced, which is what the re-fire latch keys on. Not `#error.code`: that's
85
+ * the code this adapter chose to surface, and a later cause can change the choice for a condition already
94
86
  * announced.
95
87
  */
96
88
  #reportedCode = null;
@@ -117,27 +109,23 @@ function HlsVideoMediaMixin(BaseClass) {
117
109
  });
118
110
  }
119
111
  /**
120
- * Underlying playback engine — the low-level SPF reactive composition that
121
- * drives playback. An advanced escape hatch for direct engine access;
122
- * normal playback is driven through this element's own properties and
123
- * methods.
112
+ * Underlying playback engine — the low-level SPF reactive composition that drives playback. An advanced escape
113
+ * hatch for direct engine access; normal playback is driven through this element's own properties and methods.
124
114
  */
125
115
  get engine() {
126
116
  return this.#engine;
127
117
  }
128
118
  /**
129
- * The current fatal error, or `null`. Only *fatal* conditions appear here —
130
- * the engine reports non-fatal ones too (they stay in `engine.state.errors`),
131
- * and promoting them would tell a consumer playback had failed when it
119
+ * The current fatal error, or `null`. Only _fatal_ conditions appear here — the engine reports non-fatal ones too
120
+ * (they stay in `engine.state.errors`), and promoting them would tell a consumer playback had failed when it
132
121
  * hadn't. Resets per source. Fires `'error'` when set.
133
122
  */
134
123
  get error() {
135
124
  return this.#error;
136
125
  }
137
126
  /**
138
- * The source's stream type — `'live'`, `'on-demand'`, or `'unknown'` until
139
- * a media playlist has been parsed. Setting a non-`'unknown'` value pins a
140
- * user override (detection stops updating it); setting `'unknown'` reverts
127
+ * The source's stream type — `'live'`, `'on-demand'`, or `'unknown'` until a media playlist has been parsed.
128
+ * Setting a non-`'unknown'` value pins a user override (detection stops updating it); setting `'unknown'` reverts
141
129
  * to the engine's detected value.
142
130
  */
143
131
  get streamType() {
@@ -153,12 +141,10 @@ function HlsVideoMediaMixin(BaseClass) {
153
141
  this.#updateStreamType(value);
154
142
  }
155
143
  /**
156
- * Presentation time marking the start of the live-edge window — playback at
157
- * `currentTime >= liveEdgeStart` counts as "at the live edge" (the same
158
- * target the engine's `seekToLiveEdge` seeks to: window end − HOLD-BACK).
159
- * `NaN` when the stream isn't live or nothing is resolved yet. Derived at
160
- * read time from the engine's live window — no change event; re-read on
161
- * `timeupdate`/`progress` (as the store's live feature does).
144
+ * Presentation time marking the start of the live-edge window — playback at `currentTime >= liveEdgeStart` counts
145
+ * as "at the live edge" (the same target the engine's `seekToLiveEdge` seeks to: window end − HOLD-BACK). `NaN`
146
+ * when the stream isn't live or nothing is resolved yet. Derived at read time from the engine's live window no
147
+ * change event; re-read on `timeupdate`/`progress` (as the store's live feature does).
162
148
  */
163
149
  get liveEdgeStart() {
164
150
  return getLiveEdge({
@@ -167,9 +153,8 @@ function HlsVideoMediaMixin(BaseClass) {
167
153
  })?.liveEdgeStart ?? NaN;
168
154
  }
169
155
  /**
170
- * The target live window: `NaN` for on-demand (or unknown), `0` for
171
- * standard sliding-window live, `Infinity` for DVR
172
- * (`#EXT-X-PLAYLIST-TYPE:EVENT`). Fires `targetlivewindowchange` on change.
156
+ * The target live window: `NaN` for on-demand (or unknown), `0` for standard sliding-window live, `Infinity` for
157
+ * DVR (`#EXT-X-PLAYLIST-TYPE:EVENT`). Fires `targetlivewindowchange` on change.
173
158
  */
174
159
  get targetLiveWindow() {
175
160
  return this.#targetLiveWindow;
@@ -264,14 +249,12 @@ function HlsVideoMediaMixin(BaseClass) {
264
249
  return withAlternativeMediaSuggestion(message, this);
265
250
  }
266
251
  /**
267
- * Log what this engine is delivering differently from what the playlist asked
268
- * for. Neither condition stops playback, so neither is an error — they go to
269
- * the console rather than the error surface.
252
+ * Log what this engine is delivering differently from what the playlist asked for. Neither condition stops
253
+ * playback, so neither is an error — they go to the console rather than the error surface.
270
254
  *
271
- * Once per source, not per parse: a live playlist reloads every target
272
- * duration, and the timeline track re-parses on each one. Keyed on the notice
273
- * rather than latched with a boolean so the two are independent, and cleared
274
- * when the presentation unresolves so the next source starts quiet.
255
+ * Once per source, not per parse: a live playlist reloads every target duration, and the timeline track re-parses
256
+ * on each one. Keyed on the notice rather than latched with a boolean so the two are independent, and cleared when
257
+ * the presentation unresolves so the next source starts quiet.
275
258
  */
276
259
  #reportDeliveryNotices(presentation) {
277
260
  if (!isResolvedPresentation(presentation)) {
@@ -1 +1 @@
1
- {"version":3,"file":"adapter.js","names":["#engine","#config","#createEngine","#stopLiveSync","#signals","#setDetectedStreamType","#setTargetLiveWindow","#reportDeliveryNotices","#stopErrorSync","#setError","#error","#streamType","#isUserStreamType","#updateStreamType","#targetLiveWindow","#reportedCode","#withSuggestion","#cancelPendingPlay","#preload","#disableRemotePlayback","#loadstartListener","#noticed"],"sources":["../../../../../src/playback/adapters/hls-video/adapter.ts"],"sourcesContent":["import { type MediaStreamType, MediaStreamTypes } from '@videojs/media';\nimport type { Constructor, MixinReturn } from '@videojs/utils/types';\nimport type { Composition } from '../../../core/composition/create-composition';\nimport { effect } from '../../../core/signals/effect';\nimport {\n SVTA_NO_SUPPORTED_AUDIO_TRACK,\n SVTA_NO_SUPPORTED_VIDEO_TRACK,\n SVTA_UNSUPPORTED_PLAYBACK_FEATURE,\n type SvtaError,\n} from '../../../media/errors';\nimport { resolveLiveLatency } from '../../../media/hls/reload-policy';\nimport {\n deriveStreamType,\n getMediaPlaylistMetadata,\n isResolvedPresentation,\n isResolvedTrack,\n type MaybeResolvedPresentation,\n} from '../../../media/types';\nimport { findTrackById } from '../../../media/utils/tracks';\nimport {\n createHlsVideoEngine,\n type HlsVideoEngineConfig,\n type HlsVideoEngineContext,\n type HlsVideoEngineSignals,\n type HlsVideoEngineState,\n} from '../../engines/hls/engine';\nimport {\n DVR_EXPERIMENTAL_MESSAGE,\n LOW_LATENCY_UNSUPPORTED_MESSAGE,\n UNSUPPORTED_PLAYBACK_FEATURE_MESSAGE,\n} from '../../primitives/error-messages';\nimport { getLiveEdge, type LiveWindowState, liveTrackId } from '../../primitives/live-window';\nimport {\n firstFatal,\n type HlsVideoMediaError,\n hasUnsupportedFeatureCause,\n withAlternativeMediaSuggestion,\n} from './error-surface';\n\n/**\n * The media-level stream type: the engine's detected stream type (`'live'` /\n * `'on-demand'`) plus `'unknown'` for \"no playlist parsed yet.\" `@videojs/media`'s\n * {@link MediaStreamType} itself, kept under its own name because that is what\n * this adapter's `streamType` property is documented against.\n */\nexport type HlsVideoMediaStreamType = MediaStreamType;\n\nexport type { HlsVideoMediaError } from './error-surface';\n\nexport interface HlsVideoMediaProps {\n src: string;\n preload: '' | 'none' | 'metadata' | 'auto';\n disableRemotePlayback: boolean;\n streamType: HlsVideoMediaStreamType;\n}\n\nexport const hlsVideoMediaDefaultProps: HlsVideoMediaProps = {\n src: '',\n preload: '',\n disableRemotePlayback: false,\n streamType: MediaStreamTypes.UNKNOWN,\n};\n\nexport interface HlsVideoMediaAPI extends HlsVideoMediaProps {\n readonly engine: Composition<HlsVideoEngineState, HlsVideoEngineContext>;\n readonly error: HlsVideoMediaError | null;\n readonly liveEdgeStart: number;\n readonly targetLiveWindow: number;\n attach(mediaElement: HTMLMediaElement): void;\n detach(): void;\n destroy(): void;\n play(): Promise<void>;\n}\n\n/**\n * `targetLiveWindow` per the media-ui-extensions live-edge proposal: `NaN` for\n * on-demand (or nothing resolved yet), `0` for standard sliding-window live,\n * `Infinity` for DVR (`#EXT-X-PLAYLIST-TYPE:EVENT` — the window grows from the\n * start). Read from the timeline-bearing track's playlist metadata.\n */\nfunction deriveTargetLiveWindow(\n presentation: MaybeResolvedPresentation | undefined,\n trackId: string | undefined\n): number {\n if (!isResolvedPresentation(presentation) || !trackId) return Number.NaN;\n const track = findTrackById(presentation, trackId);\n if (!track || !isResolvedTrack(track)) return Number.NaN;\n const metadata = getMediaPlaylistMetadata(track);\n if (!metadata) return Number.NaN;\n if (metadata.playlistType === 'EVENT') return Number.POSITIVE_INFINITY;\n return deriveStreamType(metadata) === 'live' ? 0 : Number.NaN;\n}\n\n// ============================================================================\n// Error surface\n// ============================================================================\n\n/**\n * Which reported conditions this composition treats as **fatal** — the ones that\n * reach `error` and fire `'error'`. Severity isn't part of an SVTA code\n * (§Approach: \"impact varies with player implementation\"), and here it also\n * varies by composition, so it's decided at this boundary rather than by the\n * reporter.\n *\n * An allow-list, deliberately: only *verdicts* are here. The per-rendition causes\n * `resolve-track` reports (unsupported format, unsupported DRM) stay in the\n * sequence as context — one unplayable rendition doesn't fail the source, and\n * promoting a cause would put a dialog over a mixed source that goes on to play.\n */\nconst FATAL_SVTA_CODES: ReadonlySet<number> = new Set<number>([\n SVTA_NO_SUPPORTED_VIDEO_TRACK,\n SVTA_NO_SUPPORTED_AUDIO_TRACK,\n]);\n\n/**\n * Mixin that adds SPF playback engine behavior to any base class.\n *\n * Implements the src/play() contract per the WHATWG HTML spec so that SPF can\n * be used anywhere a media element API is expected.\n *\n * A single engine instance is created at construction and recycled across src\n * changes.\n *\n * @fires streamtypechange - Fired when the detected stream type changes. Read `streamType` for the new value.\n * @fires targetlivewindowchange - Fired when the target live window changes. Read `targetLiveWindow` for the new value.\n * @fires error - Fired when a fatal condition is reported. Read `error` for it.\n *\n * @example\n * class HlsVideoMedia extends HlsVideoMediaMixin(HTMLVideoElementHost) {}\n *\n * const media = new HlsVideoMedia();\n * media.attach(document.querySelector('video'));\n * media.src = 'https://stream.mux.com/abc123.m3u8';\n */\nexport function HlsVideoMediaMixin<Base extends Constructor<any>>(BaseClass: Base) {\n class HlsVideoMediaImpl extends BaseClass {\n /**\n * A complete sentence naming the Media to reach for when this one can't play\n * a source — `Try the hls.js-backed Mux media instead: import the hls-js\n * flavor in place of the spf one.` Appended to the copy this adapter\n * surfaces, and to the notices it logs. Name the flavor, not an import path:\n * a Media is reached through several packages, each with its own counterpart.\n *\n * Empty here: `hls-video` has no better-equipped sibling to point at.\n * A Media that does (a Mux Video built on this engine, whose hls.js-backed\n * counterpart plays MPEG-TS and DRM) overrides this static, and its copy gains\n * the second sentence with no other change.\n */\n static get alternativeMediaSuggestion(): string | undefined {\n return undefined;\n }\n\n readonly #engine: Composition<HlsVideoEngineState, HlsVideoEngineContext>;\n #config: HlsVideoEngineConfig;\n #signals!: HlsVideoEngineSignals;\n #preload: '' | 'none' | 'metadata' | 'auto' = hlsVideoMediaDefaultProps.preload;\n #disableRemotePlayback: boolean = hlsVideoMediaDefaultProps.disableRemotePlayback;\n #streamType: HlsVideoMediaStreamType = hlsVideoMediaDefaultProps.streamType;\n #isUserStreamType = false;\n #targetLiveWindow = Number.NaN;\n #error: HlsVideoMediaError | null = null;\n /**\n * The *reported* condition currently surfaced, which is what the re-fire\n * latch keys on. Not `#error.code`: that's the code this adapter chose to\n * surface, and a later cause can change the choice for a condition already\n * announced.\n */\n #reportedCode: number | null = null;\n /** Notices already logged for the current source; cleared when it unloads. */\n #noticed = new Set<string>();\n #stopLiveSync: () => void;\n #stopErrorSync: () => void;\n\n /** Pending loadstart listener from a deferred play() retry, if any. */\n #loadstartListener: (() => void) | null = null;\n\n constructor(...args: any[]) {\n super(...args);\n\n const { config } = args?.[0] ?? {};\n this.#config = config;\n this.#engine = this.#createEngine();\n\n // Mirror the engine's live/stream-type detection onto the media surface,\n // firing the change events the store features listen for. One effect over\n // the presentation + selection signals; `liveEdgeStart` is deliberately\n // NOT cached here — it's derived at read time (the store re-reads it on\n // `timeupdate`/`progress`), so a sliding window needs no event churn.\n this.#stopLiveSync = effect(() => {\n const presentation = this.#signals.state.presentation.get();\n this.#setDetectedStreamType(presentation?.streamType ?? MediaStreamTypes.UNKNOWN);\n this.#setTargetLiveWindow(deriveTargetLiveWindow(presentation, liveTrackId(this.#signals.state)));\n this.#reportDeliveryNotices(presentation);\n });\n\n // Promote the first fatal condition out of the engine's reported sequence\n // onto the media surface. Clearing rides the same signal: `collectErrors`\n // resets the slot per source, so a new source starts with no error without\n // this needing its own source-change hook.\n this.#stopErrorSync = effect(() => {\n const errors = this.#signals.state.errors.get();\n this.#setError(firstFatal(errors, FATAL_SVTA_CODES), errors);\n });\n }\n\n /**\n * Underlying playback engine — the low-level SPF reactive composition that\n * drives playback. An advanced escape hatch for direct engine access;\n * normal playback is driven through this element's own properties and\n * methods.\n */\n get engine(): Composition<HlsVideoEngineState, HlsVideoEngineContext> {\n return this.#engine;\n }\n\n // -------------------------------------------------------------------------\n // Live surface — streamType / targetLiveWindow / liveEdgeStart\n // (the MediaStreamTypeCapability + MediaLiveCapability contract the player\n // store's stream-type and live features consume)\n // -------------------------------------------------------------------------\n\n /**\n * The current fatal error, or `null`. Only *fatal* conditions appear here —\n * the engine reports non-fatal ones too (they stay in `engine.state.errors`),\n * and promoting them would tell a consumer playback had failed when it\n * hadn't. Resets per source. Fires `'error'` when set.\n */\n get error(): HlsVideoMediaError | null {\n return this.#error;\n }\n\n /**\n * The source's stream type — `'live'`, `'on-demand'`, or `'unknown'` until\n * a media playlist has been parsed. Setting a non-`'unknown'` value pins a\n * user override (detection stops updating it); setting `'unknown'` reverts\n * to the engine's detected value.\n */\n get streamType(): HlsVideoMediaStreamType {\n return this.#streamType;\n }\n\n set streamType(value: HlsVideoMediaStreamType) {\n if (value === MediaStreamTypes.UNKNOWN) {\n this.#isUserStreamType = false;\n this.#updateStreamType(this.#signals.state.presentation.get()?.streamType ?? MediaStreamTypes.UNKNOWN);\n return;\n }\n this.#isUserStreamType = true;\n this.#updateStreamType(value);\n }\n\n /**\n * Presentation time marking the start of the live-edge window — playback at\n * `currentTime >= liveEdgeStart` counts as \"at the live edge\" (the same\n * target the engine's `seekToLiveEdge` seeks to: window end − HOLD-BACK).\n * `NaN` when the stream isn't live or nothing is resolved yet. Derived at\n * read time from the engine's live window — no change event; re-read on\n * `timeupdate`/`progress` (as the store's live feature does).\n */\n get liveEdgeStart(): number {\n const edge = getLiveEdge({\n state: this.#signals.state as LiveWindowState,\n config: { resolveLiveLatency },\n });\n return edge?.liveEdgeStart ?? Number.NaN;\n }\n\n /**\n * The target live window: `NaN` for on-demand (or unknown), `0` for\n * standard sliding-window live, `Infinity` for DVR\n * (`#EXT-X-PLAYLIST-TYPE:EVENT`). Fires `targetlivewindowchange` on change.\n */\n get targetLiveWindow(): number {\n return this.#targetLiveWindow;\n }\n\n #setDetectedStreamType(value: HlsVideoMediaStreamType): void {\n if (this.#isUserStreamType) return;\n this.#updateStreamType(value);\n }\n\n #updateStreamType(value: HlsVideoMediaStreamType): void {\n if (this.#streamType === value) return;\n this.#streamType = value;\n // Optional-chained: with an EventTarget-less base (`HlsVideoMediaElement`\n // standalone) there's nowhere to dispatch; hosts forward it to listeners.\n this.dispatchEvent?.(new Event('streamtypechange'));\n }\n\n #setTargetLiveWindow(value: number): void {\n if (Object.is(this.#targetLiveWindow, value)) return;\n this.#targetLiveWindow = value;\n this.dispatchEvent?.(new Event('targetlivewindowchange'));\n }\n\n #setError(reported: SvtaError | undefined, errors: readonly SvtaError[] | undefined): void {\n if (!reported) {\n // Cleared (new source). No event: `'error'` announces a failure, and\n // consumers reset their own copy on source change.\n this.#error = null;\n this.#reportedCode = null;\n return;\n }\n // Keyed on the code, not the object: a later append re-runs this effect\n // with an equal-but-new array, and re-firing `'error'` for a condition\n // already surfaced would look like a second failure.\n if (this.#reportedCode === reported.code) return;\n this.#reportedCode = reported.code;\n\n // A verdict says a type emptied; the causes say whether anything could\n // have played it. When they include something this engine simply doesn't\n // implement, that's the more useful thing to tell a consumer, so it\n // replaces the verdict's code on the surface.\n const unsupported = hasUnsupportedFeatureCause(errors);\n if (unsupported) {\n // The only place this engine explains itself in prose, and it's a\n // console: the viewer-facing sentence is the consumer's to localize from\n // the code. Conditions ride along structured so the specifics stay\n // inspectable.\n console.error(this.#withSuggestion(UNSUPPORTED_PLAYBACK_FEATURE_MESSAGE), { conditions: errors });\n }\n\n this.#error = {\n code: unsupported ? SVTA_UNSUPPORTED_PLAYBACK_FEATURE : reported.code,\n message: reported.message ?? '',\n ...(reported.data === undefined ? {} : { data: reported.data }),\n };\n this.dispatchEvent?.(new Event('error'));\n }\n\n // -------------------------------------------------------------------------\n // Media element lifecycle\n // -------------------------------------------------------------------------\n\n attach(mediaElement: HTMLMediaElement): void {\n super.attach?.(mediaElement);\n this.#signals.context.mediaElement.set(mediaElement);\n }\n\n detach(): void {\n this.#cancelPendingPlay();\n this.#signals.context.mediaElement.set(undefined);\n super.detach?.();\n }\n\n destroy(): void {\n this.#cancelPendingPlay();\n this.#stopLiveSync();\n this.#stopErrorSync();\n this.#engine.destroy();\n }\n\n // -------------------------------------------------------------------------\n // preload — synchronous IDL attribute (WHATWG §4.8.11.2)\n // -------------------------------------------------------------------------\n\n /** Preload type (`'none'` / `'metadata'` / `'auto'`). */\n get preload(): '' | 'none' | 'metadata' | 'auto' {\n return this.#preload;\n }\n\n set preload(value: '' | 'none' | 'metadata' | 'auto') {\n this.#preload = value;\n if (value) {\n this.#signals.state.preload.set(value);\n }\n // value = '' resets the IDL mirror (so `get preload` reflects '') but does\n // not patch state — the engine keeps its current preload until an explicit\n // W3C value replaces it.\n }\n\n // -------------------------------------------------------------------------\n // disableRemotePlayback — synchronous IDL attribute (WHATWG Remote Playback)\n // Author intent for whether the AirPlay/remote picker is offered. Mirrors\n // the DOM attribute name; the value flows to `state.disableRemotePlayback`,\n // which `setupAirPlay` reads to honor an explicit opt-out. The underlying\n // <video>'s own `disableRemotePlayback` stays programmatically managed\n // (ManagedMediaSource needs it `true` to open; AirPlay flips it `false` once\n // the source is open), so author intent and the effective flag stay distinct.\n // -------------------------------------------------------------------------\n\n get disableRemotePlayback(): boolean {\n return this.#disableRemotePlayback;\n }\n\n set disableRemotePlayback(value: boolean) {\n this.#disableRemotePlayback = value;\n this.#signals.state.disableRemotePlayback.set(value);\n }\n\n // -------------------------------------------------------------------------\n // src — synchronous IDL attribute (WHATWG §4.8.11.2)\n // Each assignment overwrites the engine's presentation state in place. The\n // resolver FSM routes back through teardown → rebuild on the same engine,\n // mirroring how the browser's load algorithm resets media state on src change\n // — without recreating the engine or re-capturing its signals. Setting an\n // empty src un-resolves the presentation, tearing the current source down to\n // the engine's fresh-but-attached \"no source\" state.\n // -------------------------------------------------------------------------\n\n get src(): string {\n return this.#signals.state.presentation.get()?.url ?? '';\n }\n\n set src(value: string) {\n // Assigning the URL already playing is not a request to reload it. The\n // presentation is set from a fresh object every time, so re-resolving an\n // unchanged URL restarts playback — which is what a caller changing only\n // the parts of a structured source that describe images, rather than the\n // stream, would get. The hls.js Media draws the same line: it announces\n // every source change and loads only when the URL or engine config moves.\n if (value === this.src) return;\n\n this.#cancelPendingPlay();\n this.#signals.state.presentation.set(value ? { url: value } : undefined);\n }\n\n // -------------------------------------------------------------------------\n // play() — WHATWG §4.8.11.8\n // Delegates to the attached media element's native play().\n // -------------------------------------------------------------------------\n\n play(): Promise<void> {\n const mediaElement = this.#signals.context.mediaElement.get();\n if (!mediaElement) {\n return Promise.reject(new Error('HlsVideoMediaElement: no media element attached'));\n }\n\n // Signal play intent — enables loading even with preload=\"none\"\n this.#signals.state.loadActivated.set(true);\n\n return mediaElement.play().catch((err: unknown) => {\n // If we have a pending HLS source, the rejection may be because MSE\n // hasn't attached a blob URL yet. Wait for loadstart (src assigned\n // by MSE setup) and retry once.\n if (this.src) {\n return new Promise<void>((resolve, reject) => {\n const listener = () => {\n this.#loadstartListener = null;\n mediaElement.play().then(resolve, reject);\n };\n this.#loadstartListener = listener;\n mediaElement.addEventListener('loadstart', listener, { once: true });\n });\n }\n throw err;\n });\n }\n\n // -------------------------------------------------------------------------\n // Private\n // -------------------------------------------------------------------------\n\n /** `message`, plus the alternative-Media sentence when this class names one. */\n #withSuggestion(message: string): string {\n return withAlternativeMediaSuggestion(message, this);\n }\n\n /**\n * Log what this engine is delivering differently from what the playlist asked\n * for. Neither condition stops playback, so neither is an error — they go to\n * the console rather than the error surface.\n *\n * Once per source, not per parse: a live playlist reloads every target\n * duration, and the timeline track re-parses on each one. Keyed on the notice\n * rather than latched with a boolean so the two are independent, and cleared\n * when the presentation unresolves so the next source starts quiet.\n */\n #reportDeliveryNotices(presentation: MaybeResolvedPresentation | undefined): void {\n if (!isResolvedPresentation(presentation)) {\n this.#noticed.clear();\n return;\n }\n\n const trackId = liveTrackId(this.#signals.state);\n const track = trackId ? findTrackById(presentation, trackId) : undefined;\n if (!track || !isResolvedTrack(track)) return;\n const metadata = getMediaPlaylistMetadata(track);\n if (!metadata) return;\n\n if (metadata.lowLatency && !this.#noticed.has('lowLatency')) {\n this.#noticed.add('lowLatency');\n console.warn(this.#withSuggestion(LOW_LATENCY_UNSUPPORTED_MESSAGE));\n }\n if (metadata.playlistType === 'EVENT' && !this.#noticed.has('dvr')) {\n this.#noticed.add('dvr');\n console.warn(this.#withSuggestion(DVR_EXPERIMENTAL_MESSAGE));\n }\n }\n\n #createEngine(): Composition<HlsVideoEngineState, HlsVideoEngineContext> {\n return createHlsVideoEngine({\n ...this.#config,\n onSignalsReady: (signals) => {\n this.#signals = signals;\n },\n });\n }\n\n #cancelPendingPlay(): void {\n if (!this.#loadstartListener) return;\n const mediaElement = this.#signals.context.mediaElement.get();\n mediaElement?.removeEventListener('loadstart', this.#loadstartListener);\n this.#loadstartListener = null;\n }\n }\n\n // `MixinReturn` sources statics from `Base`, so the adapter's own static needs\n // adding back to the type or callers can't read it.\n return HlsVideoMediaImpl as unknown as MixinReturn<Base, HlsVideoMediaAPI> & {\n readonly alternativeMediaSuggestion: string | undefined;\n };\n}\n\n/** Standalone SPF media adapter with no base class. */\nexport class HlsVideoMediaElement extends HlsVideoMediaMixin(class {}) {}\n"],"mappings":"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"}
1
+ {"version":3,"file":"adapter.js","names":["#engine","#config","#createEngine","#stopLiveSync","#signals","#setDetectedStreamType","#setTargetLiveWindow","#reportDeliveryNotices","#stopErrorSync","#setError","#error","#streamType","#isUserStreamType","#updateStreamType","#targetLiveWindow","#reportedCode","#withSuggestion","#cancelPendingPlay","#preload","#disableRemotePlayback","#loadstartListener","#noticed"],"sources":["../../../../../src/playback/adapters/hls-video/adapter.ts"],"sourcesContent":["import { type MediaStreamType, MediaStreamTypes } from '@videojs/media';\nimport type { Constructor, MixinReturn } from '@videojs/utils/types';\n\nimport type { Composition } from '../../../core/composition/create-composition';\nimport { effect } from '../../../core/signals/effect';\nimport {\n SVTA_NO_SUPPORTED_AUDIO_TRACK,\n SVTA_NO_SUPPORTED_VIDEO_TRACK,\n SVTA_UNSUPPORTED_PLAYBACK_FEATURE,\n type SvtaError,\n} from '../../../media/errors';\nimport { resolveLiveLatency } from '../../../media/hls/reload-policy';\nimport {\n deriveStreamType,\n getMediaPlaylistMetadata,\n isResolvedPresentation,\n isResolvedTrack,\n type MaybeResolvedPresentation,\n} from '../../../media/types';\nimport { findTrackById } from '../../../media/utils/tracks';\nimport {\n createHlsVideoEngine,\n type HlsVideoEngineConfig,\n type HlsVideoEngineContext,\n type HlsVideoEngineSignals,\n type HlsVideoEngineState,\n} from '../../engines/hls/engine';\nimport {\n DVR_EXPERIMENTAL_MESSAGE,\n LOW_LATENCY_UNSUPPORTED_MESSAGE,\n UNSUPPORTED_PLAYBACK_FEATURE_MESSAGE,\n} from '../../primitives/error-messages';\nimport { getLiveEdge, type LiveWindowState, liveTrackId } from '../../primitives/live-window';\nimport {\n firstFatal,\n type HlsVideoMediaError,\n hasUnsupportedFeatureCause,\n withAlternativeMediaSuggestion,\n} from './error-surface';\n\n/**\n * The media-level stream type: the engine's detected stream type (`'live'` / `'on-demand'`) plus `'unknown'` for \"no\n * playlist parsed yet.\" `@videojs/media`'s {@link MediaStreamType} itself, kept under its own name because that is what\n * this adapter's `streamType` property is documented against.\n */\nexport type HlsVideoMediaStreamType = MediaStreamType;\n\nexport type { HlsVideoMediaError } from './error-surface';\n\nexport interface HlsVideoMediaProps {\n src: string;\n preload: '' | 'none' | 'metadata' | 'auto';\n disableRemotePlayback: boolean;\n streamType: HlsVideoMediaStreamType;\n}\n\nexport const hlsVideoMediaDefaultProps: HlsVideoMediaProps = {\n src: '',\n preload: '',\n disableRemotePlayback: false,\n streamType: MediaStreamTypes.UNKNOWN,\n};\n\nexport interface HlsVideoMediaAPI extends HlsVideoMediaProps {\n readonly engine: Composition<HlsVideoEngineState, HlsVideoEngineContext>;\n readonly error: HlsVideoMediaError | null;\n readonly liveEdgeStart: number;\n readonly targetLiveWindow: number;\n attach(mediaElement: HTMLMediaElement): void;\n detach(): void;\n destroy(): void;\n play(): Promise<void>;\n}\n\n/**\n * `targetLiveWindow` per the media-ui-extensions live-edge proposal: `NaN` for on-demand (or nothing resolved yet), `0`\n * for standard sliding-window live, `Infinity` for DVR (`#EXT-X-PLAYLIST-TYPE:EVENT` — the window grows from the\n * start). Read from the timeline-bearing track's playlist metadata.\n */\nfunction deriveTargetLiveWindow(\n presentation: MaybeResolvedPresentation | undefined,\n trackId: string | undefined\n): number {\n if (!isResolvedPresentation(presentation) || !trackId) return Number.NaN;\n\n const track = findTrackById(presentation, trackId);\n if (!track || !isResolvedTrack(track)) return Number.NaN;\n\n const metadata = getMediaPlaylistMetadata(track);\n if (!metadata) return Number.NaN;\n\n if (metadata.playlistType === 'EVENT') return Number.POSITIVE_INFINITY;\n\n return deriveStreamType(metadata) === 'live' ? 0 : Number.NaN;\n}\n\n// ============================================================================\n// Error surface\n// ============================================================================\n\n/**\n * Which reported conditions this composition treats as **fatal** — the ones that reach `error` and fire `'error'`.\n * Severity isn't part of an SVTA code (§Approach: \"impact varies with player implementation\"), and here it also varies\n * by composition, so it's decided at this boundary rather than by the reporter.\n *\n * An allow-list, deliberately: only _verdicts_ are here. The per-rendition causes `resolve-track` reports (unsupported\n * format, unsupported DRM) stay in the sequence as context — one unplayable rendition doesn't fail the source, and\n * promoting a cause would put a dialog over a mixed source that goes on to play.\n */\nconst FATAL_SVTA_CODES: ReadonlySet<number> = new Set<number>([\n SVTA_NO_SUPPORTED_VIDEO_TRACK,\n SVTA_NO_SUPPORTED_AUDIO_TRACK,\n]);\n\n/**\n * Mixin that adds SPF playback engine behavior to any base class.\n *\n * Implements the src/play() contract per the WHATWG HTML spec so that SPF can be used anywhere a media element API is\n * expected.\n *\n * A single engine instance is created at construction and recycled across src changes.\n *\n * @example\n * class HlsVideoMedia extends HlsVideoMediaMixin(HTMLVideoElementHost) {}\n *\n * const media = new HlsVideoMedia();\n * media.attach(document.querySelector('video'));\n * media.src = 'https://stream.mux.com/abc123.m3u8';\n *\n * @fires streamtypechange - Fired when the detected stream type changes. Read `streamType` for the new value.\n * @fires targetlivewindowchange - Fired when the target live window changes. Read `targetLiveWindow` for the new value.\n * @fires error - Fired when a fatal condition is reported. Read `error` for it.\n */\nexport function HlsVideoMediaMixin<Base extends Constructor<any>>(BaseClass: Base) {\n class HlsVideoMediaImpl extends BaseClass {\n /**\n * A complete sentence naming the Media to reach for when this one can't play a source — `Try the hls.js-backed Mux\n * media instead: import the hls-js flavor in place of the spf one.` Appended to the copy this adapter surfaces, and\n * to the notices it logs. Name the flavor, not an import path: a Media is reached through several packages, each\n * with its own counterpart.\n *\n * Empty here: `hls-video` has no better-equipped sibling to point at. A Media that does (a Mux Video built on this\n * engine, whose hls.js-backed counterpart plays MPEG-TS and DRM) overrides this static, and its copy gains the\n * second sentence with no other change.\n */\n static get alternativeMediaSuggestion(): string | undefined {\n return undefined;\n }\n\n readonly #engine: Composition<HlsVideoEngineState, HlsVideoEngineContext>;\n #config: HlsVideoEngineConfig;\n #signals!: HlsVideoEngineSignals;\n #preload: '' | 'none' | 'metadata' | 'auto' = hlsVideoMediaDefaultProps.preload;\n #disableRemotePlayback: boolean = hlsVideoMediaDefaultProps.disableRemotePlayback;\n #streamType: HlsVideoMediaStreamType = hlsVideoMediaDefaultProps.streamType;\n #isUserStreamType = false;\n #targetLiveWindow = Number.NaN;\n #error: HlsVideoMediaError | null = null;\n /**\n * The _reported_ condition currently surfaced, which is what the re-fire latch keys on. Not `#error.code`: that's\n * the code this adapter chose to surface, and a later cause can change the choice for a condition already\n * announced.\n */\n #reportedCode: number | null = null;\n /** Notices already logged for the current source; cleared when it unloads. */\n #noticed = new Set<string>();\n #stopLiveSync: () => void;\n #stopErrorSync: () => void;\n\n /** Pending loadstart listener from a deferred play() retry, if any. */\n #loadstartListener: (() => void) | null = null;\n\n constructor(...args: any[]) {\n super(...args);\n\n const { config } = args?.[0] ?? {};\n\n this.#config = config;\n this.#engine = this.#createEngine();\n\n // Mirror the engine's live/stream-type detection onto the media surface,\n // firing the change events the store features listen for. One effect over\n // the presentation + selection signals; `liveEdgeStart` is deliberately\n // NOT cached here — it's derived at read time (the store re-reads it on\n // `timeupdate`/`progress`), so a sliding window needs no event churn.\n this.#stopLiveSync = effect(() => {\n const presentation = this.#signals.state.presentation.get();\n\n this.#setDetectedStreamType(presentation?.streamType ?? MediaStreamTypes.UNKNOWN);\n this.#setTargetLiveWindow(deriveTargetLiveWindow(presentation, liveTrackId(this.#signals.state)));\n this.#reportDeliveryNotices(presentation);\n });\n\n // Promote the first fatal condition out of the engine's reported sequence\n // onto the media surface. Clearing rides the same signal: `collectErrors`\n // resets the slot per source, so a new source starts with no error without\n // this needing its own source-change hook.\n this.#stopErrorSync = effect(() => {\n const errors = this.#signals.state.errors.get();\n\n this.#setError(firstFatal(errors, FATAL_SVTA_CODES), errors);\n });\n }\n\n /**\n * Underlying playback engine — the low-level SPF reactive composition that drives playback. An advanced escape\n * hatch for direct engine access; normal playback is driven through this element's own properties and methods.\n */\n get engine(): Composition<HlsVideoEngineState, HlsVideoEngineContext> {\n return this.#engine;\n }\n\n // -------------------------------------------------------------------------\n // Live surface — streamType / targetLiveWindow / liveEdgeStart\n // (the MediaStreamTypeCapability + MediaLiveCapability contract the player\n // store's stream-type and live features consume)\n // -------------------------------------------------------------------------\n\n /**\n * The current fatal error, or `null`. Only _fatal_ conditions appear here — the engine reports non-fatal ones too\n * (they stay in `engine.state.errors`), and promoting them would tell a consumer playback had failed when it\n * hadn't. Resets per source. Fires `'error'` when set.\n */\n get error(): HlsVideoMediaError | null {\n return this.#error;\n }\n\n /**\n * The source's stream type — `'live'`, `'on-demand'`, or `'unknown'` until a media playlist has been parsed.\n * Setting a non-`'unknown'` value pins a user override (detection stops updating it); setting `'unknown'` reverts\n * to the engine's detected value.\n */\n get streamType(): HlsVideoMediaStreamType {\n return this.#streamType;\n }\n\n set streamType(value: HlsVideoMediaStreamType) {\n if (value === MediaStreamTypes.UNKNOWN) {\n this.#isUserStreamType = false;\n this.#updateStreamType(this.#signals.state.presentation.get()?.streamType ?? MediaStreamTypes.UNKNOWN);\n return;\n }\n\n this.#isUserStreamType = true;\n this.#updateStreamType(value);\n }\n\n /**\n * Presentation time marking the start of the live-edge window — playback at `currentTime >= liveEdgeStart` counts\n * as \"at the live edge\" (the same target the engine's `seekToLiveEdge` seeks to: window end − HOLD-BACK). `NaN`\n * when the stream isn't live or nothing is resolved yet. Derived at read time from the engine's live window — no\n * change event; re-read on `timeupdate`/`progress` (as the store's live feature does).\n */\n get liveEdgeStart(): number {\n const edge = getLiveEdge({\n state: this.#signals.state as LiveWindowState,\n config: { resolveLiveLatency },\n });\n\n return edge?.liveEdgeStart ?? Number.NaN;\n }\n\n /**\n * The target live window: `NaN` for on-demand (or unknown), `0` for standard sliding-window live, `Infinity` for\n * DVR (`#EXT-X-PLAYLIST-TYPE:EVENT`). Fires `targetlivewindowchange` on change.\n */\n get targetLiveWindow(): number {\n return this.#targetLiveWindow;\n }\n\n #setDetectedStreamType(value: HlsVideoMediaStreamType): void {\n if (this.#isUserStreamType) return;\n\n this.#updateStreamType(value);\n }\n\n #updateStreamType(value: HlsVideoMediaStreamType): void {\n if (this.#streamType === value) return;\n\n this.#streamType = value;\n // Optional-chained: with an EventTarget-less base (`HlsVideoMediaElement`\n // standalone) there's nowhere to dispatch; hosts forward it to listeners.\n this.dispatchEvent?.(new Event('streamtypechange'));\n }\n\n #setTargetLiveWindow(value: number): void {\n if (Object.is(this.#targetLiveWindow, value)) return;\n\n this.#targetLiveWindow = value;\n this.dispatchEvent?.(new Event('targetlivewindowchange'));\n }\n\n #setError(reported: SvtaError | undefined, errors: readonly SvtaError[] | undefined): void {\n if (!reported) {\n // Cleared (new source). No event: `'error'` announces a failure, and\n // consumers reset their own copy on source change.\n this.#error = null;\n this.#reportedCode = null;\n return;\n }\n\n // Keyed on the code, not the object: a later append re-runs this effect\n // with an equal-but-new array, and re-firing `'error'` for a condition\n // already surfaced would look like a second failure.\n if (this.#reportedCode === reported.code) return;\n\n this.#reportedCode = reported.code;\n\n // A verdict says a type emptied; the causes say whether anything could\n // have played it. When they include something this engine simply doesn't\n // implement, that's the more useful thing to tell a consumer, so it\n // replaces the verdict's code on the surface.\n const unsupported = hasUnsupportedFeatureCause(errors);\n\n if (unsupported) {\n // The only place this engine explains itself in prose, and it's a\n // console: the viewer-facing sentence is the consumer's to localize from\n // the code. Conditions ride along structured so the specifics stay\n // inspectable.\n console.error(this.#withSuggestion(UNSUPPORTED_PLAYBACK_FEATURE_MESSAGE), { conditions: errors });\n }\n\n this.#error = {\n code: unsupported ? SVTA_UNSUPPORTED_PLAYBACK_FEATURE : reported.code,\n message: reported.message ?? '',\n ...(reported.data === undefined ? {} : { data: reported.data }),\n };\n this.dispatchEvent?.(new Event('error'));\n }\n\n // -------------------------------------------------------------------------\n // Media element lifecycle\n // -------------------------------------------------------------------------\n\n attach(mediaElement: HTMLMediaElement): void {\n super.attach?.(mediaElement);\n this.#signals.context.mediaElement.set(mediaElement);\n }\n\n detach(): void {\n this.#cancelPendingPlay();\n this.#signals.context.mediaElement.set(undefined);\n super.detach?.();\n }\n\n destroy(): void {\n this.#cancelPendingPlay();\n this.#stopLiveSync();\n this.#stopErrorSync();\n this.#engine.destroy();\n }\n\n // -------------------------------------------------------------------------\n // preload — synchronous IDL attribute (WHATWG §4.8.11.2)\n // -------------------------------------------------------------------------\n\n /** Preload type (`'none'` / `'metadata'` / `'auto'`). */\n get preload(): '' | 'none' | 'metadata' | 'auto' {\n return this.#preload;\n }\n\n set preload(value: '' | 'none' | 'metadata' | 'auto') {\n this.#preload = value;\n\n if (value) {\n this.#signals.state.preload.set(value);\n }\n // value = '' resets the IDL mirror (so `get preload` reflects '') but does\n // not patch state — the engine keeps its current preload until an explicit\n // W3C value replaces it.\n }\n\n // -------------------------------------------------------------------------\n // disableRemotePlayback — synchronous IDL attribute (WHATWG Remote Playback)\n // Author intent for whether the AirPlay/remote picker is offered. Mirrors\n // the DOM attribute name; the value flows to `state.disableRemotePlayback`,\n // which `setupAirPlay` reads to honor an explicit opt-out. The underlying\n // <video>'s own `disableRemotePlayback` stays programmatically managed\n // (ManagedMediaSource needs it `true` to open; AirPlay flips it `false` once\n // the source is open), so author intent and the effective flag stay distinct.\n // -------------------------------------------------------------------------\n\n get disableRemotePlayback(): boolean {\n return this.#disableRemotePlayback;\n }\n\n set disableRemotePlayback(value: boolean) {\n this.#disableRemotePlayback = value;\n this.#signals.state.disableRemotePlayback.set(value);\n }\n\n // -------------------------------------------------------------------------\n // src — synchronous IDL attribute (WHATWG §4.8.11.2)\n // Each assignment overwrites the engine's presentation state in place. The\n // resolver FSM routes back through teardown → rebuild on the same engine,\n // mirroring how the browser's load algorithm resets media state on src change\n // — without recreating the engine or re-capturing its signals. Setting an\n // empty src un-resolves the presentation, tearing the current source down to\n // the engine's fresh-but-attached \"no source\" state.\n // -------------------------------------------------------------------------\n\n get src(): string {\n return this.#signals.state.presentation.get()?.url ?? '';\n }\n\n set src(value: string) {\n // Assigning the URL already playing is not a request to reload it. The\n // presentation is set from a fresh object every time, so re-resolving an\n // unchanged URL restarts playback — which is what a caller changing only\n // the parts of a structured source that describe images, rather than the\n // stream, would get. The hls.js Media draws the same line: it announces\n // every source change and loads only when the URL or engine config moves.\n if (value === this.src) return;\n\n this.#cancelPendingPlay();\n this.#signals.state.presentation.set(value ? { url: value } : undefined);\n }\n\n // -------------------------------------------------------------------------\n // play() — WHATWG §4.8.11.8\n // Delegates to the attached media element's native play().\n // -------------------------------------------------------------------------\n\n play(): Promise<void> {\n const mediaElement = this.#signals.context.mediaElement.get();\n if (!mediaElement) return Promise.reject(new Error('HlsVideoMediaElement: no media element attached'));\n\n // Signal play intent — enables loading even with preload=\"none\"\n this.#signals.state.loadActivated.set(true);\n\n return mediaElement.play().catch((err: unknown) => {\n // If we have a pending HLS source, the rejection may be because MSE\n // hasn't attached a blob URL yet. Wait for loadstart (src assigned\n // by MSE setup) and retry once.\n if (this.src) {\n return new Promise<void>((resolve, reject) => {\n const listener = () => {\n this.#loadstartListener = null;\n mediaElement.play().then(resolve, reject);\n };\n\n this.#loadstartListener = listener;\n mediaElement.addEventListener('loadstart', listener, { once: true });\n });\n }\n\n throw err;\n });\n }\n\n // -------------------------------------------------------------------------\n // Private\n // -------------------------------------------------------------------------\n\n /** `message`, plus the alternative-Media sentence when this class names one. */\n #withSuggestion(message: string): string {\n return withAlternativeMediaSuggestion(message, this);\n }\n\n /**\n * Log what this engine is delivering differently from what the playlist asked for. Neither condition stops\n * playback, so neither is an error — they go to the console rather than the error surface.\n *\n * Once per source, not per parse: a live playlist reloads every target duration, and the timeline track re-parses\n * on each one. Keyed on the notice rather than latched with a boolean so the two are independent, and cleared when\n * the presentation unresolves so the next source starts quiet.\n */\n #reportDeliveryNotices(presentation: MaybeResolvedPresentation | undefined): void {\n if (!isResolvedPresentation(presentation)) {\n this.#noticed.clear();\n return;\n }\n\n const trackId = liveTrackId(this.#signals.state);\n const track = trackId ? findTrackById(presentation, trackId) : undefined;\n if (!track || !isResolvedTrack(track)) return;\n\n const metadata = getMediaPlaylistMetadata(track);\n if (!metadata) return;\n\n if (metadata.lowLatency && !this.#noticed.has('lowLatency')) {\n this.#noticed.add('lowLatency');\n console.warn(this.#withSuggestion(LOW_LATENCY_UNSUPPORTED_MESSAGE));\n }\n\n if (metadata.playlistType === 'EVENT' && !this.#noticed.has('dvr')) {\n this.#noticed.add('dvr');\n console.warn(this.#withSuggestion(DVR_EXPERIMENTAL_MESSAGE));\n }\n }\n\n #createEngine(): Composition<HlsVideoEngineState, HlsVideoEngineContext> {\n return createHlsVideoEngine({\n ...this.#config,\n onSignalsReady: (signals) => {\n this.#signals = signals;\n },\n });\n }\n\n #cancelPendingPlay(): void {\n if (!this.#loadstartListener) return;\n\n const mediaElement = this.#signals.context.mediaElement.get();\n\n mediaElement?.removeEventListener('loadstart', this.#loadstartListener);\n this.#loadstartListener = null;\n }\n }\n\n // `MixinReturn` sources statics from `Base`, so the adapter's own static needs\n // adding back to the type or callers can't read it.\n return HlsVideoMediaImpl as unknown as MixinReturn<Base, HlsVideoMediaAPI> & {\n readonly alternativeMediaSuggestion: string | undefined;\n };\n}\n\n/** Standalone SPF media adapter with no base class. */\nexport class HlsVideoMediaElement extends HlsVideoMediaMixin(class {}) {}\n"],"mappings":";;;;;;;;;;;AAwDA,MAAa,4BAAgD;CAC3D,KAAK;CACL,SAAS;CACT,uBAAuB;CACvB,YAAY,iBAAiB;AAC/B;;;;;;AAkBA,SAAS,uBACP,cACA,SACQ;CACR,IAAI,CAAC,uBAAuB,YAAY,KAAK,CAAC,SAAS,OAAO;CAE9D,MAAM,QAAQ,cAAc,cAAc,OAAO;CACjD,IAAI,CAAC,SAAS,CAAC,gBAAgB,KAAK,GAAG,OAAO;CAE9C,MAAM,WAAW,yBAAyB,KAAK;CAC/C,IAAI,CAAC,UAAU,OAAO;CAEtB,IAAI,SAAS,iBAAiB,SAAS,OAAO,OAAO;CAErD,OAAO,iBAAiB,QAAQ,MAAM,SAAS,IAAI;AACrD;;;;;;;;;;AAeA,MAAM,mCAAwC,IAAI,IAAY,CAC5D,+BACA,6BACF,CAAC;;;;;;;;;;;;;;;;;;;;AAqBD,SAAgB,mBAAkD,WAAiB;CACjF,MAAM,0BAA0B,UAAU;;;;;;;;;;;EAWxC,WAAW,6BAAiD,CAE5D;EAEA;EACA;EACA;EACA,WAA8C,0BAA0B;EACxE,yBAAkC,0BAA0B;EAC5D,cAAuC,0BAA0B;EACjE,oBAAoB;EACpB,oBAAoB;EACpB,SAAoC;;;;;;EAMpC,gBAA+B;;EAE/B,2BAAW,IAAI,IAAY;EAC3B;EACA;;EAGA,qBAA0C;EAE1C,YAAY,GAAG,MAAa;GAC1B,MAAM,GAAG,IAAI;GAEb,MAAM,EAAE,WAAW,OAAO,MAAM,CAAC;GAEjC,KAAKC,UAAU;GACf,KAAKD,UAAU,KAAKE,cAAc;GAOlC,KAAKC,gBAAgB,aAAa;IAChC,MAAM,eAAe,KAAKC,SAAS,MAAM,aAAa,IAAI;IAE1D,KAAKC,uBAAuB,cAAc,cAAc,iBAAiB,OAAO;IAChF,KAAKC,qBAAqB,uBAAuB,cAAc,YAAY,KAAKF,SAAS,KAAK,CAAC,CAAC;IAChG,KAAKG,uBAAuB,YAAY;GAC1C,CAAC;GAMD,KAAKC,iBAAiB,aAAa;IACjC,MAAM,SAAS,KAAKJ,SAAS,MAAM,OAAO,IAAI;IAE9C,KAAKK,UAAU,WAAW,QAAQ,gBAAgB,GAAG,MAAM;GAC7D,CAAC;EACH;;;;;EAMA,IAAI,SAAkE;GACpE,OAAO,KAAKT;EACd;;;;;;EAaA,IAAI,QAAmC;GACrC,OAAO,KAAKU;EACd;;;;;;EAOA,IAAI,aAAsC;GACxC,OAAO,KAAKC;EACd;EAEA,IAAI,WAAW,OAAgC;GAC7C,IAAI,UAAU,iBAAiB,SAAS;IACtC,KAAKC,oBAAoB;IACzB,KAAKC,kBAAkB,KAAKT,SAAS,MAAM,aAAa,IAAI,CAAC,EAAE,cAAc,iBAAiB,OAAO;IACrG;GACF;GAEA,KAAKQ,oBAAoB;GACzB,KAAKC,kBAAkB,KAAK;EAC9B;;;;;;;EAQA,IAAI,gBAAwB;GAM1B,OALa,YAAY;IACvB,OAAO,KAAKT,SAAS;IACrB,QAAQ,EAAE,mBAAmB;GAC/B,CAEU,CAAC,EAAE,iBAAiB;EAChC;;;;;EAMA,IAAI,mBAA2B;GAC7B,OAAO,KAAKU;EACd;EAEA,uBAAuB,OAAsC;GAC3D,IAAI,KAAKF,mBAAmB;GAE5B,KAAKC,kBAAkB,KAAK;EAC9B;EAEA,kBAAkB,OAAsC;GACtD,IAAI,KAAKF,gBAAgB,OAAO;GAEhC,KAAKA,cAAc;GAGnB,KAAK,gBAAgB,IAAI,MAAM,kBAAkB,CAAC;EACpD;EAEA,qBAAqB,OAAqB;GACxC,IAAI,OAAO,GAAG,KAAKG,mBAAmB,KAAK,GAAG;GAE9C,KAAKA,oBAAoB;GACzB,KAAK,gBAAgB,IAAI,MAAM,wBAAwB,CAAC;EAC1D;EAEA,UAAU,UAAiC,QAAgD;GACzF,IAAI,CAAC,UAAU;IAGb,KAAKJ,SAAS;IACd,KAAKK,gBAAgB;IACrB;GACF;GAKA,IAAI,KAAKA,kBAAkB,SAAS,MAAM;GAE1C,KAAKA,gBAAgB,SAAS;GAM9B,MAAM,cAAc,2BAA2B,MAAM;GAErD,IAAI,aAKF,QAAQ,MAAM,KAAKC,gBAAgB,oCAAoC,GAAG,EAAE,YAAY,OAAO,CAAC;GAGlG,KAAKN,SAAS;IACZ,MAAM,cAAc,oCAAoC,SAAS;IACjE,SAAS,SAAS,WAAW;IAC7B,GAAI,SAAS,SAAS,KAAA,IAAY,CAAC,IAAI,EAAE,MAAM,SAAS,KAAK;GAC/D;GACA,KAAK,gBAAgB,IAAI,MAAM,OAAO,CAAC;EACzC;EAMA,OAAO,cAAsC;GAC3C,MAAM,SAAS,YAAY;GAC3B,KAAKN,SAAS,QAAQ,aAAa,IAAI,YAAY;EACrD;EAEA,SAAe;GACb,KAAKa,mBAAmB;GACxB,KAAKb,SAAS,QAAQ,aAAa,IAAI,KAAA,CAAS;GAChD,MAAM,SAAS;EACjB;EAEA,UAAgB;GACd,KAAKa,mBAAmB;GACxB,KAAKd,cAAc;GACnB,KAAKK,eAAe;GACpB,KAAKR,QAAQ,QAAQ;EACvB;;EAOA,IAAI,UAA6C;GAC/C,OAAO,KAAKkB;EACd;EAEA,IAAI,QAAQ,OAA0C;GACpD,KAAKA,WAAW;GAEhB,IAAI,OACF,KAAKd,SAAS,MAAM,QAAQ,IAAI,KAAK;EAKzC;EAYA,IAAI,wBAAiC;GACnC,OAAO,KAAKe;EACd;EAEA,IAAI,sBAAsB,OAAgB;GACxC,KAAKA,yBAAyB;GAC9B,KAAKf,SAAS,MAAM,sBAAsB,IAAI,KAAK;EACrD;EAYA,IAAI,MAAc;GAChB,OAAO,KAAKA,SAAS,MAAM,aAAa,IAAI,CAAC,EAAE,OAAO;EACxD;EAEA,IAAI,IAAI,OAAe;GAOrB,IAAI,UAAU,KAAK,KAAK;GAExB,KAAKa,mBAAmB;GACxB,KAAKb,SAAS,MAAM,aAAa,IAAI,QAAQ,EAAE,KAAK,MAAM,IAAI,KAAA,CAAS;EACzE;EAOA,OAAsB;GACpB,MAAM,eAAe,KAAKA,SAAS,QAAQ,aAAa,IAAI;GAC5D,IAAI,CAAC,cAAc,OAAO,QAAQ,uBAAO,IAAI,MAAM,iDAAiD,CAAC;GAGrG,KAAKA,SAAS,MAAM,cAAc,IAAI,IAAI;GAE1C,OAAO,aAAa,KAAK,CAAC,CAAC,OAAO,QAAiB;IAIjD,IAAI,KAAK,KACP,OAAO,IAAI,SAAe,SAAS,WAAW;KAC5C,MAAM,iBAAiB;MACrB,KAAKgB,qBAAqB;MAC1B,aAAa,KAAK,CAAC,CAAC,KAAK,SAAS,MAAM;KAC1C;KAEA,KAAKA,qBAAqB;KAC1B,aAAa,iBAAiB,aAAa,UAAU,EAAE,MAAM,KAAK,CAAC;IACrE,CAAC;IAGH,MAAM;GACR,CAAC;EACH;;EAOA,gBAAgB,SAAyB;GACvC,OAAO,+BAA+B,SAAS,IAAI;EACrD;;;;;;;;;EAUA,uBAAuB,cAA2D;GAChF,IAAI,CAAC,uBAAuB,YAAY,GAAG;IACzC,KAAKC,SAAS,MAAM;IACpB;GACF;GAEA,MAAM,UAAU,YAAY,KAAKjB,SAAS,KAAK;GAC/C,MAAM,QAAQ,UAAU,cAAc,cAAc,OAAO,IAAI,KAAA;GAC/D,IAAI,CAAC,SAAS,CAAC,gBAAgB,KAAK,GAAG;GAEvC,MAAM,WAAW,yBAAyB,KAAK;GAC/C,IAAI,CAAC,UAAU;GAEf,IAAI,SAAS,cAAc,CAAC,KAAKiB,SAAS,IAAI,YAAY,GAAG;IAC3D,KAAKA,SAAS,IAAI,YAAY;IAC9B,QAAQ,KAAK,KAAKL,gBAAgB,+BAA+B,CAAC;GACpE;GAEA,IAAI,SAAS,iBAAiB,WAAW,CAAC,KAAKK,SAAS,IAAI,KAAK,GAAG;IAClE,KAAKA,SAAS,IAAI,KAAK;IACvB,QAAQ,KAAK,KAAKL,gBAAgB,wBAAwB,CAAC;GAC7D;EACF;EAEA,gBAAyE;GACvE,OAAO,qBAAqB;IAC1B,GAAG,KAAKf;IACR,iBAAiB,YAAY;KAC3B,KAAKG,WAAW;IAClB;GACF,CAAC;EACH;EAEA,qBAA2B;GACzB,IAAI,CAAC,KAAKgB,oBAAoB;GAI9B,KAF0BhB,SAAS,QAAQ,aAAa,IAE7C,CAAC,EAAE,oBAAoB,aAAa,KAAKgB,kBAAkB;GACtE,KAAKA,qBAAqB;EAC5B;CACF;CAIA,OAAO;AAGT;;AAGA,IAAa,uBAAb,cAA0C,mBAAmB,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC"}
@@ -1,12 +1,11 @@
1
1
  import { ErrorLike } from "@videojs/media";
2
2
  //#region src/playback/adapters/hls-video/error-surface.d.ts
3
3
  /**
4
- * The error shape a media surface exposes: `@videojs/media`'s {@link ErrorLike}
5
- * plus the reporter context the engine carries alongside a condition.
4
+ * The error shape a media surface exposes: `@videojs/media`'s {@link ErrorLike} plus the reporter context the engine
5
+ * carries alongside a condition.
6
6
  *
7
- * `code` is the **SVTA code**, not a `MediaError.MEDIA_ERR_*` value. Consumers
8
- * that map codes to copy currently only know 1–5, so an SVTA code falls through
9
- * to showing `message`; an extensible code lookup above the engine is the
7
+ * `code` is the **SVTA code**, not a `MediaError.MEDIA_ERR_*` value. Consumers that map codes to copy currently only
8
+ * know 1–5, so an SVTA code falls through to showing `message`; an extensible code lookup above the engine is the
10
9
  * follow-up that fixes it.
11
10
  */
12
11
  interface HlsVideoMediaError extends ErrorLike {
@@ -1 +1 @@
1
- {"version":3,"file":"error-surface.d.ts","names":[],"sources":["../../../../../src/playback/adapters/hls-video/error-surface.ts"],"mappings":";;;;;;;;;;;UAkCiB,2BAA2B;;WAEjC"}
1
+ {"version":3,"file":"error-surface.d.ts","names":[],"sources":["../../../../../src/playback/adapters/hls-video/error-surface.ts"],"mappings":";;;;;;;;;;UA8BiB,2BAA2B;;WAEjC"}
@@ -3,10 +3,9 @@ import { SVTA_UNSUPPORTED_AUDIO_FORMAT, SVTA_UNSUPPORTED_DRM_SYSTEM, SVTA_UNSUPP
3
3
  /**
4
4
  * `message`, plus the alternative-Media sentence when `media`'s class names one.
5
5
  *
6
- * Read off the class rather than passed in so a subclass can point at a
7
- * better-equipped sibling the SPF Mux Medias name the hls.js-backed one, which
8
- * plays the MPEG-TS and DRM sources SPF doesn't — without either adapter knowing
9
- * that sibling exists.
6
+ * Read off the class rather than passed in so a subclass can point at a better-equipped sibling — the SPF Mux Medias
7
+ * name the hls.js-backed one, which plays the MPEG-TS and DRM sources SPF doesn't without either adapter knowing that
8
+ * sibling exists.
10
9
  */
11
10
  function withAlternativeMediaSuggestion(message, media) {
12
11
  const { alternativeMediaSuggestion } = media.constructor;
@@ -18,13 +17,12 @@ function firstFatal(errors, fatalCodes) {
18
17
  return errors?.find((error) => fatalCodes.has(error.code));
19
18
  }
20
19
  /**
21
- * The causes that mean the engine has no pipeline for what the source delivers —
22
- * a container it can't append, or encryption it can't decrypt.
20
+ * The causes that mean the engine has no pipeline for what the source delivers — a container it can't append, or
21
+ * encryption it can't decrypt.
23
22
  *
24
- * What these have in common is that no retry, no other CDN, and no other
25
- * rendition of the same source fixes them: the source needs a capability this
26
- * engine doesn't have. That's the distinction the surfaced code exists to draw,
27
- * and it's why the set is these three rather than "every cause".
23
+ * What these have in common is that no retry, no other CDN, and no other rendition of the same source fixes them: the
24
+ * source needs a capability this engine doesn't have. That's the distinction the surfaced code exists to draw, and it's
25
+ * why the set is these three rather than "every cause".
28
26
  */
29
27
  const UNSUPPORTED_FEATURE_CAUSES = /* @__PURE__ */ new Set([
30
28
  SVTA_UNSUPPORTED_VIDEO_FORMAT,
@@ -32,15 +30,12 @@ const UNSUPPORTED_FEATURE_CAUSES = /* @__PURE__ */ new Set([
32
30
  SVTA_UNSUPPORTED_DRM_SYSTEM
33
31
  ]);
34
32
  /**
35
- * Whether anything in the sequence is a cause of the "we don't implement this"
36
- * kind.
33
+ * Whether anything in the sequence is a cause of the "we don't implement this" kind.
37
34
  *
38
- * Deliberately `some` over the whole sequence rather than a per-type match
39
- * against the verdict. A verdict means one type's candidates emptied, but the
40
- * *reason* the source is unplayable can sit on another type an audio-only
41
- * source whose sole rendition is encrypted empties the audio candidates, and a
42
- * video source with encrypted video empties the video ones. Both are the same
43
- * answer to the viewer, so both get the same code.
35
+ * Deliberately `some` over the whole sequence rather than a per-type match against the verdict. A verdict means one
36
+ * type's candidates emptied, but the _reason_ the source is unplayable can sit on another type an audio-only source
37
+ * whose sole rendition is encrypted empties the audio candidates, and a video source with encrypted video empties the
38
+ * video ones. Both are the same answer to the viewer, so both get the same code.
44
39
  */
45
40
  function hasUnsupportedFeatureCause(errors) {
46
41
  return errors?.some((error) => UNSUPPORTED_FEATURE_CAUSES.has(error.code)) ?? false;
@@ -1 +1 @@
1
- {"version":3,"file":"error-surface.js","names":[],"sources":["../../../../../src/playback/adapters/hls-video/error-surface.ts"],"sourcesContent":["/**\n * The shared half of promoting reported conditions onto a media surface.\n *\n * Every adapter that has one does the same things: pick the first condition it\n * treats as fatal, latch it so a later append doesn't re-fire, and name a\n * better-equipped Media when its own class points at one. Only the *policy*\n * differs — which codes are fatal, which the video, audio-only, and background\n * adapters each answer differently — so that stays with each adapter and\n * everything else lives here.\n *\n * `firstFatal` is the part all three share. The `ErrorLike` mapping below it is\n * for the two that feed a store and a dialog; the background adapter surfaces the\n * reported condition unmapped, so it takes the picker and nothing else.\n *\n * See `internal/design/spf/features/errors.md` for the causes-vs-verdicts split\n * this rests on.\n */\nimport type { ErrorLike } from '@videojs/media';\nimport {\n SVTA_UNSUPPORTED_AUDIO_FORMAT,\n SVTA_UNSUPPORTED_DRM_SYSTEM,\n SVTA_UNSUPPORTED_VIDEO_FORMAT,\n type SvtaError,\n} from '../../../media/errors';\n\n/**\n * The error shape a media surface exposes: `@videojs/media`'s {@link ErrorLike}\n * plus the reporter context the engine carries alongside a condition.\n *\n * `code` is the **SVTA code**, not a `MediaError.MEDIA_ERR_*` value. Consumers\n * that map codes to copy currently only know 1–5, so an SVTA code falls through\n * to showing `message`; an extensible code lookup above the engine is the\n * follow-up that fixes it.\n */\nexport interface HlsVideoMediaError extends ErrorLike {\n /** Reporter context (which selection emptied, which track, …). */\n readonly data?: unknown;\n}\n\n/**\n * `message`, plus the alternative-Media sentence when `media`'s class names one.\n *\n * Read off the class rather than passed in so a subclass can point at a\n * better-equipped sibling — the SPF Mux Medias name the hls.js-backed one, which\n * plays the MPEG-TS and DRM sources SPF doesn't — without either adapter knowing\n * that sibling exists.\n */\nexport function withAlternativeMediaSuggestion(message: string, media: object): string {\n const { alternativeMediaSuggestion } = media.constructor as { alternativeMediaSuggestion?: string };\n const suggestion = alternativeMediaSuggestion?.trim();\n\n return suggestion ? `${message} ${suggestion}` : message;\n}\n\n/** The first condition `fatalCodes` covers — the root cause, not its consequences. */\nexport function firstFatal(\n errors: readonly SvtaError[] | undefined,\n fatalCodes: ReadonlySet<number>\n): SvtaError | undefined {\n return errors?.find((error) => fatalCodes.has(error.code));\n}\n\n/**\n * The causes that mean the engine has no pipeline for what the source delivers —\n * a container it can't append, or encryption it can't decrypt.\n *\n * What these have in common is that no retry, no other CDN, and no other\n * rendition of the same source fixes them: the source needs a capability this\n * engine doesn't have. That's the distinction the surfaced code exists to draw,\n * and it's why the set is these three rather than \"every cause\".\n */\nconst UNSUPPORTED_FEATURE_CAUSES: ReadonlySet<number> = new Set<number>([\n SVTA_UNSUPPORTED_VIDEO_FORMAT,\n SVTA_UNSUPPORTED_AUDIO_FORMAT,\n SVTA_UNSUPPORTED_DRM_SYSTEM,\n]);\n\n/**\n * Whether anything in the sequence is a cause of the \"we don't implement this\"\n * kind.\n *\n * Deliberately `some` over the whole sequence rather than a per-type match\n * against the verdict. A verdict means one type's candidates emptied, but the\n * *reason* the source is unplayable can sit on another type — an audio-only\n * source whose sole rendition is encrypted empties the audio candidates, and a\n * video source with encrypted video empties the video ones. Both are the same\n * answer to the viewer, so both get the same code.\n */\nexport function hasUnsupportedFeatureCause(errors: readonly SvtaError[] | undefined): boolean {\n return errors?.some((error) => UNSUPPORTED_FEATURE_CAUSES.has(error.code)) ?? false;\n}\n"],"mappings":";;;;;;;;;;AA+CA,SAAgB,+BAA+B,SAAiB,OAAuB;CACrF,MAAM,EAAE,+BAA+B,MAAM;CAC7C,MAAM,aAAa,4BAA4B,KAAK;CAEpD,OAAO,aAAa,GAAG,QAAQ,GAAG,eAAe;AACnD;;AAGA,SAAgB,WACd,QACA,YACuB;CACvB,OAAO,QAAQ,MAAM,UAAU,WAAW,IAAI,MAAM,IAAI,CAAC;AAC3D;;;;;;;;;;AAWA,MAAM,6CAAkD,IAAI,IAAY;CACtE;CACA;CACA;AACF,CAAC;;;;;;;;;;;;AAaD,SAAgB,2BAA2B,QAAmD;CAC5F,OAAO,QAAQ,MAAM,UAAU,2BAA2B,IAAI,MAAM,IAAI,CAAC,KAAK;AAChF"}
1
+ {"version":3,"file":"error-surface.js","names":[],"sources":["../../../../../src/playback/adapters/hls-video/error-surface.ts"],"sourcesContent":["/**\n * The shared half of promoting reported conditions onto a media surface.\n *\n * Every adapter that has one does the same things: pick the first condition it treats as fatal, latch it so a later\n * append doesn't re-fire, and name a better-equipped Media when its own class points at one. Only the _policy_ differs\n * — which codes are fatal, which the video, audio-only, and background adapters each answer differently — so that stays\n * with each adapter and everything else lives here.\n *\n * `firstFatal` is the part all three share. The `ErrorLike` mapping below it is for the two that feed a store and a\n * dialog; the background adapter surfaces the reported condition unmapped, so it takes the picker and nothing else.\n *\n * See `internal/design/spf/features/errors.md` for the causes-vs-verdicts split this rests on.\n */\nimport type { ErrorLike } from '@videojs/media';\n\nimport {\n SVTA_UNSUPPORTED_AUDIO_FORMAT,\n SVTA_UNSUPPORTED_DRM_SYSTEM,\n SVTA_UNSUPPORTED_VIDEO_FORMAT,\n type SvtaError,\n} from '../../../media/errors';\n\n/**\n * The error shape a media surface exposes: `@videojs/media`'s {@link ErrorLike} plus the reporter context the engine\n * carries alongside a condition.\n *\n * `code` is the **SVTA code**, not a `MediaError.MEDIA_ERR_*` value. Consumers that map codes to copy currently only\n * know 1–5, so an SVTA code falls through to showing `message`; an extensible code lookup above the engine is the\n * follow-up that fixes it.\n */\nexport interface HlsVideoMediaError extends ErrorLike {\n /** Reporter context (which selection emptied, which track, …). */\n readonly data?: unknown;\n}\n\n/**\n * `message`, plus the alternative-Media sentence when `media`'s class names one.\n *\n * Read off the class rather than passed in so a subclass can point at a better-equipped sibling — the SPF Mux Medias\n * name the hls.js-backed one, which plays the MPEG-TS and DRM sources SPF doesn't — without either adapter knowing that\n * sibling exists.\n */\nexport function withAlternativeMediaSuggestion(message: string, media: object): string {\n const { alternativeMediaSuggestion } = media.constructor as { alternativeMediaSuggestion?: string };\n const suggestion = alternativeMediaSuggestion?.trim();\n\n return suggestion ? `${message} ${suggestion}` : message;\n}\n\n/** The first condition `fatalCodes` covers — the root cause, not its consequences. */\nexport function firstFatal(\n errors: readonly SvtaError[] | undefined,\n fatalCodes: ReadonlySet<number>\n): SvtaError | undefined {\n return errors?.find((error) => fatalCodes.has(error.code));\n}\n\n/**\n * The causes that mean the engine has no pipeline for what the source delivers a container it can't append, or\n * encryption it can't decrypt.\n *\n * What these have in common is that no retry, no other CDN, and no other rendition of the same source fixes them: the\n * source needs a capability this engine doesn't have. That's the distinction the surfaced code exists to draw, and it's\n * why the set is these three rather than \"every cause\".\n */\nconst UNSUPPORTED_FEATURE_CAUSES: ReadonlySet<number> = new Set<number>([\n SVTA_UNSUPPORTED_VIDEO_FORMAT,\n SVTA_UNSUPPORTED_AUDIO_FORMAT,\n SVTA_UNSUPPORTED_DRM_SYSTEM,\n]);\n\n/**\n * Whether anything in the sequence is a cause of the \"we don't implement this\" kind.\n *\n * Deliberately `some` over the whole sequence rather than a per-type match against the verdict. A verdict means one\n * type's candidates emptied, but the _reason_ the source is unplayable can sit on another type — an audio-only source\n * whose sole rendition is encrypted empties the audio candidates, and a video source with encrypted video empties the\n * video ones. Both are the same answer to the viewer, so both get the same code.\n */\nexport function hasUnsupportedFeatureCause(errors: readonly SvtaError[] | undefined): boolean {\n return errors?.some((error) => UNSUPPORTED_FEATURE_CAUSES.has(error.code)) ?? false;\n}\n"],"mappings":";;;;;;;;;AA0CA,SAAgB,+BAA+B,SAAiB,OAAuB;CACrF,MAAM,EAAE,+BAA+B,MAAM;CAC7C,MAAM,aAAa,4BAA4B,KAAK;CAEpD,OAAO,aAAa,GAAG,QAAQ,GAAG,eAAe;AACnD;;AAGA,SAAgB,WACd,QACA,YACuB;CACvB,OAAO,QAAQ,MAAM,UAAU,WAAW,IAAI,MAAM,IAAI,CAAC;AAC3D;;;;;;;;;AAUA,MAAM,6CAAkD,IAAI,IAAY;CACtE;CACA;CACA;AACF,CAAC;;;;;;;;;AAUD,SAAgB,2BAA2B,QAAmD;CAC5F,OAAO,QAAQ,MAAM,UAAU,2BAA2B,IAAI,MAAM,IAAI,CAAC,KAAK;AAChF"}