@amazon/vinyl 1.2.0 → 2.0.4

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 (653) hide show
  1. package/dist/index.cjs +9225 -6633
  2. package/dist/index.cjs.map +4 -4
  3. package/dist/index.js +9080 -6435
  4. package/dist/index.js.map +4 -4
  5. package/dist/test/benchmark.es5.js +266 -253
  6. package/dist/test/benchmark.js +3256 -3190
  7. package/dist/test/benchmark.js.map +4 -4
  8. package/dist/test/integ.es5.js +1404 -1093
  9. package/dist/test/integ.js +45924 -33873
  10. package/dist/test/integ.js.map +4 -4
  11. package/dist/types/current/ad/AdBreakInfo.d.ts +160 -0
  12. package/dist/types/current/ad/AdBreakInfo.d.ts.map +1 -0
  13. package/dist/types/current/ad/AdController.d.ts +229 -0
  14. package/dist/types/current/ad/AdController.d.ts.map +1 -0
  15. package/dist/types/current/ad/AdController.js +19 -0
  16. package/dist/types/current/ad/AdControllerImpl.d.ts +146 -0
  17. package/dist/types/current/ad/AdControllerImpl.d.ts.map +1 -0
  18. package/dist/types/current/ad/AdControllerImpl.js +705 -0
  19. package/dist/types/current/ad/AdError.d.ts +6 -0
  20. package/dist/types/current/ad/AdError.d.ts.map +1 -0
  21. package/dist/types/current/ad/AdError.js +14 -0
  22. package/dist/types/current/ad/AdsProvider.d.ts +28 -0
  23. package/dist/types/current/ad/AdsProvider.d.ts.map +1 -0
  24. package/dist/types/current/ad/AdsProvider.js +5 -0
  25. package/dist/types/current/ad/defaultAdLoadOptionsResolver.d.ts +12 -0
  26. package/dist/types/current/ad/defaultAdLoadOptionsResolver.d.ts.map +1 -0
  27. package/dist/types/current/ad/defaultAdLoadOptionsResolver.js +26 -0
  28. package/dist/types/current/ad/discoverHlsInterstitials.d.ts +22 -0
  29. package/dist/types/current/ad/discoverHlsInterstitials.d.ts.map +1 -0
  30. package/dist/types/current/ad/discoverHlsInterstitials.js +246 -0
  31. package/dist/types/current/drm/DrmController.d.ts +29 -4
  32. package/dist/types/current/drm/DrmController.d.ts.map +1 -1
  33. package/dist/types/current/drm/DrmControllerImpl.d.ts +13 -4
  34. package/dist/types/current/drm/DrmControllerImpl.d.ts.map +1 -1
  35. package/dist/types/current/drm/DrmControllerImpl.js +85 -14
  36. package/dist/types/current/drm/util/unpackPlayReadyChallenge.d.ts +5 -0
  37. package/dist/types/current/drm/util/unpackPlayReadyChallenge.d.ts.map +1 -1
  38. package/dist/types/current/drm/util/unpackPlayReadyChallenge.js +5 -0
  39. package/dist/types/current/index.d.ts +151 -126
  40. package/dist/types/current/index.d.ts.map +1 -1
  41. package/dist/types/current/index.js +151 -126
  42. package/dist/types/current/playback/PlaybackControllerImpl.d.ts +1 -0
  43. package/dist/types/current/playback/PlaybackControllerImpl.d.ts.map +1 -1
  44. package/dist/types/current/playback/PlaybackControllerImpl.js +44 -5
  45. package/dist/types/current/playback/PlaybackSource.d.ts +1 -1
  46. package/dist/types/current/playback/ReadonlyPlaybackController.d.ts +6 -1
  47. package/dist/types/current/playback/ReadonlyPlaybackController.d.ts.map +1 -1
  48. package/dist/types/current/playback/ReadonlyPlaybackController.js +1 -0
  49. package/dist/types/current/streaming/ContentStream.d.ts +8 -1
  50. package/dist/types/current/streaming/ContentStream.d.ts.map +1 -1
  51. package/dist/types/current/streaming/ContentStream.js +19 -2
  52. package/dist/types/current/streaming/LoadMetric.d.ts +58 -0
  53. package/dist/types/current/streaming/LoadMetric.d.ts.map +1 -0
  54. package/dist/types/current/streaming/LoadMetric.js +5 -0
  55. package/dist/types/current/streaming/ManifestController.d.ts +16 -1
  56. package/dist/types/current/streaming/ManifestController.d.ts.map +1 -1
  57. package/dist/types/current/streaming/ManifestControllerImpl.d.ts +43 -0
  58. package/dist/types/current/streaming/ManifestControllerImpl.d.ts.map +1 -0
  59. package/dist/types/current/streaming/ManifestControllerImpl.js +104 -0
  60. package/dist/types/current/streaming/MediaQualityMetadata.d.ts +16 -0
  61. package/dist/types/current/streaming/MediaQualityMetadata.d.ts.map +1 -1
  62. package/dist/types/current/streaming/MediaQualityMetadata.js +6 -0
  63. package/dist/types/current/streaming/MediaTimeline.d.ts +6 -0
  64. package/dist/types/current/streaming/MediaTimeline.d.ts.map +1 -1
  65. package/dist/types/current/streaming/SegmentController.d.ts +5 -0
  66. package/dist/types/current/streaming/SegmentController.d.ts.map +1 -1
  67. package/dist/types/current/streaming/SegmentControllerImpl.d.ts +12 -0
  68. package/dist/types/current/streaming/SegmentControllerImpl.d.ts.map +1 -1
  69. package/dist/types/current/streaming/SegmentControllerImpl.js +67 -10
  70. package/dist/types/current/streaming/StreamingEventMap.d.ts +38 -1
  71. package/dist/types/current/streaming/StreamingEventMap.d.ts.map +1 -1
  72. package/dist/types/current/streaming/StreamingEventMap.js +4 -0
  73. package/dist/types/current/streaming/abr/QualitySelectorImpl.d.ts +28 -0
  74. package/dist/types/current/streaming/abr/QualitySelectorImpl.d.ts.map +1 -1
  75. package/dist/types/current/streaming/abr/QualitySelectorImpl.js +39 -4
  76. package/dist/types/current/streaming/buffering/BufferingController.d.ts +37 -0
  77. package/dist/types/current/streaming/buffering/BufferingController.d.ts.map +1 -1
  78. package/dist/types/current/streaming/buffering/BufferingController.js +79 -3
  79. package/dist/types/current/streaming/buffering/MediaSourceController.d.ts +16 -11
  80. package/dist/types/current/streaming/buffering/MediaSourceController.d.ts.map +1 -1
  81. package/dist/types/current/streaming/buffering/MediaSourceController.js +76 -51
  82. package/dist/types/current/streaming/buffering/SourceBufferController.d.ts.map +1 -1
  83. package/dist/types/current/streaming/buffering/SourceBufferController.js +5 -2
  84. package/dist/types/current/streaming/buffering/codecDenylist.d.ts +23 -0
  85. package/dist/types/current/streaming/buffering/codecDenylist.d.ts.map +1 -0
  86. package/dist/types/current/streaming/buffering/codecDenylist.js +62 -0
  87. package/dist/types/current/streaming/createAllowedContentTypesValue.d.ts +30 -0
  88. package/dist/types/current/streaming/createAllowedContentTypesValue.d.ts.map +1 -0
  89. package/dist/types/current/streaming/createAllowedContentTypesValue.js +43 -0
  90. package/dist/types/current/streaming/createDefaultMediaTimelineTransformer.d.ts +4 -1
  91. package/dist/types/current/streaming/createDefaultMediaTimelineTransformer.d.ts.map +1 -1
  92. package/dist/types/current/streaming/createDefaultMediaTimelineTransformer.js +32 -1
  93. package/dist/types/current/streaming/mediaTimelineAccessibilityFilter.d.ts +35 -0
  94. package/dist/types/current/streaming/mediaTimelineAccessibilityFilter.d.ts.map +1 -0
  95. package/dist/types/current/streaming/mediaTimelineAccessibilityFilter.js +75 -0
  96. package/dist/types/current/streaming/mediaTimelineLanguageFilter.d.ts +24 -6
  97. package/dist/types/current/streaming/mediaTimelineLanguageFilter.d.ts.map +1 -1
  98. package/dist/types/current/streaming/mediaTimelineLanguageFilter.js +61 -16
  99. package/dist/types/current/text/SidecarTextTrackController.d.ts +91 -0
  100. package/dist/types/current/text/SidecarTextTrackController.d.ts.map +1 -0
  101. package/dist/types/current/text/SidecarTextTrackController.js +237 -0
  102. package/dist/types/current/text/SidecarTextTrackLoader.d.ts +60 -0
  103. package/dist/types/current/text/SidecarTextTrackLoader.d.ts.map +1 -0
  104. package/dist/types/current/text/SidecarTextTrackLoader.js +144 -0
  105. package/dist/types/current/text/TextTrack.d.ts +125 -0
  106. package/dist/types/current/text/TextTrack.d.ts.map +1 -0
  107. package/dist/types/current/text/TextTrack.js +9 -0
  108. package/dist/types/current/text/VttCueStyle.d.ts +41 -0
  109. package/dist/types/current/text/VttCueStyle.d.ts.map +1 -0
  110. package/dist/types/current/text/VttCueStyle.js +45 -0
  111. package/dist/types/current/text/discoverDashTextTracks.d.ts +24 -0
  112. package/dist/types/current/text/discoverDashTextTracks.d.ts.map +1 -0
  113. package/dist/types/current/text/discoverDashTextTracks.js +109 -0
  114. package/dist/types/current/text/discoverHlsTextTracks.d.ts +19 -0
  115. package/dist/types/current/text/discoverHlsTextTracks.d.ts.map +1 -0
  116. package/dist/types/current/text/discoverHlsTextTracks.js +49 -0
  117. package/dist/types/current/text/parseWebVtt.d.ts +46 -0
  118. package/dist/types/current/text/parseWebVtt.d.ts.map +1 -0
  119. package/dist/types/current/text/parseWebVtt.js +120 -0
  120. package/dist/types/current/text/pickPreferredTextTrack.d.ts +14 -0
  121. package/dist/types/current/text/pickPreferredTextTrack.d.ts.map +1 -0
  122. package/dist/types/current/text/pickPreferredTextTrack.js +68 -0
  123. package/dist/types/current/track/SeekRange.d.ts +9 -0
  124. package/dist/types/current/track/SeekRange.d.ts.map +1 -0
  125. package/dist/types/current/track/SeekRange.js +5 -0
  126. package/dist/types/current/track/Track.d.ts +50 -7
  127. package/dist/types/current/track/Track.d.ts.map +1 -1
  128. package/dist/types/current/track/TrackBase.d.ts +30 -29
  129. package/dist/types/current/track/TrackBase.d.ts.map +1 -1
  130. package/dist/types/current/track/TrackBase.js +68 -16
  131. package/dist/types/current/track/TrackController.d.ts +100 -36
  132. package/dist/types/current/track/TrackController.d.ts.map +1 -1
  133. package/dist/types/current/track/TrackController.js +368 -115
  134. package/dist/types/current/track/TrackFactory.d.ts +23 -3
  135. package/dist/types/current/track/TrackFactory.d.ts.map +1 -1
  136. package/dist/types/current/track/TrackFactory.js +9 -3
  137. package/dist/types/current/track/dash/DashManifestController.d.ts +1 -40
  138. package/dist/types/current/track/dash/DashManifestController.d.ts.map +1 -1
  139. package/dist/types/current/track/dash/DashManifestController.js +1 -79
  140. package/dist/types/current/track/dash/DashMediaQualityMetadataResolver.d.ts.map +1 -1
  141. package/dist/types/current/track/dash/DashMediaQualityMetadataResolver.js +13 -0
  142. package/dist/types/current/track/dash/DashTrack.d.ts +4 -5
  143. package/dist/types/current/track/dash/DashTrack.d.ts.map +1 -1
  144. package/dist/types/current/track/dash/DashTrack.js +3 -5
  145. package/dist/types/current/track/dash/buildDashMediaTimeline.d.ts.map +1 -1
  146. package/dist/types/current/track/dash/buildDashMediaTimeline.js +3 -2
  147. package/dist/types/current/track/dash/createDashContentTypesValue.js +2 -2
  148. package/dist/types/current/track/dash/createDashFactories.d.ts +39 -12
  149. package/dist/types/current/track/dash/createDashFactories.d.ts.map +1 -1
  150. package/dist/types/current/track/dash/createDashFactories.js +33 -5
  151. package/dist/types/current/track/dash/createSegmentControllerFactory.d.ts +0 -5
  152. package/dist/types/current/track/dash/createSegmentControllerFactory.d.ts.map +1 -1
  153. package/dist/types/current/track/dash/timeline/DashRepresentationSegmentProvider.d.ts.map +1 -1
  154. package/dist/types/current/track/dash/timeline/DashRepresentationSegmentProvider.js +2 -1
  155. package/dist/types/current/track/dash/util/mpd.d.ts +10 -0
  156. package/dist/types/current/track/dash/util/mpd.d.ts.map +1 -1
  157. package/dist/types/current/track/dash/util/mpd.js +16 -0
  158. package/dist/types/current/track/hls/HlsManifestController.d.ts +1 -25
  159. package/dist/types/current/track/hls/HlsManifestController.d.ts.map +1 -1
  160. package/dist/types/current/track/hls/HlsManifestController.js +1 -68
  161. package/dist/types/{ts3.7/track/hls/HlsManifestProvider.d.ts → current/track/hls/HlsManifestData.d.ts} +4 -6
  162. package/dist/types/current/track/hls/HlsManifestData.d.ts.map +1 -0
  163. package/dist/types/current/track/hls/HlsManifestData.js +5 -0
  164. package/dist/types/current/track/hls/HlsMediaQualityMetadataResolver.js +9 -6
  165. package/dist/types/current/track/hls/HlsTrack.d.ts +5 -6
  166. package/dist/types/current/track/hls/HlsTrack.d.ts.map +1 -1
  167. package/dist/types/current/track/hls/HlsTrack.js +3 -5
  168. package/dist/types/current/track/hls/buildHlsMediaTimeline.d.ts +8 -1
  169. package/dist/types/current/track/hls/buildHlsMediaTimeline.d.ts.map +1 -1
  170. package/dist/types/current/track/hls/buildHlsMediaTimeline.js +134 -67
  171. package/dist/types/current/track/hls/createDefaultHlsManifestTransformer.d.ts +1 -1
  172. package/dist/types/current/track/hls/createDefaultHlsManifestTransformer.d.ts.map +1 -1
  173. package/dist/types/current/track/hls/createHlsContentTypesValue.d.ts +1 -1
  174. package/dist/types/current/track/hls/createHlsContentTypesValue.d.ts.map +1 -1
  175. package/dist/types/current/track/hls/createHlsFactories.d.ts +40 -13
  176. package/dist/types/current/track/hls/createHlsFactories.d.ts.map +1 -1
  177. package/dist/types/current/track/hls/createHlsFactories.js +35 -6
  178. package/dist/types/current/track/hls/createHlsManifestProvider.d.ts +6 -0
  179. package/dist/types/current/track/hls/createHlsManifestProvider.d.ts.map +1 -0
  180. package/dist/types/current/track/hls/createHlsManifestProvider.js +9 -0
  181. package/dist/types/current/track/hls/createUrlHlsManifestProvider.d.ts +4 -4
  182. package/dist/types/current/track/hls/createUrlHlsManifestProvider.d.ts.map +1 -1
  183. package/dist/types/current/track/hls/createUrlHlsManifestProvider.js +22 -3
  184. package/dist/types/current/track/hls/index.d.ts +1 -1
  185. package/dist/types/current/track/hls/index.d.ts.map +1 -1
  186. package/dist/types/current/track/hls/index.js +1 -1
  187. package/dist/types/current/track/inferLoadOptionsFromUri.d.ts +15 -0
  188. package/dist/types/current/track/inferLoadOptionsFromUri.d.ts.map +1 -0
  189. package/dist/types/current/track/inferLoadOptionsFromUri.js +55 -0
  190. package/dist/types/current/track/mse/MseTrack.d.ts +66 -8
  191. package/dist/types/current/track/mse/MseTrack.d.ts.map +1 -1
  192. package/dist/types/current/track/mse/MseTrack.js +216 -52
  193. package/dist/types/current/track/source/SourceObjectTrack.d.ts +2 -2
  194. package/dist/types/current/track/source/SourceObjectTrack.d.ts.map +1 -1
  195. package/dist/types/current/track/source/SourceTrack.d.ts +2 -2
  196. package/dist/types/current/track/source/SourceTrack.d.ts.map +1 -1
  197. package/dist/types/current/track/source/SourceTrack.js +1 -2
  198. package/dist/types/current/track/source/SourceTrackBase.d.ts +7 -5
  199. package/dist/types/current/track/source/SourceTrackBase.d.ts.map +1 -1
  200. package/dist/types/current/track/source/SourceTrackBase.js +26 -9
  201. package/dist/types/current/tsconfig.tsbuildinfo +1 -1
  202. package/dist/types/current/util/media/codecOverrides.d.ts +33 -0
  203. package/dist/types/current/util/media/codecOverrides.d.ts.map +1 -0
  204. package/dist/types/current/util/media/codecOverrides.js +37 -0
  205. package/dist/types/current/util/media/codecSupport.d.ts +6 -0
  206. package/dist/types/current/util/media/codecSupport.d.ts.map +1 -0
  207. package/dist/types/current/util/media/codecSupport.js +17 -0
  208. package/dist/types/current/util/media/mediaSource.d.ts +5 -0
  209. package/dist/types/current/util/media/mediaSource.d.ts.map +1 -1
  210. package/dist/types/current/util/media/mediaSource.js +6 -1
  211. package/dist/types/current/vinyl/ReadonlyPlaybackStreamingState.d.ts +9 -2
  212. package/dist/types/current/vinyl/ReadonlyPlaybackStreamingState.d.ts.map +1 -1
  213. package/dist/types/current/vinyl/VinylDeps.d.ts +5 -0
  214. package/dist/types/current/vinyl/VinylDeps.d.ts.map +1 -1
  215. package/dist/types/current/vinyl/VinylOptions.d.ts +68 -4
  216. package/dist/types/current/vinyl/VinylOptions.d.ts.map +1 -1
  217. package/dist/types/current/vinyl/VinylOptions.js +17 -2
  218. package/dist/types/current/vinyl/VinylPlayer.d.ts +63 -4
  219. package/dist/types/current/vinyl/VinylPlayer.d.ts.map +1 -1
  220. package/dist/types/current/vinyl/VinylPlayer.js +216 -36
  221. package/dist/types/current/vinyl/createVinylFactories.d.ts +55 -12
  222. package/dist/types/current/vinyl/createVinylFactories.d.ts.map +1 -1
  223. package/dist/types/current/vinyl/createVinylFactories.js +4 -0
  224. package/dist/types/ts3.7/ad/AdBreakInfo.d.ts +160 -0
  225. package/dist/types/ts3.7/ad/AdController.d.ts +243 -0
  226. package/dist/types/ts3.7/ad/AdControllerImpl.d.ts +146 -0
  227. package/dist/types/ts3.7/ad/AdError.d.ts +6 -0
  228. package/dist/types/ts3.7/ad/AdsProvider.d.ts +28 -0
  229. package/dist/types/ts3.7/ad/defaultAdLoadOptionsResolver.d.ts +12 -0
  230. package/dist/types/ts3.7/ad/discoverHlsInterstitials.d.ts +22 -0
  231. package/dist/types/ts3.7/drm/DrmController.d.ts +29 -4
  232. package/dist/types/ts3.7/drm/DrmControllerImpl.d.ts +13 -4
  233. package/dist/types/ts3.7/drm/util/unpackPlayReadyChallenge.d.ts +5 -0
  234. package/dist/types/ts3.7/index.d.ts +151 -126
  235. package/dist/types/ts3.7/playback/PlaybackControllerImpl.d.ts +1 -0
  236. package/dist/types/ts3.7/playback/PlaybackSource.d.ts +1 -1
  237. package/dist/types/ts3.7/playback/ReadonlyPlaybackController.d.ts +6 -0
  238. package/dist/types/ts3.7/streaming/ContentStream.d.ts +8 -1
  239. package/dist/types/ts3.7/streaming/LoadMetric.d.ts +58 -0
  240. package/dist/types/ts3.7/streaming/ManifestController.d.ts +16 -1
  241. package/dist/types/ts3.7/streaming/ManifestControllerImpl.d.ts +40 -0
  242. package/dist/types/ts3.7/streaming/MediaQualityMetadata.d.ts +19 -0
  243. package/dist/types/ts3.7/streaming/MediaTimeline.d.ts +6 -0
  244. package/dist/types/ts3.7/streaming/SegmentController.d.ts +5 -0
  245. package/dist/types/ts3.7/streaming/SegmentControllerImpl.d.ts +12 -0
  246. package/dist/types/ts3.7/streaming/StreamingEventMap.d.ts +42 -1
  247. package/dist/types/ts3.7/streaming/abr/QualitySelectorImpl.d.ts +28 -0
  248. package/dist/types/ts3.7/streaming/buffering/BufferingController.d.ts +37 -0
  249. package/dist/types/ts3.7/streaming/buffering/MediaSourceController.d.ts +16 -11
  250. package/dist/types/ts3.7/streaming/buffering/codecDenylist.d.ts +23 -0
  251. package/dist/types/ts3.7/streaming/createAllowedContentTypesValue.d.ts +30 -0
  252. package/dist/types/ts3.7/streaming/createDefaultMediaTimelineTransformer.d.ts +4 -1
  253. package/dist/types/ts3.7/streaming/mediaTimelineAccessibilityFilter.d.ts +35 -0
  254. package/dist/types/ts3.7/streaming/mediaTimelineLanguageFilter.d.ts +24 -6
  255. package/dist/types/ts3.7/text/SidecarTextTrackController.d.ts +91 -0
  256. package/dist/types/ts3.7/text/SidecarTextTrackLoader.d.ts +60 -0
  257. package/dist/types/ts3.7/text/TextTrack.d.ts +129 -0
  258. package/dist/types/ts3.7/text/VttCueStyle.d.ts +41 -0
  259. package/dist/types/ts3.7/text/discoverDashTextTracks.d.ts +24 -0
  260. package/dist/types/ts3.7/text/discoverHlsTextTracks.d.ts +19 -0
  261. package/dist/types/ts3.7/text/parseWebVtt.d.ts +46 -0
  262. package/dist/types/ts3.7/text/pickPreferredTextTrack.d.ts +14 -0
  263. package/dist/types/ts3.7/track/SeekRange.d.ts +9 -0
  264. package/dist/types/ts3.7/track/Track.d.ts +50 -7
  265. package/dist/types/ts3.7/track/TrackBase.d.ts +21 -29
  266. package/dist/types/ts3.7/track/TrackController.d.ts +102 -37
  267. package/dist/types/ts3.7/track/TrackFactory.d.ts +22 -2
  268. package/dist/types/ts3.7/track/dash/DashManifestController.d.ts +1 -36
  269. package/dist/types/ts3.7/track/dash/DashTrack.d.ts +4 -5
  270. package/dist/types/ts3.7/track/dash/createDashFactories.d.ts +39 -12
  271. package/dist/types/ts3.7/track/dash/createSegmentControllerFactory.d.ts +0 -5
  272. package/dist/types/ts3.7/track/dash/util/mpd.d.ts +10 -0
  273. package/dist/types/ts3.7/track/hls/HlsManifestController.d.ts +1 -22
  274. package/dist/types/{current/track/hls/HlsManifestProvider.d.ts → ts3.7/track/hls/HlsManifestData.d.ts} +4 -6
  275. package/dist/types/ts3.7/track/hls/HlsTrack.d.ts +5 -6
  276. package/dist/types/ts3.7/track/hls/buildHlsMediaTimeline.d.ts +8 -1
  277. package/dist/types/ts3.7/track/hls/createDefaultHlsManifestTransformer.d.ts +1 -1
  278. package/dist/types/ts3.7/track/hls/createHlsContentTypesValue.d.ts +1 -1
  279. package/dist/types/ts3.7/track/hls/createHlsFactories.d.ts +40 -13
  280. package/dist/types/ts3.7/track/hls/createHlsManifestProvider.d.ts +6 -0
  281. package/dist/types/ts3.7/track/hls/createUrlHlsManifestProvider.d.ts +4 -4
  282. package/dist/types/ts3.7/track/hls/index.d.ts +1 -1
  283. package/dist/types/ts3.7/track/inferLoadOptionsFromUri.d.ts +15 -0
  284. package/dist/types/ts3.7/track/mse/MseTrack.d.ts +65 -7
  285. package/dist/types/ts3.7/track/source/SourceObjectTrack.d.ts +2 -2
  286. package/dist/types/ts3.7/track/source/SourceTrack.d.ts +2 -2
  287. package/dist/types/ts3.7/track/source/SourceTrackBase.d.ts +7 -5
  288. package/dist/types/ts3.7/util/media/codecOverrides.d.ts +33 -0
  289. package/dist/types/ts3.7/util/media/codecSupport.d.ts +6 -0
  290. package/dist/types/ts3.7/util/media/mediaSource.d.ts +5 -0
  291. package/dist/types/ts3.7/vinyl/ReadonlyPlaybackStreamingState.d.ts +9 -2
  292. package/dist/types/ts3.7/vinyl/VinylDeps.d.ts +5 -0
  293. package/dist/types/ts3.7/vinyl/VinylOptions.d.ts +68 -4
  294. package/dist/types/ts3.7/vinyl/VinylPlayer.d.ts +33 -4
  295. package/dist/types/ts3.7/vinyl/createVinylFactories.d.ts +55 -12
  296. package/dist/types/ts4.1/ad/AdBreakInfo.d.ts +160 -0
  297. package/dist/types/ts4.1/ad/AdController.d.ts +243 -0
  298. package/dist/types/ts4.1/ad/AdControllerImpl.d.ts +146 -0
  299. package/dist/types/ts4.1/ad/AdError.d.ts +6 -0
  300. package/dist/types/ts4.1/ad/AdsProvider.d.ts +28 -0
  301. package/dist/types/ts4.1/ad/defaultAdLoadOptionsResolver.d.ts +12 -0
  302. package/dist/types/ts4.1/ad/discoverHlsInterstitials.d.ts +22 -0
  303. package/dist/types/ts4.1/drm/DrmController.d.ts +29 -4
  304. package/dist/types/ts4.1/drm/DrmControllerImpl.d.ts +13 -4
  305. package/dist/types/ts4.1/drm/util/unpackPlayReadyChallenge.d.ts +5 -0
  306. package/dist/types/ts4.1/index.d.ts +151 -126
  307. package/dist/types/ts4.1/playback/PlaybackControllerImpl.d.ts +1 -0
  308. package/dist/types/ts4.1/playback/PlaybackSource.d.ts +1 -1
  309. package/dist/types/ts4.1/playback/ReadonlyPlaybackController.d.ts +6 -0
  310. package/dist/types/ts4.1/streaming/ContentStream.d.ts +8 -1
  311. package/dist/types/ts4.1/streaming/LoadMetric.d.ts +58 -0
  312. package/dist/types/ts4.1/streaming/ManifestController.d.ts +16 -1
  313. package/dist/types/ts4.1/streaming/ManifestControllerImpl.d.ts +40 -0
  314. package/dist/types/ts4.1/streaming/MediaQualityMetadata.d.ts +19 -0
  315. package/dist/types/ts4.1/streaming/MediaTimeline.d.ts +6 -0
  316. package/dist/types/ts4.1/streaming/SegmentController.d.ts +5 -0
  317. package/dist/types/ts4.1/streaming/SegmentControllerImpl.d.ts +12 -0
  318. package/dist/types/ts4.1/streaming/StreamingEventMap.d.ts +42 -1
  319. package/dist/types/ts4.1/streaming/abr/QualitySelectorImpl.d.ts +28 -0
  320. package/dist/types/ts4.1/streaming/buffering/BufferingController.d.ts +37 -0
  321. package/dist/types/ts4.1/streaming/buffering/MediaSourceController.d.ts +16 -11
  322. package/dist/types/ts4.1/streaming/buffering/codecDenylist.d.ts +23 -0
  323. package/dist/types/ts4.1/streaming/createAllowedContentTypesValue.d.ts +30 -0
  324. package/dist/types/ts4.1/streaming/createDefaultMediaTimelineTransformer.d.ts +4 -1
  325. package/dist/types/ts4.1/streaming/mediaTimelineAccessibilityFilter.d.ts +35 -0
  326. package/dist/types/ts4.1/streaming/mediaTimelineLanguageFilter.d.ts +24 -6
  327. package/dist/types/ts4.1/text/SidecarTextTrackController.d.ts +92 -0
  328. package/dist/types/ts4.1/text/SidecarTextTrackLoader.d.ts +60 -0
  329. package/dist/types/ts4.1/text/TextTrack.d.ts +129 -0
  330. package/dist/types/ts4.1/text/VttCueStyle.d.ts +41 -0
  331. package/dist/types/ts4.1/text/discoverDashTextTracks.d.ts +24 -0
  332. package/dist/types/ts4.1/text/discoverHlsTextTracks.d.ts +19 -0
  333. package/dist/types/ts4.1/text/parseWebVtt.d.ts +46 -0
  334. package/dist/types/ts4.1/text/pickPreferredTextTrack.d.ts +14 -0
  335. package/dist/types/ts4.1/track/SeekRange.d.ts +9 -0
  336. package/dist/types/ts4.1/track/Track.d.ts +50 -7
  337. package/dist/types/ts4.1/track/TrackBase.d.ts +21 -29
  338. package/dist/types/ts4.1/track/TrackController.d.ts +102 -37
  339. package/dist/types/ts4.1/track/TrackFactory.d.ts +22 -2
  340. package/dist/types/ts4.1/track/dash/DashManifestController.d.ts +1 -36
  341. package/dist/types/ts4.1/track/dash/DashTrack.d.ts +4 -5
  342. package/dist/types/ts4.1/track/dash/createDashFactories.d.ts +39 -12
  343. package/dist/types/ts4.1/track/dash/createSegmentControllerFactory.d.ts +0 -5
  344. package/dist/types/ts4.1/track/dash/util/mpd.d.ts +10 -0
  345. package/dist/types/ts4.1/track/hls/HlsManifestController.d.ts +1 -22
  346. package/dist/types/ts4.1/track/hls/{HlsManifestProvider.d.ts → HlsManifestData.d.ts} +4 -6
  347. package/dist/types/ts4.1/track/hls/HlsTrack.d.ts +5 -6
  348. package/dist/types/ts4.1/track/hls/buildHlsMediaTimeline.d.ts +8 -1
  349. package/dist/types/ts4.1/track/hls/createDefaultHlsManifestTransformer.d.ts +1 -1
  350. package/dist/types/ts4.1/track/hls/createHlsContentTypesValue.d.ts +1 -1
  351. package/dist/types/ts4.1/track/hls/createHlsFactories.d.ts +41 -13
  352. package/dist/types/ts4.1/track/hls/createHlsManifestProvider.d.ts +6 -0
  353. package/dist/types/ts4.1/track/hls/createUrlHlsManifestProvider.d.ts +4 -4
  354. package/dist/types/ts4.1/track/hls/index.d.ts +1 -1
  355. package/dist/types/ts4.1/track/inferLoadOptionsFromUri.d.ts +15 -0
  356. package/dist/types/ts4.1/track/mse/MseTrack.d.ts +65 -7
  357. package/dist/types/ts4.1/track/source/SourceObjectTrack.d.ts +2 -2
  358. package/dist/types/ts4.1/track/source/SourceTrack.d.ts +2 -2
  359. package/dist/types/ts4.1/track/source/SourceTrackBase.d.ts +7 -5
  360. package/dist/types/ts4.1/util/media/codecOverrides.d.ts +33 -0
  361. package/dist/types/ts4.1/util/media/codecSupport.d.ts +6 -0
  362. package/dist/types/ts4.1/util/media/mediaSource.d.ts +5 -0
  363. package/dist/types/ts4.1/vinyl/ReadonlyPlaybackStreamingState.d.ts +9 -2
  364. package/dist/types/ts4.1/vinyl/VinylDeps.d.ts +5 -0
  365. package/dist/types/ts4.1/vinyl/VinylOptions.d.ts +68 -4
  366. package/dist/types/ts4.1/vinyl/VinylPlayer.d.ts +33 -4
  367. package/dist/types/ts4.1/vinyl/createVinylFactories.d.ts +56 -12
  368. package/dist/types/ts4.7/ad/AdBreakInfo.d.ts +160 -0
  369. package/dist/types/ts4.7/ad/AdController.d.ts +243 -0
  370. package/dist/types/ts4.7/ad/AdControllerImpl.d.ts +146 -0
  371. package/dist/types/ts4.7/ad/AdError.d.ts +6 -0
  372. package/dist/types/ts4.7/ad/AdsProvider.d.ts +28 -0
  373. package/dist/types/ts4.7/ad/defaultAdLoadOptionsResolver.d.ts +12 -0
  374. package/dist/types/ts4.7/ad/discoverHlsInterstitials.d.ts +22 -0
  375. package/dist/types/ts4.7/drm/DrmController.d.ts +29 -4
  376. package/dist/types/ts4.7/drm/DrmControllerImpl.d.ts +13 -4
  377. package/dist/types/ts4.7/drm/util/unpackPlayReadyChallenge.d.ts +5 -0
  378. package/dist/types/ts4.7/index.d.ts +151 -126
  379. package/dist/types/ts4.7/playback/PlaybackControllerImpl.d.ts +1 -0
  380. package/dist/types/ts4.7/playback/PlaybackSource.d.ts +1 -1
  381. package/dist/types/ts4.7/playback/ReadonlyPlaybackController.d.ts +6 -0
  382. package/dist/types/ts4.7/streaming/ContentStream.d.ts +8 -1
  383. package/dist/types/ts4.7/streaming/LoadMetric.d.ts +58 -0
  384. package/dist/types/ts4.7/streaming/ManifestController.d.ts +16 -1
  385. package/dist/types/ts4.7/streaming/ManifestControllerImpl.d.ts +43 -0
  386. package/dist/types/ts4.7/streaming/MediaQualityMetadata.d.ts +19 -0
  387. package/dist/types/ts4.7/streaming/MediaTimeline.d.ts +6 -0
  388. package/dist/types/ts4.7/streaming/SegmentController.d.ts +5 -0
  389. package/dist/types/ts4.7/streaming/SegmentControllerImpl.d.ts +12 -0
  390. package/dist/types/ts4.7/streaming/StreamingEventMap.d.ts +42 -1
  391. package/dist/types/ts4.7/streaming/abr/QualitySelectorImpl.d.ts +28 -0
  392. package/dist/types/ts4.7/streaming/buffering/BufferingController.d.ts +37 -0
  393. package/dist/types/ts4.7/streaming/buffering/MediaSourceController.d.ts +16 -11
  394. package/dist/types/ts4.7/streaming/buffering/codecDenylist.d.ts +23 -0
  395. package/dist/types/ts4.7/streaming/createAllowedContentTypesValue.d.ts +30 -0
  396. package/dist/types/ts4.7/streaming/createDefaultMediaTimelineTransformer.d.ts +4 -1
  397. package/dist/types/ts4.7/streaming/mediaTimelineAccessibilityFilter.d.ts +35 -0
  398. package/dist/types/ts4.7/streaming/mediaTimelineLanguageFilter.d.ts +24 -6
  399. package/dist/types/ts4.7/text/SidecarTextTrackController.d.ts +91 -0
  400. package/dist/types/ts4.7/text/SidecarTextTrackLoader.d.ts +60 -0
  401. package/dist/types/ts4.7/text/TextTrack.d.ts +129 -0
  402. package/dist/types/ts4.7/text/VttCueStyle.d.ts +41 -0
  403. package/dist/types/ts4.7/text/discoverDashTextTracks.d.ts +24 -0
  404. package/dist/types/ts4.7/text/discoverHlsTextTracks.d.ts +19 -0
  405. package/dist/types/ts4.7/text/parseWebVtt.d.ts +46 -0
  406. package/dist/types/ts4.7/text/pickPreferredTextTrack.d.ts +14 -0
  407. package/dist/types/ts4.7/track/SeekRange.d.ts +9 -0
  408. package/dist/types/ts4.7/track/Track.d.ts +50 -7
  409. package/dist/types/ts4.7/track/TrackBase.d.ts +30 -29
  410. package/dist/types/ts4.7/track/TrackController.d.ts +102 -37
  411. package/dist/types/ts4.7/track/TrackFactory.d.ts +23 -3
  412. package/dist/types/ts4.7/track/dash/DashManifestController.d.ts +1 -40
  413. package/dist/types/ts4.7/track/dash/DashTrack.d.ts +4 -5
  414. package/dist/types/ts4.7/track/dash/createDashFactories.d.ts +39 -12
  415. package/dist/types/ts4.7/track/dash/createSegmentControllerFactory.d.ts +0 -5
  416. package/dist/types/ts4.7/track/dash/util/mpd.d.ts +10 -0
  417. package/dist/types/ts4.7/track/hls/HlsManifestController.d.ts +1 -25
  418. package/dist/types/ts4.7/track/hls/{HlsManifestProvider.d.ts → HlsManifestData.d.ts} +4 -6
  419. package/dist/types/ts4.7/track/hls/HlsTrack.d.ts +5 -6
  420. package/dist/types/ts4.7/track/hls/buildHlsMediaTimeline.d.ts +8 -1
  421. package/dist/types/ts4.7/track/hls/createDefaultHlsManifestTransformer.d.ts +1 -1
  422. package/dist/types/ts4.7/track/hls/createHlsContentTypesValue.d.ts +1 -1
  423. package/dist/types/ts4.7/track/hls/createHlsFactories.d.ts +40 -13
  424. package/dist/types/ts4.7/track/hls/createHlsManifestProvider.d.ts +6 -0
  425. package/dist/types/ts4.7/track/hls/createUrlHlsManifestProvider.d.ts +4 -4
  426. package/dist/types/ts4.7/track/hls/index.d.ts +1 -1
  427. package/dist/types/ts4.7/track/inferLoadOptionsFromUri.d.ts +15 -0
  428. package/dist/types/ts4.7/track/mse/MseTrack.d.ts +66 -8
  429. package/dist/types/ts4.7/track/source/SourceObjectTrack.d.ts +2 -2
  430. package/dist/types/ts4.7/track/source/SourceTrack.d.ts +2 -2
  431. package/dist/types/ts4.7/track/source/SourceTrackBase.d.ts +7 -5
  432. package/dist/types/ts4.7/util/media/codecOverrides.d.ts +33 -0
  433. package/dist/types/ts4.7/util/media/codecSupport.d.ts +6 -0
  434. package/dist/types/ts4.7/util/media/mediaSource.d.ts +5 -0
  435. package/dist/types/ts4.7/vinyl/ReadonlyPlaybackStreamingState.d.ts +9 -2
  436. package/dist/types/ts4.7/vinyl/VinylDeps.d.ts +5 -0
  437. package/dist/types/ts4.7/vinyl/VinylOptions.d.ts +68 -4
  438. package/dist/types/ts4.7/vinyl/VinylPlayer.d.ts +63 -4
  439. package/dist/types/ts4.7/vinyl/createVinylFactories.d.ts +55 -12
  440. package/dist/unit/types/current/ad/AdController.test.d.ts +2 -0
  441. package/dist/unit/types/current/ad/AdController.test.d.ts.map +1 -0
  442. package/dist/unit/types/current/ad/AdController.test.js +10 -0
  443. package/dist/unit/types/current/ad/AdControllerImpl.test.d.ts +2 -0
  444. package/dist/unit/types/current/ad/AdControllerImpl.test.d.ts.map +1 -0
  445. package/dist/unit/types/current/ad/AdControllerImpl.test.js +1456 -0
  446. package/dist/unit/types/current/ad/defaultAdLoadOptionsResolver.test.d.ts +2 -0
  447. package/dist/unit/types/current/ad/defaultAdLoadOptionsResolver.test.d.ts.map +1 -0
  448. package/dist/unit/types/current/ad/defaultAdLoadOptionsResolver.test.js +56 -0
  449. package/dist/unit/types/current/ad/discoverHlsInterstitials.test.d.ts +2 -0
  450. package/dist/unit/types/current/ad/discoverHlsInterstitials.test.d.ts.map +1 -0
  451. package/dist/unit/types/current/ad/discoverHlsInterstitials.test.js +756 -0
  452. package/dist/unit/types/current/drm/DrmControllerImpl.test.js +205 -4
  453. package/dist/unit/types/current/index.d.ts +117 -98
  454. package/dist/unit/types/current/index.d.ts.map +1 -1
  455. package/dist/unit/types/current/index.js +117 -98
  456. package/dist/unit/types/current/playback/PlaybackControllerImpl.test.js +92 -3
  457. package/dist/unit/types/current/streaming/ContentStream.test.js +11 -0
  458. package/dist/unit/types/current/streaming/ManifestControllerImpl.test.d.ts +2 -0
  459. package/dist/unit/types/current/streaming/ManifestControllerImpl.test.d.ts.map +1 -0
  460. package/dist/unit/types/current/streaming/ManifestControllerImpl.test.js +197 -0
  461. package/dist/unit/types/current/streaming/MediaTimeline.test.js +2 -0
  462. package/dist/unit/types/current/streaming/MseTrack.test.js +478 -14
  463. package/dist/unit/types/current/streaming/SegmentControllerImpl.test.js +66 -0
  464. package/dist/unit/types/current/streaming/StreamingEventMap.test.js +2 -2
  465. package/dist/unit/types/current/streaming/abr/QualitySelectorImpl.test.js +110 -0
  466. package/dist/unit/types/current/streaming/buffering/BufferingController.test.js +123 -21
  467. package/dist/unit/types/current/streaming/buffering/MediaSourceController.test.js +37 -10
  468. package/dist/unit/types/current/streaming/buffering/SourceBufferController.test.js +4 -0
  469. package/dist/unit/types/current/streaming/buffering/codecDenylist.test.d.ts +2 -0
  470. package/dist/unit/types/current/streaming/buffering/codecDenylist.test.d.ts.map +1 -0
  471. package/dist/unit/types/current/streaming/buffering/codecDenylist.test.js +56 -0
  472. package/dist/unit/types/current/streaming/createAllowedContentTypesValue.test.d.ts +2 -0
  473. package/dist/unit/types/current/streaming/createAllowedContentTypesValue.test.d.ts.map +1 -0
  474. package/dist/unit/types/current/streaming/createAllowedContentTypesValue.test.js +77 -0
  475. package/dist/unit/types/current/streaming/createDefaultMediaTimelineTransformer.test.js +144 -2
  476. package/dist/unit/types/current/streaming/mediaTimelineAccessibilityFilter.test.d.ts +2 -0
  477. package/dist/unit/types/current/streaming/mediaTimelineAccessibilityFilter.test.d.ts.map +1 -0
  478. package/dist/unit/types/current/streaming/mediaTimelineAccessibilityFilter.test.js +99 -0
  479. package/dist/unit/types/current/streaming/mediaTimelineFilter.test.js +9 -0
  480. package/dist/unit/types/current/streaming/mediaTimelineLanguageFilter.test.js +92 -3
  481. package/dist/unit/types/current/text/SidecarTextTrackController.test.d.ts +2 -0
  482. package/dist/unit/types/current/text/SidecarTextTrackController.test.d.ts.map +1 -0
  483. package/dist/unit/types/current/text/SidecarTextTrackController.test.js +587 -0
  484. package/dist/unit/types/current/text/SidecarTextTrackLoader.test.d.ts +2 -0
  485. package/dist/unit/types/current/text/SidecarTextTrackLoader.test.d.ts.map +1 -0
  486. package/dist/unit/types/current/text/SidecarTextTrackLoader.test.js +336 -0
  487. package/dist/unit/types/current/text/VttCueStyle.test.d.ts +2 -0
  488. package/dist/unit/types/current/text/VttCueStyle.test.d.ts.map +1 -0
  489. package/dist/unit/types/current/text/VttCueStyle.test.js +76 -0
  490. package/dist/unit/types/current/text/discoverDashTextTracks.test.d.ts +2 -0
  491. package/dist/unit/types/current/text/discoverDashTextTracks.test.d.ts.map +1 -0
  492. package/dist/unit/types/current/text/discoverDashTextTracks.test.js +199 -0
  493. package/dist/unit/types/current/text/discoverHlsTextTracks.test.d.ts +2 -0
  494. package/dist/unit/types/current/text/discoverHlsTextTracks.test.d.ts.map +1 -0
  495. package/dist/unit/types/current/text/discoverHlsTextTracks.test.js +177 -0
  496. package/dist/unit/types/current/text/parseWebVtt.test.d.ts +2 -0
  497. package/dist/unit/types/current/text/parseWebVtt.test.d.ts.map +1 -0
  498. package/dist/unit/types/current/text/parseWebVtt.test.js +212 -0
  499. package/dist/unit/types/current/text/pickPreferredTextTrack.test.d.ts +2 -0
  500. package/dist/unit/types/current/text/pickPreferredTextTrack.test.d.ts.map +1 -0
  501. package/dist/unit/types/current/text/pickPreferredTextTrack.test.js +67 -0
  502. package/dist/unit/types/current/track/TrackBase.test.js +50 -5
  503. package/dist/unit/types/current/track/TrackController.test.js +712 -109
  504. package/dist/unit/types/current/track/TrackFactory.test.js +13 -25
  505. package/dist/unit/types/current/track/dash/createDashContentStreamFactories.test.js +1 -0
  506. package/dist/unit/types/current/track/dash/createDashFactories.test.js +63 -2
  507. package/dist/unit/types/current/track/dash/createSegmentControllerFactory.test.js +1 -0
  508. package/dist/unit/types/current/track/dash/util/mpd.test.js +24 -1
  509. package/dist/unit/types/current/track/hls/HlsManifestController.test.js +4 -4
  510. package/dist/unit/types/current/track/hls/HlsMediaQualityMetadataResolver.test.js +4 -2
  511. package/dist/unit/types/current/track/hls/buildHlsMediaTimeline.test.js +260 -14
  512. package/dist/unit/types/current/track/hls/createHlsContentStreamFactories.test.js +1 -0
  513. package/dist/unit/types/current/track/hls/createHlsFactories.test.js +182 -4
  514. package/dist/unit/types/current/track/hls/createUrlHlsManifestProvider.test.js +19 -0
  515. package/dist/unit/types/current/track/inferLoadOptionsFromUri.test.d.ts +2 -0
  516. package/dist/unit/types/current/track/inferLoadOptionsFromUri.test.d.ts.map +1 -0
  517. package/dist/unit/types/current/track/inferLoadOptionsFromUri.test.js +165 -0
  518. package/dist/unit/types/current/track/source/SourceTrack.test.js +5 -0
  519. package/dist/unit/types/current/track/source/SourceTrackBase.test.js +24 -3
  520. package/dist/unit/types/current/tsconfig.tsbuildinfo +1 -1
  521. package/dist/unit/types/current/util/media/codecOverrides.test.d.ts +2 -0
  522. package/dist/unit/types/current/util/media/codecOverrides.test.d.ts.map +1 -0
  523. package/dist/unit/types/current/util/media/codecOverrides.test.js +42 -0
  524. package/dist/unit/types/current/util/media/codecSupport.test.d.ts +2 -0
  525. package/dist/unit/types/current/util/media/codecSupport.test.d.ts.map +1 -0
  526. package/dist/unit/types/current/util/media/codecSupport.test.js +26 -0
  527. package/dist/unit/types/current/util/media/mediaSource.test.js +6 -0
  528. package/dist/unit/types/current/vinyl/VinylPlayer.test.js +177 -75
  529. package/dist/unit/types/current/vinyl/VinylPlayerAdBreaks.test.d.ts +2 -0
  530. package/dist/unit/types/current/vinyl/VinylPlayerAdBreaks.test.d.ts.map +1 -0
  531. package/dist/unit/types/current/vinyl/VinylPlayerAdBreaks.test.js +142 -0
  532. package/dist/unit/types/current/vinyl/VinylPlayerTextTracks.test.d.ts +2 -0
  533. package/dist/unit/types/current/vinyl/VinylPlayerTextTracks.test.d.ts.map +1 -0
  534. package/dist/unit/types/current/vinyl/VinylPlayerTextTracks.test.js +263 -0
  535. package/dist/vinylTestUtil/index.js +2393 -2232
  536. package/dist/vinylTestUtil/index.js.map +4 -4
  537. package/dist/vinylTestUtil/types/current/assets/vinylTestAssets.d.ts +14 -0
  538. package/dist/vinylTestUtil/types/current/assets/vinylTestAssets.d.ts.map +1 -1
  539. package/dist/vinylTestUtil/types/current/assets/vinylTestAssets.js +49 -30
  540. package/dist/vinylTestUtil/types/current/index.d.ts +53 -51
  541. package/dist/vinylTestUtil/types/current/index.d.ts.map +1 -1
  542. package/dist/vinylTestUtil/types/current/index.js +53 -51
  543. package/dist/vinylTestUtil/types/current/mock/ad/MockAdController.d.ts +15 -0
  544. package/dist/vinylTestUtil/types/current/mock/ad/MockAdController.d.ts.map +1 -0
  545. package/dist/vinylTestUtil/types/current/mock/ad/MockAdController.js +26 -0
  546. package/dist/vinylTestUtil/types/current/mock/dash/MockDashManifestController.d.ts +8 -1
  547. package/dist/vinylTestUtil/types/current/mock/dash/MockDashManifestController.d.ts.map +1 -1
  548. package/dist/vinylTestUtil/types/current/mock/dash/MockDashManifestController.js +15 -0
  549. package/dist/vinylTestUtil/types/current/mock/dash/mockDashManifest.d.ts +12 -12
  550. package/dist/vinylTestUtil/types/current/mock/drm/MockDrmController.d.ts +2 -2
  551. package/dist/vinylTestUtil/types/current/mock/drm/MockDrmController.d.ts.map +1 -1
  552. package/dist/vinylTestUtil/types/current/mock/hls/MockHlsManifestController.d.ts +7 -1
  553. package/dist/vinylTestUtil/types/current/mock/hls/MockHlsManifestController.d.ts.map +1 -1
  554. package/dist/vinylTestUtil/types/current/mock/hls/MockHlsManifestController.js +12 -0
  555. package/dist/vinylTestUtil/types/current/mock/hls/mockHlsManifest.d.ts +3 -3
  556. package/dist/vinylTestUtil/types/current/mock/hls/mockHlsManifest.d.ts.map +1 -1
  557. package/dist/vinylTestUtil/types/current/mock/hls/mockHlsManifest.js +1 -0
  558. package/dist/vinylTestUtil/types/current/mock/player/MockVinylPlayerDependencies.d.ts +8 -0
  559. package/dist/vinylTestUtil/types/current/mock/player/MockVinylPlayerDependencies.d.ts.map +1 -1
  560. package/dist/vinylTestUtil/types/current/mock/player/MockVinylPlayerDependencies.js +17 -1
  561. package/dist/vinylTestUtil/types/current/mock/streaming/MockContentStream.d.ts +2 -1
  562. package/dist/vinylTestUtil/types/current/mock/streaming/MockContentStream.d.ts.map +1 -1
  563. package/dist/vinylTestUtil/types/current/mock/streaming/MockContentStream.js +1 -0
  564. package/dist/vinylTestUtil/types/current/mock/streaming/buffering/MockBufferingController.d.ts +1 -0
  565. package/dist/vinylTestUtil/types/current/mock/streaming/buffering/MockBufferingController.d.ts.map +1 -1
  566. package/dist/vinylTestUtil/types/current/mock/streaming/buffering/MockBufferingController.js +1 -0
  567. package/dist/vinylTestUtil/types/current/mock/streaming/buffering/MockMediaSourceController.d.ts +2 -1
  568. package/dist/vinylTestUtil/types/current/mock/streaming/buffering/MockMediaSourceController.d.ts.map +1 -1
  569. package/dist/vinylTestUtil/types/current/mock/streaming/buffering/MockMediaSourceController.js +2 -1
  570. package/dist/vinylTestUtil/types/current/mock/text/MockTextTrackController.d.ts +10 -0
  571. package/dist/vinylTestUtil/types/current/mock/text/MockTextTrackController.d.ts.map +1 -0
  572. package/dist/vinylTestUtil/types/current/mock/text/MockTextTrackController.js +14 -0
  573. package/dist/vinylTestUtil/types/current/mock/track/MockTrack.d.ts +13 -4
  574. package/dist/vinylTestUtil/types/current/mock/track/MockTrack.d.ts.map +1 -1
  575. package/dist/vinylTestUtil/types/current/mock/track/MockTrack.js +11 -0
  576. package/dist/vinylTestUtil/types/current/mock/track/MockTrackController.d.ts +3 -2
  577. package/dist/vinylTestUtil/types/current/mock/track/MockTrackController.d.ts.map +1 -1
  578. package/dist/vinylTestUtil/types/current/mock/track/MockTrackController.js +2 -1
  579. package/dist/vinylTestUtil/types/current/mock/track/dash/createMockDashDependencies.d.ts +6 -0
  580. package/dist/vinylTestUtil/types/current/mock/track/dash/createMockDashDependencies.d.ts.map +1 -1
  581. package/dist/vinylTestUtil/types/current/mock/track/dash/createMockDashDependencies.js +8 -1
  582. package/dist/vinylTestUtil/types/current/mock/track/hls/createMockHlsDependencies.d.ts +4 -0
  583. package/dist/vinylTestUtil/types/current/mock/track/hls/createMockHlsDependencies.d.ts.map +1 -1
  584. package/dist/vinylTestUtil/types/current/mock/track/hls/createMockHlsDependencies.js +6 -1
  585. package/dist/vinylTestUtil/types/current/player/createVinylSuite.d.ts.map +1 -1
  586. package/dist/vinylTestUtil/types/current/player/createVinylSuite.js +18 -7
  587. package/dist/vinylTestUtil/types/current/tsconfig.tsbuildinfo +1 -1
  588. package/dist/vinylTestUtil/types/current/util/playback/eventPromises.d.ts.map +1 -1
  589. package/dist/vinylTestUtil/types/current/util/playback/eventPromises.js +1 -1
  590. package/dist/vinylTestUtil/types/current/util/playback/expectTrackCanSeek.d.ts.map +1 -1
  591. package/dist/vinylTestUtil/types/current/util/playback/expectTrackCanSeek.js +5 -2
  592. package/dist/vinylTestUtil/types/current/util/playback/expectTrackPlays.js +3 -3
  593. package/dist/vinylTestUtil/types/current/util/playback/expectTrackPlaysUntil.d.ts.map +1 -1
  594. package/dist/vinylTestUtil/types/current/util/playback/expectTrackPlaysUntil.js +11 -7
  595. package/dist/vinylTestUtil/types/ts3.7/assets/vinylTestAssets.d.ts +14 -0
  596. package/dist/vinylTestUtil/types/ts3.7/index.d.ts +53 -51
  597. package/dist/vinylTestUtil/types/ts3.7/mock/ad/MockAdController.d.ts +15 -0
  598. package/dist/vinylTestUtil/types/ts3.7/mock/dash/MockDashManifestController.d.ts +8 -1
  599. package/dist/vinylTestUtil/types/ts3.7/mock/dash/mockDashManifest.d.ts +12 -12
  600. package/dist/vinylTestUtil/types/ts3.7/mock/drm/MockDrmController.d.ts +2 -2
  601. package/dist/vinylTestUtil/types/ts3.7/mock/hls/MockHlsManifestController.d.ts +7 -1
  602. package/dist/vinylTestUtil/types/ts3.7/mock/hls/mockHlsManifest.d.ts +3 -3
  603. package/dist/vinylTestUtil/types/ts3.7/mock/player/MockVinylPlayerDependencies.d.ts +8 -0
  604. package/dist/vinylTestUtil/types/ts3.7/mock/streaming/MockContentStream.d.ts +2 -1
  605. package/dist/vinylTestUtil/types/ts3.7/mock/streaming/buffering/MockBufferingController.d.ts +1 -0
  606. package/dist/vinylTestUtil/types/ts3.7/mock/streaming/buffering/MockMediaSourceController.d.ts +2 -1
  607. package/dist/vinylTestUtil/types/ts3.7/mock/text/MockTextTrackController.d.ts +10 -0
  608. package/dist/vinylTestUtil/types/ts3.7/mock/track/MockTrack.d.ts +13 -4
  609. package/dist/vinylTestUtil/types/ts3.7/mock/track/MockTrackController.d.ts +3 -2
  610. package/dist/vinylTestUtil/types/ts3.7/mock/track/dash/createMockDashDependencies.d.ts +6 -0
  611. package/dist/vinylTestUtil/types/ts3.7/mock/track/hls/createMockHlsDependencies.d.ts +4 -0
  612. package/dist/vinylTestUtil/types/ts4.1/assets/vinylTestAssets.d.ts +14 -0
  613. package/dist/vinylTestUtil/types/ts4.1/index.d.ts +53 -51
  614. package/dist/vinylTestUtil/types/ts4.1/mock/ad/MockAdController.d.ts +15 -0
  615. package/dist/vinylTestUtil/types/ts4.1/mock/dash/MockDashManifestController.d.ts +8 -1
  616. package/dist/vinylTestUtil/types/ts4.1/mock/dash/mockDashManifest.d.ts +12 -12
  617. package/dist/vinylTestUtil/types/ts4.1/mock/drm/MockDrmController.d.ts +2 -2
  618. package/dist/vinylTestUtil/types/ts4.1/mock/hls/MockHlsManifestController.d.ts +7 -1
  619. package/dist/vinylTestUtil/types/ts4.1/mock/hls/mockHlsManifest.d.ts +3 -3
  620. package/dist/vinylTestUtil/types/ts4.1/mock/player/MockVinylPlayerDependencies.d.ts +8 -0
  621. package/dist/vinylTestUtil/types/ts4.1/mock/streaming/MockContentStream.d.ts +2 -1
  622. package/dist/vinylTestUtil/types/ts4.1/mock/streaming/buffering/MockBufferingController.d.ts +1 -0
  623. package/dist/vinylTestUtil/types/ts4.1/mock/streaming/buffering/MockMediaSourceController.d.ts +2 -1
  624. package/dist/vinylTestUtil/types/ts4.1/mock/text/MockTextTrackController.d.ts +10 -0
  625. package/dist/vinylTestUtil/types/ts4.1/mock/track/MockTrack.d.ts +13 -4
  626. package/dist/vinylTestUtil/types/ts4.1/mock/track/MockTrackController.d.ts +3 -2
  627. package/dist/vinylTestUtil/types/ts4.1/mock/track/dash/createMockDashDependencies.d.ts +6 -0
  628. package/dist/vinylTestUtil/types/ts4.1/mock/track/hls/createMockHlsDependencies.d.ts +4 -0
  629. package/dist/vinylTestUtil/types/ts4.7/assets/vinylTestAssets.d.ts +14 -0
  630. package/dist/vinylTestUtil/types/ts4.7/index.d.ts +53 -51
  631. package/dist/vinylTestUtil/types/ts4.7/mock/ad/MockAdController.d.ts +15 -0
  632. package/dist/vinylTestUtil/types/ts4.7/mock/dash/MockDashManifestController.d.ts +8 -1
  633. package/dist/vinylTestUtil/types/ts4.7/mock/dash/mockDashManifest.d.ts +12 -12
  634. package/dist/vinylTestUtil/types/ts4.7/mock/drm/MockDrmController.d.ts +2 -2
  635. package/dist/vinylTestUtil/types/ts4.7/mock/hls/MockHlsManifestController.d.ts +7 -1
  636. package/dist/vinylTestUtil/types/ts4.7/mock/hls/mockHlsManifest.d.ts +3 -3
  637. package/dist/vinylTestUtil/types/ts4.7/mock/player/MockVinylPlayerDependencies.d.ts +8 -0
  638. package/dist/vinylTestUtil/types/ts4.7/mock/streaming/MockContentStream.d.ts +2 -1
  639. package/dist/vinylTestUtil/types/ts4.7/mock/streaming/buffering/MockBufferingController.d.ts +1 -0
  640. package/dist/vinylTestUtil/types/ts4.7/mock/streaming/buffering/MockMediaSourceController.d.ts +2 -1
  641. package/dist/vinylTestUtil/types/ts4.7/mock/text/MockTextTrackController.d.ts +10 -0
  642. package/dist/vinylTestUtil/types/ts4.7/mock/track/MockTrack.d.ts +13 -4
  643. package/dist/vinylTestUtil/types/ts4.7/mock/track/MockTrackController.d.ts +3 -2
  644. package/dist/vinylTestUtil/types/ts4.7/mock/track/dash/createMockDashDependencies.d.ts +6 -0
  645. package/dist/vinylTestUtil/types/ts4.7/mock/track/hls/createMockHlsDependencies.d.ts +4 -0
  646. package/docs/ADS.md +264 -0
  647. package/docs/USAGE.md +142 -9
  648. package/package.json +18 -18
  649. package/dist/types/current/track/hls/HlsManifestProvider.d.ts.map +0 -1
  650. package/dist/unit/types/current/track/dash/DashManifestController.test.d.ts +0 -2
  651. package/dist/unit/types/current/track/dash/DashManifestController.test.d.ts.map +0 -1
  652. package/dist/unit/types/current/track/dash/DashManifestController.test.js +0 -186
  653. /package/dist/types/current/{track/hls/HlsManifestProvider.js → ad/AdBreakInfo.js} +0 -0
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../src/index.ts", "../src/vinyl/playerConfigFactory.ts", "../src/client/Capabilities.ts", "../src/util/media/mediaSource.ts", "../src/util/media/getAudioContext.ts", "../src/client/CapabilitiesImpl.ts", "../src/vinyl/createVinylFactories.ts", "../src/patch/media/patchMediaElement.ts", "../src/patch/media/patches/createUnreliablePlaybackEventsPatch.ts", "../src/patch/media/patches/createPreventStallsPatch.ts", "../src/playback/PlaybackControllerImpl.ts", "../src/playback/PlaybackController.ts", "../src/playback/ReadonlyPlaybackController.ts", "../src/playback/error/InvalidSeekError.ts", "../src/playback/logging/playbackStateLoggingHandler.ts", "../src/event/ChangeEvent.ts", "../src/playback/nextHasMetadata.ts", "../src/playback/error/ReportableMediaError.ts", "../src/playback/logging/mediaErrorToJson.ts", "../src/playback/PlaybackSourceImpl.ts", "../src/track/TrackFactory.ts", "../src/track/source/SourceObjectTrack.ts", "../src/track/TrackBase.ts", "../src/drm/DrmOptions.ts", "../src/drm/DrmKeySystem.ts", "../src/drm/licenseProvider/LicenseProvider.ts", "../src/track/source/FixedPlaybackQuality.ts", "../src/track/source/SourceTrackBase.ts", "../src/streaming/MediaQualityMetadata.ts", "../src/streaming/DescriptorRecord.ts", "../src/track/source/SourceTrack.ts", "../src/track/dash/DashTrack.ts", "../src/track/mse/MseTrack.ts", "../src/streaming/MediaTimeline.ts", "../src/track/hls/HlsTrack.ts", "../src/track/createVinylTrackFactories.ts", "../src/track/TrackController.ts", "../src/patch/media/MediaElementPatchOptions.ts", "../src/vinyl/VinylPatchOptions.ts", "../src/track/dash/util/mpd.ts", "../src/track/dash/util/uriResolution.ts", "../src/track/dash/createDefaultDashManifestTransformer.ts", "../src/track/dash/manifestTransformUtils.ts", "../src/track/dash/DashMediaQualityMetadataResolver.ts", "../src/track/mse/codec.ts", "../src/track/dash/util/mimeType.ts", "../src/drm/CencEncryptionScheme.ts", "../src/streaming/buffering/MediaSourceController.ts", "../src/util/media/sourceBuffer.ts", "../src/streaming/buffering/error/SourceBufferError.ts", "../src/track/dash/DashManifestController.ts", "../src/streaming/buffering/SourceBufferController.ts", "../src/streaming/buffering/BufferingController.ts", "../src/streaming/SegmentController.ts", "../src/streaming/SegmentControllerImpl.ts", "../src/streaming/SegmentDataSlot.ts", "../src/streaming/SegmentPrefetch.ts", "../src/streaming/util/segment.ts", "../src/track/dash/createDashContentStreamFactories.ts", "../src/streaming/abr/QualitySelectorImpl.ts", "../src/track/dash/createDashFactories.ts", "../src/track/dash/urlDashManifestProvider.ts", "../src/track/dash/createDashManifestProvider.ts", "../src/streaming/ContentStream.ts", "../src/track/dash/createDashContentTypesValue.ts", "../src/track/dash/timeline/DashRepresentationSegmentProvider.ts", "../src/track/createSegmentDataProvider.ts", "../src/track/dash/buildDashMediaTimeline.ts", "../src/streaming/createDefaultMediaTimelineTransformer.ts", "../src/streaming/mediaTimelineFilter.ts", "../src/streaming/mediaTimelineLanguageFilter.ts", "../src/track/filters/languageFilter.ts", "../src/track/filters/resourceTypeFilter.ts", "../src/track/filters/keySystemFilter.ts", "../src/track/filters/sampleRateFilter.ts", "../src/track/hls/HlsMediaQualityMetadataResolver.ts", "../src/track/hls/HlsManifestController.ts", "../src/track/hls/createHlsFactories.ts", "../src/track/hls/createUrlHlsManifestProvider.ts", "../src/track/hls/createHlsContentTypesValue.ts", "../src/track/hls/createHlsContentStreamFactories.ts", "../src/track/hls/createDefaultHlsManifestTransformer.ts", "../src/track/hls/util/hlsByteRangeToMediaRange.ts", "../src/track/hls/util/hlsSegmentTime.ts", "../src/track/hls/buildHlsMediaTimeline.ts", "../src/drm/commonEme/MsCommonEme.ts", "../src/drm/commonEme/CommonEme.ts", "../src/drm/error/DrmError.ts", "../src/drm/commonEme/StandardCommonEme.ts", "../src/drm/commonEme/createDrmErrorHandler.ts", "../src/drm/commonEme/WebKitCommonEme.ts", "../src/drm/commonEme/CommonEmeFactory.ts", "../src/drm/DrmControllerImpl.ts", "../src/drm/util/unpackPlayReadyChallenge.ts", "../src/drm/licenseProvider/defaultLicenseProvider.ts", "../src/drm/util/extractContentId.ts", "../src/drm/util/createFairPlaySessionInitData.ts", "../src/drm/DrmKeySystemResolver.ts", "../src/playback/loudness/LoudnessNormalizationControllerImpl.ts", "../src/playback/loudness/LoudnessNormalizationControllerImplOptions.ts", "../src/track/AutoResetController.ts", "../src/vinyl/VinylOptions.ts", "../src/vinyl/VinylPlayer.ts", "../src/global/PlayerRegistry.ts", "../src/global/initializeVinylGlobal.ts", "../src/global/globalRef.ts", "../src/global/environment.ts", "../src/streaming/StreamingEventMap.ts", "../src/track/dash/createSegmentControllerFactory.ts", "../src/global/configureVinylGlobal.ts"],
4
- "sourcesContent": ["/** Auto-generated from build scripts */\nexport * from './vinyl/playerConfigFactory'\nexport * from './vinyl/createVinylFactories'\nexport * from './vinyl/VinylPlayer'\nexport * from './vinyl/VinylPatchOptions'\nexport * from './vinyl/VinylOptions'\nexport * from './vinyl/VinylDeps'\nexport * from './vinyl/ReadonlyPlaybackStreamingState'\nexport * from './util/media/sourceBuffer'\nexport * from './util/media/mediaSource'\nexport * from './util/media/getAudioContext'\nexport * from './track/createVinylTrackFactories'\nexport * from './track/createSegmentDataProvider'\nexport * from './track/TrackFactory'\nexport * from './track/TrackController'\nexport * from './track/TrackBase'\nexport * from './track/Track'\nexport * from './track/AutoResetController'\nexport * from './track/source/SourceTrackBase'\nexport * from './track/source/SourceTrack'\nexport * from './track/source/SourceObjectTrack'\nexport * from './track/source/FixedPlaybackQuality'\nexport * from './track/mse/codec'\nexport * from './track/mse/MseTrack'\nexport * from './track/hls/createUrlHlsManifestProvider'\nexport * from './track/hls/createHlsFactories'\nexport * from './track/hls/createHlsContentTypesValue'\nexport * from './track/hls/createHlsContentStreamFactories'\nexport * from './track/hls/createDefaultHlsManifestTransformer'\nexport * from './track/hls/buildHlsMediaTimeline'\nexport * from './track/hls/HlsTrack'\nexport * from './track/hls/HlsMediaQualityMetadataResolver'\nexport * from './track/hls/HlsManifestProvider'\nexport * from './track/hls/HlsManifestController'\nexport * from './track/hls/util/hlsSegmentTime'\nexport * from './track/hls/util/hlsByteRangeToMediaRange'\nexport * from './track/filters/sampleRateFilter'\nexport * from './track/filters/resourceTypeFilter'\nexport * from './track/filters/languageFilter'\nexport * from './track/filters/keySystemFilter'\nexport * from './track/dash/urlDashManifestProvider'\nexport * from './track/dash/manifestTransformUtils'\nexport * from './track/dash/createSegmentControllerFactory'\nexport * from './track/dash/createDefaultDashManifestTransformer'\nexport * from './track/dash/createDashManifestProvider'\nexport * from './track/dash/createDashFactories'\nexport * from './track/dash/createDashContentTypesValue'\nexport * from './track/dash/createDashContentStreamFactories'\nexport * from './track/dash/buildDashMediaTimeline'\nexport * from './track/dash/DashTrack'\nexport * from './track/dash/DashMediaQualityMetadataResolver'\nexport * from './track/dash/DashManifestProvider'\nexport * from './track/dash/DashManifestController'\nexport * from './track/dash/util/uriResolution'\nexport * from './track/dash/util/mpd'\nexport * from './track/dash/util/mimeType'\nexport * from './track/dash/timeline/DashRepresentationSegmentProvider'\nexport * from './streaming/mediaTimelineLanguageFilter'\nexport * from './streaming/mediaTimelineFilter'\nexport * from './streaming/createDefaultMediaTimelineTransformer'\nexport * from './streaming/StreamingEventMap'\nexport * from './streaming/SegmentReference'\nexport * from './streaming/SegmentPrefetch'\nexport * from './streaming/SegmentDataSlot'\nexport * from './streaming/SegmentControllerImpl'\nexport * from './streaming/SegmentController'\nexport * from './streaming/MediaTimeline'\nexport * from './streaming/MediaQualityMetadata'\nexport * from './streaming/ManifestController'\nexport * from './streaming/DrmInitDataType'\nexport * from './streaming/DescriptorRecord'\nexport * from './streaming/ContentTypesValue'\nexport * from './streaming/ContentStreamingOptions'\nexport * from './streaming/ContentStream'\nexport * from './streaming/util/segment'\nexport * from './streaming/buffering/SourceBufferController'\nexport * from './streaming/buffering/MediaSourceController'\nexport * from './streaming/buffering/BufferingController'\nexport * from './streaming/buffering/error/SourceBufferError'\nexport * from './streaming/abr/QualitySelectorImpl'\nexport * from './streaming/abr/QualitySelector'\nexport * from './playback/nextHasMetadata'\nexport * from './playback/ReadonlyPlaybackController'\nexport * from './playback/PlaybackSourceImpl'\nexport * from './playback/PlaybackSource'\nexport * from './playback/PlaybackControllerImpl'\nexport * from './playback/PlaybackController'\nexport * from './playback/loudness/LoudnessNormalizationControllerImplOptions'\nexport * from './playback/loudness/LoudnessNormalizationControllerImpl'\nexport * from './playback/loudness/LoudnessNormalizationController'\nexport * from './playback/logging/playbackStateLoggingHandler'\nexport * from './playback/logging/mediaErrorToJson'\nexport * from './playback/error/ReportableMediaError'\nexport * from './playback/error/InvalidSeekError'\nexport * from './patch/media/patchMediaElement'\nexport * from './patch/media/MediaElementPatchOptions'\nexport * from './patch/media/HtmlMediaElementPatch'\nexport * from './patch/media/patches/createUnreliablePlaybackEventsPatch'\nexport * from './patch/media/patches/createPreventStallsPatch'\nexport * from './global/initializeVinylGlobal'\nexport * from './global/globalRef'\nexport * from './global/environment'\nexport * from './global/configureVinylGlobal'\nexport * from './global/PlayerRegistry'\nexport * from './event/ChangeEvent'\nexport * from './event/BasicErrorEvent'\nexport * from './drm/DrmOptions'\nexport * from './drm/DrmKeySystemResolver'\nexport * from './drm/DrmKeySystem'\nexport * from './drm/DrmControllerImpl'\nexport * from './drm/DrmController'\nexport * from './drm/CencEncryptionScheme'\nexport * from './drm/util/unpackPlayReadyChallenge'\nexport * from './drm/util/extractContentId'\nexport * from './drm/util/createFairPlaySessionInitData'\nexport * from './drm/licenseProvider/defaultLicenseProvider'\nexport * from './drm/licenseProvider/LicenseProvider'\nexport * from './drm/error/DrmError'\nexport * from './drm/dom/WebKitMediaKeys'\nexport * from './drm/dom/MSMediaKeys'\nexport * from './drm/dom/HTMLMediaElement'\nexport * from './drm/commonEme/createDrmErrorHandler'\nexport * from './drm/commonEme/WebKitCommonEme'\nexport * from './drm/commonEme/StandardCommonEme'\nexport * from './drm/commonEme/MsCommonEme'\nexport * from './drm/commonEme/EncryptedInitData'\nexport * from './drm/commonEme/CommonEmeFactory'\nexport * from './drm/commonEme/CommonEme'\nexport * from './client/Client'\nexport * from './client/CapabilitiesImpl'\nexport * from './client/Capabilities'\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { data, type MutableValue } from '@amazon/vinyl-observable'\nimport type { AddDisposable, AnyRecord } from '@amazon/vinyl-util'\nimport type { Validator } from '@amazon/vinyl-validation'\n\nexport function playerConfigFactory<T>(\n defaults: T,\n validator: Validator<T>\n): (_deps: AnyRecord, add: AddDisposable) => MutableValue<T> {\n return (_deps, add) => {\n const config = data<T>(defaults)\n add(\n config.onData((data) => {\n // Throws if data does not pass validation\n validator.assert(data)\n })\n )\n return config\n }\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { DrmKeySystem } from '../drm/DrmKeySystem'\nimport type { DrmKeySystemSupport } from '../drm/DrmController'\n\nexport enum CanPlayTypeResult {\n /**\n * The media cannot be played on the current device.\n */\n NO = 'no',\n\n /**\n * There is not enough information to determine whether the media can play.\n */\n MAYBE = 'maybe',\n\n /**\n * The media is probably playable on this device.\n */\n PROBABLY = 'probably',\n}\n\n/**\n * Detected capabilities of the device.\n */\nexport interface Capabilities {\n /**\n * Returns true if Media Source Extensions are supported.\n *\n * Note that this does not test DRM or any DRM key systems.\n */\n readonly mse: boolean\n\n /**\n * Returns true if Encrypted Media Extensions are supported.\n */\n readonly eme: boolean\n\n /**\n * Returns true if native Dynamic Adaptive Streaming is supported.\n *\n * (Legacy Edge 12-18 and XBox One)\n * Note that this is not the same as supporting a dash track.\n */\n readonly dash: boolean\n\n /**\n * Returns true if native HTTP Live Streaming is supported.\n *\n * iOS 7.0+, Safari 8.0+\n * Note that this does not do FairPlay detection.\n */\n readonly hls: boolean\n\n /**\n * Returns the sample rate, in samples per second, that this platform supports.\n * Returns null if the sample rate cannot be determined.\n */\n readonly sampleRate: number | null\n\n /**\n * Returns a string that specifies whether the client can play a given media resource type for progressive\n * content.\n *\n * @param type A string specifying the MIME type of the media and (optionally) a codecs\n * parameter containing a comma-separated list of the supported codecs.\n */\n canPlayType(type: string): CanPlayTypeResult\n\n /**\n * Returns a boolean that specifies whether the client can play a given media resource type for streaming\n * content with media source extensions.\n *\n * @param type A string specifying the MIME type of the media and (optionally) a codecs\n * parameter containing a comma-separated list of the supported codecs.\n */\n canPlayTypeMse(type: string): boolean\n\n /**\n * Returns a promise describing support for the given key system.\n *\n * @param keySystem\n */\n supportsKeySystem(keySystem: DrmKeySystem): Promise<DrmKeySystemSupport>\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { MediaUnsupportedError } from '@amazon/vinyl-util'\nimport type { Unsubscribe } from '@amazon/vinyl-util'\nimport type { SignalOptions } from '@amazon/vinyl-util'\nimport { withTimeout } from '@amazon/vinyl-util'\n\ndeclare global {\n var ManagedMediaSource: typeof MediaSource | undefined\n}\n\n/**\n * Returns true if the UA supports media source extensions.\n */\nexport function supportsMse(): boolean {\n return (\n typeof ManagedMediaSource === 'function' ||\n typeof MediaSource === 'function'\n )\n}\n\n/**\n * Returns ManagedMediaSource or MediaSource.\n */\nfunction getMediaSourceCtor(): typeof MediaSource {\n if (typeof ManagedMediaSource === 'function') return ManagedMediaSource\n else return MediaSource\n}\n\n/**\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaSource/isTypeSupported_static)\n */\nexport function isTypeSupported(type: string): boolean {\n assertMseSupported()\n return getMediaSourceCtor().isTypeSupported(type)\n}\n\n/**\n * Constructs a new ManagedMediaSource or MediaSource.\n */\nexport function createMediaSource(): MediaSource {\n assertMseSupported()\n return new (getMediaSourceCtor())()\n}\n\n/**\n * Throws a MediaUnsupportedError if MSE is not supported.\n */\nexport function assertMseSupported(): void {\n if (!supportsMse())\n throw new MediaUnsupportedError(\n 'Media Source Extensions not supported',\n 'mse-unsupported'\n )\n}\n\n/**\n * Invokes a callback when the media source is open.\n * The callback will be invoked immediately if already open.\n */\nexport function onMediaSourceOpen(\n mediaSource: MediaSource,\n callback: () => void,\n options?: SignalOptions\n): Unsubscribe {\n const open = mediaSource.readyState === 'open'\n if (open) callback()\n const handler = () => callback()\n if (!options?.once || !open) {\n // compatibility note: MediaSource.addEventListener is more widely supported than onsourceopen\n // https://caniuse.com/mdn-api_mediasource_sourceopen_event\n mediaSource.addEventListener('sourceopen', handler, options)\n return () => mediaSource.removeEventListener('sourceopen', handler)\n } else {\n return () => {}\n }\n}\n\n/**\n * Invokes a callback when the media source is next ended.\n * The callback will be invoked immediately if already ended.\n */\nexport function onMediaSourceEnded(\n mediaSource: MediaSource,\n callback: () => void,\n options?: SignalOptions\n): Unsubscribe {\n const ended = mediaSource.readyState === 'ended'\n if (ended) callback()\n const handler = () => callback()\n if (!options?.once || !ended) {\n mediaSource.addEventListener('sourceended', handler, options)\n return () => mediaSource.removeEventListener('sourceended', handler)\n } else {\n return () => {}\n }\n}\n\n/**\n * Returns a Promise that resolves when the media source is next in an 'ended' state.\n *\n * @param mediaSource\n * @param timeout The number of seconds before rejecting with a TimeoutError.\n * @param timeoutMessage\n */\nexport function nextMediaSourceEnded(\n mediaSource: MediaSource,\n timeout: number = 5,\n timeoutMessage?: string\n): Promise<void> {\n return withTimeout(\n new Promise((resolve) => {\n onMediaSourceEnded(mediaSource, resolve, { once: true })\n }),\n timeout,\n timeoutMessage\n )\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { globalRef, lazy } from '@amazon/vinyl-util'\n\ntype MaybeAudioContext = typeof AudioContext | undefined\n\ndeclare global {\n var webkitAudioContext: MaybeAudioContext\n}\n\n/**\n * Creates a new AudioContext.\n * Returns null if not supported on this platform.\n */\nexport function createAudioContext(): AudioContext | null {\n const ctor =\n (global.AudioContext as MaybeAudioContext) ?? global.webkitAudioContext\n return ctor ? new ctor() : null\n}\n\n/**\n * Some devices have a hard limit to how many audio context objects can be created.\n * Uses a lazy instance to ensure only one context is created, even within integ tests.\n */\nconst audioContextSingleton = /* @__PURE__ */ lazy(createAudioContext)\n\n/**\n * The audio context global reference.\n */\nexport const audioContextRef = /* @__PURE__ */ globalRef<AudioContext | null>(\n () => audioContextSingleton.value\n)\n\n/**\n * Returns an AudioContext singleton, or returns null if not supported on this platform.\n *\n * If the first time this is called is outside a user gesture, the AudioContext will be unable to start in a\n * running state.\n */\nexport function getAudioContext(): AudioContext | null {\n return audioContextRef.value\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { type DrmKeySystem } from '../drm/DrmKeySystem'\nimport type { Capabilities } from './Capabilities'\nimport { CanPlayTypeResult } from './Capabilities'\nimport { isTypeSupported, supportsMse } from '../util/media/mediaSource'\nimport { getAudioContext } from '../util/media/getAudioContext'\nimport type { DrmController, DrmKeySystemSupport } from '../drm/DrmController'\n\n/**\n * Dependencies for CapabilitiesImpl.\n */\nexport interface CapabilitiesImplDeps {\n readonly media: HTMLMediaElement\n readonly drmController: DrmController\n}\n\n/**\n * Client support detection.\n */\nexport class CapabilitiesImpl implements Capabilities {\n constructor(private readonly deps: CapabilitiesImplDeps) {}\n\n get mse(): boolean {\n return supportsMse()\n }\n\n get dash(): boolean {\n return this.canPlayType('application/dash+xml') !== CanPlayTypeResult.NO\n }\n\n get hls(): boolean {\n return (\n this.canPlayType('application/vnd.apple.mpegurl') !==\n CanPlayTypeResult.NO\n )\n }\n\n get eme(): boolean {\n return this.deps.drmController.isEmeSupported()\n }\n\n get sampleRate(): number | null {\n return getAudioContext()?.sampleRate ?? null\n }\n\n canPlayType(type: string): CanPlayTypeResult {\n const media: HTMLMediaElement = this.deps.media\n if (typeof media.canPlayType === 'undefined')\n return CanPlayTypeResult.NO\n const str = media.canPlayType(type)\n switch (str) {\n case '':\n return CanPlayTypeResult.NO\n case 'maybe':\n return CanPlayTypeResult.MAYBE\n case 'probably':\n return CanPlayTypeResult.PROBABLY\n }\n }\n\n canPlayTypeMse(type: string): boolean {\n return isTypeSupported(type)\n }\n\n async supportsKeySystem(\n keySystem: DrmKeySystem\n ): Promise<DrmKeySystemSupport> {\n // Take the most commonly supported codec and media format, check the DrmController if\n // it is supported with the given key system.\n return this.deps.drmController.isSupported({\n initDataType: 'cenc',\n encryptionScheme: 'cenc',\n contentType: 'audio',\n mimeType: 'audio/mp4; codecs=\"mp4a.40.2\"',\n contentProtections: [{ keySystem }],\n })\n }\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { CapabilitiesImplDeps } from '../client/CapabilitiesImpl'\nimport { CapabilitiesImpl } from '../client/CapabilitiesImpl'\nimport type { Merge, PartialDeep, PatchedRef } from '@amazon/vinyl-util'\nimport { mergeDeep, noop } from '@amazon/vinyl-util'\nimport { patchMediaElement } from '../patch/media/patchMediaElement'\nimport type {\n PlaybackControllerImplDeps,\n PlaybackControllerImplOptions,\n} from '../playback/PlaybackControllerImpl'\nimport { PlaybackControllerImpl } from '../playback/PlaybackControllerImpl'\nimport type { PlaybackSourceImplDeps } from '../playback/PlaybackSourceImpl'\nimport { PlaybackSourceImpl } from '../playback/PlaybackSourceImpl'\nimport {\n createVinylTrackFactories,\n type VinylTrackFactoryDeps,\n} from '../track/createVinylTrackFactories'\nimport type {\n TrackControllerImplDeps,\n TrackControllerImplOptions,\n} from '../track/TrackController'\nimport { TrackControllerImpl } from '../track/TrackController'\nimport { createTrackFactory } from '../track/TrackFactory'\nimport type { VinylDeps } from './VinylDeps'\nimport type { VinylPatchOptions } from './VinylPatchOptions'\nimport { defaultPatchOptions } from './VinylPatchOptions'\nimport { type QualitySelectorImplOptions } from '../streaming/abr/QualitySelectorImpl'\nimport { createDashFactories } from '../track/dash/createDashFactories'\nimport { createHlsFactories } from '../track/hls/createHlsFactories'\nimport { type DrmOptions } from '../drm/DrmOptions'\nimport { commonEmeFactory } from '../drm/commonEme/CommonEmeFactory'\nimport {\n DrmControllerImpl,\n type DrmControllerImplDeps,\n} from '../drm/DrmControllerImpl'\nimport { defaultDrmKeySystemResolver } from '../drm/DrmKeySystemResolver'\nimport { LoudnessNormalizationControllerImpl } from '../playback/loudness/LoudnessNormalizationControllerImpl'\nimport {\n AutoResetControllerImpl,\n type AutoResetControllerImplDeps,\n type AutoResetControllerImplOptions,\n} from '../track/AutoResetController'\nimport type { Dependencies, Factories } from '@amazon/vinyl-di'\nimport { validateFactories } from '@amazon/vinyl-di'\nimport type { ContentStreamingOptions } from '../streaming/ContentStreamingOptions'\nimport {\n defaultVinylOptions,\n type VinylOptions,\n vinylOptionsValidator,\n} from './VinylOptions'\nimport { playerConfigFactory } from './playerConfigFactory'\nimport type { ObservableValue } from '@amazon/vinyl-observable'\n\n/**\n * Configuration used by the default dependency factories for Vinyl.\n *\n * These options are used during player construction, changes after construction will have no\n * effect.\n */\nexport interface VinylDependencyOptions {\n /**\n * The media element.\n */\n readonly media: HTMLMediaElement\n\n /**\n * Flags for patches that should be applied browser-specifically.\n * These will be defaulted based on the user-agent.\n */\n readonly patches?: PartialDeep<VinylPatchOptions>\n\n /**\n * Configuration for the track controller.\n */\n readonly trackController?: Partial<TrackControllerImplOptions>\n\n /**\n * Configuration for the playback controller.\n */\n readonly playbackController?: Partial<PlaybackControllerImplOptions>\n\n /**\n * Configuration for segmented streaming tracks (hls / dash).\n */\n readonly streaming?: PartialDeep<ContentStreamingOptions>\n\n /**\n * Configuration for all drm-related components.\n */\n readonly drm?: Partial<DrmOptions>\n\n /**\n * Configuration for adaptive bitrate switching.\n */\n readonly abr?: PartialDeep<QualitySelectorImplOptions>\n\n /**\n * Configuration for auto-reset behavior.\n */\n readonly autoReset?: Partial<AutoResetControllerImplOptions>\n}\n\n/**\n * Creates the dependency factories for a standard player.\n *\n * @param options\n */\nexport function createVinylFactories(options: VinylDependencyOptions) {\n const patches = mergeDeep([\n defaultPatchOptions.value,\n options.patches ?? {},\n ])\n return validateFactories({\n options: playerConfigFactory<VinylOptions>(\n defaultVinylOptions,\n vinylOptionsValidator\n ),\n patchedMedia: (): PatchedRef<HTMLMediaElement> => {\n // Patches the media element if necessary.\n return patchMediaElement(options.media, patches.media)\n },\n media: (deps: {\n readonly patchedMedia: {\n readonly patched: HTMLMediaElement\n }\n }): HTMLMediaElement => deps.patchedMedia.patched,\n playbackController: (deps: PlaybackControllerImplDeps) =>\n new PlaybackControllerImpl(deps, options.playbackController),\n playbackSource: (deps: PlaybackSourceImplDeps) =>\n new PlaybackSourceImpl(deps),\n loudnessNormalizationController: (deps: {\n options: ObservableValue<\n Pick<VinylOptions, 'loudnessNormalization'>\n >\n }) =>\n new LoudnessNormalizationControllerImpl({\n options: deps.options.pick('loudnessNormalization'),\n }),\n capabilities: (deps: CapabilitiesImplDeps) =>\n new CapabilitiesImpl(deps),\n requestInterceptor: () => noop,\n trackFactory: (deps: VinylTrackFactoryDeps) =>\n createTrackFactory(createVinylTrackFactories(deps)),\n trackController: (deps: TrackControllerImplDeps<any>) =>\n new TrackControllerImpl<any>(deps, options.trackController),\n drmKeySystemResolver: () => defaultDrmKeySystemResolver,\n drmController: (deps: DrmControllerImplDeps) =>\n new DrmControllerImpl(deps, options.drm),\n commonEme: commonEmeFactory,\n autoResetController: (deps: AutoResetControllerImplDeps) =>\n new AutoResetControllerImpl(deps, options.autoReset),\n createDashFactories: createDashFactories(options),\n createHlsFactories: createHlsFactories(options),\n } as const) satisfies Factories<VinylDeps>\n}\n\n/**\n * The dependency map type of the default player dependency factories.\n */\nexport type DefaultVinylFactories = ReturnType<typeof createVinylFactories>\n\n/**\n * Provides the dependency type for a dependency with merged overrides.\n */\nexport type InferVinylOverrideDependencyType<\n Overrides,\n K extends keyof DefaultVinylFactories,\n> = Dependencies<\n Overrides extends Factories\n ? Merge<DefaultVinylFactories, Overrides>\n : DefaultVinylFactories\n>[K]\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { type PatchedRef, patchTargetFromFlags } from '@amazon/vinyl-util'\nimport type { MediaElementPatchOptions } from './MediaElementPatchOptions'\nimport { createUnreliablePlaybackEventsPatch } from './patches/createUnreliablePlaybackEventsPatch'\nimport { createPreventStallsPatch } from './patches/createPreventStallsPatch'\n\n/**\n * Applies patches corresponding to the patch flags on the given media element.\n *\n * Adds logging for fabricated or squelched events.\n */\nexport function patchMediaElement<\n T extends HTMLMediaElement = HTMLMediaElement,\n>(media: T, options: MediaElementPatchOptions): PatchedRef<T> {\n return patchTargetFromFlags(\n media,\n options,\n ['unreliablePlaybackEvents', createUnreliablePlaybackEventsPatch],\n ['preventStalls', createPreventStallsPatch]\n )\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { Browser, hasBrowser, type Timestamp } from '@amazon/vinyl-util'\nimport {\n closeTo,\n createDisposer,\n DomEventHost,\n onAny,\n SignalImpl,\n} from '@amazon/vinyl-util'\nimport type { HtmlMediaElementPatch } from '../HtmlMediaElementPatch'\n\n/**\n * The interval (in seconds) to poll for time progress in a media element.\n *\n * @private\n */\nexport const UNRELIABLE_EVENTS_POLL_INTERVAL = 0.2\n\n/**\n * Minimum amount of time playback must be stalled before fabricating a waiting event.\n */\nexport const MIN_STALLED_BEFORE_FAB = 0.8\n\n/**\n * Minimum amount of time playback must be progressing before fabricating a playing event.\n */\nexport const MIN_PLAYING_BEFORE_FAB = 0.4\n\n/**\n * If currentTime does not change larger than this value, it will be considered to be stalled.\n */\nconst MIN_PLAYING_DELTA = 0.05\n\n/**\n * If currentTime changes beyond this tolerance the apparent state will be considered to be seeking.\n */\nconst MIN_SEEKING_DELTA = 0.5\n\nenum PlayHeadState {\n /**\n * The last time update was an increment from the previous.\n */\n PLAYING,\n\n /**\n * The last time update was close to the previous.\n */\n STOPPED,\n\n /**\n * The last time update was a non-incremental change.\n */\n SEEKING,\n}\n\n/**\n * Playback events such as playing, canPlay, and waiting are unreliable on this platform.\n * Watch playback state and fabricate events when necessary.\n */\nexport function createUnreliablePlaybackEventsPatch(\n media: HTMLMediaElement\n): HtmlMediaElementPatch {\n const { add, dispose } = createDisposer()\n const domEvents = add(new DomEventHost<HTMLMediaElementEventMap>(media))\n const eventFabricated = add(new SignalImpl<Event>())\n\n // The timestamp of the last change.\n let stateChangedAt: Timestamp = Date.now()\n\n // The current observed state based on the play head progress.\n let currentApparentState: PlayHeadState = PlayHeadState.STOPPED\n\n /**\n * @param state The new apparent state.\n * @param changedAt The timestamp the apparent state was changed.\n */\n function setApparentState(\n state: PlayHeadState,\n changedAt: Timestamp = Date.now()\n ) {\n if (currentApparentState !== state) {\n currentApparentState = state\n stateChangedAt = changedAt\n }\n }\n\n /**\n * Returns the number of seconds since the last state change.\n */\n function elapsedStateTime(): number {\n return (Date.now() - stateChangedAt) / 1000\n }\n\n let lastTimestamp: Timestamp = Date.now()\n let lastTime = media.currentTime\n\n let waiting = false\n let seeking = false\n\n onAny(\n domEvents,\n ['emptied', 'ended', 'pause', 'playing', 'seeking'],\n () => {\n waiting = false\n }\n )\n\n let playing = false\n onAny(\n domEvents,\n ['emptied', 'ended', 'pause', 'seeking', 'waiting'],\n () => {\n playing = false\n }\n )\n\n domEvents.on('seeking', () => {\n seeking = true\n })\n domEvents.on('seeked', () => {\n seeking = false\n setApparentState(PlayHeadState.SEEKING)\n })\n domEvents.on('play', () => {\n // Resets the timer so that the !paused state does not immediately trigger a 'waiting' event.\n stateChangedAt = Date.now()\n })\n\n // All events that can affect the ready state.\n // canplay and canplaythrough are handled in the overridden events map.\n const readyStateEvents = [\n 'emptied',\n 'loadeddata',\n 'loadedmetadata',\n 'waiting',\n ] as const\n let lastReadyStateEvent = 'emptied'\n add(\n onAny(domEvents, readyStateEvents, (_, type) => {\n lastReadyStateEvent = type\n })\n )\n\n const checkApparentState = () => {\n const progressed = (media.currentTime - lastTime) / media.playbackRate\n const now = Date.now()\n if (Math.abs(progressed) > MIN_SEEKING_DELTA) {\n setApparentState(PlayHeadState.SEEKING, lastTimestamp)\n } else if (progressed >= MIN_PLAYING_DELTA) {\n setApparentState(PlayHeadState.PLAYING, lastTimestamp)\n } else if (closeTo(progressed, 0, MIN_PLAYING_DELTA)) {\n setApparentState(PlayHeadState.STOPPED, lastTimestamp)\n }\n lastTime = media.currentTime\n lastTimestamp = now\n\n if (\n !playing &&\n !seeking &&\n !media.paused &&\n !media.ended &&\n media.readyState >= media.HAVE_FUTURE_DATA &&\n currentApparentState === PlayHeadState.PLAYING &&\n elapsedStateTime() >= MIN_PLAYING_BEFORE_FAB\n ) {\n // The play head is progressing but a playing event was never observed.\n waiting = false\n playing = true\n\n if (\n lastReadyStateEvent !== 'canplay' &&\n lastReadyStateEvent !== 'canplaythrough'\n ) {\n lastReadyStateEvent = 'canplay'\n eventFabricated.dispatch(new CustomEvent('canplay'))\n }\n if (media.readyState >= media.HAVE_ENOUGH_DATA) {\n if (lastReadyStateEvent !== 'canplaythrough') {\n lastReadyStateEvent = 'canplaythrough'\n eventFabricated.dispatch(new CustomEvent('canplaythrough'))\n }\n }\n eventFabricated.dispatch(new CustomEvent('playing'))\n }\n if (\n !waiting &&\n !media.paused &&\n !media.ended &&\n currentApparentState === PlayHeadState.STOPPED &&\n elapsedStateTime() >= MIN_STALLED_BEFORE_FAB\n ) {\n waiting = true\n playing = false\n // currentTime is not changing; playback has stopped but no 'waiting' event\n // was observed.\n eventFabricated.dispatch(new CustomEvent('waiting'))\n }\n }\n\n const playbackWatchIntervalId = setInterval(\n checkApparentState,\n UNRELIABLE_EVENTS_POLL_INTERVAL * 1000\n )\n add(() => {\n clearInterval(playbackWatchIntervalId)\n })\n return {\n eventFabricated,\n properties: {\n /**\n * Platforms that have unreliable waiting events, also have unreliable ready state\n * when the end of buffered data has been reached. If the media is in a waiting state,\n * the highest ready state that is possible is HAVE_METADATA.\n */\n readyState: {\n get() {\n return waiting\n ? Math.min(media.readyState, media.HAVE_METADATA)\n : media.readyState\n },\n },\n },\n events: {\n canplay(event) {\n // Do not emit the canplay event if one was fabricated.\n const eventOrNull =\n lastReadyStateEvent === 'canplay' ? null : event\n lastReadyStateEvent = 'canplay'\n return eventOrNull\n },\n\n canplaythrough(event) {\n // Do not emit the canplaythrough event if one was fabricated.\n const eventOrNull =\n lastReadyStateEvent === 'canplaythrough' ? null : event\n lastReadyStateEvent = 'canplaythrough'\n return eventOrNull\n },\n\n playing(event) {\n if (playing) {\n // Do not emit the playing event if one was fabricated.\n return null\n }\n setApparentState(PlayHeadState.PLAYING)\n playing = true\n return event\n },\n\n waiting(event) {\n if (waiting) {\n // Do not emit the waiting event if one was fabricated.\n return null\n }\n waiting = true\n setApparentState(PlayHeadState.STOPPED)\n return event\n },\n },\n\n dispose,\n }\n}\n\n/**\n * Chrome <= 53 has unreliable waiting events.\n * Safari, and Edge Legacy miss playing events after seeking.\n */\nexport function requiresUnreliablePlaybackEventsPatch(): boolean {\n return (\n hasBrowser(Browser.SAFARI) ||\n hasBrowser(Browser.EDGE_LEGACY) ||\n hasBrowser(Browser.CHROMIUM, null, '53')\n )\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {\n Browser,\n closeTo,\n createDisposer,\n createLogPrefix,\n DomEventHost,\n hasBrowser,\n logInfo,\n type LogTarget,\n logWarn,\n noop,\n} from '@amazon/vinyl-util'\nimport type { HtmlMediaElementPatch } from '../HtmlMediaElementPatch'\n\n/**\n * The number of timeupdate events stuck at the same position before attempting to jiggle the playhead.\n * @private\n */\nexport const MAX_UNCHANGED_COUNT = 10\n\n/**\n * On affected UAs, playback can become stuck. timeupdate events are observed but playback position is never changing.\n * This patch applies a workaround which will pause and play again after max number of timeupdate events with no\n * actual time progression.\n */\nexport function createPreventStallsPatch(\n media: HTMLMediaElement\n): HtmlMediaElementPatch {\n const { add, dispose } = createDisposer()\n const domEvents = add(new DomEventHost<HTMLMediaElementEventMap>(media))\n const pathTarget: LogTarget = {\n logPrefix: createLogPrefix('createPreventStallsPatch'),\n }\n let unchangedCount = 0\n let attemptedFix = false\n let previousTime = media.currentTime\n domEvents.on('timeupdate', () => {\n if (media.paused) return\n if (closeTo(media.currentTime, previousTime, 0.01)) {\n if (++unchangedCount >= MAX_UNCHANGED_COUNT && !attemptedFix) {\n logWarn(\n pathTarget,\n `Detected stall at time ${media.currentTime}, attempting fix`\n )\n attemptedFix = true\n unchangedCount = 0\n media.pause()\n media.play().catch(noop)\n }\n } else {\n if (attemptedFix) {\n logInfo(pathTarget, 'stall ended')\n attemptedFix = false\n } // Unstuck\n unchangedCount = 0\n previousTime = media.currentTime\n }\n })\n\n return {\n dispose,\n }\n}\n\n/**\n * Returns true if stall detection should be enabled for the current user agent.\n */\nexport function requiresPreventStallsPatch(): boolean {\n return hasBrowser(Browser.EDGE_LEGACY)\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {\n Abort,\n AbortError,\n Browser,\n clamp,\n closeTo,\n createDisposer,\n createTimeRangesReader,\n DomEventHost,\n ErrorLevel,\n ErrorOrigin,\n EventHostImpl,\n getUserAgentInfo,\n hasBrowser,\n logDebug,\n logInfo,\n logWarn,\n nextEventAsPromise,\n onAny,\n ownKeys,\n type ReadonlyEventHost,\n type ReadonlyRanges,\n TimeoutSlot,\n toLowerCase,\n withAbort,\n withTimeout,\n} from '@amazon/vinyl-util'\nimport { LIVE_DURATION, type PlaybackController } from './PlaybackController'\nimport {\n type PlaybackControllerEventMap,\n PlaybackReadyState,\n playedReasons,\n waitedReasons,\n} from './ReadonlyPlaybackController'\nimport { InvalidSeekError } from './error/InvalidSeekError'\nimport { playbackStateLoggingHandler } from './logging/playbackStateLoggingHandler'\nimport { createChangeEventTrigger } from '../event/ChangeEvent'\nimport { nextHasMetadata } from './nextHasMetadata'\nimport type { LoudnessNormalizationController } from './loudness/LoudnessNormalizationController'\nimport { ReportableMediaError } from './error/ReportableMediaError'\n\nexport interface PlaybackControllerImplOptions {\n /**\n * An affordance when comparing the last currentTime and the new currentTime after a seek.\n * Most browsers have around 30-40 time updates per second, but some constrained devices only\n * have a few. This value needs to be large enough where the last timeupdate in a looping track\n * is at currentTime >= duration - LOOP_TIME_AFFORDANCE.\n * Default: 2\n */\n readonly loopTimeAffordance: number\n\n /**\n * The minimum number of seconds before the end of the next seekable range allowed for a seek\n * operation. Some browsers will never complete a seek operation if the seek is too close to\n * this end range.\n * Default: getMinSeekableBufferDefault() which is between 0.5 and 5, browser dependent.\n */\n readonly minSeekableBuffer: number\n\n /**\n * The number of seconds before the promise returned by play() is rejected regardless whether\n * the media element response has settled.\n * Default: 30\n */\n readonly playTimeout: number\n\n /**\n * The number of seconds before the promise returned by seek() is rejected.\n * Default: 30\n */\n readonly seekTimeout: number\n}\n\nexport const defaultPlaybackControllerImplOptions = {\n loopTimeAffordance: 2,\n minSeekableBuffer: -1, // Default comes from getMinSeekableBufferDefault()\n playTimeout: 30,\n seekTimeout: 30,\n} as const satisfies PlaybackControllerImplOptions\n\n/**\n * Safari and Edge Legacy cannot reliably seek close to the end of a seekable range.\n * Firefox can but if the playhead reaches the end of track before the media stream is closed, an 'ended' event\n * will never fire.\n */\nexport function getMinSeekableBufferDefault() {\n return !hasBrowser(Browser.CHROMIUM) ? 5 : 2\n}\n\nexport interface PlaybackControllerImplDeps {\n readonly media: HTMLMediaElement\n readonly loudnessNormalizationController: LoudnessNormalizationController\n}\n\nexport class PlaybackControllerImpl\n extends EventHostImpl<PlaybackControllerEventMap>\n implements PlaybackController\n{\n private readonly loudnessNormalizationController: LoudnessNormalizationController\n get [Symbol.toStringTag](): string {\n return 'PlaybackControllerImpl'\n }\n\n private _error: Error | null = null\n private readonly media: HTMLMediaElement\n private readonly domEvents: DomEventHost<HTMLMediaElementEventMap>\n private readonly disposer = /* @__PURE__ */ createDisposer()\n private _playing = false\n private _seeking = false\n private _waiting = false\n\n // default user volume (0.0 to 1.0 scale)\n private userVolume: number = 1.0\n private _pendingPlay: Promise<void> | null = null\n private playAbort: Abort | null = null\n private disposeAbort = /* @__PURE__ */ new Abort()\n\n readonly options: PlaybackControllerImplOptions\n\n constructor(\n deps: PlaybackControllerImplDeps,\n options?: Partial<PlaybackControllerImplOptions>\n ) {\n super()\n this.options = {\n ...defaultPlaybackControllerImplOptions,\n minSeekableBuffer: getMinSeekableBufferDefault(),\n ...options,\n }\n this.loudnessNormalizationController =\n deps.loudnessNormalizationController\n logInfo(this, 'constructed', this.options)\n this.media = deps.media\n\n const { add } = this.disposer\n add(() => {\n this.disposeAbort.abort()\n this.disposeAbort.dispose()\n })\n\n this.domEvents = add(\n new DomEventHost<HTMLMediaElementEventMap>(deps.media)\n )\n\n // Log media events.\n add(playbackStateLoggingHandler(this))\n\n // Reports media errors\n this.domEvents.on('error', (_) => {\n const error = new ReportableMediaError(this.media.error)\n if (error.level === ErrorLevel.SILENT) {\n // Not a fatal error, log and ignore\n logInfo(this, error.message)\n return\n }\n this._error = error\n this.dispatch('error', {\n target: this,\n error,\n })\n })\n\n this.initializeEvents()\n\n // Listen for loudness normalization changes\n add(\n this.loudnessNormalizationController.on('change', () => {\n this.refreshVolume()\n })\n )\n }\n\n /**\n * Updates volume with loudness gain, on the mediaElement.\n * @private\n */\n private refreshVolume(): void {\n const effectiveVolume =\n this.userVolume * this.loudnessNormalizationController.gain\n this.media.volume = Math.min(1.0, effectiveVolume) // valid range (0-1)\n logDebug(this, 'refreshVolume', {\n userVolume: this.userVolume,\n lnGain: this.loudnessNormalizationController.gain,\n effectiveVolume: this.media.volume,\n })\n }\n\n /**\n * Listens to select events on the media element, redispatching as playback state events.\n * @private\n */\n private initializeEvents() {\n this.initializePlainEvents()\n this.initializeChangeEvents()\n this.initializeOperationEvents()\n this.initializeMutedEvent()\n this.initializeLoopedEvent()\n this.initializeReadyStateChangeEvent()\n }\n\n /**\n * Re-dispatches the plain DOM events without extra information.\n *\n * @private\n */\n private initializePlainEvents() {\n // Re-dispatch html media element events exposed on the playback controller as empty events.\n for (const key of [\n 'abort',\n 'canPlay',\n 'canPlayThrough',\n 'emptied',\n 'ended',\n 'loadStart',\n 'loadedData',\n 'loadedMetadata',\n 'pause',\n 'play',\n 'playing',\n 'seeking',\n 'waiting',\n 'waitingForKey',\n ] as const) {\n this.domEvents.on(toLowerCase(key), () => this.dispatch(key, {}))\n }\n\n // Keep specific event information for progress events.\n\n this.domEvents.on('progress', (e) => {\n this.dispatch('progress', { loaded: e.loaded, total: e.total })\n })\n }\n\n /**\n * Delegates the DOM events with additional information about what the previous and current\n * values are.\n * @private\n */\n private initializeChangeEvents() {\n const changeEventGetters = {\n durationChange: () => this.duration,\n timeUpdate: () => this.currentTime,\n volumeChange: () => this.volume,\n rateChange: () => this.playbackRate,\n } as const\n for (const key of ownKeys(changeEventGetters)) {\n this.domEvents.on(\n toLowerCase(key),\n createChangeEventTrigger(changeEventGetters[key], (event) => {\n this.dispatch(key, event)\n })\n )\n }\n }\n\n /**\n * Operation events provide an easy way to listen for the terminus of a state.\n * For example after a 'waiting' event, there are several different events that indicate that\n * the waiting has finished, and this API provides those events conflated into a single\n * 'waited' event.\n * @private\n */\n private initializeOperationEvents() {\n // seeking state + seeked event\n // media element has a seeked event, add operation details and set state.\n this.operationEvent(\n this.domEvents,\n 'seeking',\n // A seeked event may not be emitted in certain cases such as changing tracks before the seek can finish.\n ['seeked', 'emptied'],\n () => (this._seeking = true),\n (info) => {\n this._seeking = false\n this.dispatch('seeked', info)\n }\n )\n\n // waiting state + waited event\n this.operationEvent(\n this,\n 'waiting',\n waitedReasons,\n () => (this._waiting = true),\n (info) => {\n this._waiting = false\n this.dispatch('waited', info)\n }\n )\n\n // playing state + played event\n let startedTime = 0\n this.operationEvent(\n this,\n 'playing',\n playedReasons,\n () => {\n this._playing = true\n startedTime = this.currentTime\n },\n (info) => {\n this._playing = false\n this.dispatch('played', {\n ...info,\n playbackTime: this.currentTime - startedTime,\n })\n }\n )\n }\n\n /**\n * When going into a state from a beginEvent, dispatches endEvent when any of the endEvents\n * is dispatched.\n *\n * This allows consumers of the playback state to listen for the exit of a state without\n * needing to know every event that ends that state.\n *\n * @param host The event host emitting the primary events.\n * @param beginEvent The event that enters a state.\n * @param endEvents A list of events that exits the entered state.\n * @param onBegin Invoked when the operation has begun.\n * @param onEnd Invoked when the operation has completed.\n */\n private operationEvent<EventMap, const EndEvent extends keyof EventMap>(\n host: ReadonlyEventHost<EventMap>,\n beginEvent: keyof EventMap,\n endEvents: readonly EndEvent[],\n onBegin: () => void,\n onEnd: (info: {\n started: number\n ended: number\n duration: number\n reason: EndEvent\n }) => void\n ) {\n let startedAt = 0\n let started = false\n host.on(beginEvent, () => {\n onBegin()\n started = true\n startedAt = Date.now()\n })\n onAny(host, endEvents, (_, event) => {\n if (started) {\n started = false\n const now = Date.now()\n onEnd({\n started: startedAt,\n ended: now,\n duration: (now - startedAt) / 1000,\n reason: event,\n })\n }\n })\n }\n\n /**\n * Dispatches a 'mutedChange' event when 'muted' state has changed.\n *\n * The DOM element only provides a 'volumeChange' event, which is filtered to watch when\n * muted has changed.\n *\n * @private\n */\n private initializeMutedEvent() {\n const { add } = this.disposer\n let previousMuted = this.muted\n\n // Dispatches a mutedChange event if the muted property changed since the last check.\n const maybeDispatchMutedChange = () => {\n if (this.muted === previousMuted) return\n previousMuted = this.muted\n this.dispatch('mutedChange', {\n previous: !this.muted,\n current: this.muted,\n })\n }\n const mutedTimeoutSlot = add(new TimeoutSlot())\n this.on('volumeChange', () => {\n maybeDispatchMutedChange()\n // The volumechange event may be emitted before the muted property change.\n // This has been observed on legacy edge and as a rare occurrence for Chrome.\n mutedTimeoutSlot.set(maybeDispatchMutedChange, 0.2)\n })\n }\n\n /**\n * Dispatches a looped event if loop is true and playback wraps back to the start.\n * Safari emits timeupdate events at duration and then 0 before the seeking event\n * Other browsers emit the seeking before the timeupdate near zero.\n * Firefox timeupdate after the loop is near zero, not exactly.\n *\n * @private\n */\n private initializeLoopedEvent() {\n let lastTime = 0\n this.on('timeUpdate', () => {\n if (\n this.loop &&\n !this.paused &&\n this.currentTime <= this.options.loopTimeAffordance &&\n lastTime >= this.duration - this.options.loopTimeAffordance\n ) {\n if (getUserAgentInfo().browserLike?.name === Browser.FIREFOX) {\n // Firefox does not emit a 'playing' event after a loop, fabricate one.\n logDebug(this, 'fabricating Firefox playing event on loop')\n this.dispatch('playing', {})\n }\n this.dispatch('looped', {})\n }\n lastTime = this.currentTime\n })\n }\n\n get buffered(): ReadonlyRanges {\n return createTimeRangesReader(this.media.buffered)\n }\n\n get currentTime(): number {\n return this.media.currentTime\n }\n\n get currentTimePercent(): number {\n return this.duration > 0 ? this.currentTime / this.duration : 0\n }\n\n get defaultPlaybackRate(): number {\n return this.media.defaultPlaybackRate\n }\n\n set defaultPlaybackRate(value: number) {\n logDebug(this, `defaultPlaybackRate set to ${value}`)\n this.media.defaultPlaybackRate = value\n }\n\n get duration(): number {\n if (this.media.duration >= LIVE_DURATION)\n return Number.POSITIVE_INFINITY\n return this.media.duration\n }\n\n get ended(): boolean {\n return this.media.ended\n }\n\n get error(): Error | null {\n return this._error\n }\n\n get loop(): boolean {\n return this.media.loop\n }\n\n set loop(value: boolean) {\n logDebug(this, `loop set to ${value}`)\n this.media.loop = value\n }\n\n get muted(): boolean {\n return this.media.muted\n }\n\n set muted(value: boolean) {\n logDebug(this, `muted set to ${value}`)\n this.media.muted = value\n }\n\n get networkState(): number {\n return this.media.networkState\n }\n\n get paused(): boolean {\n return this.media.paused\n }\n\n get playbackRate(): number {\n return this.media.playbackRate\n }\n\n set playbackRate(value: number) {\n logDebug(this, `playbackRate set to ${value}`)\n this.media.playbackRate = value\n }\n\n get playing(): boolean {\n return this._playing\n }\n\n get preservesPitch(): boolean {\n return this.media.preservesPitch\n }\n\n set preservesPitch(value: boolean) {\n logDebug(this, `preservesPitch set to ${value}`)\n this.media.preservesPitch = value\n }\n\n get readyState(): PlaybackReadyState {\n return this.media.readyState\n }\n\n get seekable(): ReadonlyRanges {\n return createTimeRangesReader(this.media.seekable)\n }\n\n get seeking(): boolean {\n return this._seeking\n }\n\n get volume(): number {\n return this.userVolume\n }\n\n set volume(value: number) {\n logDebug(this, `volume set to ${value}`)\n this.userVolume = value\n this.refreshVolume()\n }\n\n get waiting(): boolean {\n return this._waiting\n }\n\n pause(): void {\n logDebug(this, 'pause')\n this.playAbort?.abort(\n new AbortError(\n 'The play() request was interrupted by a call to pause().'\n )\n )\n this.pendingPlay = null\n this.media.pause()\n }\n\n private get pendingPlay(): Promise<void> | null {\n return this._pendingPlay\n }\n\n private set pendingPlay(value: Promise<void> | null) {\n this._pendingPlay = value\n this.dispatch('playIsPendingChange', {\n previous: value == null,\n current: value != null,\n })\n }\n\n play(): Promise<void> {\n logDebug(this, 'play')\n if (!this.pendingPlay) {\n const playAbort = new Abort()\n this.playAbort = playAbort\n this.pendingPlay = withAbort(\n (async () => {\n await nextHasMetadata(this)\n playAbort.throwIfAborted()\n await withTimeout(\n this.media.play(),\n this.options.playTimeout,\n 'play() timed out after {time}s',\n ErrorOrigin.INTERNAL,\n ErrorLevel.SILENT\n )\n })(),\n playAbort\n )\n .catch((reason) => {\n this.dispatch('playRejected', { reason })\n throw reason\n })\n .finally(() => {\n this.pendingPlay = null\n this.playAbort = null\n })\n }\n return this.pendingPlay\n }\n\n get canPlay(): boolean {\n return this.readyState >= PlaybackReadyState.HAVE_FUTURE_DATA\n }\n\n get canPlayThrough(): boolean {\n return this.readyState >= PlaybackReadyState.HAVE_ENOUGH_DATA\n }\n\n get hasMetadata(): boolean {\n return this.readyState >= PlaybackReadyState.HAVE_METADATA\n }\n\n get playIsPending(): boolean {\n return this.pendingPlay != null\n }\n\n async seekTo(time: number, tolerance = 0.5): Promise<void> {\n logDebug(this, `seekTo: ${time}`)\n const nextEvent = <K extends keyof PlaybackControllerEventMap>(\n type: K\n ): Promise<PlaybackControllerEventMap[K]> => {\n return withAbort(\n withTimeout(\n nextEventAsPromise(this, type),\n this.options.seekTimeout,\n `seek timed out on ${type} event after {time}s`,\n ErrorOrigin.INTERNAL,\n ErrorLevel.WARN\n ),\n this.disposeAbort\n )\n }\n\n // Cannot seek until there are seekable ranges.\n if (!this.hasMetadata) {\n await nextEvent('loadedMetadata')\n }\n\n const seekable = this.seekable\n const range = seekable.getRangeAt(\n clamp(time, 0, this.duration),\n tolerance\n )\n if (range == null) {\n logWarn(\n this,\n `seekTo: seek outside of seekable ranges, seek ignored`\n )\n throw new InvalidSeekError(time, seekable, tolerance)\n }\n const clampedTime = Math.max(\n Math.min(time, range[1] - this.options.minSeekableBuffer),\n range[0]\n )\n\n // No-op check\n\n logDebug(\n this,\n `seekTo operation, requested: ${time}, actual: ${clampedTime}`\n )\n\n if (closeTo(clampedTime, this.currentTime, tolerance)) {\n // Within tolerance of the currentTime, no seek needed.\n logDebug(\n this,\n `seekTo: requested: ${time}, actual: ${clampedTime} no-op`\n )\n } else {\n const seeking = nextEvent('seeking')\n this.media.currentTime = clampedTime\n await seeking\n const seekedEvent = await nextEvent('seeked')\n if (seekedEvent.reason === 'emptied') {\n // Seek finished due to track unloading. Abort any pending seek.\n throw new AbortError()\n }\n }\n }\n\n /**\n * Dispatches a readyStateChange event when {@link readyState} changes.\n * @private\n */\n private initializeReadyStateChangeEvent() {\n let previous = this.readyState\n onAny(\n this,\n [\n 'canPlay',\n 'canPlayThrough',\n 'emptied',\n 'loadedData',\n 'loadedMetadata',\n 'waiting',\n ],\n () => {\n const current = this.readyState\n if (previous !== current) {\n this.dispatch('readyStateChange', {\n previous,\n current,\n })\n previous = this.readyState\n }\n }\n )\n }\n\n reset() {\n if (this._error == null) {\n logDebug(this, 'reset no-op')\n return\n }\n logDebug(this, 'reset')\n this._error = null\n this.dispatch('reset', {})\n }\n\n /**\n * True if this controller has been disposed.\n */\n get disposed(): boolean {\n return this.disposer.disposed\n }\n\n dispose() {\n this.disposer.dispose()\n }\n}\n\n/**\n * Returns true if the play rejection reason is a not allowed error. This indicates that play\n * should be retried within a user interaction stack.\n * @param reason\n */\nexport function isNotAllowedError(\n reason: any\n): reason is { name: 'NotAllowedError' } {\n return reason?.name === 'NotAllowedError'\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { ReadonlyPlaybackController } from './ReadonlyPlaybackController'\n\nexport interface PlaybackController extends ReadonlyPlaybackController {\n defaultPlaybackRate: number\n loop: boolean\n muted: boolean\n playbackRate: number\n preservesPitch: boolean\n volume: number\n\n /**\n * Pauses playback of the media, if the media is already in a paused state\n * this method will have no effect.\n * If a play is pending, the play will be aborted and the promise returned by play() will be\n * rejected.\n *\n * @see pendingPlay\n * @see play\n */\n pause(): void\n\n /**\n * Attempts to begin playback of the media. It returns a Promise which is resolved when\n * playback has been successfully started.\n *\n * Failure to begin playback for any reason, such as permission issues or interruption via\n * pause, results in the promise being rejected.\n *\n * The first time play() is invoked, except muted video, should be in response to a user\n * interaction such as a button click.\n *\n * @see isNotAllowedError\n */\n play(): Promise<void>\n\n /**\n * Safely seeks to the given time.\n * The seek will begin only after {@link readyState} is at least\n * {@link PlaybackReadyState.HAVE_METADATA}.\n * If a previous seek was still pending, the previous seek will be ignored.\n * Returns a Promise that resolves when the seek has completed. If the seek is interrupted\n * by another seek, the promise will be rejected with an `AbortError`.\n * If the seek is not to a seekable range, the promise will reject with an {@link InvalidSeekError}.\n *\n * @param time The value, in seconds, to set the playback time.\n * @param tolerance The amount of tolerance to have when the time is outside the seekable\n * ranges to snap, in seconds. If time is outside all seekable ranges beyond this tolerance,\n * the seek will be ignored. Default: 0.5\n */\n seekTo(time: number, tolerance?: number): Promise<void>\n\n /**\n * Resets the error state.\n */\n reset(): void\n}\n\n/**\n * The maximum duration media can be before it is considered 'live'.\n */\nexport const LIVE_DURATION = 4294967296 // 2 ** 32\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type {\n AnyRecord,\n ReadonlyEventHost,\n ReadonlyRanges,\n Timestamp,\n} from '@amazon/vinyl-util'\nimport type { ChangeEvent } from '../event/ChangeEvent'\nimport type { BasicErrorEvent } from '../event/BasicErrorEvent'\n\nexport interface ProgressEvent {\n readonly loaded: number\n readonly total: number\n}\n\nexport interface OperationCompletedEvent<K> {\n /**\n * The timestamp the operation began.\n */\n readonly started: Timestamp\n\n /**\n * The timestamp the operation completed.\n */\n readonly ended: Timestamp\n\n /**\n * The total number of seconds the operation took.\n */\n readonly duration: number\n\n /**\n * The reason the operation completed.\n */\n readonly reason: K\n}\n\nexport interface PlayedEvent extends OperationCompletedEvent<PlayedReason> {\n /**\n * The total number of seconds elapsed for the track (using `currentTime`).\n */\n readonly playbackTime: number\n}\n\n/**\n * The reason playback has stopped.\n * These are source event types from the media element that all indicate playback has stopped.\n * @see PlaybackControllerEventMap\n */\nexport enum PlayedReason {\n EMPTIED = 'emptied',\n /**\n * Note - 'ended' reason is generally unused, however it is not part of the w3c spec to guarantee a 'pause' event\n * before 'ended'.\n */\n ENDED = 'ended',\n PAUSE = 'pause',\n SEEKING = 'seeking',\n WAITING = 'waiting',\n}\n\n/**\n * A list of all events that cause the 2nd-order 'played' event.\n */\nexport const playedReasons = [\n PlayedReason.EMPTIED,\n PlayedReason.ENDED,\n PlayedReason.PAUSE,\n PlayedReason.SEEKING,\n PlayedReason.WAITING,\n] as const satisfies readonly PlayedReason[]\n\nexport interface PlayRejectedEvent {\n /**\n * The reason for the play() rejection.\n *\n * @see #isNotAllowedError\n */\n reason: any\n}\n\nexport interface PlaybackControllerEventMap {\n /**\n * Fired when the resource was not fully loaded, but not as the result of an error.\n */\n readonly abort: AnyRecord\n\n /**\n * Fired when the user agent can play the media, but estimates that not enough data has been\n * loaded to play the media up to its end without having to stop for further buffering of\n * content.\n *\n * readyState will be at least {@link PlaybackReadyState.HAVE_FUTURE_DATA}\n */\n readonly canPlay: AnyRecord\n\n /**\n * Fired when the user agent can play the media, and estimates that enough data has been\n * loaded to play the media up to its end without having to stop for further buffering of content.\n *\n * readyState will be at least {@link PlaybackReadyState.HAVE_ENOUGH_DATA}\n */\n readonly canPlayThrough: AnyRecord\n\n /**\n * Fired when the duration attribute has been updated.\n */\n readonly durationChange: ChangeEvent<number>\n\n /**\n * Fired when the media has become empty; for example, this event is sent if the media has\n * already been loaded (or partially loaded), and the load() method is called to reload it.\n *\n * readyState will be {@link PlaybackReadyState.HAVE_NOTHING}\n */\n readonly emptied: AnyRecord\n\n /**\n * Fired when playback or streaming has stopped because the end of the media was reached or\n * because no further data is available.\n */\n readonly ended: AnyRecord\n\n /**\n * Dispatched when the media element dispatches an error.\n */\n readonly error: BasicErrorEvent\n\n /**\n * Fired when {@link ReadonlyPlaybackController.playIsPending} has changed.\n */\n readonly playIsPendingChange: ChangeEvent<boolean>\n\n /**\n * Fired when the frame at the current playback position of the media has finished loading;\n * often the first frame.\n *\n * readyState will be at least {@link PlaybackReadyState.HAVE_CURRENT_DATA}\n */\n readonly loadedData: AnyRecord\n\n /**\n * Fired when the metadata has been loaded.\n *\n * readyState will be at least {@link PlaybackReadyState.HAVE_METADATA}\n */\n readonly loadedMetadata: AnyRecord\n\n /**\n * Fired when the browser has started to load a resource.\n */\n readonly loadStart: AnyRecord\n\n /**\n * Fired when {@link ReadonlyPlaybackController.loop} is true and playback has looped to track beginning.\n */\n readonly looped: AnyRecord\n\n /**\n * Fired when the mute status has changed.\n */\n readonly mutedChange: ChangeEvent<boolean>\n\n /**\n * Fired when a request to pause an activity is handled and the activity has entered its paused\n * state, most commonly after the media has been paused through a call to the element's\n * pause() method.\n */\n readonly pause: AnyRecord\n\n /**\n * Fired when the paused property is changed from true to false, as a result of the play\n * method, or the autoplay attribute.\n */\n readonly play: AnyRecord\n\n /**\n * Fired if play() has been attempted, but rejected.\n */\n readonly playRejected: PlayRejectedEvent\n\n /**\n * Fired when playback has stopped, for any reason.\n *\n * When media begins playing, a `playing` event is emitted. If playback stops due to 'pause',\n * 'seeking', 'emptied', 'waiting', or 'ended', then `played` will be fired.\n */\n readonly played: PlayedEvent\n\n /**\n * Fired after playback is first started, and whenever it is restarted. For example, it is\n * fired when playback resumes after having been paused or delayed due to lack of data.\n */\n readonly playing: AnyRecord\n\n /**\n * Fired periodically as the browser loads a resource.\n */\n readonly progress: ProgressEvent\n\n /**\n * Fired when the playback rate has changed.\n */\n readonly rateChange: ChangeEvent<number>\n\n /**\n * Fired when {@link ReadonlyPlaybackController.readyState} has changed.\n *\n * This is fired when any of the following events have fired:\n * {@link loadedData},\n * {@link loadedMetadata}\n * {@link canPlay}\n * {@link canPlayThrough}\n * {@link emptied}\n * {@link waiting}\n */\n readonly readyStateChange: ChangeEvent<PlaybackReadyState>\n\n /**\n * Fired when a seek operation completed, the current playback position has changed, and the\n * Boolean seeking attribute is changed to false.\n */\n readonly seeked: OperationCompletedEvent<'seeked' | 'playing' | 'emptied'>\n\n /**\n * Fired when a seek operation starts, meaning the Boolean seeking attribute has changed to\n * true and the media is seeking a new position.\n */\n readonly seeking: AnyRecord\n\n /**\n * Fired when the time indicated by the currentTime attribute has been updated.\n */\n readonly timeUpdate: ChangeEvent<number>\n\n /**\n * Fired when the volume has changed.\n */\n readonly volumeChange: ChangeEvent<number>\n\n /**\n * Fired when playback has stopped because of a temporary lack of data.\n *\n * Note: this includes during initial loading or after a seek and data is needed to buffer.\n * Will not be emitted when paused.\n */\n readonly waiting: AnyRecord\n\n /**\n * Fired when waiting has completed.\n * This will be emitted after a waiting event when playback has resumed, paused, or unloaded.\n */\n readonly waited: OperationCompletedEvent<WaitedReason>\n\n /**\n * Playback is blocked waiting for a key.\n */\n readonly waitingForKey: AnyRecord\n\n /**\n * Emitted when the error state has been reset.\n */\n readonly reset: AnyRecord\n}\n\n/**\n * Reasons why a 'waiting' operation has ended.\n */\nexport enum WaitedReason {\n PLAYING = 'playing',\n PAUSE = 'pause',\n EMPTIED = 'emptied',\n SEEKING = 'seeking',\n}\n\n/**\n * A list of all events that cause the 2nd-order 'waited' event.\n */\nexport const waitedReasons = [\n WaitedReason.PLAYING,\n WaitedReason.PAUSE,\n WaitedReason.EMPTIED,\n WaitedReason.SEEKING,\n] as const satisfies readonly WaitedReason[]\n\nexport const ALL_PLAYBACK_STATE_EVENTS = [\n 'abort',\n 'canPlay',\n 'canPlayThrough',\n 'durationChange',\n 'emptied',\n 'ended',\n 'error',\n 'playIsPendingChange',\n 'loadedData',\n 'loadedMetadata',\n 'loadStart',\n 'looped',\n 'mutedChange',\n 'pause',\n 'play',\n 'playRejected',\n 'played',\n 'playing',\n 'progress',\n 'rateChange',\n 'readyStateChange',\n 'reset',\n 'seeked',\n 'seeking',\n 'timeUpdate',\n 'volumeChange',\n 'waited',\n 'waiting',\n 'waitingForKey',\n] as const satisfies readonly (keyof PlaybackControllerEventMap)[]\n\nexport enum PlaybackReadyState {\n /**\n * No information is available about the media resource.\n *\n * readyState will be this after `emptied`\n */\n HAVE_NOTHING = 0,\n\n /**\n * Enough of the media resource has been retrieved that the metadata attributes are initialized\n * Seeking will no longer raise an exception.\n *\n * readyState will be at least this after `loadedMetadata`\n */\n HAVE_METADATA = 1,\n\n /**\n * Data is available for the current playback position, but not enough to actually play more\n * than one frame.\n *\n * readyState will be at least this after `loadedData`\n */\n HAVE_CURRENT_DATA = 2,\n\n /**\n * Data for the current playback position as well as for at least a little bit of time into the\n * future is available (in other words, at least two frames of video, for example).\n *\n * readyState will be at least this after `canPlay`\n */\n HAVE_FUTURE_DATA = 3,\n\n /**\n * Enough data is available\u2014and the download rate is high enough\u2014that the media can be played\n * through to the end without interruption.\n *\n * readyState will be at least this after `canPlayThrough`\n */\n HAVE_ENOUGH_DATA = 4,\n}\n\n/**\n * An enumeration of possible networkState values on a media element.\n */\nexport enum PlaybackNetworkState {\n /**\n * There is no data yet. Also, readyState is HAVE_NOTHING.\n */\n NETWORK_EMPTY = 0,\n\n /**\n * HTMLMediaElement is active and has selected a resource, but is not using the network.\n */\n NETWORK_IDLE = 1,\n\n /**\n * The browser is downloading HTMLMediaElement data.\n */\n NETWORK_LOADING = 2,\n\n /**\n * No HTMLMediaElement src found.\n */\n NETWORK_NO_SOURCE = 3,\n}\n\nexport interface ReadonlyPlaybackController extends ReadonlyEventHost<PlaybackControllerEventMap> {\n /**\n * Returns a new static normalized ReadonlyRanges object that represents the ranges of the\n * media resource, if any, that the user agent has buffered at the moment the buffered\n * property is accessed.\n *\n * Note: `ReadonlyRanges` is a view to the DOM `TimeRanges` object.\n */\n readonly buffered: ReadonlyRanges\n\n /**\n * True if the {@link readyState} is {@link PlaybackReadyState.HAVE_FUTURE_DATA}\n * This will be true after a {@link PlaybackControllerEventMap.canPlay} event.\n *\n * Note that security permissions may not allow a track to load past metadata before there has\n * been a user interaction. This should not be relied upon before invoking\n * {@link PlaybackController.play}.\n */\n readonly canPlay: boolean\n\n /**\n * True if the {@link readyState} is {@link PlaybackReadyState.HAVE_ENOUGH_DATA}\n * This will be true after a {@link PlaybackControllerEventMap.canPlayThrough} event.\n *\n * Note that security permissions may not allow a track to load past metadata before there has\n * been a user interaction. This should not be relied upon before invoking\n * {@link PlaybackController.play}.\n */\n readonly canPlayThrough: boolean\n\n /**\n * The current playback time in seconds.\n * When changed, a 'timeUpdate' event is emitted.\n */\n readonly currentTime: number\n\n /**\n * Returns current time as a percent of the total duration.\n *\n * @return A number between 0-1\n */\n readonly currentTimePercent: number\n\n /**\n * The default playback rate when the user is not using fast forward or reverse for a\n * video or audio resource.\n */\n readonly defaultPlaybackRate: number\n\n /**\n * The length of the element's media in seconds.\n * Observe changes with `durationChange` events.\n */\n readonly duration: number\n\n /**\n * Indicates whether the media element has ended playback.\n */\n readonly ended: boolean\n\n /**\n * The Error object for the most recent error, or null if there has not been an error.\n * When an error event is received by the element, you can determine details about what\n * happened by examining this object.\n */\n readonly error: Error | null\n\n /**\n * True if the {@link readyState} is at least {@link PlaybackReadyState.HAVE_METADATA}\n *\n * This will be true after a {@link PlaybackControllerEventMap.loadedMetadata} event and\n * false after an {@link PlaybackControllerEventMap.emptied} event.\n */\n readonly hasMetadata: boolean\n\n /**\n * Controls whether the media element should start over when it reaches the end.\n */\n readonly loop: boolean\n\n /**\n * Indicates whether the media element muted.\n * Observe changes with `mutedChange` events.\n */\n readonly muted: boolean\n\n /**\n * Indicates the current state of the fetching of media over the network.\n */\n readonly networkState: PlaybackNetworkState\n\n /**\n * Indicates whether the media element is paused.\n * Observe changes with `play` and `pause` events.\n */\n readonly paused: boolean\n\n /**\n * Sets the rate at which the media is being played back. This is used to implement user\n * controls for fast-forward, slow motion, and so forth. The normal playback rate is\n * multiplied by this value to obtain the current rate, so a value of 1.0 indicates normal\n * speed.\n */\n readonly playbackRate: number\n\n /**\n * True if playback has started, is not paused, stalled, or seeking.\n * Observe changes with 'playing' and 'played' events.\n */\n readonly playing: boolean\n\n /**\n * True if `play` has been called and the returned promise is currently in a pending state.\n * Observe changes with {@link PlaybackControllerEventMap.playIsPendingChange} events.\n */\n readonly playIsPending: boolean\n\n /**\n * Determines whether the browser should adjust the pitch of the audio to compensate\n * for changes to the playback rate.\n * Default: true\n */\n readonly preservesPitch: boolean\n\n /**\n * Indicates the readiness state of the media.\n * Observe changes with {@link PlaybackControllerEventMap.readyStateChange} events.\n */\n readonly readyState: PlaybackReadyState\n\n /**\n * Returns a new static normalized `ReadonlyRanges` object that represents the ranges of the\n * media resource, if any, that the user agent is able to seek to at the time seekable\n * property is accessed.\n *\n * Note: `ReadonlyRanges` is a view to the DOM `TimeRanges` object.\n */\n readonly seekable: ReadonlyRanges\n\n /**\n * True if the element is currently seeking.\n * Observe changes with `seeking` and `seeked` events.\n */\n readonly seeking: boolean\n\n /**\n * The volume level for audio portions of the media element.\n * Observe changes with `volumeChange` events.\n */\n readonly volume: number\n\n /**\n * True if playback is stopped due to waiting for data.\n * Observe changes with `waiting` and `waited` events.\n */\n readonly waiting: boolean\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { ErrorLevel, type Json, ReportableError } from '@amazon/vinyl-util'\nimport { ErrorOrigin } from '@amazon/vinyl-util'\nimport type { ReadonlyRanges } from '@amazon/vinyl-util'\n\n/**\n * An error indicating a seek was out of range.\n * This will have an error level of `ErrorLevel.WARN`.\n * This indicates a bad seek request, but is recoverable.\n */\nexport class InvalidSeekError extends ReportableError {\n get [Symbol.toStringTag](): string {\n return 'InvalidSeekError'\n }\n\n constructor(\n readonly time: number,\n readonly seekable: ReadonlyRanges,\n readonly tolerance: number\n ) {\n super(\n `Could not seek to time: ${time}, outside of seekable ranges ${seekable} with tolerance ${tolerance}`,\n ErrorOrigin.API,\n ErrorLevel.WARN\n )\n Object.setPrototypeOf(this, InvalidSeekError.prototype)\n }\n\n toJSON(): Json {\n return {\n ...super.toJSON(),\n time: this.time,\n seekable: Array.from(this.seekable),\n }\n }\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { Disposable } from '@amazon/vinyl-util'\nimport { createDisposer } from '@amazon/vinyl-util'\nimport { logDebug } from '@amazon/vinyl-util'\nimport type { ReadonlyPlaybackController } from '../ReadonlyPlaybackController'\nimport { ALL_PLAYBACK_STATE_EVENTS } from '../ReadonlyPlaybackController'\nimport { throttle } from '@amazon/vinyl-util'\nimport { substitute } from '@amazon/vinyl-util'\nimport { createLogPrefix, type LogTarget } from '@amazon/vinyl-util'\n\n/**\n * The number of seconds to throttle timeupdate logs.\n * Logs will not be emitted for timeupdate events less than this interval.\n */\nexport const TIMEUPDATE_THROTTLE = 5\n\n/**\n * @private\n */\nconst locale = {\n /**\n * The timeupdate log message when grouping several updates together.\n *\n * Param start - start time\n * Param end - end time\n * Param count - number of events\n */\n timeupdateLogBatch: 'timeUpdate {start}-{end} x{count}',\n} as const\n\n/**\n * Logs all playback state events.\n *\n * @param playbackState The event host with playback events to observe.\n * @return Returns a disposable handle to remove all added handlers.\n */\nexport function playbackStateLoggingHandler(\n playbackState: ReadonlyPlaybackController\n): Disposable {\n const target: LogTarget = {\n logPrefix: createLogPrefix('Playback'),\n }\n const disposer = createDisposer()\n const { add } = disposer\n\n // Log time update events so that sequential time updates are debounced.\n let timeUpdateCount = 0\n let startTime: number | null = null\n\n /**\n * Logs the cumulated timeupdate event counts, resetting the window.\n */\n const logTimeupdateBatch = () => {\n if (startTime == null) return\n const currentTime = playbackState.currentTime\n logDebug(\n target,\n substitute(locale.timeupdateLogBatch, {\n start: startTime.toFixed(1),\n end: currentTime.toFixed(1),\n count: timeUpdateCount,\n })\n )\n timeUpdateCount = 0\n startTime = null\n }\n\n /**\n * Throttles timeupdate logs to the given interval.\n */\n const logTimeupdateBatchThrottled = add(\n throttle(logTimeupdateBatch, TIMEUPDATE_THROTTLE, { trailing: true })\n )\n\n add(\n playbackState.on('timeUpdate', () => {\n timeUpdateCount++\n if (startTime == null) startTime = playbackState.currentTime\n logTimeupdateBatchThrottled()\n })\n )\n\n for (const type of ALL_PLAYBACK_STATE_EVENTS) {\n if (type === 'timeUpdate') continue\n add(\n playbackState.on(type, (event) => {\n logTimeupdateBatch()\n logDebug(target, type, event)\n })\n )\n }\n\n return disposer\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nexport interface ChangeEvent<T> {\n readonly previous: T | null\n readonly current: T\n}\n\n/**\n * Creates a function, which when invoked, will call `inner` with a new ChangeEvent.\n *\n * @param getter\n * @param inner\n */\nexport function createChangeEventTrigger<T>(\n getter: () => T,\n inner: (event: ChangeEvent<T>) => void\n): () => void {\n let current = getter()\n return () => {\n const event: ChangeEvent<T> = {\n previous: current,\n current: getter(),\n }\n current = event.current\n inner(event)\n }\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type {\n PlaybackControllerEventMap,\n ReadonlyPlaybackController,\n} from './ReadonlyPlaybackController'\nimport {\n type AnyRecord,\n nextEventAsPromise,\n type NextEventAsPromiseOptions,\n} from '@amazon/vinyl-util'\n\nexport function nextHasMetadata(\n controller: ReadonlyPlaybackController,\n options?: NextEventAsPromiseOptions<\n PlaybackControllerEventMap,\n 'loadedMetadata'\n >\n): Promise<AnyRecord> {\n if (controller.hasMetadata) return Promise.resolve({})\n return nextEventAsPromise(controller, 'loadedMetadata', options)\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {\n ErrorLevel,\n ErrorOrigin,\n type Json,\n type Maybe,\n ReportableError,\n} from '@amazon/vinyl-util'\nimport { mediaErrorToJson } from '../logging/mediaErrorToJson'\n\n/**\n * An error from the media element\n */\nexport class ReportableMediaError extends ReportableError {\n // Copied from MediaError to ensure compatibility in Node\n static readonly MEDIA_ERR_ABORTED = 1\n static readonly MEDIA_ERR_NETWORK = 2\n static readonly MEDIA_ERR_DECODE = 3\n static readonly MEDIA_ERR_SRC_NOT_SUPPORTED = 4\n\n get [Symbol.toStringTag](): string {\n return 'ReportableMediaError'\n }\n\n readonly reason: string\n readonly code: number\n\n constructor(error: Maybe<MediaError>) {\n const { name, code, message } = mediaErrorToJson(error)\n const level =\n error == null || code === ReportableMediaError.MEDIA_ERR_ABORTED\n ? ErrorLevel.SILENT\n : ErrorLevel.FATAL\n super(message, ErrorOrigin.MEDIA, level)\n this.reason = name\n this.code = code\n Object.setPrototypeOf(this, ReportableMediaError.prototype)\n }\n\n toJSON(): Json {\n return {\n ...super.toJSON(),\n reason: this.reason,\n code: this.code,\n }\n }\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { Maybe } from '@amazon/vinyl-util'\n\nexport function mediaErrorToJson(error: Maybe<MediaError>): {\n readonly name: string\n readonly message: string\n readonly code: number\n} {\n let message: string = 'An unknown media error has occurred.'\n let name: string = 'UNKNOWN_MEDIA_ERROR'\n let code = -1\n if (error) {\n code = error.code\n switch (error.code) {\n case error.MEDIA_ERR_ABORTED: {\n message = `The requesting of the associated resource was aborted by the user's request.`\n name = 'MEDIA_ERR_ABORTED'\n break\n }\n case error.MEDIA_ERR_NETWORK: {\n message = 'A network error occurred.'\n name = 'MEDIA_ERR_NETWORK'\n break\n }\n case error.MEDIA_ERR_DECODE: {\n name = 'MEDIA_ERR_DECODE'\n message =\n 'An error occurred while trying to decode the media resource.'\n break\n }\n case error.MEDIA_ERR_SRC_NOT_SUPPORTED: {\n name = 'MEDIA_ERR_SRC_NOT_SUPPORTED'\n message = 'The associated resource was not supported.'\n break\n }\n }\n }\n return {\n name,\n message,\n code,\n }\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { CrossOrigin, PlaybackSource } from './PlaybackSource'\n\nexport interface PlaybackSourceImplDeps {\n readonly media: HTMLMediaElement\n}\n\nexport class PlaybackSourceImpl implements PlaybackSource {\n protected readonly media: HTMLMediaElement\n\n constructor(deps: PlaybackSourceImplDeps) {\n this.media = deps.media\n }\n\n get crossOrigin(): CrossOrigin {\n return this.media.crossOrigin as CrossOrigin\n }\n\n set crossOrigin(value: CrossOrigin) {\n this.media.crossOrigin = value\n }\n\n get currentSrc(): string {\n return this.media.currentSrc\n }\n\n load(): void {\n this.media.load()\n }\n\n get src(): string {\n return this.media.src\n }\n\n set src(value: string | null) {\n if (!value) this.media.removeAttribute('src')\n else this.media.src = value\n }\n\n get srcObject(): MediaStream | null {\n return this.media.srcObject as MediaStream | null\n }\n\n set srcObject(value: MediaStream | null) {\n this.media.srcObject = value\n }\n\n get disableRemotePlayback(): boolean {\n return this.media.disableRemotePlayback\n }\n\n set disableRemotePlayback(value: boolean) {\n this.media.disableRemotePlayback = value\n }\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { AnyRecord, Maybe, ReadonlyRecord } from '@amazon/vinyl-util'\nimport { ErrorOrigin, ownKeys } from '@amazon/vinyl-util'\nimport type { ObjectSchema } from '@amazon/vinyl-validation'\nimport {\n isOneOf,\n object,\n string,\n type ValueSchema,\n} from '@amazon/vinyl-validation'\n\nimport type { Track, TrackTypeId, TrackUri } from './Track'\n\nexport interface TrackLoadOptions {\n /**\n * The track type, used to map to a track factory.\n */\n readonly type: TrackTypeId\n\n /**\n * The track identifier.\n */\n readonly uri: TrackUri\n\n /**\n * The track configuration.\n */\n readonly config?: Maybe<AnyRecord>\n}\n\nexport const trackLoadOptionsValidator: ObjectSchema<TrackLoadOptions> = /* @__PURE__ */ object(\n {\n type: /* @__PURE__ */ string(),\n uri: /* @__PURE__ */ /* @__PURE__ */ string().notEmpty(),\n config: /* @__PURE__ */ /* @__PURE__ */ /* @__PURE__ */ object({}).maybe().optional(),\n }\n)\n\n/**\n * Produces a new Track for the given configuration options.\n */\nexport interface TrackFactory<TrackLoadOptionsType extends TrackLoadOptions> {\n /**\n * Throws a validation error if the track options are invalid.\n */\n validate(options: TrackLoadOptionsType): void\n\n /**\n * Constructs a new track from the provided load options.\n */\n createTrack(options: TrackLoadOptionsType): Track\n}\n\nexport type InferLoadOptionsFromFactory<T extends TrackFactory<any>> =\n T extends TrackFactory<infer LoadOptions> ? LoadOptions : never\n\nexport type CombinedTrackFactoryOptions<\n T extends ReadonlyRecord<TrackTypeId, TrackFactory<TrackLoadOptions>>,\n> = InferLoadOptionsFromFactory<T[keyof T]>\n\nexport type TrackFactoryRecord = ReadonlyRecord<\n TrackTypeId,\n TrackFactory<TrackLoadOptions>\n>\n\n/**\n * Validates that the keys of the track factory record match the track type\n * for the track factory.\n */\nexport type ValidTrackFactoryRecord<T extends TrackFactoryRecord> = {\n readonly [K in keyof T]: K extends InferLoadOptionsFromFactory<T[K]>['type']\n ? T[K]\n : never\n}\n\n/**\n * Given a map of TrackTypeId => TrackFactory, returns a track factory\n * that supports any of the provided track types.\n * The factory will be mapped by the track load options `type` property.\n *\n * @param factories\n */\nexport function createTrackFactory<T extends TrackFactoryRecord>(\n factories: ValidTrackFactoryRecord<T>\n): TrackFactory<CombinedTrackFactoryOptions<T>> {\n // Validates that the track type attempting to be created exists in the factory map.\n const typeValidator: ValueSchema<keyof T> = isOneOf(...ownKeys(factories))\n return {\n validate(options): void {\n typeValidator.assert(options.type, ErrorOrigin.API)\n factories[options.type].validate(options)\n },\n\n createTrack(options): Track {\n return factories[options.type].createTrack(options)\n },\n }\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { PlaybackSource } from '../../playback/PlaybackSource'\nimport type { Track, TrackTypeId, TrackUri } from '../Track'\nimport { type TrackBaseDeps } from '../TrackBase'\nimport {\n type TrackFactory,\n type TrackLoadOptions,\n trackLoadOptionsValidator,\n} from '../TrackFactory'\nimport { ErrorOrigin, type Maybe } from '@amazon/vinyl-util'\nimport { func, isOneOf, type ObjectSchema } from '@amazon/vinyl-validation'\nimport {\n SourceTrackBase,\n type SourceTrackBaseOptions,\n sourceTrackBaseOptionsValidator,\n} from './SourceTrackBase'\n\n/**\n * Dependencies for a SourceObjectTrack.\n */\nexport interface SourceObjectTrackDeps extends TrackBaseDeps {\n readonly playbackSource: PlaybackSource\n}\n\nexport interface SourceObjectTrackLoadOptions extends TrackLoadOptions {\n readonly type: 'srcObject'\n\n /**\n * A function to produce a MediaStream, or Promise<MediaStream>.\n */\n readonly srcObjectProvider: (\n uri: TrackUri\n ) => Promise<MediaStream> | MediaStream\n\n /**\n * Configuration options for the SourceObjectTrack.\n * Will be provided on preload and activate.\n */\n readonly config?: Maybe<SourceTrackBaseOptions>\n}\n\nconst loadOptionsValidator: ObjectSchema<SourceObjectTrackLoadOptions> =\n /* @__PURE__ */ trackLoadOptionsValidator.extend({\n srcObjectProvider: /* @__PURE__ */ func(),\n type: /* @__PURE__ */ isOneOf('srcObject'),\n config: /* @__PURE__ */ /* @__PURE__ */ sourceTrackBaseOptionsValidator.maybe().optional(),\n })\n\nexport function createSourceObjectTrackFactory(\n deps: SourceObjectTrackDeps\n): TrackFactory<SourceObjectTrackLoadOptions> {\n return {\n validate(options: SourceObjectTrackLoadOptions): void {\n loadOptionsValidator.assert(options, ErrorOrigin.API)\n },\n\n createTrack(options: SourceObjectTrackLoadOptions): Track {\n return new SourceObjectTrack(\n options.uri,\n options.type,\n Promise.resolve(options.srcObjectProvider(options.uri)),\n deps\n )\n },\n }\n}\n\n// TODO: Accept a provider function instead of a Promise for srcObject to support reset.\nexport class SourceObjectTrack extends SourceTrackBase<MediaStream> {\n get [Symbol.toStringTag](): string {\n return 'SourceObjectTrack'\n }\n\n constructor(\n uri: TrackUri,\n type: TrackTypeId,\n srcObject: Promise<MediaStream>,\n protected readonly deps: SourceObjectTrackDeps\n ) {\n super(uri, type, srcObject, deps)\n }\n\n protected setSrc(src: MediaStream) {\n this.deps.playbackSource.srcObject = src\n }\n\n protected clearSrc(): void {\n this.deps.playbackSource.srcObject = null\n this.deps.playbackSource.load()\n }\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { ObjectSchema } from '@amazon/vinyl-validation'\nimport { any, number, object } from '@amazon/vinyl-validation'\nimport {\n createAbortSlot,\n createDisposer,\n emptyRanges,\n EventHostImpl,\n isSilentError,\n logDebug,\n type Maybe,\n noop,\n type ReadonlyRanges,\n type ReadonlySet,\n} from '@amazon/vinyl-util'\nimport type { PlaybackController } from '../playback/PlaybackController'\nimport type {\n Track,\n TrackEventMap,\n TrackPreloadOptions,\n TrackTypeId,\n TrackUri,\n} from './Track'\nimport { type DrmController } from '../drm/DrmController'\nimport type {\n ContentType,\n MediaQualityMetadata,\n} from '../streaming/MediaQualityMetadata'\nimport { type DrmOptions, drmOptionsValidator } from '../drm/DrmOptions'\n\n/**\n * Dependencies for TrackBase.\n */\nexport interface TrackBaseDeps {\n /**\n * When the track is activated, playback will seek to the track's start time.\n */\n readonly playbackController: PlaybackController\n\n /**\n * DrmController manages track encryption.\n */\n readonly drmController: DrmController\n}\n\n/**\n * General configuration for tracks set in track load options.\n */\nexport interface TrackBaseOptions {\n /**\n * The time to seek to when the track has been activated.\n * For MSE tracks this will affect pre-fetching.\n */\n readonly startTime?: Maybe<number>\n\n /**\n * Extra application data to associate with the track.\n */\n readonly extra?: any\n\n /**\n * DRM Configuration overrides for this track.\n */\n readonly drm?: Partial<DrmOptions>\n}\n\nexport const trackBaseOptionsValidator: ObjectSchema<TrackBaseOptions> = /* @__PURE__ */ object(\n {\n extra: /* @__PURE__ */ /* @__PURE__ */ any().optional(),\n startTime: /* @__PURE__ */ /* @__PURE__ */ /* @__PURE__ */ number().maybe().optional(),\n drm: /* @__PURE__ */ /* @__PURE__ */ drmOptionsValidator.partial().optional(),\n }\n)\n\n/**\n * A base class for all tracks.\n */\nexport abstract class TrackBase<\n EventMap extends TrackEventMap = TrackEventMap,\n LoadOptionsType extends TrackBaseOptions = TrackBaseOptions,\n>\n extends EventHostImpl<EventMap>\n implements Track<LoadOptionsType>\n{\n get [Symbol.toStringTag](): string {\n return 'TrackBase'\n }\n\n /**\n * The current load options, if this is an active track.\n */\n protected loadOptions: LoadOptionsType | null = null\n\n protected readonly errorHandler = (error: any): void => {\n if (this._error) return // Already in an error state\n if (!isSilentError(error)) {\n this._error = error\n this.dispatch('error', {\n target: this,\n error,\n })\n }\n }\n protected readonly disposer = /* @__PURE__ */ createDisposer()\n protected drmSessionAbort = /* @__PURE__ */ createAbortSlot()\n\n get fetchedRanges(): ReadonlyRanges {\n return emptyRanges\n }\n\n abstract get contentTypes(): ReadonlySet<ContentType>\n\n abstract get qualities(): readonly MediaQualityMetadata[] | null\n abstract get qualitiesUnfiltered(): readonly MediaQualityMetadata[] | null\n\n abstract getStreamingQuality(\n contentType: ContentType\n ): MediaQualityMetadata | null\n abstract getBufferingQuality(\n contentType: ContentType\n ): MediaQualityMetadata | null\n abstract getPlaybackQuality(\n contentType: ContentType\n ): MediaQualityMetadata | null\n\n /**\n * Sets on handleError, cleared on 'reset'.\n */\n protected _error: Error | null = null\n\n private _active = false\n\n protected constructor(\n /**\n * The identifier of this track, used as the key in the track cache.\n */\n readonly uri: TrackUri,\n\n /**\n * The track type.\n */\n readonly type: TrackTypeId,\n\n protected readonly deps: TrackBaseDeps\n ) {\n super()\n }\n\n get error(): Error | null {\n return this._error\n }\n\n preload(\n _trackOptions: TrackPreloadOptions,\n _loadOptions: LoadOptionsType\n ): void {}\n\n get extra(): any {\n return this.loadOptions?.extra ?? null\n }\n\n get active(): boolean {\n return this._active\n }\n\n get disposed(): boolean {\n return this.disposer.disposed\n }\n\n activate(loadOptions: LoadOptionsType): void {\n if (this._active) return\n this.loadOptions = loadOptions\n this.reset() // Reset error state on activate\n this._active = true\n logDebug(this, 'activate', this.uri)\n this.deps.playbackController\n .seekTo(loadOptions.startTime ?? 0)\n .catch(noop)\n this.deps.drmController.configure(loadOptions.drm)\n this.onActivated(loadOptions)\n }\n\n /**\n * The track has been activated.\n * Operations on shared resources such as the playback controller may only be done while the\n * track is currently active. For example if there is a loading operation before the\n * playback source is set, isActive must be checked before the property is changed.\n */\n abstract onActivated(loadOptions: LoadOptionsType): void\n\n deactivate(): void {\n if (!this._active) return\n this._active = false\n this.loadOptions = null\n logDebug(this, 'deactivate', this.uri)\n this.deps.playbackController.pause()\n this.onDeactivated()\n this.closeDrmSessions()\n }\n\n abstract onDeactivated(): void\n\n toString(): string {\n return `[${this[Symbol.toStringTag]}#${this.uri}]`\n }\n\n protected closeDrmSessions() {\n this.drmSessionAbort.abort()\n }\n\n abstract clearPrefetch(): void\n\n /**\n * Resets the track to recover from error states.\n * Base implementation does nothing.\n *\n * Overrides should dispatch 'reset' after resetting error state.\n */\n reset(): void {\n if (this._error == null) {\n logDebug(this, 'reset no-op')\n return\n }\n logDebug(this, 'reset')\n this._error = null\n this.dispatch('reset', {})\n }\n\n dispose() {\n if (this.active) this.deactivate()\n else this.closeDrmSessions() // closes sessions created from prefetch.\n this.disposer.dispose()\n super.dispose()\n }\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { ReadonlyRecord, ValueProvider } from '@amazon/vinyl-util'\nimport type { DrmInitDataType } from '../streaming/DrmInitDataType'\nimport type { MediaFormatMetadata } from '../streaming/MediaQualityMetadata'\nimport {\n enumOf,\n func,\n isOneOf,\n number,\n object,\n type ObjectSchema,\n record,\n recordValues,\n string,\n type ValueSchema,\n} from '@amazon/vinyl-validation'\nimport { DrmKeySystem, drmKeySystemValidator } from './DrmKeySystem'\nimport {\n type LicenseProvider,\n type LicenseServerOptions,\n licenseServerOptionsValidator,\n} from './licenseProvider/LicenseProvider'\n\n/**\n * DrmRobustness is the requested security level for audio or video decryption.\n */\nexport enum DrmRobustness {\n SW_SECURE_CRYPTO = 'SW_SECURE_CRYPTO',\n SW_SECURE_DECODE = 'SW_SECURE_DECODE',\n HW_SECURE_CRYPTO = 'HW_SECURE_CRYPTO',\n HW_SECURE_DECODE = 'HW_SECURE_DECODE',\n HW_SECURE_ALL = 'HW_SECURE_ALL',\n}\n\n/**\n * DrmConfig configures DrmController and LicenseProvider.\n */\nexport interface DrmOptions {\n readonly keySystems: {\n readonly [p in DrmKeySystem]?: DrmKeySystemOptions\n } & {\n readonly [DrmKeySystem.CLEAR_KEY]?: DrmClearKeySystemOptions\n } & {\n /**\n * A wildcard to match any key system when there wasn't a match.\n */\n readonly ['*']?: DrmKeySystemOptions\n }\n\n /**\n *\n * If not set, the license provider from the player dependencies will\n * be used.\n */\n readonly licenseProvider?: LicenseProvider\n}\n\n/**\n * Clear key system options that extend base DRM key system options with clear\n * key mappings. Used for unencrypted content or testing scenarios where keys\n * are provided in plain text.\n */\nexport type DrmClearKeySystemOptions = DrmKeySystemOptions & {\n readonly keys: ReadonlyRecord<string, string>\n}\n\nexport interface DrmKeySystemOptions {\n /**\n * License server configuration used to make license requests.\n */\n readonly licenseServer?: ValueProvider<LicenseServerOptions>\n\n /**\n * Audio-specific DRM configuration.\n */\n readonly audio?: DrmMediaKeySystemOptions\n\n /**\n * Video-specific DRM configuration.\n */\n readonly video?: DrmMediaKeySystemOptions\n\n /**\n * Key systems with a higher priority take precedence.\n * If two key systems have equal priority, the order will be as it appears\n * in DrmInfo (provided by the manifest).\n */\n readonly priority?: number\n\n /**\n * Transform applied to init data before session creation.\n * Always invoked for every key system. The default implementation\n * handles {@link DrmKeySystem.FAIR_PLAY_1_0} by packing the init data,\n * content ID, and server certificate into the format expected by\n * WebKit-prefixed EME. For all other key systems, returns init data\n * unchanged.\n */\n readonly initDataTransformer?: InitDataTransformer\n}\n\n/**\n * Transforms raw init data before it is passed to the CDM for session creation.\n *\n * @param initData - The raw initialization data.\n * @param initDataType - The initialization data type (e.g. 'cenc', 'skd').\n * @param drmInfo - The media format metadata for the current content.\n * @returns The transformed init data to pass to the CDM.\n */\nexport type InitDataTransformer = (\n initData: Uint8Array<ArrayBuffer>,\n initDataType: DrmInitDataType,\n drmInfo: MediaFormatMetadata\n) => Uint8Array<ArrayBuffer>\n\nexport interface DrmMediaKeySystemOptions {\n readonly robustness?: DrmRobustness\n}\n\nexport const drmRobustnessValidator: ValueSchema<DrmRobustness> =\n /* @__PURE__ */ enumOf(DrmRobustness)\n\nexport const drmMediaKeySystemOptionsValidator: ObjectSchema<DrmMediaKeySystemOptions> =\n /* @__PURE__ */ object({\n robustness: /* @__PURE__ */ drmRobustnessValidator.optional(),\n })\n\nexport const drmKeySystemOptionsValidator: ObjectSchema<DrmKeySystemOptions> =\n /* @__PURE__ */ object({\n licenseServer: /* @__PURE__ */ /* @__PURE__ */ /* @__PURE__ */ func().or(licenseServerOptionsValidator).optional(),\n audio: /* @__PURE__ */ drmMediaKeySystemOptionsValidator.optional(),\n video: /* @__PURE__ */ drmMediaKeySystemOptionsValidator.optional(),\n priority: /* @__PURE__ */ /* @__PURE__ */ number().optional(),\n initDataTransformer: /* @__PURE__ */ /* @__PURE__ */ func().optional(),\n })\n\nexport const drmClearKeySystemOptionsValidator: ObjectSchema<DrmClearKeySystemOptions> =\n /* @__PURE__ */ drmKeySystemOptionsValidator.extend({\n keys: /* @__PURE__ */ recordValues(/* @__PURE__ */ string()),\n })\n\nexport const drmOptionsValidator: ObjectSchema<DrmOptions> = /* @__PURE__ */ object({\n keySystems: /* @__PURE__ */ /* @__PURE__ */ record(\n /* @__PURE__ */ drmKeySystemValidator.or(/* @__PURE__ */ isOneOf('*')),\n /* @__PURE__ */ drmKeySystemOptionsValidator.optional()\n ).and(\n /* @__PURE__ */ object<{\n readonly [DrmKeySystem.CLEAR_KEY]?: DrmClearKeySystemOptions\n }>({\n [DrmKeySystem.CLEAR_KEY]:\n /* @__PURE__ */ drmClearKeySystemOptionsValidator.optional(),\n })\n ),\n\n licenseProvider: /* @__PURE__ */ /* @__PURE__ */ func().optional(),\n})\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { ValueSchema } from '@amazon/vinyl-validation'\nimport { string } from '@amazon/vinyl-validation'\n\nexport enum DrmKeySystem {\n /**\n * Plain text encryption.\n */\n CLEAR_KEY = 'org.w3.clearkey',\n\n /**\n * Google's Widevine.\n */\n WIDEVINE = 'com.widevine.alpha',\n\n /**\n * Microsoft's PlayReady.\n *\n * - Deprecated.\n * - Will be removed in a future release.\n * - Non-compliant with any version of the EME specification.\n */\n PLAY_READY = 'com.microsoft.playready',\n\n /**\n * Microsoft's PlayReady for Chromecast.\n *\n * - Deprecated.\n * - Will be removed in a future release.\n * - Non-compliant with any version of the EME specification.\n */\n PLAY_READY_CHROMECAST = 'com.chromecast.playready',\n\n /**\n * Microsoft's PlayReady.\n *\n * - Security Level 2000.\n * - Best effort compliance with latest EME specification.\n */\n PLAY_READY_RECOMMENDATION = 'com.microsoft.playready.recommendation',\n\n /**\n * Microsoft's PlayReady.\n *\n * - Supported on devices with required hardware.\n * - Security Level 3000.\n * - Best effort compliance with latest EME specification.\n */\n PLAY_READY_3000 = 'com.microsoft.playready.recommendation.3000',\n\n /**\n * Apple's Fairplay for modern EME.\n */\n FAIR_PLAY = 'com.apple.fps',\n\n /**\n * Apple's Fairplay for legacy Apple Media Keys.\n */\n FAIR_PLAY_1_0 = 'com.apple.fps.1_0',\n}\n\n/**\n * Validates that the key system value is a string.\n * While DrmKeySystem is an enum to be useful for providing known key systems,\n * avoid strict validation to allow for unknown key systems.\n */\nexport const drmKeySystemValidator =\n /* @__PURE__ */ /* @__PURE__ */ string().notEmpty() as ValueSchema<DrmKeySystem>\n\nexport const PLAY_READY_KEY_SYSTEMS: readonly DrmKeySystem[] = [\n DrmKeySystem.PLAY_READY,\n DrmKeySystem.PLAY_READY_CHROMECAST,\n DrmKeySystem.PLAY_READY_RECOMMENDATION,\n DrmKeySystem.PLAY_READY_3000,\n] as const\n\nexport function isPlayReady(keySystem: DrmKeySystem): boolean {\n return PLAY_READY_KEY_SYSTEMS.includes(keySystem)\n}\n\nexport const FAIR_PLAY_KEY_SYSTEMS: readonly DrmKeySystem[] = [\n DrmKeySystem.FAIR_PLAY,\n DrmKeySystem.FAIR_PLAY_1_0,\n] as const\n\nexport function isFairPlay(keySystem: DrmKeySystem): boolean {\n return FAIR_PLAY_KEY_SYSTEMS.includes(keySystem)\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { type Maybe, type ReadonlyAbort } from '@amazon/vinyl-util'\nimport type { DrmKeySystem } from '../DrmKeySystem'\nimport {\n any,\n instanceOf,\n object,\n type ObjectSchema,\n string,\n} from '@amazon/vinyl-validation'\n\n/**\n * LicenseProvider handles requesting DRM licenses for specific key systems.\n */\nexport type LicenseProvider = (\n keySystem: DrmKeySystem,\n serverOptions: LicenseServerOptions,\n challenge: ArrayBuffer,\n abort?: ReadonlyAbort\n) => Promise<ArrayBuffer>\n\n/**\n * Basic license server configuration.\n * The license provider is given the matching configuration for the selected\n * key system.\n */\nexport interface LicenseServerOptions {\n /**\n * The license server URL.\n * This is required when using the default license provider.\n */\n readonly url?: Maybe<string | URL>\n\n /**\n * License request init options.\n */\n readonly init?: Maybe<RequestInit>\n\n /**\n * If set, provides the server certificate.\n * An ArrayBufferLike object containing the server certificate.\n * The contents are Key System-specific.\n * If a `string` is provided, the value will be considered to be Base 64.\n */\n readonly serverCertificate?: Maybe<ServerCertificate>\n}\n\n/**\n * An ArrayBufferLike object containing the server certificate.\n * The contents are Key System-specific.\n * If a `string` is provided, the value will be considered to be Base 64.\n */\nexport type ServerCertificate = ArrayBuffer | string\n\nexport const licenseServerOptionsValidator: ObjectSchema<LicenseServerOptions> =\n /* @__PURE__ */ object({\n url: /* @__PURE__ */ /* @__PURE__ */ /* @__PURE__ */ /* @__PURE__ */ string().or(/* @__PURE__ */ instanceOf(URL)).maybe().optional(),\n init: /* @__PURE__ */ /* @__PURE__ */ /* @__PURE__ */ /* @__PURE__ */ object({}).cast<RequestInit>().maybe().optional(),\n serverCertificate: /* @__PURE__ */ /* @__PURE__ */ any().optional(),\n })\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { TrackEventMap } from '../Track'\nimport type { Unsubscribe } from '@amazon/vinyl-util'\nimport { EventHostImpl, type ReadonlySet } from '@amazon/vinyl-util'\nimport { PlaybackReadyState } from '../../playback/ReadonlyPlaybackController'\nimport type { PlaybackController } from '../../playback/PlaybackController'\nimport type { ChangeEvent } from '../../event/ChangeEvent'\nimport type {\n ContentType,\n MediaQualityMetadata,\n} from '../../streaming/MediaQualityMetadata'\n\n/**\n * FixedPlaybackQuality has a singular quality for selection.\n *\n * streamingQuality will always be the fixed quality.\n *\n * bufferingQuality will be the fixed quality when active, otherwise null.\n *\n * playbackQuality will be the fixed quality when active and data is buffered, otherwise null.\n */\nexport class FixedPlaybackQuality extends EventHostImpl<\n Pick<\n TrackEventMap,\n | 'streamingQualityChange'\n | 'bufferingQualityChange'\n | 'playbackQualityChange'\n >\n> {\n private _fixedQuality!: MediaQualityMetadata\n private _contentTypes = /* @__PURE__ */ new Set<ContentType>()\n\n private _isActive = false\n get active(): boolean {\n return this._isActive\n }\n\n constructor(\n fixedQuality: MediaQualityMetadata,\n private readonly deps: {\n readonly playbackController: PlaybackController\n }\n ) {\n super()\n this.fixedQuality = fixedQuality\n }\n\n get contentTypes(): ReadonlySet<ContentType> {\n return this._contentTypes\n }\n\n get fixedQuality(): MediaQualityMetadata {\n return this._fixedQuality\n }\n\n set fixedQuality(value: MediaQualityMetadata) {\n const previous = this._fixedQuality\n this._fixedQuality = value\n this._contentTypes = new Set()\n if (value.contentType) this._contentTypes.add(value.contentType)\n this.dispatch('streamingQualityChange', {\n previous,\n current: this._fixedQuality,\n })\n if (this.active) {\n this.bufferingQuality = value\n if (\n this.deps.playbackController.readyState >=\n PlaybackReadyState.HAVE_CURRENT_DATA\n ) {\n this.playbackQuality = value\n }\n }\n }\n\n getStreamingQuality(contentType: ContentType): MediaQualityMetadata | null {\n if (contentType !== this._fixedQuality.contentType) return null\n return this._fixedQuality\n }\n\n private _bufferingQuality: MediaQualityMetadata | null = null\n getBufferingQuality(contentType: ContentType): MediaQualityMetadata | null {\n if (contentType !== this._bufferingQuality?.contentType) return null\n return this._bufferingQuality\n }\n\n private set bufferingQuality(value: MediaQualityMetadata | null) {\n const previous = this._bufferingQuality\n if (previous === value) return\n this._bufferingQuality = value\n this.dispatch('bufferingQualityChange', {\n previous,\n current: this._bufferingQuality,\n })\n }\n\n private _playbackQuality: MediaQualityMetadata | null = null\n getPlaybackQuality(contentType: ContentType): MediaQualityMetadata | null {\n if (contentType !== this._playbackQuality?.contentType) return null\n return this._playbackQuality\n }\n\n private set playbackQuality(value: MediaQualityMetadata | null) {\n const previous = this._playbackQuality\n if (previous === value) return\n this._playbackQuality = value\n this.dispatch('playbackQualityChange', {\n previous,\n current: this._playbackQuality,\n })\n }\n\n private readyStateChangeSub: Unsubscribe | null = null\n activate() {\n if (this._isActive) return\n this._isActive = true\n this.bufferingQuality = this._fixedQuality\n const pC = this.deps.playbackController\n this.readyStateChangeSub = pC.on(\n 'readyStateChange',\n this.onReadyStateChange\n )\n if (pC.readyState >= PlaybackReadyState.HAVE_CURRENT_DATA) {\n this.playbackQuality = this._fixedQuality\n }\n }\n\n deactivate() {\n if (!this._isActive) return\n this._isActive = false\n this.readyStateChangeSub!()\n this.readyStateChangeSub = null\n this.bufferingQuality = null\n this.playbackQuality = null\n }\n\n private onReadyStateChange = (event: ChangeEvent<PlaybackReadyState>) => {\n const hasData = event.current >= PlaybackReadyState.HAVE_CURRENT_DATA\n this.playbackQuality = hasData ? this._fixedQuality : null\n }\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {\n TrackBase,\n type TrackBaseDeps,\n type TrackBaseOptions,\n trackBaseOptionsValidator,\n} from '../TrackBase'\nimport type {\n TrackEventMap,\n TrackPreloadOptions,\n TrackTypeId,\n TrackUri,\n} from '../Track'\nimport { FixedPlaybackQuality } from './FixedPlaybackQuality'\nimport {\n logDebug,\n type Maybe,\n type ReadonlySet,\n redispatchEvents,\n} from '@amazon/vinyl-util'\nimport {\n type ContentType,\n createEmptyMediaQualityMetadata,\n type MediaQualityMetadata,\n mediaQualityMetadataValidator,\n} from '../../streaming/MediaQualityMetadata'\nimport type { ObjectSchema } from '@amazon/vinyl-validation'\n\nexport interface SourceTrackBaseOptions extends TrackBaseOptions {\n /**\n * Quality metadata.\n * May be used to configure DRM (for native HLS), codec, or other track metadata.\n */\n readonly qualityMetadata?: Maybe<Partial<MediaQualityMetadata>>\n}\n\nexport const sourceTrackBaseOptionsValidator: ObjectSchema<SourceTrackBaseOptions> =\n /* @__PURE__ */ trackBaseOptionsValidator.extend({\n qualityMetadata: /* @__PURE__ */ /* @__PURE__ */ /* @__PURE__ */ mediaQualityMetadataValidator\n .partial()\n .maybe()\n .optional(),\n })\n\nconst emptyMediaQualityMetadata: MediaQualityMetadata =\n /* @__PURE__ */ createEmptyMediaQualityMetadata()\n\nexport abstract class SourceTrackBase<\n SrcType,\n EventMap extends TrackEventMap = TrackEventMap,\n LoadOptionsType extends SourceTrackBaseOptions = SourceTrackBaseOptions,\n> extends TrackBase<EventMap, LoadOptionsType> {\n private readonly fixedPlaybackQuality: FixedPlaybackQuality\n private _resolvedSrc: SrcType | null = null\n\n protected constructor(\n uri: TrackUri,\n type: TrackTypeId,\n public readonly src: Promise<SrcType>,\n protected readonly deps: TrackBaseDeps\n ) {\n super(uri, type, deps)\n const add = this.disposer.add\n this.src\n .then((src) => {\n this._resolvedSrc = src\n if (this.active) this.setSrc(src)\n })\n .catch(this.errorHandler)\n this.fixedPlaybackQuality = add(\n new FixedPlaybackQuality(emptyMediaQualityMetadata, deps)\n )\n this.fixedPlaybackQuality.on('bufferingQualityChange', (event) => {\n this.deps.drmController.setBufferingDrmInfo(\n event.current,\n this.drmSessionAbort.value\n )\n })\n redispatchEvents(this, this.fixedPlaybackQuality, [\n 'streamingQualityChange',\n 'bufferingQualityChange',\n 'playbackQualityChange',\n ])\n }\n\n preload(trackOptions: TrackPreloadOptions, loadOptions: LoadOptionsType) {\n super.preload(trackOptions, loadOptions)\n this.fixedPlaybackQuality.fixedQuality = {\n ...emptyMediaQualityMetadata,\n ...loadOptions.qualityMetadata,\n }\n }\n\n get contentTypes(): ReadonlySet<ContentType> {\n return this.fixedPlaybackQuality.contentTypes\n }\n\n get qualities(): readonly MediaQualityMetadata[] | null {\n return null\n }\n\n get qualitiesUnfiltered(): readonly MediaQualityMetadata[] | null {\n return null\n }\n\n getStreamingQuality(contentType: ContentType): MediaQualityMetadata | null {\n return this.fixedPlaybackQuality.getStreamingQuality(contentType)\n }\n\n getBufferingQuality(contentType: ContentType): MediaQualityMetadata | null {\n return this.fixedPlaybackQuality.getBufferingQuality(contentType)\n }\n\n getPlaybackQuality(contentType: ContentType): MediaQualityMetadata | null {\n return this.fixedPlaybackQuality.getPlaybackQuality(contentType)\n }\n\n onActivated(): void {\n this.fixedPlaybackQuality.activate()\n this.deps.drmController.initializeForPlayback(\n this.fixedPlaybackQuality.fixedQuality,\n this.drmSessionAbort.value\n )\n if (this._resolvedSrc != null) this.setSrc(this._resolvedSrc)\n }\n\n protected abstract setSrc(src: SrcType): void\n protected abstract clearSrc(): void\n\n onDeactivated(): void {\n if (this._resolvedSrc != null) this.clearSrc()\n this.fixedPlaybackQuality.deactivate()\n }\n\n clearPrefetch() {\n // Source tracks do not prefetch\n logDebug(this, 'clearPrefetch no-op')\n }\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {\n createShortUid,\n type Maybe,\n type MutableDeep,\n} from '@amazon/vinyl-util'\nimport type { ObjectSchema } from '@amazon/vinyl-validation'\nimport {\n array,\n enumOf,\n isOneOf,\n number,\n object,\n string,\n tuple,\n} from '@amazon/vinyl-validation'\nimport {\n type DescriptorRecord,\n descriptorRecordValidator,\n descriptorValidator,\n} from './DescriptorRecord'\n\nimport type { DrmInitDataType } from './DrmInitDataType'\nimport type { CencEncryptionScheme } from '../drm/CencEncryptionScheme'\nimport { DrmKeySystem } from '../drm/DrmKeySystem'\nimport type { FrameRate } from '@amazon/vinyl-mpd-parser'\n\nexport type ContentType = 'audio' | 'video' | 'text'\n\nexport const ALL_CONTENT_TYPES = [\n 'video',\n 'audio',\n 'text',\n] as const satisfies ContentType[]\n\n/**\n * Contains media formatting and encryption metadata.\n */\nexport interface MediaFormatMetadata {\n /**\n * The content type of the representation, e.g. 'audio', 'video', 'text'\n * Must be non-null for segmented media.\n */\n readonly contentType: ContentType | null\n\n /**\n * The full MIME type of the media.\n *\n * Must be non-null for segmented media.\n */\n readonly mimeType: string | null\n\n /**\n * The initialization data format.\n */\n readonly initDataType: DrmInitDataType | null\n\n /**\n * The method of encryption, or null.\n */\n readonly encryptionScheme: CencEncryptionScheme | null\n\n /**\n * Protection schemes used in this media.\n */\n readonly contentProtections: readonly DrmProtection[]\n}\n\n/**\n * Protection information for a key system.\n * Media may have more than one protection system.\n */\nexport interface DrmProtection {\n /**\n * The key system used in the encryption.\n */\n readonly keySystem: DrmKeySystem\n\n /**\n * The initialization key, in base 64.\n */\n readonly pssh?: Maybe<string>\n\n /**\n * PlayReady object.\n */\n readonly pro?: Maybe<string>\n}\n\nexport const drmProtectionValidator: ObjectSchema<DrmProtection> =\n /* @__PURE__ */ descriptorValidator.extend({\n keySystem: /* @__PURE__ */ enumOf(DrmKeySystem),\n pro: /* @__PURE__ */ /* @__PURE__ */ /* @__PURE__ */ string().maybe().optional(),\n pssh: /* @__PURE__ */ /* @__PURE__ */ /* @__PURE__ */ string().maybe().optional(),\n })\n\nexport const mediaFormatMetadataValidator: ObjectSchema<MediaFormatMetadata> =\n /* @__PURE__ */ object({\n contentProtections: /* @__PURE__ */ /* @__PURE__ */ array(drmProtectionValidator).readonly(),\n contentType: /* @__PURE__ */ /* @__PURE__ */ isOneOf('audio', 'video', 'text').orNull(),\n initDataType: /* @__PURE__ */ /* @__PURE__ */ string().orNull(),\n encryptionScheme: /* @__PURE__ */ /* @__PURE__ */ string().orNull(),\n mimeType: /* @__PURE__ */ /* @__PURE__ */ string().orNull(),\n })\n\n/**\n * Metadata representing attributes of a media representation.\n */\nexport interface MediaQualityMetadata extends MediaFormatMetadata {\n /**\n * Provides a decoding identifier. If this value changes from the previously buffered\n * segment, the initialization segment must be buffered before appending the media segment.\n * Unique to the track.\n */\n readonly decoderId: string\n\n /**\n * The quality id identifies the quality representation.\n * Unique to the track.\n */\n readonly qualityId: string\n\n /**\n * Optional string specifying the codec(s) used for this representation. The format follows the RFC 6381 codec\n * string format.\n */\n readonly codecs: string | null\n\n /**\n * The average bandwidth in bits per second required for playing this representation.\n * For HLS, and non-segmented media this will be null.\n */\n readonly bandwidth: number | null\n\n /**\n * The peak bandwidth in bits per second required for playing this representation\n * with its cumulative A/V content streams.\n *\n * Guaranteed to be set for segmented media.\n */\n readonly bandwidthTotal: number | null\n\n /**\n * Audio sampling rate(s) in samples per second.\n * An array of either one or two decimal integer values. If there are two elements this represents a minimum and\n * maximum sampling rate of the audio media.\n */\n readonly audioSamplingRate: readonly number[] | null\n\n /**\n * Frame rate for video representations, specified either as a ratio of integers, e.g. [30000, 1001]\n */\n readonly frameRate: FrameRate | null\n\n /**\n * For video representations, the width of the video in pixels.\n */\n readonly width: number | null\n\n /**\n * For video representations, the height of the video in pixels.\n */\n readonly height: number | null\n\n /**\n * Information that may enhance playback or presentation.\n */\n readonly supplementalProperties: DescriptorRecord\n\n /**\n * Specifies the language of the content, using a code as defined by RFC 5646.\n */\n readonly lang: string | null\n\n /**\n * Identifies the group this quality belongs to (e.g. the adaptation set).\n */\n readonly groupId: string\n\n /**\n * The group IDs that this quality is permitted to switch to during playback.\n * Derived from the DASH `urn:mpeg:dash:adaptation-set-switching:2016` supplemental property.\n * Includes the quality's own groupId.\n * Null means no switching constraint (all groups are permitted).\n * An array restricts switching to only the listed group IDs.\n * Default behavior:\n * - DASH: restricted to own group unless adaptation-set-switching property is present.\n * - HLS: restricted to variants with the same base codec and language.\n */\n readonly switchingGroupIds: readonly string[] | null\n}\n\n/**\n * Creates a new, empty media format metadata object.\n */\nexport function createEmptyMediaFormatMetadata(): MutableDeep<MediaFormatMetadata> {\n return {\n contentType: null,\n mimeType: null,\n initDataType: null,\n encryptionScheme: null,\n contentProtections: [],\n }\n}\n\n/**\n * Creates a new empty media quality metadata object.\n */\nexport function createEmptyMediaQualityMetadata(): MutableDeep<MediaQualityMetadata> {\n return {\n ...createEmptyMediaFormatMetadata(),\n decoderId: createShortUid(),\n qualityId: createShortUid(),\n codecs: null,\n bandwidth: null,\n bandwidthTotal: null,\n supplementalProperties: {},\n audioSamplingRate: null,\n frameRate: null,\n height: null,\n width: null,\n lang: null,\n groupId: createShortUid(),\n switchingGroupIds: null,\n }\n}\n\nexport const mediaQualityMetadataValidator: ObjectSchema<MediaQualityMetadata> =\n /* @__PURE__ */ mediaFormatMetadataValidator.extend({\n audioSamplingRate: /* @__PURE__ */ /* @__PURE__ */ /* @__PURE__ */ array(/* @__PURE__ */ number()).readonly().orNull(),\n bandwidth: /* @__PURE__ */ /* @__PURE__ */ number().orNull(),\n bandwidthTotal: /* @__PURE__ */ /* @__PURE__ */ number().orNull(),\n codecs: /* @__PURE__ */ /* @__PURE__ */ string().orNull(),\n decoderId: /* @__PURE__ */ string(),\n frameRate: /* @__PURE__ */ /* @__PURE__ */ /* @__PURE__ */ tuple(/* @__PURE__ */ number(), /* @__PURE__ */ number()).readonly().orNull(),\n height: /* @__PURE__ */ /* @__PURE__ */ number().orNull(),\n qualityId: /* @__PURE__ */ string(),\n supplementalProperties: descriptorRecordValidator,\n width: /* @__PURE__ */ /* @__PURE__ */ number().orNull(),\n lang: /* @__PURE__ */ /* @__PURE__ */ string().orNull(),\n groupId: /* @__PURE__ */ string(),\n switchingGroupIds: /* @__PURE__ */ /* @__PURE__ */ /* @__PURE__ */ array(/* @__PURE__ */ string()).readonly().orNull(),\n })\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {\n array,\n object,\n type ObjectSchema,\n record,\n type RecordSchema,\n string,\n} from '@amazon/vinyl-validation'\nimport { first, type Maybe, type ReadonlyRecord } from '@amazon/vinyl-util'\nimport { type Uri } from '@amazon/vinyl-xml'\n\n/**\n * A map of scheme URIs to a descriptor list.\n */\nexport type DescriptorRecord = ReadonlyRecord<\n Uri,\n readonly Descriptor[] | undefined\n>\n\n/**\n * A generic descriptor providing extended information.\n */\nexport interface Descriptor {\n /**\n * An optional unique identifier for the descriptor.\n */\n readonly id?: Maybe<string>\n\n /**\n * An optional value associated with the descriptor, whose interpretation depends on the scheme.\n */\n readonly value?: Maybe<string>\n}\n\n/**\n * Gets The first matching descriptor value from a record with a matching URI and optional id.\n *\n * @param record The descriptor record.\n * @param uri The URI key.\n * @param id An optional id. If provided the descriptor must have a matching id.\n */\nexport function getDescriptorValue(\n record: DescriptorRecord,\n uri: Uri,\n id?: Maybe<string>\n): string | null {\n let arr = record[uri]\n if (!arr) return null\n if (id !== undefined) arr = arr.filter((descriptor) => descriptor.id === id)\n return first(arr)?.value ?? null\n}\n\nexport const descriptorValidator: ObjectSchema<Descriptor> = /* @__PURE__ */ object({\n id: /* @__PURE__ */ /* @__PURE__ */ /* @__PURE__ */ string().maybe().optional(),\n value: /* @__PURE__ */ /* @__PURE__ */ /* @__PURE__ */ string().maybe().optional(),\n})\n\nexport const descriptorRecordValidator: RecordSchema<DescriptorRecord> = /* @__PURE__ */ record<\n Uri,\n readonly Descriptor[] | undefined\n>(/* @__PURE__ */ string(), /* @__PURE__ */ /* @__PURE__ */ /* @__PURE__ */ array(descriptorValidator).readonly().orUndefined())\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { Track, TrackTypeId, TrackUri } from '../Track'\nimport { type TrackBaseDeps } from '../TrackBase'\nimport {\n type TrackFactory,\n type TrackLoadOptions,\n trackLoadOptionsValidator,\n} from '../TrackFactory'\nimport { ErrorOrigin, type Maybe } from '@amazon/vinyl-util'\nimport {\n func,\n isOneOf,\n type ObjectSchema,\n string,\n} from '@amazon/vinyl-validation'\nimport {\n SourceTrackBase,\n type SourceTrackBaseOptions,\n sourceTrackBaseOptionsValidator,\n} from './SourceTrackBase'\nimport type { PlaybackSource } from '../../playback/PlaybackSource'\n\n/**\n * Dependencies for a SourceTrack.\n */\nexport interface SourceTrackDeps extends TrackBaseDeps {\n readonly playbackSource: PlaybackSource\n}\n\nexport interface SourceTrackLoadOptions extends TrackLoadOptions {\n readonly type: 'src'\n\n /**\n * If set, will be called to provide the track src.\n * Otherwise, the uri will be used.\n */\n readonly srcProvider?: Maybe<(uri: TrackUri) => Promise<string> | string>\n\n /**\n * Configuration options for the SourceTrack.\n * Will be provided on preload and activate.\n */\n readonly config?: Maybe<SourceTrackBaseOptions>\n}\n\nconst loadOptionsValidator: ObjectSchema<SourceTrackLoadOptions> =\n /* @__PURE__ */ trackLoadOptionsValidator.extend({\n config: /* @__PURE__ */ /* @__PURE__ */ sourceTrackBaseOptionsValidator.maybe().optional(),\n srcProvider: /* @__PURE__ */ /* @__PURE__ */ /* @__PURE__ */ func().maybe().optional(),\n type: /* @__PURE__ */ isOneOf('src'),\n uri: /* @__PURE__ */ /* @__PURE__ */ string().notEmpty(),\n })\n\nexport function createSourceTrackFactory(\n deps: SourceTrackDeps\n): TrackFactory<SourceTrackLoadOptions> {\n return {\n validate(options: SourceTrackLoadOptions) {\n loadOptionsValidator.assert(options, ErrorOrigin.API)\n },\n\n createTrack(options: SourceTrackLoadOptions): Track {\n return new SourceTrack(\n options.uri,\n options.type,\n options.srcProvider\n ? Promise.resolve(options.srcProvider(options.uri))\n : Promise.resolve(options.uri),\n deps\n )\n },\n }\n}\n\n// TODO: Accept a provider function instead of a Promise for src to support reset.\nexport class SourceTrack extends SourceTrackBase<string> {\n get [Symbol.toStringTag](): string {\n return 'SourceTrack'\n }\n\n constructor(\n uri: TrackUri,\n type: TrackTypeId,\n src: Promise<string>,\n protected readonly deps: SourceTrackDeps\n ) {\n super(uri, type, src, deps)\n }\n\n protected setSrc(src: string) {\n this.deps.playbackSource.src = src\n }\n\n protected clearSrc() {\n this.deps.playbackSource.src = null\n this.deps.playbackSource.load()\n }\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { type TrackBaseOptions, trackBaseOptionsValidator } from '../TrackBase'\nimport {\n type DashManifestProvider,\n type DashManifestData,\n} from './DashManifestProvider'\nimport type { DashManifestController } from './DashManifestController'\nimport type { TrackFactory, TrackLoadOptions } from '../TrackFactory'\nimport type { ObservableValue } from '@amazon/vinyl-observable'\nimport {\n ErrorOrigin,\n type Maybe,\n type RequestInitOptions,\n} from '@amazon/vinyl-util'\nimport {\n func,\n isOneOf,\n object,\n type ObjectSchema,\n string,\n} from '@amazon/vinyl-validation'\nimport type { Track } from '../Track'\nimport { type Factories } from '@amazon/vinyl-di'\nimport type { DashMediaQualityMetadataResolver } from './DashMediaQualityMetadataResolver'\nimport { MseTrack, type MseTrackDeps } from '../mse/MseTrack'\nimport type { MediaTimeline } from '../../streaming/MediaTimeline'\n\nexport interface DashTrackLoadOptions extends TrackLoadOptions {\n readonly type: 'dash'\n\n /**\n * If set, will be used to resolve the dash manifest.\n * Otherwise, the uri will be assumed to represent a URL to an MPD.\n * The manifest provider is not expected to cache results.\n */\n readonly manifestProvider?: Maybe<DashManifestProvider>\n\n /**\n * If a manifest provider is not set, the uri will be used to fetch a manifest.\n * This can be set to provide Request initialization options such as headers or request method.\n */\n readonly requestInit?: Maybe<RequestInitOptions>\n\n /**\n * Request initialization options for segment requests, such as headers.\n * Range headers set by the player for byte-range requests will not be overridden.\n */\n readonly segmentRequestInit?: Maybe<RequestInitOptions>\n\n /**\n * Configuration options for the DashTrack.\n * Will be set before the track is activated.\n */\n readonly config?: Maybe<TrackBaseOptions>\n}\n\nconst loadOptionsValidator: ObjectSchema<DashTrackLoadOptions> = /* @__PURE__ */ object({\n config: /* @__PURE__ */ /* @__PURE__ */ trackBaseOptionsValidator.maybe().optional(),\n manifestProvider: /* @__PURE__ */ /* @__PURE__ */ /* @__PURE__ */ func().maybe().optional(),\n requestInit: /* @__PURE__ */ /* @__PURE__ */ /* @__PURE__ */ /* @__PURE__ */ object({}).cast<RequestInitOptions>().maybe().optional(),\n segmentRequestInit: /* @__PURE__ */ /* @__PURE__ */ /* @__PURE__ */ /* @__PURE__ */ object({})\n .cast<RequestInitOptions>()\n .maybe()\n .optional(),\n type: /* @__PURE__ */ isOneOf('dash'),\n uri: /* @__PURE__ */ /* @__PURE__ */ string().notEmpty(),\n})\n\nexport type DashTrackFactoryDeps = {\n readonly createDashFactories: (\n loadOptions: DashTrackLoadOptions\n ) => Factories<DashTrackDeps>\n}\n\nexport function createDashTrackFactory(\n deps: DashTrackFactoryDeps\n): TrackFactory<DashTrackLoadOptions> {\n return {\n validate(options: DashTrackLoadOptions) {\n loadOptionsValidator.assert(options, ErrorOrigin.API)\n },\n\n createTrack(loadOptions: DashTrackLoadOptions): Track {\n return new MseTrack(\n loadOptions.uri,\n loadOptions.type,\n deps.createDashFactories(loadOptions)\n )\n },\n }\n}\n\nexport interface DashTrackDeps extends MseTrackDeps {\n readonly manifestController: DashManifestController\n readonly mediaQualityMetadataResolver: DashMediaQualityMetadataResolver\n readonly manifestTransformed: ObservableValue<Promise<DashManifestData>>\n readonly mediaTimeline: ObservableValue<Promise<MediaTimeline>>\n readonly mediaTimelineTransformed: ObservableValue<Promise<MediaTimeline>>\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {\n TrackBase,\n type TrackBaseDeps,\n type TrackBaseOptions,\n} from '../TrackBase'\nimport {\n Abort,\n equalDeep,\n type Fun,\n IntersectionRanges,\n logDebug,\n type ReadonlyRanges,\n type ReadonlySet,\n redispatchEvents,\n type Unsubscribe,\n} from '@amazon/vinyl-util'\nimport type { TrackPreloadOptions, TrackTypeId, TrackUri } from '../Track'\nimport type {\n ContentType,\n MediaQualityMetadata,\n} from '../../streaming/MediaQualityMetadata'\nimport { createContainer, type Factories } from '@amazon/vinyl-di'\nimport type {\n ContentStream,\n ContentStreamActivateOptions,\n ContentStreamPreloadOptions,\n} from '../../streaming/ContentStream'\nimport type { MediaSourceController } from '../../streaming/buffering/MediaSourceController'\nimport type { PlaybackSource } from '../../playback/PlaybackSource'\nimport type { ContentTypesValue } from '../../streaming/ContentTypesValue'\nimport type { ManifestController } from '../../streaming/ManifestController'\nimport type { ObservableValue } from '@amazon/vinyl-observable'\nimport type { MediaTimeline } from '../../streaming/MediaTimeline'\nimport {\n getMediaPeriodAtTime,\n type MediaPeriod,\n} from '../../streaming/MediaTimeline'\n\nexport type MseTrackDeps = TrackBaseDeps & {\n readonly contentTypesValue: ContentTypesValue\n readonly contentStreamFactory: (contentType: ContentType) => ContentStream\n readonly manifestController: ManifestController<unknown>\n readonly mediaSourceController: MediaSourceController\n readonly playbackSource: PlaybackSource\n readonly mediaTimeline: ObservableValue<Promise<MediaTimeline>>\n readonly mediaTimelineTransformed: ObservableValue<Promise<MediaTimeline>>\n}\n\ntype FunctionKeys<T> = {\n [P in keyof T]: T[P] extends Fun ? P : never\n}[keyof T]\n\n/**\n * An MseTrack uses media source extensions for streaming.\n */\nexport class MseTrack extends TrackBase {\n get [Symbol.toStringTag](): string {\n return 'MseTrack'\n }\n\n declare protected readonly deps: MseTrackDeps\n\n private readonly streams: ContentStream[] = []\n private readonly disposeAbort = /* @__PURE__ */ new Abort()\n private lastPreloadOptions: ContentStreamPreloadOptions | null = null\n private activateOptions: ContentStreamActivateOptions | null = null\n private readonly allFetchedRanges: ReadonlyRanges[] = []\n private readonly _fetchedRanges = /* @__PURE__ */ new IntersectionRanges(\n this.allFetchedRanges,\n { useCache: true }\n )\n private _contentTypes: ReadonlySet<ContentType> = /* @__PURE__ */ new Set()\n\n private _qualities: readonly MediaQualityMetadata[] | null = null\n private _qualitiesUnfiltered: readonly MediaQualityMetadata[] | null = null\n private timeUpdateSub: Unsubscribe | null = null\n private _cachedPeriod: MediaPeriod | null = null\n\n constructor(\n uri: TrackUri,\n type: TrackTypeId,\n dependencyFactories: Factories<MseTrackDeps>\n ) {\n const depsContainer = createContainer(dependencyFactories)\n const deps = depsContainer.dependencies\n super(uri, type, deps)\n logDebug(this, 'constructed')\n const { add } = this.disposer\n add(depsContainer)\n this.deps = deps\n\n add(\n deps.contentTypesValue.onData((contentTypesPromise) => {\n contentTypesPromise\n .then((contentTypes) => {\n if (this.disposer.disposed) return\n if (equalDeep(this.contentTypes, contentTypes)) return // no-op\n logDebug(this, 'content types:', contentTypes)\n this.clearStreams()\n for (const contentType of contentTypes) {\n this.createStream(contentType)\n }\n // Sets the content types and dispatches a change event:\n this.contentTypes = contentTypes\n })\n .catch(this.errorHandler)\n })\n )\n\n // DRM\n this.on('streamingQualityChange', (event) => {\n if (this.activateOptions) {\n this.deps.drmController.initializeForPlayback(\n event.current,\n this.disposeAbort\n )\n }\n })\n\n this.on('bufferingQualityChange', (event) => {\n this.deps.drmController.setBufferingDrmInfo(\n event.current,\n this.disposeAbort\n )\n })\n\n // Listen for timeline changes to update qualities.\n add(\n deps.mediaTimelineTransformed.onData(() => {\n this._cachedPeriod = null\n this.updateQualities()\n })\n )\n add(\n deps.mediaTimeline.onData(() => {\n this._cachedPeriod = null\n this.updateQualitiesUnfiltered()\n })\n )\n }\n\n /**\n * Updates the cached qualities list from the transformed timeline for the current period.\n */\n private updateQualities(): void {\n const time = this.deps.playbackController.currentTime\n this.deps.mediaTimelineTransformed.value\n .then((timeline) => {\n if (this.disposer.disposed) return\n const period = getMediaPeriodAtTime(timeline, time)\n this._cachedPeriod = period\n const newQualities = period\n ? period.qualities.map((q) => q.metadata)\n : null\n if (!equalDeep(newQualities, this._qualities)) {\n const previous = this._qualities\n this._qualities = newQualities\n if (newQualities) {\n this.dispatch('qualitiesChange', {\n previous: previous ?? [],\n current: newQualities,\n })\n }\n }\n })\n .catch(this.errorHandler)\n }\n\n /**\n * Updates the cached unfiltered qualities list from the raw timeline for the current period.\n */\n private updateQualitiesUnfiltered(): void {\n const time = this.deps.playbackController.currentTime\n this.deps.mediaTimeline.value\n .then((timeline) => {\n if (this.disposer.disposed) return\n const period = getMediaPeriodAtTime(timeline, time)\n const newQualities = period\n ? period.qualities.map((q) => q.metadata)\n : null\n if (!equalDeep(newQualities, this._qualitiesUnfiltered)) {\n const previous = this._qualitiesUnfiltered\n this._qualitiesUnfiltered = newQualities\n if (newQualities) {\n this.dispatch('qualitiesUnfilteredChange', {\n previous: previous ?? [],\n current: newQualities,\n })\n }\n }\n })\n .catch(this.errorHandler)\n }\n\n /**\n * Creates and adds a content stream for the given content type.\n *\n * @param contentType\n */\n protected createStream(contentType: ContentType): void {\n const stream = this.deps.contentStreamFactory(contentType)\n redispatchEvents(this, stream, [\n 'fetchedRangesChange',\n 'streamingQualityChange',\n 'bufferingQualityChange',\n 'playbackQualityChange',\n ])\n stream.on('bufferingEnded', () => {\n if (this.bufferingEnded) {\n this.deps.mediaSourceController.endOfStream()\n this.dispatch('bufferingEnded', {})\n }\n })\n stream.on('fetchedRangesChange', () => {\n this._fetchedRanges.invalidate()\n })\n stream.on('error', (event) => {\n if (!this._error) {\n // Set error state and bubble event\n this._error = event.error\n this.dispatch('error', event)\n }\n })\n\n // The fetched ranges of the track is the intersection of all content stream fetched ranges.\n this.allFetchedRanges.push(stream.fetchedRanges)\n this._fetchedRanges.invalidate()\n\n this.streams.push(stream)\n if (this.lastPreloadOptions) {\n stream.preload(this.lastPreloadOptions)\n }\n if (this.activateOptions) {\n stream.activate(this.activateOptions)\n }\n }\n\n preload(trackOptions: TrackPreloadOptions, loadOptions: TrackBaseOptions) {\n const options = {\n startTime: loadOptions.startTime,\n prefetchPriority: trackOptions.prefetchPriority,\n }\n this.lastPreloadOptions = options\n this.callOnStreams('preload', options)\n }\n\n get contentTypes(): ReadonlySet<ContentType> {\n return this._contentTypes\n }\n\n set contentTypes(value: ReadonlySet<ContentType>) {\n const previous = this._contentTypes\n this._contentTypes = value\n this.dispatch('contentTypesChange', {\n previous,\n current: value,\n })\n }\n\n get qualities(): readonly MediaQualityMetadata[] | null {\n return this._qualities\n }\n\n get qualitiesUnfiltered(): readonly MediaQualityMetadata[] | null {\n return this._qualitiesUnfiltered\n }\n\n get fetchedRanges(): ReadonlyRanges {\n return this._fetchedRanges\n }\n\n /**\n * Clears all fetched fragments and source buffers. Streaming will resume.\n * This should be called if a change has been made where the user would expect an immediate change,\n * for example, changing streaming quality from SD to HD.\n */\n clearPrefetch() {\n logDebug(this, 'clearPrefetch')\n this.callOnStreams('clearPrefetch')\n }\n\n /**\n * Resets the track to recover from error states.\n * Resets both the segment controller and buffering controller to clear failed segments and error conditions.\n */\n reset(): void {\n if (!this.error) {\n logDebug(this, 'reset no-op')\n return\n }\n this.deps.manifestController.reset()\n this.callOnStreams('reset')\n super.reset()\n }\n\n onActivated(loadOptions: TrackBaseOptions): void {\n this.activateOptions = loadOptions\n // AirPlay not supported using managed media sources\n this.deps.playbackSource.disableRemotePlayback = true\n\n this.streams.forEach((stream) => {\n this.deps.drmController.initializeForPlayback(\n stream.streamingQuality,\n this.disposeAbort\n )\n })\n this.deps.playbackSource.src =\n this.deps.mediaSourceController.createUrl()\n this.callOnStreams('activate', loadOptions)\n\n // Listen for timeUpdate to detect period changes.\n this.timeUpdateSub = this.deps.playbackController.on(\n 'timeUpdate',\n () => {\n const time = this.deps.playbackController.currentTime\n const cached = this._cachedPeriod\n if (\n cached &&\n time >= cached.startTime &&\n time < cached.endTime\n ) {\n return\n }\n this.updateQualities()\n this.updateQualitiesUnfiltered()\n }\n )\n }\n\n onDeactivated(): void {\n this.activateOptions = null\n this.timeUpdateSub?.()\n this.timeUpdateSub = null\n this.callOnStreams('deactivate')\n\n this.deps.playbackSource.src = null\n this.deps.playbackSource.load()\n }\n\n getStreamingQuality(contentType: ContentType): MediaQualityMetadata | null {\n return this.getStream(contentType)?.streamingQuality ?? null\n }\n\n getBufferingQuality(contentType: ContentType): MediaQualityMetadata | null {\n return this.getStream(contentType)?.bufferingQuality ?? null\n }\n\n getPlaybackQuality(contentType: ContentType): MediaQualityMetadata | null {\n return this.getStream(contentType)?.playbackQuality ?? null\n }\n\n /**\n * Calls the specified method on all streams with the provided arguments.\n */\n private callOnStreams<K extends FunctionKeys<ContentStream>>(\n functionName: K,\n ...args: Parameters<ContentStream[K]>\n ) {\n this.streams.forEach((stream) => {\n ;(stream[functionName] as Fun)(...args)\n })\n }\n\n private getStream(contentType: ContentType): ContentStream | undefined {\n return this.streams.find((s) => s.contentType === contentType)\n }\n\n private clearStreams() {\n this.callOnStreams('dispose')\n this.streams.length = 0\n this.allFetchedRanges.length = 0\n this._fetchedRanges.invalidate()\n }\n\n get bufferingEnded(): boolean {\n return this.streams.every((stream) => stream.bufferingEnded)\n }\n\n dispose(): void {\n logDebug(this, 'dispose')\n this.timeUpdateSub?.()\n this.timeUpdateSub = null\n this.clearStreams()\n super.dispose()\n }\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { SegmentReference } from './SegmentReference'\nimport type { SegmentDataProvider } from './SegmentDataSlot'\nimport type { MediaQualityMetadata } from './MediaQualityMetadata'\nimport { sortedInsertionIndex } from '@amazon/vinyl-util'\n\n/**\n * Represents a single quality within a period, providing access to its metadata\n * and segment data.\n */\nexport interface MediaQualityData {\n readonly metadata: MediaQualityMetadata\n\n /**\n * Gets the segment reference at the given time, or null if the time is outside the range.\n * @param time The time, in seconds, relative to the presentation timeline.\n * @param affordance Forward-snap tolerance in seconds: if `time` falls just before a\n * segment's start (within `affordance`), that segment is returned. Defaults to `0`.\n */\n getSegment(\n time: number,\n affordance?: number\n ): Promise<SegmentReference<SegmentDataProvider> | null>\n}\n\n/**\n * Represents a period within the media timeline.\n */\nexport interface MediaPeriod {\n readonly startTime: number\n readonly endTime: number\n readonly qualities: readonly MediaQualityData[]\n}\n\n/**\n * Represents the full media timeline, composed of one or more periods.\n */\nexport interface MediaTimeline {\n readonly periods: readonly MediaPeriod[]\n\n /**\n * The minimum duration of the buffer that a client should maintain for uninterrupted playback.\n */\n readonly minBufferTime: number\n\n /**\n * The total duration of the media, in seconds.\n * Returns `Infinity` for live streams.\n * Rejects when there are no segments to derive a duration from.\n */\n getDuration(): Promise<number>\n}\n\n/**\n * Gets the period spanning the given presentation time.\n */\nexport function getMediaPeriodAtTime(\n timeline: MediaTimeline,\n time: number\n): MediaPeriod | null {\n const index =\n sortedInsertionIndex(timeline.periods, time, (time, period) => {\n return time - period.startTime\n }) - 1\n if (index < 0) return null\n const period = timeline.periods[index]\n return time >= period.endTime ? null : period\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { Maybe, RequestInitOptions } from '@amazon/vinyl-util'\nimport { ErrorOrigin } from '@amazon/vinyl-util'\nimport type { TrackLoadOptions, TrackFactory } from '../TrackFactory'\nimport type { TrackBaseOptions } from '../TrackBase'\nimport type { Track } from '../Track'\nimport type { HlsManifestProvider } from './HlsManifestProvider'\nimport type { HlsManifestController } from './HlsManifestController'\nimport type { HlsManifestData } from './HlsManifestProvider'\nimport type { HlsMediaQualityMetadataResolver } from './HlsMediaQualityMetadataResolver'\nimport type { MseTrackDeps } from '../mse/MseTrack'\nimport { MseTrack } from '../mse/MseTrack'\nimport {\n func,\n isOneOf,\n object,\n string,\n type ObjectSchema,\n} from '@amazon/vinyl-validation'\nimport { trackBaseOptionsValidator } from '../TrackBase'\nimport type { Factories } from '@amazon/vinyl-di'\nimport type { ObservableValue } from '@amazon/vinyl-observable'\nimport type { MediaTimeline } from '../../streaming/MediaTimeline'\n\nexport interface HlsTrackLoadOptions extends TrackLoadOptions {\n readonly type: 'hls'\n readonly manifestProvider?: Maybe<HlsManifestProvider>\n readonly requestInit?: Maybe<RequestInitOptions>\n readonly segmentRequestInit?: Maybe<RequestInitOptions>\n readonly config?: Maybe<TrackBaseOptions>\n}\n\nconst loadOptionsValidator: ObjectSchema<HlsTrackLoadOptions> = /* @__PURE__ */ object({\n config: /* @__PURE__ */ /* @__PURE__ */ trackBaseOptionsValidator.maybe().optional(),\n manifestProvider: /* @__PURE__ */ /* @__PURE__ */ /* @__PURE__ */ func().maybe().optional(),\n requestInit: /* @__PURE__ */ /* @__PURE__ */ /* @__PURE__ */ /* @__PURE__ */ object({}).cast<RequestInitOptions>().maybe().optional(),\n segmentRequestInit: /* @__PURE__ */ /* @__PURE__ */ /* @__PURE__ */ /* @__PURE__ */ object({})\n .cast<RequestInitOptions>()\n .maybe()\n .optional(),\n type: /* @__PURE__ */ isOneOf('hls'),\n uri: /* @__PURE__ */ /* @__PURE__ */ string().notEmpty(),\n})\n\nexport interface HlsTrackDeps extends MseTrackDeps {\n readonly manifestController: HlsManifestController\n readonly manifestTransformed: ObservableValue<Promise<HlsManifestData>>\n readonly mediaQualityMetadataResolver: HlsMediaQualityMetadataResolver\n readonly mediaTimeline: ObservableValue<Promise<MediaTimeline>>\n readonly mediaTimelineTransformed: ObservableValue<Promise<MediaTimeline>>\n}\n\nexport type HlsTrackFactoryDeps = {\n readonly createHlsFactories: (\n loadOptions: HlsTrackLoadOptions\n ) => Factories<HlsTrackDeps>\n}\n\nexport function createHlsTrackFactory(\n deps: HlsTrackFactoryDeps\n): TrackFactory<HlsTrackLoadOptions> {\n return {\n validate(options: HlsTrackLoadOptions) {\n loadOptionsValidator.assert(options, ErrorOrigin.API)\n },\n\n createTrack(loadOptions: HlsTrackLoadOptions): Track {\n return new MseTrack(\n loadOptions.uri,\n loadOptions.type,\n deps.createHlsFactories(loadOptions)\n )\n },\n }\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {\n createSourceObjectTrackFactory,\n type SourceObjectTrackDeps,\n type SourceObjectTrackLoadOptions,\n} from './source/SourceObjectTrack'\nimport {\n createSourceTrackFactory,\n type SourceTrackDeps,\n type SourceTrackLoadOptions,\n} from './source/SourceTrack'\nimport type { TrackTypeId } from './Track'\nimport type { TrackFactory } from './TrackFactory'\nimport type { ReadonlyRecord } from '@amazon/vinyl-util'\nimport {\n createDashTrackFactory,\n type DashTrackFactoryDeps,\n type DashTrackLoadOptions,\n} from './dash/DashTrack'\nimport {\n createHlsTrackFactory,\n type HlsTrackFactoryDeps,\n type HlsTrackLoadOptions,\n} from './hls/HlsTrack'\n\nexport interface VinylTrackFactoryDeps\n extends\n SourceTrackDeps,\n SourceObjectTrackDeps,\n DashTrackFactoryDeps,\n HlsTrackFactoryDeps {}\n\nexport type VinylTrackLoadOptions =\n | SourceObjectTrackLoadOptions\n | SourceTrackLoadOptions\n | DashTrackLoadOptions\n | HlsTrackLoadOptions\n\n/**\n * Provides a map of track type id to their respective loaders.\n * @param deps\n */\nexport function createVinylTrackFactories(deps: VinylTrackFactoryDeps) {\n return {\n src: createSourceTrackFactory(deps),\n srcObject: createSourceObjectTrackFactory(deps),\n dash: createDashTrackFactory(deps),\n hls: createHlsTrackFactory(deps),\n } as const satisfies ReadonlyRecord<\n TrackTypeId,\n TrackFactory<VinylTrackLoadOptions>\n >\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {\n type AnyRecord,\n countElements,\n createDisposer,\n type Disposable,\n EventHostImpl,\n first,\n getOrSet,\n logDebug,\n logInfo,\n LruCache,\n type Maybe,\n noop,\n type ReadonlyEventHost,\n type TimeoutId,\n} from '@amazon/vinyl-util'\nimport type { PlaybackController } from '../playback/PlaybackController'\nimport type { ReadonlyTrack, Track, TrackUri } from './Track'\nimport type { TrackFactory, TrackLoadOptions } from './TrackFactory'\nimport type { ChangeEvent } from '../event/ChangeEvent'\n\nexport interface TrackControllerEventMap<\n TrackLoadOptionsType extends TrackLoadOptions,\n> {\n /**\n * Emitted when the current track is changing.\n * This is emitted before the previous track has been deactivated and\n * new track has been activated.\n */\n readonly currentTrackChanging: ChangeEvent<ReadonlyTrack | null>\n\n /**\n * Emitted when the current track has changed.\n * If there is a queue change, the currentTrackChange event is always emitted first.\n * This is emitted after the previous track has been deactivated and\n * new track has been activated.\n */\n readonly currentTrackChange: ChangeEvent<ReadonlyTrack | null>\n\n /**\n * Dispatched when the queue has changed.\n */\n readonly queueChange: ChangeEvent<readonly TrackLoadOptionsType[]>\n\n /**\n * Emitted when the last track of the playback queue has ended.\n * When the last track in a queue has ended, the track will not change and therefore a `currentTrackChange`\n * event will not be emitted.\n */\n readonly queueEnded: AnyRecord\n}\n\nexport const ALL_TRACK_CONTROLLER_EVENTS = [\n 'currentTrackChanging',\n 'currentTrackChange',\n 'queueChange',\n 'queueEnded',\n] as const satisfies readonly (keyof TrackControllerEventMap<any>)[]\n\n/**\n * A readonly interface to the track controller.\n */\nexport interface ReadonlyTrackController<\n TrackLoadOptionsType extends TrackLoadOptions,\n> extends ReadonlyEventHost<TrackControllerEventMap<TrackLoadOptionsType>> {\n /**\n * Returns the current track.\n */\n readonly currentTrack: ReadonlyTrack | null\n\n /**\n * Returns the current queue of TrackLoadOptions.\n * Observe 'queueChange' for changes to this queue.\n */\n readonly queue: readonly TrackLoadOptionsType[]\n\n /**\n * Returns true if there is at least one track in the queue.\n */\n hasNext(): boolean\n\n /**\n * Returns true if the track with the given URI is cached.\n */\n isTrackCached(uri: TrackUri): boolean\n\n /**\n * Returns the cached track for the given URI, or null if the track is not cached.\n */\n getCachedTrack(uri: TrackUri): ReadonlyTrack | null\n\n /**\n * Returns an iterator of currently cached tracks.\n */\n getCachedTracks(): IterableIterator<ReadonlyTrack>\n}\n\n/**\n * Responsible for queuing track load configurations.\n * This is the authority for which is the current track.\n */\nexport interface TrackController<\n TrackLoadOptionsType extends TrackLoadOptions,\n> extends ReadonlyTrackController<TrackLoadOptionsType> {\n /**\n * Preloads the given list of tracks.\n * The tracks provided will not be enqueued.\n * The track controller's cache size will automatically increase to accommodate the request.\n *\n * Prefetch priority note:\n * Tracks have a prefetch priority, later calls to preload will have a higher precedence than previous calls.\n * Previous tracks given to `preload` will drop off when they are evicted from the cache. This is dependent on\n * cache size.\n *\n * @param loadOptionsList\n */\n preload(...loadOptionsList: readonly TrackLoadOptionsType[]): void\n\n /**\n * Sets the current queue to the provided track list.\n * When the track ends, the next will be played.\n *\n * `load` does not begin playback. Call `play()` after a load to start playback.\n * Browser autoplay policies may require the first call to `play()` to be in response to a user interaction\n * such as a click, touch, keypress, or voice event.\n *\n * Note that if the current track is the first track provided in the list, that track will be restarted.\n * To set the queue without unloading the current track, use {@link clearQueue} followed by {@link enqueue}.\n *\n * @param loadOptionsList A list of load configuration objects to set as a playback queue.\n */\n load(...loadOptionsList: readonly TrackLoadOptionsType[]): void\n\n /**\n * Unloads the active track and clears the queue.\n * This is the same as calling {@link load} with zero parameters.\n */\n unload(): void\n\n /**\n * Appends the given tracks to the current queue.\n *\n * @param loadOptionsList The track load configurations to append.\n */\n enqueue(...loadOptionsList: readonly TrackLoadOptionsType[]): void\n\n /**\n * Activates the next track in the queue.\n * If the media is not paused the next track will begin playing automatically.\n *\n * @see ReadonlyTrackController.hasNext\n */\n next(): void\n\n /**\n * Clears all fetched fragments and source buffers.\n * Playback will be interrupted, and streaming will resume again when data has been fetched and buffered.\n * This should be called if a change has been made where the user would expect an immediate change,\n * for example, changing streaming quality from SD to HD.\n *\n * Does not unload manifests.\n */\n clearPrefetch(): void\n\n /**\n * Clears the track cache and unloads the current track.\n */\n clearTrackCache(): void\n\n /**\n * Clears the current queue.\n * Does not stop the current track or affect the prefetched cache.\n */\n clearQueue(): void\n\n /**\n * Resets the current track's error state.\n */\n reset(): void\n}\n\nexport interface TrackControllerImplDeps<\n TrackLoadOptionsType extends TrackLoadOptions,\n> {\n readonly trackFactory: TrackFactory<TrackLoadOptionsType>\n\n readonly playbackController: PlaybackController\n}\n\nexport interface TrackControllerImplOptions {\n /**\n * When tracks are queued, the number of tracks to prefetch ahead of the current track.\n * Default: 2\n */\n readonly trackPrefetchCount: number\n\n /**\n * The number of seconds before load calls will time out if the first track's metadata is not loaded within\n * this time.\n * Default: 60\n */\n readonly loadTimeout: number\n\n /**\n * The number of tracks that may be preloaded at one time (not counting queue prefetch).\n * This extends the track cache capacity and allows a certain number of tracks no longer in the queue to remain\n * cached.\n *\n * Default: 2\n */\n readonly preloadCapacity: number\n}\n\nconst defaultTrackControllerImplOptions = {\n trackPrefetchCount: 2,\n loadTimeout: 60,\n preloadCapacity: 2,\n} as const satisfies TrackControllerImplOptions\n\n/**\n * Track priority will be assigned based on calls to `preload`.\n * Segment background prefetching is shared if there are multiple players instances (in the rare case there would be\n * multiple players). Having a global incrementing trackPriority prevents one player from starving another.\n */\nexport const trackPriority = {\n value: 0,\n}\n\nexport class TrackControllerImpl<TrackLoadOptionsType extends TrackLoadOptions>\n extends EventHostImpl<TrackControllerEventMap<TrackLoadOptionsType>>\n implements TrackController<TrackLoadOptionsType>, Disposable\n{\n get [Symbol.toStringTag](): string {\n return 'TrackControllerImpl'\n }\n\n // When tracks are preloaded, the cache capacity may expand automatically to accommodate.\n private _autoPreloadCapacity = 0\n private readonly trackCache = /* @__PURE__ */ new LruCache<string, Track>(0)\n private _queue: readonly TrackLoadOptionsType[] = []\n private _current: TrackLoadOptionsType | null = null\n private readonly disposer = /* @__PURE__ */ createDisposer()\n private _options: TrackControllerImplOptions =\n defaultTrackControllerImplOptions\n\n private trackEndedTimeoutId: TimeoutId | null = null\n\n constructor(\n private readonly deps: TrackControllerImplDeps<TrackLoadOptionsType>,\n initialOptions?: Partial<TrackControllerImplOptions>\n ) {\n super()\n const { add } = this.disposer\n\n this.trackCache.onEvicting = (track) => {\n // Do not evict tracks within the prefetch range.\n return (\n this.prefetched.find((value) => value.uri === track.uri) == null\n )\n }\n\n this.trackCache.onEvict = (track) => {\n logDebug(this, `Disposing track: ${track.uri}`)\n track.dispose()\n return true\n }\n\n add(\n deps.playbackController.on('ended', () => {\n this.trackEndedTimeoutId = setTimeout(() => {\n // Adds a frame delay to allow applications an opportunity to respond to 'ended' events before the\n // track is changed.\n this.trackEndedTimeoutId = null\n if (this.hasNext()) {\n this.next()\n } else {\n logInfo(this, 'queueEnded')\n this.dispatch('queueEnded', {})\n }\n })\n })\n )\n this.configure(initialOptions)\n }\n\n private clearTrackEndedTimeout() {\n if (this.trackEndedTimeoutId) {\n clearTimeout(this.trackEndedTimeoutId)\n this.trackEndedTimeoutId = null\n }\n }\n\n /**\n * Returns the currently set configuration.\n */\n get options(): TrackControllerImplOptions {\n return this._options\n }\n\n /**\n * Configures this track queue from the provided partial options.\n *\n * @param options\n */\n configure(options: Maybe<Partial<TrackControllerImplOptions>>) {\n logDebug(this, 'configure', options)\n this._options = {\n ...this._options,\n ...options,\n }\n this.checkCacheCapacity()\n }\n\n /**\n * Checks if the cache capacity needs to be changed.\n */\n private checkCacheCapacity() {\n const capacity =\n this.preloadCapacity + this._options.trackPrefetchCount + 1\n if (capacity !== this.trackCache.capacity) {\n logDebug(this, 'track cache capacity changed:', capacity)\n this.trackCache.capacity = capacity\n }\n }\n\n get queue(): readonly TrackLoadOptionsType[] {\n return this._queue\n }\n\n /**\n * Returns the subset of the queue that should be prefetched.\n * @private\n */\n private get prefetched(): readonly TrackLoadOptionsType[] {\n const tracks: TrackLoadOptionsType[] = []\n if (this._current) tracks.push(this._current)\n tracks.push(...this._queue.slice(0, this.options.trackPrefetchCount))\n return tracks\n }\n\n isTrackCached(uri: TrackUri): boolean {\n return this.trackCache.has(uri)\n }\n\n getCachedTrack(uri: TrackUri): ReadonlyTrack | null {\n return this.trackCache.get(uri) ?? null\n }\n\n getCachedTracks(): IterableIterator<ReadonlyTrack> {\n return this.trackCache.values()\n }\n\n /**\n * Returns the current preload capacity.\n * This automatically increases when preload is called with more tracks than the current capacity.\n */\n get preloadCapacity(): number {\n return Math.max(\n this._autoPreloadCapacity,\n this._options.preloadCapacity\n )\n }\n\n private validateLoadOptions = (loadOptions: TrackLoadOptionsType) =>\n this.deps.trackFactory.validate(loadOptions)\n\n preload(...loadOptionsList: readonly TrackLoadOptionsType[]): void {\n logDebug(this, `preload ${loadOptionsList.length} items`)\n loadOptionsList.forEach(this.validateLoadOptions)\n this._preload(loadOptionsList)\n }\n\n private _preload(loadOptionsList: readonly TrackLoadOptionsType[]): void {\n const prefetched = this.prefetched\n // Calculate the required preload capacity as the number of tracks requested that are not within the\n // prefetch window. If this value is greater than the current preloadCapacity, increase the cache size.\n const requiredPreloadCapacity = countElements(\n loadOptionsList,\n (loadOptions) => {\n return (\n prefetched.find((element) => {\n return element.uri === loadOptions.uri\n }) == null\n )\n }\n )\n if (this._autoPreloadCapacity < requiredPreloadCapacity) {\n this._autoPreloadCapacity = requiredPreloadCapacity\n this.checkCacheCapacity()\n }\n // Tracks requested to preload will have a priority where the first track in the list (next track) has\n // the highest precedence. (Higher priority values take precedence)\n trackPriority.value += loadOptionsList.length\n let priority = trackPriority.value\n for (const loadOptions of loadOptionsList) {\n const track = this.getOrCreateTrack(loadOptions.uri, loadOptions)\n track.preload(\n {\n prefetchPriority: priority--,\n },\n loadOptions.config ?? {}\n )\n }\n }\n\n load(...loadOptionsList: readonly TrackLoadOptionsType[]): void {\n logDebug(this, `load ${loadOptionsList.length} items`)\n loadOptionsList.forEach(this.validateLoadOptions)\n this.clearTrackEndedTimeout()\n this._current = loadOptionsList[0] ?? null\n const previousQueue = this._queue\n this._queue = loadOptionsList.slice(1)\n this._preload(this.prefetched)\n this.activateCurrent()\n this.dispatch('queueChange', {\n previous: previousQueue,\n current: this._queue,\n })\n }\n\n unload() {\n this.load()\n }\n\n enqueue(...loadOptionsList: readonly TrackLoadOptionsType[]): void {\n logDebug(this, `enqueue ${loadOptionsList.length} items`)\n loadOptionsList.forEach(this.validateLoadOptions)\n const previousQueue = this._queue\n this._queue = this._queue.concat(loadOptionsList)\n this._preload(this.prefetched)\n if (this.currentTrack == null && this.hasNext()) this.next()\n this.dispatch('queueChange', {\n previous: previousQueue,\n current: this._queue,\n })\n }\n\n hasNext(): boolean {\n return this._queue.length > 0\n }\n\n next(): void {\n this.clearTrackEndedTimeout()\n const playbackController = this.deps.playbackController\n const shouldPlay =\n playbackController.ended || !playbackController.paused\n const next = first(this._queue)\n const previousQueue = this._queue\n this._queue = this._queue.slice(1)\n this._current = next ?? null\n logDebug(this, 'next, nextTrack:', this._current)\n if (\n this.options.trackPrefetchCount > 0 &&\n this._queue.length >= this.options.trackPrefetchCount\n ) {\n this._preload([this._queue[this.options.trackPrefetchCount - 1]])\n }\n this.activateCurrent()\n if (shouldPlay) void playbackController.play().catch(noop)\n this.dispatch('queueChange', {\n previous: previousQueue,\n current: this._queue,\n })\n }\n\n clearTrackCache() {\n logDebug(this, 'clearTrackCache')\n this.clearTrackEndedTimeout()\n const previousQueue = this._queue\n this._queue = []\n this.trackCache.forEach((track) => {\n track.dispose()\n })\n this.trackCache.clear()\n this._autoPreloadCapacity = 0\n this.checkCacheCapacity()\n this.clearCurrentTrack()\n this.dispatch('queueChange', {\n previous: previousQueue,\n current: this._queue,\n })\n }\n\n clearPrefetch(): void {\n for (const cachedTrack of this.trackCache.values()) {\n cachedTrack.clearPrefetch()\n }\n }\n\n clearQueue(): void {\n this.clearTrackEndedTimeout()\n const previous = this._queue\n this._queue = []\n this.dispatch('queueChange', {\n previous,\n current: this._queue,\n })\n }\n\n /**\n * If the given track id is the current track or in the cache, returns that track.\n * Otherwise, constructs a new track, adds it to the cache, and returns it.\n *\n * @param uri The unique resource identifier.\n * @param loadOptions\n * @private\n */\n private getOrCreateTrack(\n uri: TrackUri,\n loadOptions: TrackLoadOptionsType\n ): Track {\n return getOrSet(this.trackCache, uri, () => {\n const newTrack = this.deps.trackFactory.createTrack(loadOptions)\n this.trackCache.set(uri, newTrack)\n return newTrack\n })\n }\n\n /**\n * Get the current track from cache or create a new track, then activates that track.\n */\n private activateCurrent(): void {\n const loadOptions = this._current\n if (!loadOptions) {\n this.clearCurrentTrack()\n return\n }\n this.setCurrentTrack(\n this.getOrCreateTrack(loadOptions.uri, loadOptions),\n loadOptions\n )\n }\n\n private _currentTrack: Track | null = null\n get currentTrack(): ReadonlyTrack | null {\n return this._currentTrack\n }\n\n /**\n * Sets the current track. If the given track is already current, it will be de-activated and re-activated and\n * the currentTrackChange event will still be emitted.\n * The same track may be in the queue multiple times.\n */\n private setCurrentTrack(\n value: Track | null,\n loadOptions: TrackLoadOptionsType | null\n ) {\n const previousTrack = this._currentTrack\n this.dispatch('currentTrackChanging', {\n previous: previousTrack,\n current: value,\n })\n this._currentTrack = value\n if (previousTrack?.active === true) previousTrack.deactivate()\n const loadOptionsConfig = loadOptions?.config ?? {}\n if (value?.active === false) value.activate(loadOptionsConfig)\n logDebug(\n this,\n `currentTrackChange, previous: ${previousTrack} current: ${value}`\n )\n this.dispatch('currentTrackChange', {\n previous: previousTrack,\n current: value,\n })\n }\n\n private clearCurrentTrack() {\n this.setCurrentTrack(null, null)\n }\n\n reset() {\n this._currentTrack?.reset()\n }\n\n dispose() {\n logDebug(this, 'dispose')\n super.dispose()\n this.clearTrackCache()\n this.disposer.dispose()\n }\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { lazy } from '@amazon/vinyl-util'\nimport { requiresUnreliablePlaybackEventsPatch } from './patches/createUnreliablePlaybackEventsPatch'\nimport { requiresPreventStallsPatch } from './patches/createPreventStallsPatch'\n\nexport interface MediaElementPatchOptions {\n /**\n * Playback events 'playing' and 'waiting' are unreliable after seeking.\n *\n * Risks for false positive: LOW. Timing of emitted playing events may be subtly\n * different, but they will not be duplicated.\n * Risks for false negative: MEDIUM. Certain playback events on affected platforms will be missed.\n */\n readonly unreliablePlaybackEvents?: boolean\n\n /**\n * The affected user agent gets into a state where playback can become stalled and needs help getting unstuck.\n */\n readonly preventStalls?: boolean\n}\n\n/**\n * Aggregates flags for toggling patches.\n */\nexport const defaultMediaElementPatchOptions = /* @__PURE__ */ lazy<\n Required<MediaElementPatchOptions>\n>(() => {\n return {\n unreliablePlaybackEvents: requiresUnreliablePlaybackEventsPatch(),\n preventStalls: requiresPreventStallsPatch(),\n } as const satisfies Required<MediaElementPatchOptions>\n})\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { MediaElementPatchOptions } from '../patch/media/MediaElementPatchOptions'\nimport { defaultMediaElementPatchOptions } from '../patch/media/MediaElementPatchOptions'\nimport { lazy } from '@amazon/vinyl-util'\n\n/**\n * Flags for applying patches.\n * Default flags will be applied based on user agent, but may be overridden during player creation.\n */\nexport interface VinylPatchOptions {\n readonly media: MediaElementPatchOptions\n}\n\nexport const defaultPatchOptions = /* @__PURE__ */ lazy<VinylPatchOptions>(() => {\n return {\n media: defaultMediaElementPatchOptions.value,\n } as const satisfies VinylPatchOptions\n})\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { last, merge, sortedInsertionIndex } from '@amazon/vinyl-util'\n\nimport {\n type AdaptationSetType,\n type DashManifest,\n type MPDtype,\n type PeriodType,\n type RepresentationType,\n type SegmentBaseType,\n type SegmentListType,\n type SegmentTemplateType,\n} from '@amazon/vinyl-mpd-parser'\n\n// TODO: For dynamic MPDs, availability time offsets should be summed.\n\n/**\n * Calculates the inherited SegmentList for the given representation. Or returns undefined if no SegmentList is\n * present in the hierarchy.\n */\nexport function getSegmentList(\n representation: RepresentationType\n): SegmentListType | undefined {\n return mergeIfAnyDefined(\n representation.parent.parent.SegmentList,\n representation.parent.SegmentList,\n representation.SegmentList\n )\n}\n\n/**\n * Calculates the inherited SegmentTemplate for the given representation. Or returns undefined if no SegmentTemplate is\n * present in the hierarchy.\n */\nexport function getSegmentTemplate(\n representation: RepresentationType\n): SegmentTemplateType | undefined {\n return mergeIfAnyDefined(\n representation.parent.parent.SegmentTemplate,\n representation.parent.SegmentTemplate,\n representation.SegmentTemplate\n )\n}\n\n/**\n * Calculates the inherited SegmentBase for the given representation. Or returns undefined if no SegmentBase is\n * present in the hierarchy.\n */\nexport function getSegmentBase(\n representation: RepresentationType\n): SegmentBaseType | undefined {\n return mergeIfAnyDefined(\n representation.parent.parent.SegmentBase,\n representation.parent.SegmentBase,\n representation.SegmentBase\n )\n}\n\n/**\n * Returns the representation's ancestry: [MPD, Period, AdaptationSet, Representation]\n */\nexport function getRepresentationAncestry(\n representation: RepresentationType\n): readonly [MPDtype, PeriodType, AdaptationSetType, RepresentationType] {\n const adaptationSet = representation.parent\n const period = adaptationSet.parent\n const mpd = period.parent\n return [mpd, period, adaptationSet, representation]\n}\n\n/**\n * Merges the properties of all sources into a new object.\n * Used to calculate inherited properties.\n * If all sources are undefined, returns undefined.\n */\nfunction mergeIfAnyDefined<T>(...sources: T[]): T | undefined {\n if (!sources.some((source) => source)) return undefined\n return merge(...sources)\n}\n\nexport type PeriodRange = readonly [number, number | null]\n\n/**\n * Calculates the period start and end time.\n */\nexport function calculatePeriodTimeRange(period: PeriodType): PeriodRange {\n return [calculatePeriodStart(period), calculatePeriodEnd(period)]\n}\n\n/**\n * Calculates the start time of the given period.\n *\n * In a static presentation, the first period SHALL start at the zero point of the MPD timeline (with a\n * Period@start value of 0 seconds).\n */\nexport function calculatePeriodStart(period: PeriodType): number {\n return period.start ?? 0\n}\n\n/**\n * In a static presentation, the last period SHALL have a Period@duration.\n *\n * In a dynamic presentation, the first period SHALL start at or after the zero point of the MPD timeline (with a\n * Period@start value of 0 seconds or greater).\n *\n * In a dynamic presentation, the last period MAY have a Period@duration, in which case it has a fixed duration. If\n * without Period@duration, the last period in a dynamic presentation has an unlimited duration (that may later be\n * shortened by an MPD update).\n */\nexport function calculatePeriodEnd(period: PeriodType): number | null {\n if (period.start != null && period.duration != null)\n return period.start + period.duration\n\n const mpd = period.parent\n const periodIndex = mpd.Period.indexOf(period)\n if (periodIndex < mpd.Period.length - 1)\n return calculatePeriodStart(mpd.Period[periodIndex + 1])\n else return mpd.mediaPresentationDuration ?? null\n}\n\n/**\n * Converts a sample time to an MPD-relative time.\n *\n * The samples within a representation exist on a linear sample timeline defined by the encoder. This function maps\n * those sample times onto the MPD timeline.\n *\n * https://dashif-documents.azurewebsites.net/Guidelines-TimingModel/master/Guidelines-TimingModel.html\n *\n * @param sampleTime The sample start time, in timescale units, relative to the media.\n * @param periodStart The presentation start time of the period, relative to the MPD timeline.\n * @param presentationTimeOffset Specifies a presentation time offset in the media timeline relative to the start\n * of the Period, in timescale units, used to adjust the timing of media presentation.\n * @param timescale The timescale, in units per second.\n */\nexport function sampleToMpdTime(\n sampleTime: number,\n periodStart: number,\n presentationTimeOffset: number,\n timescale: number\n): number {\n return periodStart + (sampleTime - presentationTimeOffset) / timescale\n}\n\n/**\n * Gets the period spanning the given presentation time.\n */\nexport function getPeriodAtTime(\n manifest: DashManifest,\n time: number\n): PeriodType | null {\n const index =\n sortedInsertionIndex(manifest.MPD.Period, time, (time, period) => {\n return time - calculatePeriodStart(period)\n }) - 1\n if (index < 0) return null\n const period = manifest.MPD.Period[index]\n const periodEnd = calculatePeriodEnd(period)\n return periodEnd != null && time >= periodEnd ? null : period\n}\n\n/**\n * Flattens representations across all adaptation sets for the given Period.\n */\nexport function flattenRepresentations(\n period: PeriodType\n): RepresentationType[] {\n const out: RepresentationType[] = []\n period.AdaptationSet?.forEach((adaptationSet) => {\n adaptationSet.Representation?.forEach((representation) => {\n out.push(representation)\n })\n })\n return out\n}\n\n/**\n * Calculates the manifest duration, either from the mediaPresentationDuration or the last period end time.\n * Returns `Infinity` for live (dynamic) presentations.\n * Throws if duration cannot be determined.\n */\nexport function calculateDuration(manifest: DashManifest): number {\n if (manifest.MPD.type === 'dynamic') return Infinity\n const mpdDuration = manifest.MPD.mediaPresentationDuration\n if (mpdDuration != null) return mpdDuration\n const lastPeriod = last(manifest.MPD.Period)\n if (!lastPeriod) {\n throw new Error('Unable to determine manifest duration: no periods')\n }\n const end = calculatePeriodEnd(lastPeriod)\n if (end == null) {\n throw new Error('Unable to determine manifest duration')\n }\n return end\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { BaseURLType, RepresentationType } from '@amazon/vinyl-mpd-parser'\nimport { getRepresentationAncestry } from './mpd'\nimport type { Uri } from '@amazon/vinyl-xml'\nimport type { Maybe } from '@amazon/vinyl-util'\nimport {\n ErrorOrigin,\n IllegalArgumentError,\n resolveUrl,\n substituteIdentifiers,\n ValidationError,\n} from '@amazon/vinyl-util'\n\n/**\n * Selects a base URL alternate.\n */\nexport interface BaseUrlSelector {\n /**\n * Given a list of Dash base URLs, chooses which one will be used.\n *\n * @param baseUrls A list of Dash base URL objects for a single scope.\n * Guaranteed to not be empty.\n */\n selectBaseUrl(baseUrls: readonly BaseURLType[]): BaseURLType\n}\n\nexport const pickFirstBaseUrlSelector: BaseUrlSelector = {\n selectBaseUrl(baseUrls: readonly BaseURLType[]): BaseURLType {\n return baseUrls[0]\n },\n}\n\nexport interface DashUriResolveDeps {\n /**\n * Selects the BaseURL from provided alternates.\n */\n readonly baseUrlSelector: BaseUrlSelector\n}\n\nexport interface ResolvedDashUri {\n /**\n * The absolute URL.\n */\n readonly url: string\n\n /**\n * The service location.\n * @see BaseURL.serviceLocation\n */\n readonly serviceLocation: string | null\n}\n\nexport interface DashUriResolveOptions {\n /**\n * The URI to resolve.\n */\n readonly uri?: Maybe<Uri>\n\n /**\n * The representation to use as the scope for BaseURL resolution.\n */\n readonly representation: RepresentationType\n\n /**\n * The resource location of the manifest.\n */\n readonly baseUrl: string\n}\n\n/**\n * Resolves the base URL. Walks down the ancestry, concatenating BaseURL paths according to\n * MPEG-DASH ISO/IEC 23009-1 standard, section 5.6.4.\n *\n * The BaseURL elements are used to define the base URL against which relative URLs specified in the manifest are\n * resolved. This can occur at multiple levels within the manifest (e.g., at the Period, Adaptation Set, or\n * Representation level).\n * Relative URLs are resolved according to standard URL resolution rules, as defined by RFC 3986. This involves\n * resolving the relative URL against the effective base URL, which could be the URL of the manifest itself or\n * a <BaseURL> specified at a higher level in the manifest hierarchy.\n *\n * Manifest URL as Base: If no <BaseURL> is specified, the URL from which the DASH manifest (MPD file) was\n * retrieved acts as the base URL for resolving any relative URLs.\n *\n * https://standards.iso.org/ittf/PubliclyAvailableStandards/index.html\n *\n * Note: URL resolution is not a simple concatenation, the `URL` class is used to resolve relative URLs per RFC\n * 3986:2005.\n *\n * @return Returns a resolved BaseURL object with calculated values according to inheritance rules.\n */\nexport function resolveDashUri(\n deps: DashUriResolveDeps,\n options: DashUriResolveOptions\n): ResolvedDashUri {\n const { representation, baseUrl, uri } = options\n const baseUrlSelector = deps.baseUrlSelector\n\n const scopeChain = getRepresentationAncestry(representation)\n\n let resolved = baseUrl\n let serviceLocation: string | null = null\n scopeChain.forEach((scope) => {\n if (scope.BaseURL && scope.BaseURL.length) {\n const selectedBaseUrl = baseUrlSelector.selectBaseUrl(scope.BaseURL)\n resolved = resolveUrl(selectedBaseUrl._content, resolved)\n if (selectedBaseUrl.serviceLocation)\n serviceLocation = selectedBaseUrl.serviceLocation\n }\n })\n if (uri != null) {\n resolved = resolveUrl(uri, resolved)\n } else if (resolved === baseUrl) {\n throw new ValidationError(\n 'media missing URI or BaseURL',\n ErrorOrigin.MEDIA\n )\n }\n return { url: resolved, serviceLocation }\n}\n\nexport interface SegmentTemplateUriOptions {\n /**\n * The sequence number of the segment. Will replace `$Number$` in url templates.\n */\n readonly segmentNumber?: Maybe<number>\n\n /**\n * The sample time of the segment. Will replace `$Time$` in url templates.\n */\n readonly sampleTime?: Maybe<number>\n\n /**\n * The representation, will use the id and bandwidth for replacement tokens.\n */\n readonly representation: RepresentationType\n}\n\n/**\n * Supported segment template tokens\n *\n * Does not currently support SubNumber.\n */\ninterface SegmentTemplateTokens {\n /**\n * This placeholder is replaced by the ID of the representation.\n */\n readonly RepresentationID: string\n\n /**\n * This placeholder is replaced by the sequence number of the segment.\n */\n readonly Number: number\n\n /**\n * This placeholder is replaced by the calculated sample time of the segment.\n */\n readonly Time: number\n\n /**\n * Replaced by the bandwidth attribute of the representation.\n */\n readonly Bandwidth: number\n}\n\n/**\n * Creates a segment url using segment template tokens, as defined in 5.3.9.4.4.\n */\nexport function segmentTemplateUrl(\n uri: Uri,\n options: SegmentTemplateUriOptions\n): Uri {\n try {\n return substituteIdentifiers(uri, {\n Bandwidth: options.representation.bandwidth,\n Number: options.segmentNumber ?? 0,\n RepresentationID: options.representation.id,\n Time: options.sampleTime ?? 0,\n } as const satisfies SegmentTemplateTokens)\n } catch (error) {\n if (error instanceof IllegalArgumentError) {\n // An IllegalArgumentError here indicates that a template URL provided was unsupported.\n throw new ValidationError(error.message, ErrorOrigin.MEDIA)\n } else {\n throw error\n }\n }\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { ObservableValue } from '@amazon/vinyl-observable'\nimport type { DashManifestData } from './DashManifestProvider'\nimport type {\n AdaptationSetType,\n DashManifest,\n RepresentationType,\n} from '@amazon/vinyl-mpd-parser'\nimport { type Comparator, compareBy } from '@amazon/vinyl-util'\nimport {\n sortDashAdaptationSets,\n sortDashRepresentations,\n} from './manifestTransformUtils'\n\nexport interface DashManifestTransformerDeps {\n readonly manifestController: ObservableValue<Promise<DashManifestData>>\n}\n\n/**\n * The default dash manifest transformer sorts adaptation sets and representations.\n * Quality filtering is handled by the media timeline transformer.\n */\nexport function createDefaultDashManifestTransformer(\n deps: DashManifestTransformerDeps\n): ObservableValue<Promise<DashManifestData>> {\n return deps.manifestController.map(async (manifestAndPath) => {\n const { manifest, baseUrl } = await manifestAndPath\n let m: DashManifest = sortDashAdaptationSets(\n createDefaultAdaptationSetComparator(),\n manifest\n )\n m = sortDashRepresentations(createDefaultRepresentationComparator(), m)\n return { baseUrl, manifest: m }\n })\n}\n\n/**\n * The default adaptation set comparator orders by descending selectionPriority.\n */\nexport function createDefaultAdaptationSetComparator(): Comparator<AdaptationSetType> {\n return compareBy((adaptationSet) => -adaptationSet.selectionPriority)\n}\n\n/**\n * The default representation comparator orders by ascending quality ranking and descending bandwidth.\n */\nexport function createDefaultRepresentationComparator(): Comparator<RepresentationType> {\n return compareBy(\n (representation) => representation.qualityRanking,\n (representation) => -representation.bandwidth\n )\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type {\n AdaptationSetType,\n DashManifest,\n RepresentationType,\n} from '@amazon/vinyl-mpd-parser'\nimport type { DashManifestData } from './DashManifestProvider'\nimport type { ObservableValue } from '@amazon/vinyl-observable'\nimport {\n clone,\n type Comparator,\n type FilterPredicate,\n type MaybePromise,\n} from '@amazon/vinyl-util'\n\n/**\n * Returns true if the given Dash manifest has unfiltered representations in every Period.\n */\nexport function manifestIsPlayable(manifest: DashManifest): boolean {\n return manifest.MPD.Period.every((period) =>\n period.AdaptationSet?.some(\n (adaptationSet) => adaptationSet.Representation?.length\n )\n )\n}\n\n/**\n * Filters dash representations using a synchronous predicate.\n */\nexport function filterDashRepresentations(\n filter: FilterPredicate<RepresentationType>,\n throwError: () => never,\n manifest: DashManifest\n): DashManifest {\n const result = clone(manifest)\n\n for (const period of result.MPD.Period) {\n if (period.AdaptationSet) {\n for (const adaptationSet of period.AdaptationSet) {\n if (adaptationSet.Representation) {\n adaptationSet.Representation =\n adaptationSet.Representation.filter(filter)\n }\n }\n }\n }\n\n if (!manifestIsPlayable(result)) {\n throwError()\n }\n\n return result\n}\n\n/**\n * Filters dash adaptation sets using a synchronous predicate.\n */\nexport function filterDashAdaptationSets(\n filter: FilterPredicate<AdaptationSetType>,\n throwError: () => never,\n manifest: DashManifest\n): DashManifest {\n const result = clone(manifest)\n\n for (const period of result.MPD.Period) {\n if (period.AdaptationSet) {\n period.AdaptationSet = period.AdaptationSet.filter(filter)\n }\n }\n\n if (!manifestIsPlayable(result)) {\n throwError()\n }\n\n return result\n}\n\n/**\n * Sorts dash adaptation sets using a comparator.\n */\nexport function sortDashAdaptationSets(\n comparator: Comparator<AdaptationSetType>,\n manifest: DashManifest\n): DashManifest {\n const result = clone(manifest)\n\n for (const period of result.MPD.Period) {\n period.AdaptationSet?.sort(comparator)\n }\n\n return result\n}\n\n/**\n * Sorts dash representations using a comparator.\n */\nexport function sortDashRepresentations(\n comparator: Comparator<RepresentationType>,\n manifest: DashManifest\n): DashManifest {\n const result = clone(manifest)\n\n for (const period of result.MPD.Period) {\n if (period.AdaptationSet) {\n for (const adaptationSet of period.AdaptationSet) {\n if (adaptationSet.Representation) {\n adaptationSet.Representation.sort(comparator)\n }\n }\n }\n }\n\n return result\n}\n\n/**\n * Maps a manifest transformation function over a DashManifestData observable.\n * Handles the boilerplate of extracting manifest/baseUrl and reconstructing the result.\n */\nexport function mapManifestTransform(\n manifestController: ObservableValue<Promise<DashManifestData>>,\n transformManifest: (manifest: DashManifest) => MaybePromise<DashManifest>\n): ObservableValue<Promise<DashManifestData>> {\n return manifestController.map(async (manifestAndPath) => {\n const { manifest, baseUrl } = await manifestAndPath\n return {\n baseUrl,\n manifest: await transformManifest(manifest),\n }\n })\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {\n ErrorOrigin,\n type ExtractValues,\n getOrSet,\n getOrSetProp,\n memoize,\n type MutableDeep,\n sortedInsertionIndex,\n ValidationError,\n} from '@amazon/vinyl-util'\nimport {\n type AdaptationSetType,\n type ContentProtection,\n ContentProtectionScheme,\n type DescriptorType,\n type PeriodType,\n type RepresentationBaseType,\n type RepresentationType,\n} from '@amazon/vinyl-mpd-parser'\nimport type {\n ContentType,\n DrmProtection,\n MediaQualityMetadata,\n} from '../../streaming/MediaQualityMetadata'\nimport { type DrmKeySystemResolver } from '../../drm/DrmKeySystemResolver'\nimport { getRepresentationMimeInfo } from './util/mimeType'\nimport type { DescriptorRecord } from '../../streaming/DescriptorRecord'\nimport type { DrmInitDataType } from '../../streaming/DrmInitDataType'\nimport {\n type CencEncryptionScheme,\n parseCencEncryptionScheme,\n} from '../../drm/CencEncryptionScheme'\n\n/**\n * DASH supplemental property scheme URI for adaptation set switching.\n * @see https://dashif.org/docs/DASH-IF-IOP-v4.3.pdf Section 3.8\n */\nexport const ADAPTATION_SET_SWITCHING_SCHEME =\n 'urn:mpeg:dash:adaptation-set-switching:2016'\n\n/**\n * Creates abstract MediaQualityMetadata from a Dash Representation.\n */\nexport type DashMediaQualityMetadataResolver = (\n representation: RepresentationType\n) => MediaQualityMetadata\n\n/**\n * Returns a dash metadata resolver that calculates media encoding metadata from the representation.\n * The most recently used representations will return cached results.\n */\nexport function createDefaultDashMediaQualityMetadataResolver(\n deps: DashMediaQualityMetadataResolverDeps\n): DashMediaQualityMetadataResolver {\n return memoize(\n (representation) =>\n createMediaQualityMetadataFromDashRepresentation(\n representation,\n deps\n ),\n (representation) => representation,\n 30\n )\n}\n\nexport interface DashMediaQualityMetadataResolverDeps {\n readonly drmKeySystemResolver: DrmKeySystemResolver\n}\n\nexport function createMediaQualityMetadataFromDashRepresentation(\n representation: RepresentationType,\n deps: DashMediaQualityMetadataResolverDeps\n): MediaQualityMetadata {\n const { contentType, mimeType } = getRepresentationMimeInfo(representation)\n if (!contentType || !mimeType)\n throw new ValidationError(\n 'mimeType cannot be inferred',\n ErrorOrigin.MEDIA\n )\n const adaptationSet = representation.parent\n const period = adaptationSet.parent\n const mpd = period.parent\n\n const periodId = period.id ?? `$${mpd.Period.indexOf(period)}`\n const adaptationSetId =\n adaptationSet.id ?? `$${period.AdaptationSet!.indexOf(adaptationSet)}`\n const qualityId = `${periodId}_${adaptationSetId}_${representation.id}`\n // Representations within the same adaptation set where bitstreamSwitching is true can be changed without\n // reinitializing the decoder.\n let decoderId = `${periodId}_${adaptationSetId}`\n const bitstreamSwitching =\n adaptationSet.bitstreamSwitching ?? period.bitstreamSwitching\n if (!bitstreamSwitching) decoderId += `_${representation.id}`\n\n // Resolve the adaptation set switching group. Adaptation sets that declare\n // urn:mpeg:dash:adaptation-set-switching:2016 with each other's IDs form a switching group,\n // meaning their representations are permitted to switch between each other.\n const groupId = `${periodId}_${adaptationSetId}`\n const switchingGroupIds = resolveAdaptationSetSwitchingGroupIds(\n adaptationSet,\n periodId,\n adaptationSetId\n )\n\n // Pick a representation base property which may be inherited from the adaptation set.\n function pick<K extends keyof RepresentationBaseType>(\n key: K\n ): NonNullable<RepresentationBaseType[K]> | null {\n return representation[key] ?? adaptationSet[key] ?? null\n }\n\n // Combines the descriptors for the given key into a map of scheme URI to Descriptor lists.\n type DescriptorProps = keyof ExtractValues<\n Required<RepresentationBaseType>,\n readonly DescriptorType[]\n >\n function mergeDescriptors(key: DescriptorProps): DescriptorRecord {\n const arr1 = adaptationSet[key] ?? []\n const arr2 = representation[key] ?? []\n return mapDescriptors([...arr1, ...arr2])\n }\n\n const contentProtections = [\n ...(adaptationSet.ContentProtection ?? []),\n ...(representation.ContentProtection ?? []),\n ]\n\n // Get the encryption scheme from the parsed CENC ContentProtection value.\n let initDataType: DrmInitDataType | null = null\n let encryptionScheme: CencEncryptionScheme | null = null\n for (let i = contentProtections.length - 1; i >= 0; i--) {\n const cP = contentProtections[i]\n if (cP.schemeIdUri === ContentProtectionScheme.CENC) {\n initDataType = 'cenc'\n encryptionScheme =\n parseCencEncryptionScheme(cP.value)?.scheme ?? null\n break\n }\n }\n\n return {\n qualityId,\n decoderId,\n groupId,\n switchingGroupIds,\n mimeType,\n contentType,\n codecs: pick('codecs'),\n bandwidth: representation.bandwidth,\n bandwidthTotal: estimatePeakBandwidth(representation, contentType),\n audioSamplingRate: pick('audioSamplingRate'),\n frameRate: pick('frameRate'),\n width: pick('width'),\n height: pick('height'),\n lang: adaptationSet.lang ?? null,\n contentProtections: contentProtections.flatMap((cP) =>\n contentProtectionToMetadata(cP, deps)\n ),\n encryptionScheme,\n initDataType,\n supplementalProperties: mergeDescriptors('SupplementalProperty'),\n }\n}\n\n/**\n * Estimates the total bandwidth a representation would use when paired with\n * proportionally matched qualities from sibling content types.\n *\n * For each sibling content type, the representation's relative position within its own\n * content type's sorted bandwidth list is mapped to the corresponding position in the\n * sibling's list. This produces realistic pairings \u2014 e.g. with video [v1,v2,v3,v4] and\n * audio [a1,a2], v1 pairs with a1, v2 with a1, v3 with a2, v4 with a2.\n */\nexport function estimatePeakBandwidth(\n representation: RepresentationType,\n contentType: ContentType\n): number {\n const sortedByType = getPeriodSortedBandwidths(representation.parent.parent)\n const own = sortedByType.get(contentType)\n if (!own || own.length === 0) return representation.bandwidth\n // Find the closest match in the descending-sorted array. indexOf would return -1\n // when the representation's bandwidth was collapsed by the 10% dedup threshold.\n const ownIndex = Math.max(\n 0,\n sortedInsertionIndex(own, representation.bandwidth, (a, b) => b - a) - 1\n )\n const position = own.length <= 1 ? 0 : ownIndex / (own.length - 1)\n let total = representation.bandwidth\n for (const [ct, bandwidths] of sortedByType) {\n if (ct === contentType) continue\n const peerIndex = Math.min(\n Math.round(position * (bandwidths.length - 1)),\n bandwidths.length - 1\n )\n total += bandwidths[peerIndex]\n }\n return total\n}\n\n/**\n * Returns sorted (descending) bandwidth arrays per content type for a period.\n * Bandwidths within 10% of an existing entry are collapsed to reduce noise\n * from near-duplicate quality tiers.\n * Cached by period reference.\n */\nexport const getPeriodSortedBandwidths = /* @__PURE__ */ memoize(\n (period: PeriodType): ReadonlyMap<ContentType, readonly number[]> => {\n const byType = new Map<ContentType, number[]>()\n for (const as of period.AdaptationSet ?? []) {\n for (const rep of as.Representation ?? []) {\n const contentType = getRepresentationMimeInfo(rep).contentType\n if (!contentType) continue\n const arr = getOrSet(byType, contentType, () => [])\n if (\n !arr.some(\n (existing) =>\n Math.abs(existing - rep.bandwidth) / existing < 0.1\n )\n ) {\n const index = sortedInsertionIndex(\n arr,\n rep.bandwidth,\n (a, b) => b - a\n )\n arr.splice(index, 0, rep.bandwidth)\n }\n }\n }\n return byType\n },\n (period) => period,\n 5\n)\n\n/**\n * Converts a Dash ContentProtection element to a list of DrmProtection metadata.\n */\nexport function contentProtectionToMetadata(\n contentProtection: ContentProtection,\n deps: DashMediaQualityMetadataResolverDeps\n): readonly DrmProtection[] {\n const keySystems = deps.drmKeySystemResolver(contentProtection.schemeIdUri)\n return keySystems.map((keySystem) => {\n return {\n keySystem,\n pssh: contentProtection.pssh?._content ?? null,\n pro: contentProtection.pro?._content ?? null,\n }\n })\n}\n\n/**\n * Creates a DescriptorRecord from the Dash list of DescriptorType objects.\n * @param descriptors\n */\nfunction mapDescriptors(\n descriptors: readonly DescriptorType[]\n): DescriptorRecord {\n const out: MutableDeep<DescriptorRecord> = {}\n for (const descriptor of descriptors) {\n const arr = getOrSetProp(out, descriptor.schemeIdUri, () => [])!\n arr.push({\n id: descriptor.id ?? null,\n value: descriptor.value ?? null,\n })\n }\n return out\n}\n\n/**\n * Resolves the group IDs that the given adaptation set is permitted to switch to.\n *\n * Per DASH spec, adaptation sets declare `urn:mpeg:dash:adaptation-set-switching:2016` with a\n * comma-separated list of other adaptation set IDs they can switch to.\n *\n * Always includes the adaptation set's own groupId. If no switching property is present,\n * returns only the adaptation set's own groupId.\n */\nfunction resolveAdaptationSetSwitchingGroupIds(\n adaptationSet: AdaptationSetType,\n periodId: string,\n adaptationSetId: string | number\n): readonly string[] | null {\n const selfGroupId = `${periodId}_${adaptationSetId}`\n const switchingProp = adaptationSet.SupplementalProperty?.find(\n (p) => p.schemeIdUri === ADAPTATION_SET_SWITCHING_SCHEME\n )\n if (!switchingProp) return [selfGroupId]\n\n const value = switchingProp.value?.trim()\n if (!value) return [selfGroupId]\n\n const targetIds = value.split(',').map((s) => s.trim())\n return [selfGroupId, ...targetIds.map((id) => `${periodId}_${id}`)]\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { ContentType } from '../../streaming/MediaQualityMetadata'\n\n/**\n * RFC 6381 codec prefixes for video content.\n */\nconst VIDEO_CODEC_PREFIXES = [\n 'avc1',\n 'avc3',\n 'hvc1',\n 'hev1',\n 'vp09',\n 'av01',\n 'dvh1',\n 'dvhe',\n] as const\n\n/**\n * RFC 6381 codec prefixes for audio content.\n */\nconst AUDIO_CODEC_PREFIXES = ['mp4a', 'ac-3', 'ec-3', 'opus', 'flac'] as const\n\n/**\n * RFC 6381 codec prefixes for text/subtitle content.\n */\nconst TEXT_CODEC_PREFIXES = ['stpp', 'wvtt'] as const\n\n/**\n * Returns the ContentType for a single RFC 6381 codec string, or null if\n * unrecognized.\n */\nexport function codecToContentType(codec: string): ContentType | null {\n const lower = codec.trim().toLowerCase()\n for (const p of VIDEO_CODEC_PREFIXES) {\n if (lower.startsWith(p)) return 'video'\n }\n for (const p of AUDIO_CODEC_PREFIXES) {\n if (lower.startsWith(p)) return 'audio'\n }\n for (const p of TEXT_CODEC_PREFIXES) {\n if (lower.startsWith(p)) return 'text'\n }\n return null\n}\n\n/**\n * Splits a comma-separated CODECS attribute value and returns the set of\n * ContentType values present.\n */\nexport function codecsToContentTypes(codecs: string): Set<ContentType> {\n const types = new Set<ContentType>()\n for (const codec of codecs.split(',')) {\n const type = codecToContentType(codec)\n if (type) types.add(type)\n }\n return types\n}\n\n/**\n * Returns the full MIME type string for a content type, optionally with codecs.\n */\nexport function contentTypeToMimeType(\n contentType: ContentType,\n codecs: string | null\n): string {\n const base = contentType === 'video' ? 'video/mp4' : 'audio/mp4'\n return codecs ? `${base}; codecs=\"${codecs}\"` : base\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { RepresentationType } from '@amazon/vinyl-mpd-parser'\nimport type { ContentType } from '../../../streaming/MediaQualityMetadata'\nimport { codecToContentType } from '../../mse/codec'\n\nexport interface RepresentationMimeInfo {\n readonly mimeType: string | null\n readonly contentType: ContentType | null\n}\n\n/**\n * Returns the full mime type with codecs and the inferred content type from the\n * provided representation.\n */\nexport function getRepresentationMimeInfo(\n representation: RepresentationType\n): RepresentationMimeInfo {\n const adaptationSet = representation.parent\n let mimeType = representation.mimeType ?? adaptationSet.mimeType\n const codecs = representation.codecs ?? adaptationSet.codecs\n if (!mimeType) {\n const contentType =\n (adaptationSet.contentType as ContentType | undefined) ??\n (codecs ? codecToContentType(codecs.split(',')[0]) : null)\n switch (contentType) {\n case 'audio':\n mimeType = 'audio/mp4'\n break\n case 'video':\n mimeType = 'video/mp4'\n break\n default:\n return { mimeType: null, contentType: null }\n }\n const fullMimeType = codecs\n ? `${mimeType}; codecs=\"${codecs}\"`\n : mimeType\n return { mimeType: fullMimeType, contentType }\n }\n const fullMimeType = codecs ? `${mimeType}; codecs=\"${codecs}\"` : mimeType\n let contentType: ContentType | null =\n (adaptationSet.contentType as ContentType | undefined) ?? null\n if (!contentType) {\n if (mimeType.startsWith('audio/')) contentType = 'audio'\n else if (mimeType.startsWith('video/')) contentType = 'video'\n else if (\n mimeType.startsWith('text/') ||\n mimeType === 'application/json' ||\n mimeType === 'application/xml'\n )\n contentType = 'text'\n }\n return { mimeType: fullMimeType, contentType }\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {\n type Maybe,\n parseIntSafe,\n type ReadonlyRecord,\n} from '@amazon/vinyl-util'\n\n/**\n * https://www.w3.org/TR/encrypted-media-2/#dom-mediakeysystemmediacapability-encryptionscheme\n */\nexport type CencEncryptionScheme =\n /**\n * AES-CTR mode full sample and video NAL subsample encryption.\n */\n | 'cenc'\n\n /**\n * AES-CBC mode partial video NAL pattern encryption. For video, the spec allows various encryption patterns.\n */\n | 'cbcs'\n\n /**\n * The same as \"cbcs\" mode, but with a specific encrypt:skip pattern of 1:9 for video.\n */\n | 'cbcs-1-9'\n | string\n\nexport interface CencEncryptionSchemeAndVersion {\n readonly scheme: CencEncryptionScheme\n readonly version: number | null\n}\n\nconst encryptionSchemeRegex = /([a-z]{4})(?::([\\da-f]{1,8}))?/\n\nconst protectionSchemeCodes: ReadonlyRecord<\n string,\n CencEncryptionScheme | undefined\n> = {\n ['cbcs']: 'cbcs',\n ['cenc']: 'cenc',\n}\n\n/**\n * 5.8.5.2.2 The MP4 Protection Scheme\n *\n * For Representations based on ISO/IEC 14496-12, the following URI is defined to indicate protection\n * schemes identified by the Scheme Type within the Scheme Type Box of the Protection Scheme\n * Information Box of the file:\n * urn:mpeg:dash:mp4protection:2011\n * In this scheme, the `value` attribute shall present and shall be the 4CC contained in the Scheme Type\n * Box, suitably percent-encoded according to IETF RFC 8141, and may include the version number. The\n * 4CC and the version number, if present, shall be separated by a \":\". The version number shall be encoded\n * as up to 8 hexadecimal digits, where the leading '0's may be omitted.\n *\n * @param value\n */\nexport function parseCencEncryptionScheme(\n value: Maybe<string>\n): CencEncryptionSchemeAndVersion | null {\n if (!value) return null\n const match = encryptionSchemeRegex.exec(value)\n if (!match) return null\n const version = parseIntSafe(match[2], 16)\n const scheme = protectionSchemeCodes[match[1]]\n if (!scheme) return null\n return {\n scheme,\n version,\n }\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {\n type AnyRecord,\n closeTo,\n createDisposer,\n type Disposable,\n DomEventHost,\n ErrorLevel,\n ErrorOrigin,\n EventHostImpl,\n isSilentError,\n type Json,\n logDebug,\n type LogTarget,\n type ReadonlyEventHost,\n type ReadonlySet,\n ReportableError,\n toJson,\n toLowerCase,\n} from '@amazon/vinyl-util'\nimport type { ObservableValue } from '@amazon/vinyl-observable'\nimport type { ContentTypesValue } from '../ContentTypesValue'\nimport type { BasicErrorEvent } from '../../event/BasicErrorEvent'\nimport type { ContentType } from '../MediaQualityMetadata'\nimport type { MediaTimeline } from '../MediaTimeline'\nimport { LIVE_DURATION } from '../../playback/PlaybackController'\nimport { nextSourceBufferIdle } from '../../util/media/sourceBuffer'\n\n/**\n * Chrome 52 has decoding errors when duration is set to the mediaPresentationDuration.\n * Adds a slight padding as a workaround.\n * @private\n */\nexport const DURATION_PADDING = 0.1\n\nexport interface SourceBufferRef extends Disposable {\n /**\n * The source buffer.\n */\n readonly value: SourceBuffer\n}\n\nexport interface MediaSourceControllerEventMap {\n /**\n * The media source has entered a 'closed' state.\n */\n readonly sourceClose: AnyRecord\n\n /**\n * The media source has entered an 'ended' state.\n */\n readonly sourceEnded: AnyRecord\n\n /**\n * The media source has entered an 'open' state.\n */\n readonly sourceOpen: AnyRecord\n\n /**\n * All source buffers have been created, the media source duration has been set, and data\n * may be appended.\n */\n readonly readyToAppend: AnyRecord\n\n /**\n * An error has occurred.\n */\n readonly error: BasicErrorEvent\n}\n\nexport interface ReadonlyMediaSourceController extends ReadonlyEventHost<MediaSourceControllerEventMap> {\n /**\n * Returns the parent media source ready state.\n */\n readonly readyState: ReadyState\n\n /**\n * True if all source buffers have been created and data may be appended.\n */\n readonly readyToAppend: boolean\n}\n\nexport interface MediaSourceController extends ReadonlyMediaSourceController {\n /**\n * Constructs a new SourceBuffer with the given content type and mime type.\n */\n createSourceBuffer(\n contentType: ContentType,\n mimeType: string\n ): SourceBufferRef\n\n /**\n * Signals the end of the stream.\n * @param error A string representing an error to throw when the end of the stream is reached.\n */\n endOfStream(error?: EndOfStreamError): void\n\n /**\n * Creates an Object URL to use as the source for this stream.\n */\n createUrl(): string\n}\n\nexport interface MediaSourceControllerImplDeps {\n /**\n * Creates a new media source.\n */\n readonly mediaSourceFactory: () => MediaSource\n\n /**\n * Provides the streams that must be created before appending.\n */\n readonly contentTypesValue: ContentTypesValue\n\n /**\n * The media timeline used to determine duration.\n */\n readonly mediaTimelineTransformed: ObservableValue<Promise<MediaTimeline>>\n}\n\nexport class MediaSourceControllerImpl\n extends EventHostImpl<MediaSourceControllerEventMap>\n implements MediaSourceController, LogTarget\n{\n get [Symbol.toStringTag](): string {\n return 'MediaSourceControllerImpl'\n }\n\n private readonly sourceBuffers = /* @__PURE__ */ new Set<SourceBuffer>()\n\n private readonly mediaSource: MediaSource\n private readonly disposer = /* @__PURE__ */ createDisposer()\n private contentTypes: ReadonlySet<ContentType> | null = null\n private durationSet = false\n\n /**\n * Token for the in-flight duration update; used to discard stale results when\n * the timeline changes or the source closes mid-fetch.\n */\n private durationToken = 0\n\n constructor(private readonly deps: MediaSourceControllerImplDeps) {\n super()\n this.mediaSource = deps.mediaSourceFactory()\n this.initializeEvents()\n this.disposer.add(\n deps.contentTypesValue.onData((value) => {\n this.contentTypes = null\n value\n .then((contentTypes) => {\n this.contentTypes = contentTypes\n this.checkReady()\n })\n .catch(this.errorHandler)\n })\n )\n }\n\n private get sourceBufferCount(): number {\n return this.sourceBuffers.size\n }\n\n private readonly errorHandler = (error: any) => {\n if (isSilentError(error)) return\n this.dispatch('error', {\n target: this,\n error,\n })\n }\n\n /**\n * Subscription to mediaTimelineTransformed; only attached while the media source is open\n * so the timeline pipeline isn't forced to evaluate before the source has opened.\n */\n private timelineSub: (() => void) | null = null\n\n private initializeEvents(): void {\n const domEvents = new DomEventHost<MediaSourceEventMap>(\n this.mediaSource\n )\n for (const key of [\n 'sourceClose',\n 'sourceOpen',\n 'sourceEnded',\n ] as const) {\n domEvents.on(toLowerCase(key), () => this.dispatch(key, {}))\n }\n this.timelineSub = this.deps.mediaTimelineTransformed.onData(() => {\n this.refreshDuration().catch(this.errorHandler)\n })\n this.on('sourceOpen', () => {\n this.refreshDuration().catch(this.errorHandler)\n })\n this.on('sourceClose', () => {\n this.durationSet = false\n ++this.durationToken\n })\n }\n\n /**\n * Sets the duration on the media source from the current media timeline.\n * Live streams use LIVE_DURATION since not all browsers support +Infinity duration.\n *\n * MSE throws InvalidStateError if duration is set while any source buffer is updating,\n * so we wait for all tracked source buffers to be idle first.\n */\n private async refreshDuration(): Promise<void> {\n const timelinePromise = this.deps.mediaTimelineTransformed.value\n const token = ++this.durationToken\n const timeline = await timelinePromise\n const duration = await timeline.getDuration()\n const value =\n duration === Infinity ? LIVE_DURATION : duration + DURATION_PADDING\n await Promise.all(Array.from(this.sourceBuffers, nextSourceBufferIdle))\n if (\n token !== this.durationToken ||\n this.mediaSource.readyState !== 'open' ||\n closeTo(this.mediaSource.duration, value, 0.1)\n )\n return\n logDebug(this, `setting duration: ${value}`)\n this.mediaSource.duration = value\n this.durationSet = true\n this.checkReady()\n }\n\n get readyState(): ReadyState {\n return this.mediaSource.readyState\n }\n\n createSourceBuffer(\n contentType: ContentType,\n mimeType: string\n ): SourceBufferRef {\n const mediaSource = this.mediaSource\n logDebug(\n this,\n 'create source buffer',\n contentType,\n mimeType,\n mediaSource.readyState,\n 'sourceBufferCount:',\n this.sourceBufferCount\n )\n let sourceBuffer: SourceBuffer\n try {\n sourceBuffer = mediaSource.addSourceBuffer(mimeType)\n } catch (error: any) {\n throw new MediaSourceError('error creating source buffer', error)\n }\n sourceBuffer.mode = 'sequence'\n this.sourceBuffers.add(sourceBuffer)\n this.checkReady()\n\n const dispose = () => {\n logDebug(\n this,\n 'removing source buffer from media source',\n mediaSource.readyState\n )\n if (mediaSource.readyState !== 'closed') {\n mediaSource.removeSourceBuffer(sourceBuffer)\n }\n this.sourceBuffers.delete(sourceBuffer)\n }\n\n return {\n value: sourceBuffer,\n dispose,\n }\n }\n\n /**\n * Emits a 'readyToAppend' event if all source buffers have been created and the duration\n * has been applied to the media source.\n */\n private readonly checkReady = () => {\n if (this.readyToAppend) this.dispatch('readyToAppend', {})\n }\n\n endOfStream(error?: EndOfStreamError) {\n logDebug(this, 'endOfStream, error:', error)\n this.mediaSource.endOfStream(error)\n }\n\n createUrl(): string {\n return URL.createObjectURL(this.mediaSource)\n }\n\n get readyToAppend(): boolean {\n return (\n this.durationSet &&\n this.contentTypes?.size === this.sourceBufferCount\n )\n }\n\n dispose() {\n super.dispose()\n this.timelineSub?.()\n this.timelineSub = null\n this.disposer.dispose()\n }\n}\n\nexport class MediaSourceError extends ReportableError {\n get [Symbol.toStringTag](): string {\n return 'MediaSourceError'\n }\n\n constructor(\n message: string,\n private readonly reason: Error\n ) {\n super(message, ErrorOrigin.INTERNAL, ErrorLevel.FATAL)\n Object.setPrototypeOf(this, MediaSourceError.prototype)\n }\n\n toJSON(): Json {\n return {\n ...super.toJSON(),\n reason: toJson(this.reason),\n }\n }\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { promise } from '@amazon/vinyl-util'\nimport type { Maybe } from '@amazon/vinyl-util'\nimport { SourceBufferError } from '../../streaming/buffering/error/SourceBufferError'\nimport { AbortError } from '@amazon/vinyl-util'\n\n/**\n * Returns a promise that resolves when the given source buffer is next idle.\n * If the source buffer errs, the promise will be rejected with a {@link SourceBufferError}.\n *\n * @param sourceBuffer\n */\nexport function nextSourceBufferIdle(\n sourceBuffer: Maybe<SourceBuffer>\n): Promise<void> {\n if (!sourceBuffer) return Promise.resolve()\n if (!sourceBuffer.updating) return Promise.resolve()\n return promise((resolve, reject) => {\n const removeListeners = () => {\n sourceBuffer.removeEventListener('error', onErred)\n sourceBuffer.removeEventListener('abort', onAborted)\n sourceBuffer.removeEventListener('update', onEnded)\n }\n const onEnded = () => {\n removeListeners()\n resolve()\n }\n const onErred = (_event: any) => {\n removeListeners()\n reject(new SourceBufferError())\n }\n const onAborted = () => {\n removeListeners()\n reject(new AbortError())\n }\n sourceBuffer.addEventListener('error', onErred)\n sourceBuffer.addEventListener('abort', onAborted)\n sourceBuffer.addEventListener('update', onEnded)\n })\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { ErrorOrigin } from '@amazon/vinyl-util'\nimport { ReportableError } from '@amazon/vinyl-util'\n\n/**\n * An error emitted from the SourceBuffer.\n */\nexport class SourceBufferError extends ReportableError {\n get [Symbol.toStringTag](): string {\n return 'SourceBufferError'\n }\n\n constructor(\n message = `A SourceBuffer error has occurred.`,\n origin = ErrorOrigin.MEDIA\n ) {\n super(message, origin)\n Object.setPrototypeOf(this, SourceBufferError.prototype)\n }\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { data } from '@amazon/vinyl-observable'\nimport { createAbortSlot, createDisposer, logDebug } from '@amazon/vinyl-util'\nimport type {\n DashManifestData,\n DashManifestProvider,\n} from './DashManifestProvider'\nimport type { ManifestController } from '../../streaming/ManifestController'\n\nexport type DashManifestController = ManifestController<\n Promise<DashManifestData>\n>\n\nexport interface DashManifestControllerImplDeps {\n /**\n * Resolves the untransformed manifest.\n */\n readonly manifestProvider: DashManifestProvider\n}\n\nexport class DashManifestControllerImpl implements DashManifestController {\n get [Symbol.toStringTag](): string {\n return 'DashManifestControllerImpl'\n }\n\n get logPrefix(): string {\n return 'DashManifestControllerImpl'\n }\n\n private readonly _data = /* @__PURE__ */ data<Promise<DashManifestData>>(\n /* @__PURE__ */ Promise.reject(/* @__PURE__ */ new Error('manifest not loaded'))\n )\n private _error: Error | null = null\n private readonly abortSlot = /* @__PURE__ */ createAbortSlot()\n private readonly disposer = /* @__PURE__ */ createDisposer()\n\n constructor(readonly deps: DashManifestControllerImplDeps) {\n // Suppress unhandled rejection on the initial placeholder.\n this._data.value.catch(() => {})\n this.refresh()\n }\n\n /**\n * The most recent error from the manifest provider, or null.\n * This may be a silent error, such as an AbortError.\n */\n get error(): Error | null {\n return this._error\n }\n\n /**\n * Reloads the manifest. Aborts any in-flight request and clears any\n * previous error before starting a new fetch.\n */\n refresh() {\n logDebug(this, 'refresh')\n this.abort()\n this._error = null\n const promise = this.deps.manifestProvider(this.abortSlot.value)\n promise.catch((error: Error) => {\n this._error = error\n })\n this._data.value = promise\n }\n\n /**\n * If the manifest is in an error state, triggers a refresh.\n */\n reset() {\n logDebug(this, 'reset')\n if (this._error) {\n this.refresh()\n }\n }\n\n get value() {\n return this._data.value\n }\n\n get changeId() {\n return this._data.changeId\n }\n\n getValue() {\n return this._data.getValue()\n }\n\n onData(\n callback: (\n value: Promise<DashManifestData>,\n previous: Promise<DashManifestData> | undefined\n ) => void\n ) {\n return this._data.onData(callback)\n }\n\n map<U>(transform: (value: Promise<DashManifestData>) => U) {\n return this._data.map(transform)\n }\n\n pick<K extends keyof NonNullable<Promise<DashManifestData>>>(prop: K) {\n return this._data.pick(prop)\n }\n\n private abort() {\n this.abortSlot.abort()\n }\n\n get disposed(): boolean {\n return this.disposer.disposed\n }\n\n dispose() {\n this.abort()\n this.disposer.dispose()\n }\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {\n createLogPrefix,\n createTaskQueue,\n createTimeRangesReader,\n type Disposable,\n emptyRanges,\n ErrorOrigin,\n IllegalStateError,\n logDebug,\n type LogTarget,\n nextEventAsPromise,\n type ReadonlyRanges,\n type Task,\n} from '@amazon/vinyl-util'\nimport { nextSourceBufferIdle } from '../../util/media/sourceBuffer'\nimport { SourceBufferError } from './error/SourceBufferError'\nimport type {\n MediaSourceController,\n SourceBufferRef,\n} from './MediaSourceController'\nimport type { ContentType } from '../MediaQualityMetadata'\n\n// Prevents unintentionally dropped keyframes\nexport const APPEND_WINDOW_START_OFFSET = 0.05\nexport const APPEND_WINDOW_END_OFFSET = 0.01\n\n// The number of seconds before aborting the wait for media source controller's readyToAppend event.\nexport const READY_TO_APPEND_TIMEOUT = 30\n\nexport type SourceBufferControllerFactory = () => SourceBufferController\n\nexport interface SourceBufferController extends Disposable {\n readonly buffered: ReadonlyRanges\n\n /**\n * Returns true if an operation is currently running.\n */\n isBusy(): boolean\n\n /**\n * Enqueues an operation.\n * Guaranteed to be invoked when the source buffer is not updating.\n */\n enqueue<T = void>(task: Task<T>): Promise<T>\n\n /**\n * Enqueues appending an initialization segment, reinitializing the decoder.\n */\n appendInit(data: ArrayBuffer, mimeType: string): Promise<void>\n\n /**\n * Enqueues appending a media segment.\n * An `appendInit` call must precede appending media segments.\n * A promise is returned that will resolve when the task is complete.\n */\n append(data: ArrayBuffer): Promise<void>\n\n /**\n * Sets the timestampOffset on the backing source buffer.\n */\n setTimestampOffset(timestampOffset: number): Promise<void>\n\n /**\n * Sets the append window on the backing source buffer.\n * Keyframes outside this range will be discarded.\n */\n setAppendWindow(\n appendWindowStart?: number,\n appendWindowEnd?: number\n ): Promise<void>\n\n /**\n * Removes media segments within a specific time range from the SourceBuffer.\n */\n remove(startTime: number, endTime: number): Promise<void>\n\n /**\n * Aborts any pending buffers and clears all buffered ranges.\n */\n clear(): Promise<void>\n}\n\nexport interface SourceBufferControllerImplDeps {\n /**\n * Produces the source buffer for appending.\n */\n readonly mediaSourceController: MediaSourceController\n}\n\n/**\n * The SourceBufferController manages a single source buffer. It provides queued commands for appending and clearing\n * data.\n */\nexport class SourceBufferControllerImpl\n implements LogTarget, SourceBufferController, Disposable\n{\n get [Symbol.toStringTag](): string {\n return 'SourceBufferController'\n }\n\n private sourceBufferRef: SourceBufferRef | null = null\n\n private mimeType: string | null = null\n private queue = /* @__PURE__ */ createTaskQueue()\n\n readonly logPrefix = /* @__PURE__ */ createLogPrefix(this)\n private readonly mediaSourceController: MediaSourceController\n\n constructor(\n deps: SourceBufferControllerImplDeps,\n readonly contentType: ContentType\n ) {\n logDebug(this, 'constructed, contentType:', contentType)\n this.mediaSourceController = deps.mediaSourceController\n }\n\n private get sourceBuffer(): SourceBuffer | null {\n return this.sourceBufferRef && this.sourceBufferRef.value\n }\n\n private _buffered: ReadonlyRanges | null = null\n get buffered(): ReadonlyRanges {\n if (this._buffered == null) {\n if (!this.sourceBuffer) this._buffered = emptyRanges\n else\n this._buffered = createTimeRangesReader(\n this.sourceBuffer.buffered\n )\n }\n return this._buffered\n }\n\n /**\n * Clears the cached buffered ranges. They will be recreated next access.\n */\n private clearBufferedCache = () => {\n this._buffered = null\n }\n\n isBusy(): boolean {\n return this.queue.running > 0\n }\n\n enqueue<T = void>(task: Task<T>): Promise<T> {\n return this.queue.enqueue(task)\n }\n\n async appendInit(data: ArrayBuffer, mimeType: string): Promise<void> {\n return this.queue.enqueue(async (abort) => {\n if (this.mimeType !== mimeType) {\n if (this.sourceBuffer && 'changeType' in this.sourceBuffer) {\n // There is an existing source buffer and its mime type can be changed.\n logDebug(this, 'changeType', mimeType)\n this.sourceBuffer.changeType(mimeType)\n } else {\n // There is either no existing source buffer or a new buffer must be created\n // with the new mime type.\n this.sourceBufferRef?.dispose()\n const newSourceBufferRef =\n this.mediaSourceController.createSourceBuffer(\n this.contentType,\n mimeType\n )\n // Do not append to the source buffer until all streams have been created:\n if (!this.mediaSourceController.readyToAppend)\n await nextEventAsPromise(\n this.mediaSourceController,\n 'readyToAppend',\n { timeout: READY_TO_APPEND_TIMEOUT, abort }\n ).catch((error) => {\n // The readyToAppend was aborted or timed out, dispose the source buffer\n newSourceBufferRef.dispose()\n throw error\n })\n this.sourceBufferRef = newSourceBufferRef\n }\n this.mimeType = mimeType\n }\n const sourceBuffer = this.sourceBuffer!\n logDebug(this, `appending init ${data.byteLength} bytes`)\n sourceBuffer.appendBuffer(data)\n await this.nextIdle()\n logDebug(this, 'appended init')\n })\n }\n\n async append(data: ArrayBuffer): Promise<void> {\n return this.queue.enqueue(async () => {\n logDebug(this, `appending ${data.byteLength} bytes`)\n const sourceBuffer = this.sourceBuffer\n if (!sourceBuffer)\n throw new SourceBufferError(\n 'media segment provided before init segment',\n ErrorOrigin.INTERNAL\n )\n sourceBuffer.appendBuffer(data)\n await this.nextIdle()\n logDebug(this, 'appended', this.buffered)\n })\n }\n\n setTimestampOffset(timestampOffset: number): Promise<void> {\n return this.queue.enqueue(() => {\n const sourceBuffer = this.sourceBuffer\n if (!sourceBuffer)\n throw new IllegalStateError(\n 'source buffer must be initialized before setting timestamp offset'\n )\n logDebug(this, 'timestampOffset:', timestampOffset.toFixed(4))\n sourceBuffer.timestampOffset = timestampOffset\n })\n }\n\n setAppendWindow(\n appendWindowStart: number = 0,\n appendWindowEnd: number = Number.POSITIVE_INFINITY\n ): Promise<void> {\n return this.queue.enqueue(() => {\n const sourceBuffer = this.sourceBuffer\n if (!sourceBuffer)\n throw new IllegalStateError(\n 'source buffer must be initialized before setting append window'\n )\n const finalAppendWindowStart = Math.max(\n 0,\n appendWindowStart - APPEND_WINDOW_START_OFFSET\n )\n const finalAppendWindowEnd =\n appendWindowEnd + APPEND_WINDOW_END_OFFSET\n logDebug(\n this,\n 'appendWindow:',\n finalAppendWindowStart.toFixed(4),\n finalAppendWindowEnd.toFixed(4)\n )\n\n // start may not be greater than end, even temporarily.\n // Avoids the error: \"Failed to set the 'appendWindow___' property\"\n sourceBuffer.appendWindowStart = 0\n sourceBuffer.appendWindowEnd = finalAppendWindowEnd\n sourceBuffer.appendWindowStart = finalAppendWindowStart\n })\n }\n\n remove(startTime: number, endTime: number): Promise<void> {\n return this.queue.enqueue(async () => {\n if (endTime > startTime) {\n logDebug(this, `removing range: ${startTime}-${endTime}`)\n this.sourceBuffer?.remove(startTime, endTime)\n await this.nextIdle()\n logDebug(this, 'removed, new buffered:', this.buffered)\n }\n })\n }\n\n /**\n * Returns a promise that resolves when the source buffer is no longer updating.\n * @private\n */\n private nextIdle = (): Promise<void> =>\n nextSourceBufferIdle(this.sourceBuffer).finally(this.clearBufferedCache)\n\n async clear(): Promise<void> {\n await this.remove(0, Number.POSITIVE_INFINITY)\n }\n\n /**\n * Aborts any pending operations and disposes the backed SourceBuffer.\n */\n dispose() {\n logDebug(this, 'dispose')\n this.queue.abort()\n this.sourceBufferRef?.dispose()\n this.sourceBufferRef = null\n }\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {\n type AnyRecord,\n type Clearable,\n createAbortSlot,\n createDisposer,\n createTaskQueue,\n type Disposable,\n type Disposer,\n EventHostImpl,\n getLogLevel,\n isSilentError,\n LinkedList,\n logDebug,\n LogLevel,\n logVerbose,\n logWarn,\n type ReadonlyEventHost,\n throttle,\n} from '@amazon/vinyl-util'\nimport type { ReadonlyPlaybackController } from '../../playback/ReadonlyPlaybackController'\nimport type { SourceBufferController } from './SourceBufferController'\nimport type { ReadonlySegmentController } from '../SegmentController'\nimport type { SegmentReference } from '../SegmentReference'\nimport type { BasicErrorEvent } from '../../event/BasicErrorEvent'\nimport type { ChangeEvent } from '../../event/ChangeEvent'\nimport type { ContentType, MediaQualityMetadata } from '../MediaQualityMetadata'\nimport { type MediaSourceController } from './MediaSourceController'\nimport { SEGMENT_START_AFFORDANCE } from '../SegmentController'\n\n/**\n * The interval to throttle polling the buffer.\n * Reset after a seek.\n * @private\n */\nexport const POLL_BUFFER_THROTTLE = 0.1\n\n/**\n * If segments are too large to append, reduces the max append size.\n */\nexport const QUOTA_REACHED_SCALE = 0.8\n\n/**\n * If quota exceeded errors are hit, the max append size will not be reduced below this value and the buffering\n * controller will be set to an erred state.\n */\nexport const MIN_APPEND_SIZE = 524288 // 512 * 1024\n\n/**\n * If the content type does not match a config setting.\n */\nexport const DEFAULT_MAX_APPEND_SIZE = 10485760 // 10 * 1024 * 1024\n\nexport interface BufferingControllerEventMap {\n /**\n * Dispatched when an error of severity warning or fatal occurred while buffering.\n */\n readonly error: BasicErrorEvent\n\n /**\n * Dispatched when the currently playing media encoding has changed.\n */\n readonly playbackQualityChange: ChangeEvent<MediaQualityMetadata | null>\n\n /**\n * Dispatched when the currently buffering quality changes.\n * This is dispatched before the segment is appended.\n */\n readonly bufferingQualityChange: ChangeEvent<MediaQualityMetadata | null>\n\n /**\n * The last segment has finished appending.\n */\n readonly bufferingEnded: AnyRecord\n}\n\nexport interface BufferingController\n extends\n ReadonlyEventHost<BufferingControllerEventMap>,\n Clearable,\n Disposable {\n /**\n * The last error emitted.\n * Buffering will halt if this controller is in an error state.\n * Deactivating this controller will reset the error state.\n */\n readonly error: Error | null\n\n /**\n * The currently buffering media quality.\n * This is set immediately before a segment of a new quality is appended.\n *\n * Listen to {@link BufferingControllerEventMap.bufferingQualityChange} events for changes.\n */\n readonly bufferingQuality: MediaQualityMetadata | null\n\n /**\n * The currently playing media quality.\n *\n * Listen to {@link BufferingControllerEventMap.playbackQualityChange} events for changes.\n */\n readonly playbackQuality: MediaQualityMetadata | null\n\n /**\n * True if this buffering controller is active.\n */\n readonly active: boolean\n\n /**\n * True if the stream has buffered the last segment.\n */\n readonly bufferingEnded: boolean\n\n /**\n * Begins buffering.\n */\n activate(): void\n\n /**\n * Stops buffering.\n */\n deactivate(): void\n\n /**\n * If this controller is in an error state, resets and tries again.\n */\n reset(): void\n}\n\n/**\n * The measured source buffer quotas.\n */\nconst sourceBufferQuotas = /* @__PURE__ */ new Map<string, number>()\n\n/**\n * Clears the current estimated source buffer quota.\n * @private\n */\nexport function clearSourceBufferQuota() {\n sourceBufferQuotas.clear()\n}\n\n/**\n * Returns the measured source buffer quota for the given content type.\n * Will return null if the quota was never reached.\n *\n * @param contentType\n */\nexport function getSourceBufferQuota(contentType: ContentType): number | null {\n return sourceBufferQuotas.get(contentType) ?? null\n}\n\nexport interface BufferingControllerImplDeps {\n readonly mediaSourceController: MediaSourceController\n readonly segmentController: ReadonlySegmentController\n readonly playbackController: ReadonlyPlaybackController\n readonly sourceBufferControllerFactory: () => SourceBufferController\n}\nexport interface BufferingControllerImplOptions {\n /**\n * When the buffer falls below this time threshold, the next segment will be requested from the\n * segment controller and appended.\n * Default: 4s\n */\n readonly minBuffer: number\n\n /**\n * The maximum number of bytes to append at a time per content type.\n * Default: { audio: 1MiB, video: 15MiB }\n */\n readonly maxAppendSize: Partial<Record<ContentType, number>>\n}\n\nconst defaultBufferingControllerOptions = {\n minBuffer: 4.0,\n maxAppendSize: {\n audio: 10485760, // 10 * 1024 * 1024\n video: 157286400, // 150 * 1024 * 1024\n },\n} as const satisfies BufferingControllerImplOptions\n\n/**\n * The buffering controller is responsible for requesting and appending segments to the source\n * buffer controller.\n */\nexport class BufferingControllerImpl\n extends EventHostImpl<BufferingControllerEventMap>\n implements BufferingController, Disposable\n{\n get [Symbol.toStringTag](): string {\n return 'BufferingControllerImpl'\n }\n\n readonly options: BufferingControllerImplOptions\n private readonly mediaSourceController: MediaSourceController\n private readonly playbackController: ReadonlyPlaybackController\n private readonly segmentController: ReadonlySegmentController\n\n private sourceBufferController: SourceBufferController | null = null\n private decoderId: string | null = null\n\n /**\n * The currently buffered segments.\n */\n private buffered = /* @__PURE__ */ new LinkedList<SegmentReference<ArrayBuffer>>()\n private appendOffset = 0\n\n /**\n * The currently buffering quality.\n */\n private _bufferingQuality: MediaQualityMetadata | null = null\n\n /**\n * If true and in a bufferingEnded state, the segment provider will be queried again.\n * This will be set to true after the segment controller reports a change event, indicating that there may be new\n * segments to append.\n */\n private reopen = false\n private _error: Error | null = null\n private _bufferingEnded = false\n\n private readonly queue = /* @__PURE__ */ createTaskQueue()\n\n private disposer = /* @__PURE__ */ createDisposer()\n private _active = false\n private activateDisposer: Disposer | null = null\n\n private readonly segmentAbort = /* @__PURE__ */ createAbortSlot()\n\n constructor(\n readonly deps: BufferingControllerImplDeps,\n readonly contentType: ContentType,\n options?: Partial<BufferingControllerImplOptions>\n ) {\n super()\n this.options = {\n ...defaultBufferingControllerOptions,\n ...options,\n }\n logDebug(this, 'constructed', this.options)\n this.mediaSourceController = deps.mediaSourceController\n this.playbackController = deps.playbackController\n this.segmentController = deps.segmentController\n }\n\n get active(): boolean {\n return this._active\n }\n\n /**\n * Activates the buffering controller, watching the playhead and segment controller.\n */\n activate() {\n if (this._active) return\n this._active = true\n logDebug(this, 'activate')\n this.activateDisposer = createDisposer()\n const { add } = this.activateDisposer\n this.sourceBufferController = add(\n this.deps.sourceBufferControllerFactory()\n )\n add(this.playbackController.on('timeUpdate', this.pollBuffer))\n add(\n this.playbackController.on('seeking', () => {\n this.clear()\n })\n )\n\n const onMediaSourceOpen = () => {\n logDebug(this, 'media source opened')\n this.pollBufferImmediate()\n }\n if (this.mediaSourceOpen) {\n onMediaSourceOpen()\n } else {\n add(this.mediaSourceController.on('sourceOpen', onMediaSourceOpen))\n }\n add(\n this.segmentController.on('change', () => {\n this.reopen = true\n this.pollBufferImmediate()\n })\n )\n }\n\n deactivate() {\n if (!this._active) return\n logDebug(this, 'deactivate')\n this.abortCurrentSegment()\n this.resetBufferedState()\n this.activateDisposer!.dispose()\n this.activateDisposer = null\n this.sourceBufferController = null\n this._active = false\n }\n\n reset(): void {\n if (!this._error) {\n logDebug(this, 'reset no-op')\n return\n }\n logDebug(this, 'reset')\n this._error = null\n this.pollBufferImmediate()\n }\n\n /**\n * Returns true if there are active operations.\n */\n get busy(): boolean {\n return this.queue.running > 0\n }\n\n /**\n * Resets the throttle and polls the buffer on the next frame.\n */\n private pollBufferImmediate = () => {\n this.pollBuffer.reset()\n setTimeout(() => {\n if (this.active) this.pollBuffer()\n })\n }\n\n /**\n * If buffered time reaches below minBuffer, request the segment for the next unbuffered\n * time and append.\n * @private\n */\n private readonly pollBuffer = /* @__PURE__ */ this.disposer.add(\n /* @__PURE__ */ throttle(\n () => {\n const time = this.playbackController.currentTime\n if (getLogLevel() === LogLevel.VERBOSE) {\n logVerbose(\n this,\n `pollBuffer time: ${time}, bufferedTime: ${this.getBufferedTime()}, busy: ${this.busy}, error: ${this.error != null}, readyState: ${this.mediaSourceController.readyState}`\n )\n }\n this.refreshHead()\n if (!this.shouldAppend()) return\n this.reopen = false\n this.queue\n .enqueue(() => this.appendNext())\n .catch(this.handleError)\n // An append has finished. Poll again on the next frame.\n // The append either completed successfully, erred fatally (setting an error state),\n // or erred silently (an abort).\n .finally(this.pollBufferImmediate)\n },\n POLL_BUFFER_THROTTLE,\n {\n leading: true,\n trailing: true,\n }\n )\n )\n\n private shouldAppend(): boolean {\n return (\n this.active &&\n !this.busy &&\n !this.error &&\n !this.mediaSourceClosed &&\n (!this.bufferingEnded || this.reopen) &&\n // Return true if the current buffer is less than the minimum buffer and the playhead has not reached duration.\n this.getBufferedTime() <= this.options.minBuffer\n )\n }\n\n /**\n * The buffered segment at the playhead.\n */\n private get head(): SegmentReference<ArrayBuffer> | undefined {\n return this.buffered.head?.value\n }\n\n /**\n * The most recently buffered segment.\n */\n private get tail(): SegmentReference<ArrayBuffer> | undefined {\n return this.buffered.tail?.value\n }\n\n protected async appendNext(): Promise<void> {\n logVerbose(this, 'appendNext')\n const sourceBufferController = this.sourceBufferController!\n const time = this.playbackController.currentTime\n\n const tail = this.tail\n let streamingSegment: SegmentReference<ArrayBuffer> | null\n // If appendOffset is less than the last buffered segment size, this indicates a partial append, continue\n // buffering the last segment.\n if (tail && this.appendOffset < tail.data.byteLength) {\n streamingSegment = tail\n } else {\n streamingSegment = await this.segmentController.getSegment(\n // If buffering is a continuation from the previous segment, use its end time.\n // Otherwise, start streaming from slightly behind the playhead.\n tail?.endTime ?? time - SEGMENT_START_AFFORDANCE,\n this.segmentAbort.value\n )\n logVerbose(this, 'streamingSegment', streamingSegment)\n if (streamingSegment) this.appendOffset = 0\n }\n if (!streamingSegment) {\n await sourceBufferController.enqueue(() => {\n if (this.mediaSourceOpen) this.endBuffering()\n })\n return\n }\n this.bufferingQuality = streamingSegment.quality\n if (this.decoderId !== streamingSegment.quality.decoderId) {\n // Append the initialization segment before the media segment if the decoder\n // needs (re)-initialization.\n this.decoderId = null\n await sourceBufferController.appendInit(\n streamingSegment.initData,\n streamingSegment.quality.mimeType!\n )\n this.decoderId = streamingSegment.quality.decoderId\n }\n // Set the timestamp offset only if appending from an unbuffered position.\n if (!tail) {\n await sourceBufferController.setTimestampOffset(\n streamingSegment.timestampOffset\n )\n }\n\n const maxAppendSize = this.getMaxAppendSize(\n streamingSegment.quality.contentType!\n )\n\n const currentBitrate =\n streamingSegment.data.byteLength /\n (streamingSegment.endTime - streamingSegment.startTime)\n const appendSize =\n maxAppendSize - currentBitrate * this.getBufferedTime()\n if (appendSize <= 0) {\n // current buffered data is filling entire quota\n return\n }\n\n const byteLength = streamingSegment.data.byteLength\n if (byteLength > appendSize) {\n const newOffset = this.appendOffset + appendSize\n const chunk = streamingSegment.data.slice(\n this.appendOffset,\n newOffset\n )\n await sourceBufferController.append(chunk)\n if (this.appendOffset === 0) {\n this.buffered.push(streamingSegment)\n }\n this.appendOffset = newOffset\n logVerbose(\n this,\n `appended chunk, this.appendOffset: ${this.appendOffset}`\n )\n } else {\n await sourceBufferController.append(streamingSegment.data)\n this.appendOffset = streamingSegment.data.byteLength\n this.buffered.push(streamingSegment)\n }\n if (!tail) this.refreshHead() // Update quality immediately if buffer was empty\n }\n\n private abortCurrentSegment() {\n this.segmentAbort.abort()\n }\n\n /**\n * Checks if the playhead has progressed past the current head segment and shifts the linked list.\n * Updates the playback quality if changed.\n */\n private refreshHead() {\n const head = this.head\n const tail = this.tail\n const time = this.playbackController.currentTime\n if (head && time >= head.endTime && head !== tail) {\n // The playhead has passed the end of the head segment.\n this.buffered.shift()\n }\n this.playbackQuality = this.head?.quality ?? null\n }\n\n private getMaxAppendSize(contentType: ContentType): number {\n const maxAppendSize =\n this.options.maxAppendSize[contentType] ?? DEFAULT_MAX_APPEND_SIZE\n const sourceBufferQuota = sourceBufferQuotas.get(contentType)\n return sourceBufferQuota == null\n ? maxAppendSize\n : Math.min(sourceBufferQuota, maxAppendSize)\n }\n\n private _playbackQuality: MediaQualityMetadata | null = null\n\n get playbackQuality(): MediaQualityMetadata | null {\n return this._playbackQuality\n }\n\n /**\n * Returns the quality currently buffering.\n */\n get bufferingQuality(): MediaQualityMetadata | null {\n return this._bufferingQuality\n }\n\n private set bufferingQuality(value: MediaQualityMetadata | null) {\n const previous = this._bufferingQuality\n if (value?.qualityId === previous?.qualityId) return\n this._bufferingQuality = value\n logDebug(this, 'bufferingQualityChange', value)\n this.dispatch('bufferingQualityChange', {\n previous,\n current: value,\n })\n }\n\n /**\n * Sets the current playback quality and emits a playbackQualityChange event.\n * No-ops if quality id has not changed.\n */\n private set playbackQuality(value: MediaQualityMetadata | null) {\n const previous = this._playbackQuality\n if (value?.qualityId === previous?.qualityId) return\n this._playbackQuality = value\n logDebug(this, 'playbackQualityChange', value)\n this.dispatch('playbackQualityChange', {\n previous,\n current: value,\n })\n }\n\n /**\n * The last error emitted.\n * Buffering will halt if this controller is in an error state.\n * Deactivating this controller will reset the error state.\n */\n get error(): Error | null {\n return this._error\n }\n\n /**\n * Returns true if the media source's ready state is 'open'\n */\n private get mediaSourceOpen(): boolean {\n return this.mediaSourceController.readyState === 'open'\n }\n\n /**\n * Returns true if the media source's ready state is 'closed'\n */\n private get mediaSourceClosed(): boolean {\n return this.mediaSourceController.readyState === 'closed'\n }\n\n /**\n * Returns true if the last segment has been appended.\n */\n get bufferingEnded(): boolean {\n return this._bufferingEnded\n }\n\n private readonly handleError = (error: Error) => {\n if ('name' in error && error.name === 'QuotaExceededError') {\n const contentType = this.bufferingQuality?.contentType\n if (contentType) {\n const newAppendSize =\n this.getMaxAppendSize(contentType) * QUOTA_REACHED_SCALE\n if (newAppendSize >= MIN_APPEND_SIZE) {\n sourceBufferQuotas.set(contentType, newAppendSize)\n logWarn(\n this,\n 'QuotaExceededError, new source buffer limit:',\n (newAppendSize / 1024 / 1024).toFixed(1) + ' MiB'\n )\n const sourceBufferController = this.sourceBufferController\n if (sourceBufferController) {\n this.clear()\n }\n return // If the quota size was successfully reduced, do not err and try again.\n }\n }\n }\n if (!isSilentError(error)) {\n // Set this controller to an error state. If in an error state, buffering will\n // not continue.\n this._error = error\n this.dispatch('error', {\n target: this,\n error,\n })\n }\n }\n\n /**\n * Returns the amount of time buffered at the current media position.\n * @private\n */\n getBufferedTime(): number {\n if (!this.active) return 0\n const time = this.playbackController.currentTime\n const range = this.sourceBufferController!.buffered.getRangeAt(time)\n if (!range) return 0\n return range[1] - time\n }\n\n /**\n * Cancels any currently buffering fragments and clears the source buffer.\n */\n clear(): void {\n if (!this.active) return\n logDebug(this, 'clear')\n this.abortCurrentSegment()\n // Enqueue clearing the buffer and buffered list.\n this.queue\n .enqueue(this.finishAndClearBuffers)\n .catch(this.handleError)\n .finally(() => {\n this.resetBufferedState()\n this.pollBufferImmediate()\n })\n }\n\n private endBuffering(): void {\n logDebug(this, 'bufferingEnded')\n this._bufferingEnded = true\n this.bufferingQuality = null\n this.dispatch('bufferingEnded', {})\n }\n\n private resetBufferedState() {\n this.decoderId = null\n this.appendOffset = 0\n this.buffered.clear()\n this._bufferingEnded = false\n this.bufferingQuality = null\n this.playbackQuality = null\n }\n\n /**\n * Finish any partial appends and clear the source buffer.\n */\n private finishAndClearBuffers = async () => {\n if (!this.active) return\n logVerbose(this, 'finishAndClearBuffers')\n await this.sourceBufferController!.clear()\n logVerbose(this, 'finishAndClearBuffers complete')\n }\n\n get disposed(): boolean {\n return this.disposer.disposed\n }\n\n dispose() {\n this.deactivate()\n super.dispose()\n this.disposer.dispose()\n }\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type {\n AnyRecord,\n Disposable,\n ReadonlyAbort,\n ReadonlyEventHost,\n ReadonlyRanges,\n} from '@amazon/vinyl-util'\nimport type { SegmentReference } from './SegmentReference'\nimport type { ChangeEvent } from '../event/ChangeEvent'\nimport type { MediaQualityMetadata } from './MediaQualityMetadata'\n\n/**\n * Forward-snap tolerance, in seconds, applied when looking up a segment by time.\n *\n * If the requested time falls within this window before a segment's `startTime`,\n * that segment is returned rather than treating the gap as uncovered. This absorbs\n * small alignment differences between qualities, where one quality's segment may\n * begin a few milliseconds later than another's at the same logical boundary.\n *\n * Pass to `getSegmentAtTime` (and `MediaQualityData.getSegment`) as the `affordance`\n * argument. Callers resuming streaming after a seek should also bias the requested\n * time *behind* the playhead by at least this amount, so any subsequent appends\n * cover the playhead without leaving a gap. The `SegmentController` clamps negative\n * request times to `0`, so callers don't need to guard against the bias going below\n * the start of the timeline.\n */\nexport const SEGMENT_START_AFFORDANCE = 0.2\n\nexport interface SegmentControllerEventMap {\n /**\n * fetchedRanges have been updated.\n */\n readonly fetchedRangesChange: AnyRecord\n\n /**\n * Emitted when the timeline has changed.\n */\n readonly change: AnyRecord\n\n /**\n * Dispatched when the current streaming quality changes.\n * This is dispatched when a new quality is requested.\n */\n readonly streamingQualityChange: ChangeEvent<MediaQualityMetadata | null>\n}\n\n/**\n * The SegmentController provides segments to buffer for the given time.\n * It is expected to prefetch segments based on the expectation of when the segments will be\n * needed next.\n */\nexport interface ReadonlySegmentController extends ReadonlyEventHost<SegmentControllerEventMap> {\n readonly error: Error | null\n\n /**\n * The time ranges currently fetched.\n */\n readonly fetchedRanges: ReadonlyRanges\n\n /**\n * The most recently requested quality metadata.\n */\n readonly streamingQuality: MediaQualityMetadata | null\n\n /**\n * Returns a Promise for a segment covering the given time, with quality chosen by\n * the configured `QualitySelector`. Resolves to `null` if no media exists at that\n * time. Negative `time` values are clamped to `0`.\n *\n * The lookup forward-snaps by `SEGMENT_START_AFFORDANCE`: if `time` falls within\n * that window before a segment's `startTime`, that segment is returned. This\n * absorbs sub-second segment-boundary differences across qualities so an ABR\n * switch doesn't replay or skip media at the boundary.\n *\n * Calling this also blocks the prefetch queue until the returned promise settles,\n * so the active request is prioritized over background prefetching.\n *\n * @param time The time, in seconds, the requested segment should span.\n * @param abort Aborts the returned promise (rejecting with `AbortError`) and\n * releases the prefetch-queue lock. The underlying network request may continue\n * so its result can still populate the cache.\n */\n getSegment(\n time: number,\n abort?: ReadonlyAbort\n ): Promise<SegmentReference<ArrayBuffer> | null>\n}\n\n/**\n * Configuration the track is expected to provide to the SegmentController.\n */\nexport interface PrefetchOptions {\n /**\n * The prefetching priority of the track. Higher numbers take precedence.\n */\n readonly trackPrefetchPriority: number\n\n /**\n * When the track is inactive, the starting time to prefetch from.\n */\n readonly startTime: number\n}\n\n/**\n * Provides segments for a given time.\n * Handles segment prefetching and caching.\n */\nexport interface SegmentController\n extends ReadonlySegmentController, Disposable {\n /**\n * Configures this segment provider.\n */\n configure(options: Partial<PrefetchOptions>): void\n\n /**\n * Clears the cached segments.\n * Currently pending segment promises will be rejected with an abort reason.\n */\n clear(): void\n\n /**\n * Indicates that this segment provider is providing segments for an active track and should be prioritized\n * accordingly.\n */\n activate(): void\n\n /**\n * Indicates that this segment provider is providing segments for an inactive track.\n */\n deactivate(): void\n\n /**\n * Resets failed segments to a pending state.\n */\n reset(): void\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { Mutable, Unsubscribe } from '@amazon/vinyl-util'\nimport {\n Abort,\n clone,\n closeTo,\n createDisposer,\n EventHostImpl,\n getNetworkState,\n getOrSet,\n isSilentError,\n logDebug,\n logError,\n noop,\n type Range,\n rangeIntersects,\n RangesImpl,\n type ReadonlyAbort,\n type ReadonlyRanges,\n throttle,\n withAbort,\n} from '@amazon/vinyl-util'\nimport type { ReadonlyPlaybackController } from '../playback/ReadonlyPlaybackController'\nimport {\n type PrefetchOptions,\n SEGMENT_START_AFFORDANCE,\n type SegmentController,\n type SegmentControllerEventMap,\n} from './SegmentController'\nimport {\n type SegmentDataProvider,\n SegmentDataSlot,\n SegmentStatus,\n} from './SegmentDataSlot'\nimport {\n defaultTrackPriority,\n enqueueSegmentPrefetch,\n immediatePrefetchPriority,\n type SegmentPrefetchPriority,\n} from './SegmentPrefetch'\nimport {\n getSegmentAtTime,\n getSegmentInsertionIndexAtTime,\n} from './util/segment'\nimport type { SegmentReference } from './SegmentReference'\nimport type { ContentType, MediaQualityMetadata } from './MediaQualityMetadata'\nimport type { ObservableValue } from '@amazon/vinyl-observable'\nimport type { MediaTimeline } from './MediaTimeline'\nimport { getMediaPeriodAtTime, type MediaPeriod } from './MediaTimeline'\nimport type { PrefetchState, QualitySelector } from './abr/QualitySelector'\n\n/**\n * The interval to check if additional segments should be prefetched.\n */\nexport const PREFETCH_POLL_THROTTLE = 1\n\nexport interface SegmentControllerImplDeps {\n readonly playbackController: ReadonlyPlaybackController\n\n readonly mediaTimelineTransformed: ObservableValue<Promise<MediaTimeline>>\n\n readonly qualitySelector: QualitySelector\n}\n\nexport interface SegmentControllerImplOptions {\n /**\n * The amount of time ahead of the playhead to prefetch when the track is active.\n * Default: 240\n */\n readonly prefetchActive: number\n\n /**\n * The amount of time to prefetch when the track is not active.\n * Default: 20\n */\n readonly prefetchInactive: number\n\n /**\n * The number of seconds behind the playhead to retain segments.\n * Default: 30\n */\n readonly retainTail: number\n}\n\nexport const defaultSegmentControllerBaseOptions: SegmentControllerImplOptions =\n {\n prefetchActive: 180,\n prefetchInactive: 20,\n retainTail: 30,\n }\n\n/**\n * Default SegmentController implementation.\n * Provides segments for a given time.\n * Handles segment prefetching and caching.\n *\n * Uses mediaTimelineTransformed to resolve segments directly from the MediaTimeline.\n */\nexport class SegmentControllerImpl\n extends EventHostImpl<SegmentControllerEventMap>\n implements SegmentController\n{\n get [Symbol.toStringTag](): string {\n return 'SegmentControllerImpl'\n }\n\n private _active = false\n get active(): boolean {\n return this._active\n }\n\n private readonly _fetchedRanges = /* @__PURE__ */ new RangesImpl()\n private _startTime = 0\n\n /**\n * A map of decoder id to init segment slots.\n * This allows representations with seamless bitstream switching to share initialization segments without\n * making unnecessary requests or decoder re-initializations.\n */\n private readonly cachedInitSegments = /* @__PURE__ */ new Map<string, SegmentDataSlot>()\n private readonly cachedSegments: SegmentReference<SegmentDataSlot>[] = []\n\n private readonly disposer = /* @__PURE__ */ createDisposer()\n readonly options: SegmentControllerImplOptions\n\n private prefetchingPriority: Mutable<SegmentPrefetchPriority> =\n /* @__PURE__ */ clone(defaultTrackPriority)\n\n /**\n * True if the last segment in the prefetch range has been cached.\n */\n private ended = false\n private prefetching = false\n private _error: Error | null = null\n\n private timeUpdateSub: Unsubscribe | null = null\n private seekingSub: Unsubscribe | null = null\n\n // When disposed, aborts in-flight operations.\n private readonly abort = /* @__PURE__ */ new Abort()\n\n /**\n * Cached last period lookup for fast repeated access.\n */\n private _cachedPeriod: MediaPeriod | null = null\n\n constructor(\n readonly deps: SegmentControllerImplDeps,\n readonly contentType: ContentType,\n options?: Partial<SegmentControllerImplOptions>\n ) {\n super()\n logDebug(this, 'constructed')\n const { add } = this.disposer\n this.options = {\n ...defaultSegmentControllerBaseOptions,\n ...options,\n }\n add(\n deps.mediaTimelineTransformed.onData(() => {\n // If the media timeline changes, re-check ended state.\n this.ended = false\n this._cachedPeriod = null\n this.pollPrefetch()\n this.dispatch('change', {})\n })\n )\n\n add(\n getNetworkState().on('online', () => {\n logDebug(this, 'online, resetting prefetch')\n this.reset()\n })\n )\n }\n\n get error(): Error | null {\n return this._error\n }\n\n /**\n * Gets the period at the given time, using a cache for the last returned period.\n */\n private async getPeriodAtTime(time: number): Promise<MediaPeriod | null> {\n if (\n this._cachedPeriod &&\n time >= this._cachedPeriod.startTime &&\n time < this._cachedPeriod.endTime\n ) {\n return this._cachedPeriod\n }\n const timeline = await this.deps.mediaTimelineTransformed.value\n const period = getMediaPeriodAtTime(timeline, time)\n if (period) this._cachedPeriod = period\n return period\n }\n\n /**\n * Configures this segment provider and initiates prefetching.\n * This may be called multiple times, for example when re-using a cached track a new track priority and start time\n * can be provided.\n */\n configure(options: Partial<PrefetchOptions>) {\n if (options.startTime != null) this._startTime = options.startTime\n if (options.trackPrefetchPriority != null)\n this.prefetchingPriority.trackPriority =\n options.trackPrefetchPriority\n this.ended = false\n this.pollPrefetch()\n }\n\n get startTime(): number {\n return this._startTime\n }\n\n get trackPrefetchPriority(): number {\n return this.prefetchingPriority.trackPriority\n }\n\n /**\n * Returns the range that should be prefetched.\n */\n private get prefetchRange(): Range {\n return this.active\n ? this.prefetchRangeActive\n : this.prefetchRangeInactive\n }\n\n /**\n * Returns the range that should be prefetched when inactive.\n * This range will not be removed during sweeps unless `clear` is called.\n */\n private get prefetchRangeInactive(): Range {\n const prefetchFrom = this.startTime\n const prefetchTo = prefetchFrom + this.options.prefetchInactive\n return [prefetchFrom, prefetchTo]\n }\n\n /**\n * Returns the range that should be prefetched while active.\n */\n private get prefetchRangeActive(): Range {\n const prefetchFrom = this.deps.playbackController.currentTime\n const prefetchTo = prefetchFrom + this.options.prefetchActive\n return [prefetchFrom, prefetchTo]\n }\n\n /**\n * Clears data segments no longer within the current prefetch range.\n * Init segments will not be changed.\n */\n private sweepCachedSegments() {\n // The inactive range (typically first couple segments of a track) will not be removed.\n const inactiveRange = this.prefetchRangeInactive\n\n // The active range prefetch expanded to include the retain tail will not be removed if the track is active.\n const activeRange = this.active\n ? ([\n this.prefetchRangeActive[0] - this.options.retainTail,\n this.prefetchRangeActive[1],\n ] as const)\n : null\n let n = this.cachedSegments.length\n for (let i = 0; i < n; i++) {\n const cachedSegment = this.cachedSegments[i]\n // Check if the cached segment is still within our retain window.\n const { startTime, endTime } = cachedSegment\n const cachedRange = [startTime, endTime] as const\n if (\n !rangeIntersects(inactiveRange, cachedRange) &&\n !(activeRange && rangeIntersects(activeRange, cachedRange))\n ) {\n // No longer need the segment. Does nothing if inactive.\n cachedSegment.data.clear()\n this.cachedSegments.splice(i, 1)\n logDebug(\n this,\n 'removing cached segment at: ',\n cachedSegment.startTime\n )\n i--\n n--\n }\n }\n }\n\n /**\n * Gets the next time to prefetch, or null if the prefetch range has been filled.\n */\n private getNextTimeToPrefetch(): number | null {\n const [prefetchFrom, prefetchTo] = this.prefetchRange\n // fetchedRanges are directly from the segments, safe to use when getting next segment.\n const currentRange = this.fetchedRanges.getRangeAt(prefetchFrom)\n const nextTime = currentRange == null ? prefetchFrom : currentRange[1]\n if (nextTime >= prefetchTo - Number.EPSILON) return null\n return nextTime\n }\n\n private pollPrefetch = /* @__PURE__ */ this.disposer.add(\n /* @__PURE__ */ throttle(\n () => {\n if (this.error) return\n this.sweepCachedSegments()\n if (this.ended || this.prefetching) return\n\n const nextTime = this.getNextTimeToPrefetch()\n if (nextTime == null) return // Prefetched the full range\n this.prefetching = true\n // Enqueue the prefetch.\n enqueueSegmentPrefetch(\n async () => {\n this.abort.throwIfAborted()\n // Quality selection is done at the time of getSegment(), which is called when\n // a slot is created. Defer slot creation until request is about to be made.\n logDebug(this, `Prefetching`, nextTime.toFixed(4))\n const slot = await this.getSlotAtTime(nextTime)\n this.abort.throwIfAborted()\n if (!slot) {\n logDebug(this, 'prefetch ended')\n this.ended = true\n return\n }\n await withAbort(\n Promise.all([\n slot.initData.request(),\n slot.data.request(),\n ]),\n this.abort\n )\n },\n this.contentType,\n this.prefetchingPriority\n )\n .catch(this.prefetchErrorHandler)\n .finally(() => {\n this.prefetching = false\n if (!this.disposed) this.pollPrefetch()\n })\n },\n PREFETCH_POLL_THROTTLE,\n {\n leading: true,\n trailing: true,\n }\n )\n )\n\n private prefetchErrorHandler = (error: any) => {\n // Only log the error for prefetch failures, it will get reported if/when it is attempted\n // to be buffered.\n if (!isSilentError(error)) {\n logError(this, 'Error prefetching segment', error)\n this._error = error\n }\n }\n\n get fetchedRanges(): ReadonlyRanges {\n return this._fetchedRanges\n }\n\n /**\n * Gets the number of seconds currently prefetched.\n */\n get fetchedTime(): number {\n const time = this.active\n ? this.deps.playbackController.currentTime\n : this._startTime\n const currentRange = this.fetchedRanges.getRangeAt(time)\n if (!currentRange) return 0\n return currentRange[1] - time\n }\n\n private _streamingQuality: MediaQualityMetadata | null = null\n\n get streamingQuality(): MediaQualityMetadata | null {\n return this._streamingQuality\n }\n\n private set streamingQuality(value: MediaQualityMetadata | null) {\n const previous = this._streamingQuality\n if (value?.qualityId === previous?.qualityId) return\n this._streamingQuality = value\n logDebug(this, 'streamingQualityChange', value)\n this.dispatch('streamingQualityChange', {\n previous,\n current: value,\n })\n }\n\n getSegment(\n time: number,\n abort?: ReadonlyAbort\n ): Promise<SegmentReference<ArrayBuffer> | null> {\n logDebug(this, `requesting segment at time: ${time.toFixed(4)}`)\n const segmentReferencePromise = withAbort(\n this._getSegment(Math.max(0, time)),\n abort\n )\n\n // When a segment is actively needed, block the prefetch queue until the active segment promise settles:\n enqueueSegmentPrefetch(\n () => segmentReferencePromise,\n this.contentType,\n immediatePrefetchPriority\n ).catch(noop)\n return segmentReferencePromise\n }\n\n private async _getSegment(\n time: number\n ): Promise<SegmentReference<ArrayBuffer> | null> {\n const streamingSlot = await this.getSlotAtTime(time)\n if (!streamingSlot) return null\n logDebug(\n this,\n `init status: ${streamingSlot.initData.status}, data status: ${streamingSlot.data.status}`\n )\n // If prefetch failed, try again now that the segment is actively needed:\n this.resetSlot(streamingSlot)\n\n const initAndDataPromise = Promise.all([\n streamingSlot.initData.request(),\n streamingSlot.data.request(),\n ])\n\n // If the requested time is close to the start of the next segment, immediately start prefetching the next\n // segment, and not resolving until both are cached.\n let minBufferPrefetch: Promise<void> = Promise.resolve()\n const minBufferTime = await this.getMinBufferTime()\n if (streamingSlot.endTime - time < minBufferTime) {\n minBufferPrefetch = this.prefetchImmediate(\n streamingSlot.endTime\n ).catch(noop) // Ignore error until it is the next segment needed\n }\n const [initData, data] = await initAndDataPromise\n await minBufferPrefetch\n return {\n ...streamingSlot,\n initData,\n data,\n }\n }\n\n /**\n * Gets the minimum buffer time from the timeline.\n * Falls back to a reasonable default.\n */\n private async getMinBufferTime(): Promise<number> {\n const timeline = await this.deps.mediaTimelineTransformed.value\n return timeline.minBufferTime\n }\n\n /**\n * Prefetches the segment at the given time. Does not use the background scheduler.\n *\n * @param time\n */\n private async prefetchImmediate(time: number): Promise<void> {\n const slot = await this.getSlotAtTime(time)\n if (!slot) return\n await Promise.all([slot.initData.request(), slot.data.request()])\n }\n\n /**\n * Gets a streaming segment slot that spans the given time, or null if there is no media at that time.\n * Slots will be cached until they slide out of the retention range or `clear` is called.\n */\n private async getSlotAtTime(\n time: number\n ): Promise<SegmentReference<SegmentDataSlot> | null> {\n // Check if there is a cached slot.\n const cachedSegment = getSegmentAtTime(\n time,\n this.cachedSegments,\n SEGMENT_START_AFFORDANCE\n )\n if (cachedSegment) return cachedSegment\n\n const newSlot = await withAbort(\n this.createSlotForTime(time),\n this.abort\n )\n this.abort.throwIfAborted()\n\n if (!newSlot) return null\n newSlot.data.onStatusChange = () => {\n // When the data segment settles, update the fetched ranges.\n if (newSlot.data.status === SegmentStatus.RESOLVED)\n this._fetchedRanges.add(newSlot.startTime, newSlot.endTime)\n else if (newSlot.data.status === SegmentStatus.INACTIVE)\n this._fetchedRanges.remove(newSlot.startTime, newSlot.endTime)\n this.dispatch('fetchedRangesChange', {})\n }\n\n // Insert the slot, in order.\n const insertionIndex = getSegmentInsertionIndexAtTime(\n newSlot.startTime,\n this.cachedSegments\n )\n\n // Slot creation is asynchronous, to allow requesting index ranges. Check if a slot for this time was already\n // created.\n if (insertionIndex > 0) {\n const cachedSegment = this.cachedSegments[insertionIndex - 1]\n if (closeTo(newSlot.startTime, cachedSegment.startTime)) {\n return cachedSegment\n }\n }\n logDebug(\n this,\n `created slot at ${insertionIndex} for time ${newSlot.startTime.toFixed(4)}`\n )\n this.cachedSegments.splice(insertionIndex, 0, newSlot)\n return newSlot\n }\n\n /**\n * Gets a cached init segment slot for the given decoder id. If a slot is not cached, create one.\n */\n private getOrCreateInitSlot(\n decoderId: string,\n segmentDataProvider: SegmentDataProvider\n ): SegmentDataSlot {\n return getOrSet(this.cachedInitSegments, decoderId, () => {\n return new SegmentDataSlot(segmentDataProvider)\n })\n }\n\n /**\n * Creates a slot that spans the given time, or returns null if there is no media at that time.\n * Uses the mediaTimelineTransformed to resolve segments directly.\n */\n private async createSlotForTime(\n time: number\n ): Promise<SegmentReference<SegmentDataSlot> | null> {\n const period = await this.getPeriodAtTime(time)\n if (!period) return null\n\n // Filter qualities to this content type.\n const filteredQualities = period.qualities.filter(\n (q) => q.metadata.contentType === this.contentType\n )\n if (filteredQualities.length === 0) return null\n\n // Gets the preceding segment encoding metadata for quality selection.\n let previousQuality: MediaQualityMetadata | null = null\n const previousIndex =\n getSegmentInsertionIndexAtTime(time, this.cachedSegments) - 1\n if (previousIndex >= 0)\n previousQuality = this.cachedSegments[previousIndex].quality\n\n const prefetchState: PrefetchState = {\n fetchedTime: this.fetchedTime,\n previousQuality,\n active: this.active,\n }\n\n const metadataArray = filteredQualities.map((q) => q.metadata)\n const index = this.deps.qualitySelector.selectQuality(\n metadataArray,\n prefetchState\n )\n const selectedQuality = filteredQualities[index]\n\n const segment = await selectedQuality.getSegment(\n time,\n SEGMENT_START_AFFORDANCE\n )\n this.abort.throwIfAborted()\n this.streamingQuality = segment?.quality ?? null\n if (!segment) return null\n\n return {\n ...segment,\n quality: segment.quality,\n initData: this.getOrCreateInitSlot(\n segment.quality.decoderId,\n segment.initData\n ),\n data: new SegmentDataSlot(segment.data),\n }\n }\n\n /**\n * Indicates that this segment provider is providing segments for an active track and should be prioritized\n * accordingly.\n * Time ranges to be prefetched will change to the active prefetch window.\n */\n activate(): void {\n if (this._active) return\n logDebug(this, 'activate')\n this._active = true\n this.pollPrefetch()\n const playbackController = this.deps.playbackController\n this.timeUpdateSub = playbackController.on(\n 'timeUpdate',\n this.pollPrefetch\n )\n this.seekingSub = playbackController.on('seeking', () => {\n this.ended = false\n this._error = null\n this.pollPrefetch()\n })\n }\n\n /**\n * Deactivates the segment provider.\n * This clears cached segments not within the inactive prefetch range.\n * Time ranges to be prefetched will change to the inactive prefetch window.\n */\n deactivate(): void {\n if (!this._active) return\n logDebug(this, 'deactivate')\n this._active = false\n this.sweepCachedSegments()\n this.timeUpdateSub!()\n this.timeUpdateSub = null\n this.seekingSub!()\n this.seekingSub = null\n }\n\n clear(): void {\n logDebug(this, 'clear')\n this.cachedSegments.forEach((slot) => {\n slot.data.onStatusChange = null\n slot.data.clear()\n slot.initData.clear()\n })\n this.cachedSegments.length = 0\n this.cachedInitSegments.clear()\n this._fetchedRanges.clear()\n this.ended = false\n this._error = null\n this._cachedPeriod = null\n if (!this.disposed) this.pollPrefetch()\n this.dispatch('fetchedRangesChange', {})\n }\n\n reset(): void {\n logDebug(this, 'reset')\n this.cachedSegments.forEach((slot) => this.resetSlot(slot))\n this._error = null\n this.pollPrefetch()\n }\n\n /**\n * Resets the slot if it's in an error state.\n * @param slot\n */\n private resetSlot(slot: SegmentReference<SegmentDataSlot>) {\n if (slot.data.status === SegmentStatus.ERRED) {\n logDebug(this, 'resetting failed segment at time:', slot.startTime)\n this.ended = false\n slot.data.clear()\n }\n if (slot.initData.status === SegmentStatus.ERRED) {\n logDebug(this, 'resetting failed init segment')\n this.ended = false\n slot.initData.clear()\n }\n }\n\n get disposed(): boolean {\n return this.disposer.disposed\n }\n\n dispose(): void {\n logDebug(this, 'disposing')\n super.dispose()\n this.disposer.dispose()\n this.deactivate()\n this.clear()\n this.abort.abort()\n }\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { Disposable, Maybe } from '@amazon/vinyl-util'\nimport {\n createAbortSlot,\n isSilentError,\n type ReadonlyAbort,\n} from '@amazon/vinyl-util'\n\nexport enum SegmentStatus {\n /**\n * This segment has not been requested.\n */\n INACTIVE = 'inactive',\n\n /**\n * The segment has been requested but not yet completed.\n */\n PENDING = 'pending',\n\n /**\n * The segment has finished requesting.\n */\n RESOLVED = 'resolved',\n\n /**\n * The segment failed to load.\n */\n ERRED = 'erred',\n}\n\n/**\n * A function that returns a promise to segment data.\n */\nexport type SegmentDataProvider = (\n abort?: Maybe<ReadonlyAbort>\n) => Promise<ArrayBuffer>\n\n/**\n * A SegmentSlot is a holder for a segment buffer. It may be requested, cleared, and its status observed.\n */\nexport class SegmentDataSlot implements Disposable {\n /**\n * Called when the status has changed.\n */\n onStatusChange: (() => void) | null = null\n\n private _status: SegmentStatus = SegmentStatus.INACTIVE\n private readonly abortSlot = /* @__PURE__ */ createAbortSlot()\n\n private bufferPromise: Promise<ArrayBuffer> | null = null\n\n constructor(private readonly requestSegmentData: SegmentDataProvider) {}\n\n /**\n * This segment's request status.\n */\n get status(): SegmentStatus {\n return this._status\n }\n\n private set status(value: SegmentStatus) {\n this._status = value\n if (this.onStatusChange) this.onStatusChange()\n }\n\n /**\n * Aborts the request if the status is currently {@link SegmentStatus.PENDING}, and clears the cached buffer.\n * The status will go back to {@link SegmentStatus.INACTIVE} and the segment may be requested again in the future.\n */\n clear(): void {\n if (this.status === SegmentStatus.INACTIVE) return\n this.abortSlot.abort()\n this.bufferPromise = null\n this.status = SegmentStatus.INACTIVE\n }\n\n /**\n * Begins the segment request now if it has not already been requested.\n * The promise returned will settle after this slot's status has updated and onStatusChange callback invoked.\n */\n request(): Promise<ArrayBuffer> {\n if (!this.bufferPromise) {\n this.status = SegmentStatus.PENDING\n\n // Chains status handling to the promise returned by requestSegment.\n this.bufferPromise = this.requestSegmentData(this.abortSlot.value)\n .then((result) => {\n this.status = SegmentStatus.RESOLVED\n return result\n })\n .catch((error) => {\n if (isSilentError(error)) {\n // Allows this data slot to be requested again.\n this.bufferPromise = null\n this.status = SegmentStatus.INACTIVE\n } else {\n // A higher severity error, do not try again.\n this.status = SegmentStatus.ERRED\n }\n throw error\n })\n }\n return this.bufferPromise\n }\n\n /**\n * Clears this segment and removes its handler.\n */\n dispose(): void {\n this.clear()\n this.onStatusChange = null\n }\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { Task, TaskQueue } from '@amazon/vinyl-util'\nimport {\n type Comparator,\n compareBy,\n createTaskQueue,\n globalRef,\n} from '@amazon/vinyl-util'\nimport type { ContentType } from './MediaQualityMetadata'\n\n/**\n * Properties affecting segment prefetch priority.\n * Each track when prefetching will only add one segment to the prefetch queue at a time.\n */\nexport interface SegmentPrefetchPriority {\n /**\n * The track's prefetch priority.\n */\n readonly trackPriority: number\n\n /**\n * The starting time of the segment.\n */\n readonly segmentStartTime: number\n\n /**\n * The time position prefetching starts for this segment's track.\n */\n readonly prefetchStartTime: number\n}\n\nexport const defaultTrackPriority = {\n // Default priority is lowest, but not used. Use enqueueSegmentPrefetch to enqueue.\n trackPriority: 0,\n segmentStartTime: 9007199254740991, // Number.MAX_SAFE_INTEGER,\n prefetchStartTime: 0,\n} as const satisfies SegmentPrefetchPriority\n\n/**\n * Highest priority; used to block prefetching while an actively-needed operation is enqueued.\n */\nexport const immediatePrefetchPriority = {\n trackPriority: 9007199254740991, // Number.MAX_SAFE_INTEGER,\n segmentStartTime: 0,\n prefetchStartTime: 0,\n}\n\n/**\n * A comparator for segment prefetching.\n * Given tracks A, B, and C with track priorities 1, 2, and 3 respectively:\n * The expected prefetch order will be:\n *\n * A0\n * B0 // \"lean forward\" case\n * C0 // \"lean forward\" case\n * A1 ... An\n * B1 ... Bn\n * C1 ... Cn\n *\n * Note that background prefetching is in parallel to prefetching for the active track.\n */\nexport const segmentPriorityComparatorRef = /* @__PURE__ */ globalRef<\n Comparator<SegmentPrefetchPriority>\n>(() => {\n return compareBy(\n (e) => {\n // First segments always take priority over subsequent ones.\n return e.segmentStartTime <= e.prefetchStartTime ? 0 : 1\n },\n // Next, consider track priority.\n (e) => -e.trackPriority\n )\n})\n\n// Task queues for each content type\nexport const prefetchPriorityQueuesRef = /* @__PURE__ */ globalRef<\n Record<ContentType, TaskQueue<SegmentPrefetchPriority>>\n>(() => {\n return {\n video: createTaskQueue<SegmentPrefetchPriority>(\n segmentPriorityComparatorRef.value,\n defaultTrackPriority\n ),\n audio: createTaskQueue<SegmentPrefetchPriority>(\n segmentPriorityComparatorRef.value,\n defaultTrackPriority\n ),\n text: createTaskQueue<SegmentPrefetchPriority>(\n segmentPriorityComparatorRef.value,\n defaultTrackPriority\n ),\n }\n})\n\n/**\n * Enqueues a task to request a streaming segment for a specific content type.\n * This should only be used for low priority background requests. Active tracks should request without\n * prioritization for the immediately needed segment.\n * Tracks are expected to prefetch one segment at a time, in order.\n *\n * @param requestTask\n * @param contentType\n * @param priority\n */\nexport function enqueueSegmentPrefetch(\n requestTask: Task<any>,\n contentType: ContentType,\n priority: SegmentPrefetchPriority\n): Promise<void> {\n return prefetchPriorityQueuesRef.value[contentType].enqueue(\n requestTask,\n priority\n )\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { sortedInsertionIndex } from '@amazon/vinyl-util'\nimport type { MediaSegmentMetadata } from '../SegmentReference'\n\n/**\n * Returns the segment whose range covers `time` (`startTime <= time < endTime`), or\n * \u2014 when `affordance > 0` \u2014 the next segment if `time` falls within `affordance`\n * seconds before its `startTime`. Returns `null` if neither applies.\n *\n * Note: with `affordance > 0`, when `time` lies in the last `affordance` seconds of a\n * segment that does cover it, the *next* segment is returned instead. This is\n * deliberate \u2014 callers use `affordance` to absorb sub-second boundary differences\n * across qualities \u2014 but it means the result is not strictly the segment containing\n * `time`. Callers needing exact containment should pass `affordance = 0`.\n *\n * @param time Lookup time, in seconds.\n * @param segments Segments sorted by `startTime` ascending.\n * @param affordance Forward-snap tolerance in seconds: if `time` falls just before a\n * segment's `startTime` (within `affordance`), that segment is returned. The original\n * `time` is still compared against `endTime`, so coverage never extends past it.\n */\nexport function getSegmentAtTime<T extends MediaSegmentMetadata>(\n time: number,\n segments: readonly T[],\n affordance = 0\n): T | null {\n const index =\n getSegmentInsertionIndexAtTime(time + affordance, segments) - 1\n if (index < 0) return null\n const segment = segments[index]\n return time >= segment.endTime ? null : segment\n}\n\n/**\n * Returns the count of segments whose `startTime <= time` \u2014 i.e. the index at which a\n * segment with that `startTime` would be inserted to keep the array sorted ascending.\n *\n * @param time Lookup time, in seconds.\n * @param segments Segments sorted by `startTime` ascending.\n */\nexport function getSegmentInsertionIndexAtTime(\n time: number,\n segments: readonly MediaSegmentMetadata[]\n): number {\n return sortedInsertionIndex(\n segments,\n time,\n (time, element) => time - element.startTime\n )\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { MediaSourceController } from '../../streaming/buffering/MediaSourceController'\nimport type { PlaybackController } from '../../playback/PlaybackController'\nimport type { QualitySelector } from '../../streaming/abr/QualitySelector'\nimport type { ObservableValue } from '@amazon/vinyl-observable'\nimport { type ContentStreamImplDeps } from '../../streaming/ContentStream'\nimport type { ContentType } from '../../streaming/MediaQualityMetadata'\nimport {\n SourceBufferControllerImpl,\n type SourceBufferControllerImplDeps,\n} from '../../streaming/buffering/SourceBufferController'\nimport {\n BufferingControllerImpl,\n type BufferingControllerImplDeps,\n} from '../../streaming/buffering/BufferingController'\nimport {\n SegmentControllerImpl,\n type SegmentControllerImplDeps,\n} from '../../streaming/SegmentControllerImpl'\nimport { type Maybe, memoize } from '@amazon/vinyl-util'\nimport {\n externalDependencies,\n type Factories,\n validateFactories,\n} from '@amazon/vinyl-di'\nimport type { ContentStreamingOptions } from '../../streaming/ContentStreamingOptions'\nimport type { MediaTimeline } from '../../streaming/MediaTimeline'\n\n/**\n * Dependencies needed for a new content stream provided by the dash track.\n */\nexport interface DashContentStreamTrackDeps {\n readonly mediaSourceController: MediaSourceController\n readonly playbackController: PlaybackController\n readonly mediaTimelineTransformed: ObservableValue<Promise<MediaTimeline>>\n readonly qualitySelector: QualitySelector\n}\n\n/**\n * Returns a function to produce the Factories needed for a new ContentStreamImpl.\n */\nexport function createDashContentStreamFactories(\n options: Maybe<ContentStreamingOptions>\n) {\n return (deps: DashContentStreamTrackDeps) =>\n memoize(\n (contentType: ContentType) => {\n return validateFactories({\n ...externalDependencies(deps),\n sourceBufferControllerFactory:\n (deps: SourceBufferControllerImplDeps) => () =>\n new SourceBufferControllerImpl(deps, contentType),\n bufferingController: (deps: BufferingControllerImplDeps) =>\n new BufferingControllerImpl(\n deps,\n contentType,\n options?.buffering\n ),\n segmentController: (deps: SegmentControllerImplDeps) =>\n new SegmentControllerImpl(\n deps,\n contentType,\n options?.segmentController\n ),\n } as const) satisfies Factories<ContentStreamImplDeps>\n },\n (contentType) => contentType\n )\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { PrefetchState, QualitySelector } from './QualitySelector'\nimport {\n clamp,\n createDisposer,\n createLogPrefix,\n type Disposable,\n getNetworkMetrics,\n type LogTarget,\n lerp,\n type Maybe,\n} from '@amazon/vinyl-util'\nimport {\n boolean,\n enumOf,\n number,\n object,\n type ObjectSchema,\n} from '@amazon/vinyl-validation'\nimport type { MediaQualityMetadata } from '../MediaQualityMetadata'\nimport type { ObservableValue } from '@amazon/vinyl-observable'\n\nexport interface QualitySelectorImplOptions {\n /**\n * If at least this amount of time (in seconds) is currently fetched, don't consider an ABR-down.\n * Also used as the upper bound for interpolating between {@link bandwidthMultiplierLow} and\n * {@link bandwidthMultiplierHigh} based on the current fetched time.\n * Default: 15\n */\n readonly highBufferThreshold?: number\n\n /**\n * If less than this amount of time (in seconds) is currently fetched, don't consider an ABR-up.\n * Default: 4\n */\n readonly lowBufferThreshold?: number\n\n /**\n * Defines the strategy used for quality selection.\n *\n * Default: BEST (ABR will be enabled)\n */\n readonly strategy?: AbrStrategy\n\n /**\n * A multiplier applied to the estimated bandwidth when the fetched buffer is empty (0 seconds).\n * Lower values are more conservative (reduce the bandwidth used for quality selection) and help\n * avoid rebuffers when the buffer is low.\n *\n * As the fetched buffer fills toward {@link highBufferThreshold}, the effective multiplier\n * linearly interpolates between this value and {@link bandwidthMultiplierHigh}.\n *\n * Default: 0.4\n */\n readonly bandwidthMultiplierLow?: number\n\n /**\n * A multiplier applied to the estimated bandwidth when the fetched buffer is at or above\n * {@link highBufferThreshold}. Higher values are more optimistic and allow selection of higher\n * qualities once enough data is buffered to absorb short-term bandwidth dips.\n *\n * As the fetched buffer fills from 0 toward {@link highBufferThreshold}, the effective multiplier\n * linearly interpolates between {@link bandwidthMultiplierLow} and this value.\n *\n * Default: 0.9\n */\n readonly bandwidthMultiplierHigh?: number\n\n /**\n * When true, avoids changing codecs when considering choosing a higher audio bitrate\n * than what is currently playing. A decoder re-initialization is often an audible change,\n * so consumers that prefer to avoid audible artifacts may enable this. ABR-down is still\n * allowed across decoders because the subtle audio artifact is more desirable than a rebuffer.\n * Default: false\n */\n readonly restrictDecoderChangeOnAudioAbrUp?: boolean\n\n /**\n * Maximum bandwidth in bits per second a quality may use to be selectable.\n *\n * Soft cap: if no qualities fit within the limit (including when set to 0),\n * the quality with the lowest bandwidth is selected so playback is still\n * possible.\n *\n * Has no effect when {@link strategy} is {@link AbrStrategy.LOWEST} or\n * {@link AbrStrategy.HIGHEST}, since those strategies pin the selection\n * regardless of bandwidth.\n *\n * Default: null (no limit).\n */\n readonly maxBandwidth?: Maybe<number>\n}\n\nexport enum AbrStrategy {\n /**\n * Selects lowest quality, regardless of bandwidth conditions.\n */\n LOWEST = 'lowest',\n\n /**\n * Selects highest quality, regardless of bandwidth conditions.\n */\n HIGHEST = 'highest',\n\n /**\n * Selects the best quality based on user bandwidth data.\n * Uses an EWMA estimation.\n */\n BEST = 'best',\n\n /**\n * Selects the initial quality based on bandwidth information, but will not change qualities mid-stream.\n *\n * May choose new quality after streaming clear, such as after a seek.\n */\n FIXED = 'fixed',\n}\n\nexport const qualitySelectorImplOptionsValidator: ObjectSchema<QualitySelectorImplOptions> =\n /* @__PURE__ */ object({\n highBufferThreshold: /* @__PURE__ */ /* @__PURE__ */ number().optional(),\n lowBufferThreshold: /* @__PURE__ */ /* @__PURE__ */ number().optional(),\n strategy: /* @__PURE__ */ /* @__PURE__ */ enumOf(AbrStrategy).optional(),\n bandwidthMultiplierLow: /* @__PURE__ */ /* @__PURE__ */ number().optional(),\n bandwidthMultiplierHigh: /* @__PURE__ */ /* @__PURE__ */ number().optional(),\n restrictDecoderChangeOnAudioAbrUp: /* @__PURE__ */ /* @__PURE__ */ boolean().optional(),\n maxBandwidth: /* @__PURE__ */ /* @__PURE__ */ /* @__PURE__ */ number().maybe().optional(),\n })\n\nexport const defaultQualitySelectorImplOptions = {\n highBufferThreshold: 15,\n lowBufferThreshold: 4,\n strategy: AbrStrategy.BEST,\n bandwidthMultiplierLow: 0.4,\n bandwidthMultiplierHigh: 0.9,\n restrictDecoderChangeOnAudioAbrUp: false,\n maxBandwidth: null,\n} as const satisfies QualitySelectorImplOptions\n\nexport interface QualitySelectorImplDeps {\n readonly options: ObservableValue<QualitySelectorImplOptions>\n}\n\nexport class QualitySelectorImpl\n implements QualitySelector, LogTarget, Disposable\n{\n get [Symbol.toStringTag](): string {\n return 'QualitySelectorImpl'\n }\n\n readonly logPrefix = /* @__PURE__ */ createLogPrefix(this)\n private _options: Required<QualitySelectorImplOptions> =\n defaultQualitySelectorImplOptions\n\n private disposer = /* @__PURE__ */ createDisposer()\n\n constructor(deps: QualitySelectorImplDeps) {\n const { add } = this.disposer\n add(\n deps.options.onData((v) => {\n this._options = { ...defaultQualitySelectorImplOptions, ...v }\n })\n )\n }\n\n get options(): Required<QualitySelectorImplOptions> {\n return this._options\n }\n\n selectQuality(\n qualities: readonly MediaQualityMetadata[],\n prefetchState: PrefetchState\n ): number {\n const {\n strategy,\n highBufferThreshold,\n lowBufferThreshold,\n bandwidthMultiplierLow,\n bandwidthMultiplierHigh,\n restrictDecoderChangeOnAudioAbrUp,\n maxBandwidth,\n } = this.options\n const previousQuality = prefetchState.previousQuality\n // previousIndex will be -1 if the previously playing quality is not within the current qualities list.\n const previousIndex =\n previousQuality == null\n ? -1\n : qualities.findIndex(\n (quality) =>\n quality.qualityId === previousQuality.qualityId\n )\n\n if (strategy === AbrStrategy.LOWEST) {\n return qualities.length - 1\n } else if (strategy === AbrStrategy.HIGHEST) {\n return 0\n } else if (strategy === AbrStrategy.FIXED) {\n if (previousIndex >= 0) return previousIndex\n }\n\n const fetchedTime = prefetchState.fetchedTime\n const bandwidthEstimate = getNetworkMetrics().estimatedDownlinkBandwidth\n // Interpolate the bandwidth multiplier between the low and high values based on how much\n // buffer is currently fetched. An empty buffer uses bandwidthMultiplierLow (conservative)\n // to reduce rebuffer risk; a buffer at or above highBufferThreshold uses\n // bandwidthMultiplierHigh (optimistic) since buffered data can absorb short-term dips.\n // The interpolation is linear with respect to the buffer ratio.\n // If the track is not active (i.e. prefetch), always use the high multiplier.\n const bufferRatio =\n highBufferThreshold > 0\n ? clamp(fetchedTime / highBufferThreshold, 0, 1)\n : 1\n const bandwidthMultiplier = prefetchState.active\n ? lerp(bandwidthMultiplierLow, bandwidthMultiplierHigh, bufferRatio)\n : bandwidthMultiplierHigh\n\n // Choose bandwidth based on pessimistic network information.\n // If the track is active, take the lesser of the latest recorded bandwidth stat and the weighted\n // average to allow for fast ABR-down in variable conditions.\n let bandwidth =\n (prefetchState.active\n ? Math.min(bandwidthEstimate.ewmaLow, bandwidthEstimate.latest)\n : bandwidthEstimate.ewmaLow) * bandwidthMultiplier\n\n // Apply the maxBandwidth cap as a soft upper bound on the bandwidth budget.\n if (maxBandwidth != null && maxBandwidth < bandwidth) {\n bandwidth = maxBandwidth\n }\n\n let restrictDecoderId: string | null = null\n let restrictSwitchingGroupIds: readonly string[] | null = null\n if (previousQuality && previousIndex >= 0) {\n // Restrict to qualities whose groupId is in the previous quality's switching group.\n // Null switchingGroupIds means no switching constraint.\n if (previousQuality.switchingGroupIds != null) {\n restrictSwitchingGroupIds = previousQuality.switchingGroupIds\n }\n\n // Intra-track ABR rules\n if (\n previousQuality.bandwidthTotal &&\n bandwidth < previousQuality.bandwidthTotal\n ) {\n // Measured bandwidth lower than current streaming bandwidth.\n if (fetchedTime >= highBufferThreshold) {\n // Do not ABR-down inter-track when there is ample fetched data.\n return previousIndex\n }\n } else {\n if (fetchedTime < lowBufferThreshold) {\n // Do not ABR-up inter-track when there is not enough fetched data.\n return previousIndex\n }\n\n // Measured bandwidth is at least current streaming bandwidth.\n // Restrict to the previous decoder id for audio to avoid an audible artifact\n // from decoder re-initialization.\n if (\n restrictDecoderChangeOnAudioAbrUp &&\n previousQuality.contentType === 'audio'\n ) {\n restrictDecoderId = previousQuality.decoderId\n }\n }\n }\n const index = qualities.findIndex((quality) => {\n if (\n restrictSwitchingGroupIds != null &&\n !restrictSwitchingGroupIds.includes(quality.groupId)\n )\n return false\n if (\n restrictDecoderId != null &&\n quality.decoderId !== restrictDecoderId\n )\n return false\n return (\n quality.bandwidthTotal == null ||\n quality.bandwidthTotal <= bandwidth\n )\n })\n return index === -1 ? qualities.length - 1 : index\n }\n\n get disposed(): boolean {\n return this.disposer.disposed\n }\n\n dispose() {\n this.disposer.dispose()\n }\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { DashTrackDeps, DashTrackLoadOptions } from './DashTrack'\nimport { type Maybe, type RequestInterceptor } from '@amazon/vinyl-util'\nimport { pickFirstBaseUrlSelector } from './util/uriResolution'\nimport { createDefaultDashManifestTransformer } from './createDefaultDashManifestTransformer'\nimport { createMediaSource } from '../../util/media/mediaSource'\nimport {\n createDefaultDashMediaQualityMetadataResolver,\n type DashMediaQualityMetadataResolverDeps,\n} from './DashMediaQualityMetadataResolver'\nimport {\n MediaSourceControllerImpl,\n type MediaSourceControllerImplDeps,\n} from '../../streaming/buffering/MediaSourceController'\nimport type { PlaybackController } from '../../playback/PlaybackController'\nimport {\n type DashManifestController,\n DashManifestControllerImpl,\n type DashManifestControllerImplDeps,\n} from './DashManifestController'\nimport { createDashContentStreamFactories } from './createDashContentStreamFactories'\nimport type { DrmKeySystemResolver } from '../../drm/DrmKeySystemResolver'\nimport type { DrmController } from '../../drm/DrmController'\nimport type { Capabilities } from '../../client/Capabilities'\nimport {\n QualitySelectorImpl,\n type QualitySelectorImplOptions,\n} from '../../streaming/abr/QualitySelectorImpl'\nimport type { PlaybackSource } from '../../playback/PlaybackSource'\nimport {\n externalDependencies,\n type Factories,\n validateFactories,\n} from '@amazon/vinyl-di'\nimport { createDashManifestProvider } from './createDashManifestProvider'\nimport { createContentStreamFactory } from '../../streaming/ContentStream'\nimport type { ContentStreamingOptions } from '../../streaming/ContentStreamingOptions'\nimport { createDashContentTypesValue } from './createDashContentTypesValue'\nimport type { ObservableValue } from '@amazon/vinyl-observable'\nimport type { VinylOptions } from '../../vinyl/VinylOptions'\nimport {\n buildDashMediaTimeline,\n type BuildDashMediaTimelineDeps,\n} from './buildDashMediaTimeline'\nimport { createDefaultMediaTimelineTransformer } from '../../streaming/createDefaultMediaTimelineTransformer'\nimport type { DashManifestData } from './DashManifestProvider'\n\n/**\n * Player-level dependencies needed for the Dash-specific factories.\n */\nexport interface DashFactoryDeps {\n readonly options: ObservableValue<{\n readonly abr: QualitySelectorImplOptions\n readonly preferredAudioLanguage: string | null\n }>\n readonly playbackController: PlaybackController\n readonly playbackSource: PlaybackSource\n readonly drmKeySystemResolver: DrmKeySystemResolver\n readonly requestInterceptor: RequestInterceptor\n readonly drmController: DrmController\n readonly capabilities: Capabilities\n}\n\nexport type DashInitOptions = {\n readonly streaming?: Maybe<ContentStreamingOptions>\n}\n\n/**\n * Returns a function that provides default dependency factories required for\n * a new DashTrack.\n */\nexport function createDashFactories(options: Maybe<DashInitOptions>) {\n return (\n // Player-level dependencies\n deps: DashFactoryDeps\n ) => {\n return (loadOptions: DashTrackLoadOptions) =>\n validateFactories({\n // Track-level dependencies\n ...externalDependencies(deps),\n\n contentTypesValue: createDashContentTypesValue,\n baseUrlSelector: () => pickFirstBaseUrlSelector,\n segmentRequestInit: () => loadOptions.segmentRequestInit,\n manifestProvider: createDashManifestProvider(loadOptions),\n manifestController: (\n deps: DashManifestControllerImplDeps\n ): DashManifestController =>\n new DashManifestControllerImpl(deps),\n mediaSourceFactory: () => createMediaSource,\n mediaQualityMetadataResolver: (\n deps: DashMediaQualityMetadataResolverDeps\n ) => createDefaultDashMediaQualityMetadataResolver(deps),\n mediaSourceController: (deps: MediaSourceControllerImplDeps) =>\n new MediaSourceControllerImpl(deps),\n\n createContentStreamFactories: createDashContentStreamFactories(\n options?.streaming\n ),\n contentStreamFactory: createContentStreamFactory,\n\n qualitySelector: (deps: {\n options: ObservableValue<Pick<VinylOptions, 'abr'>>\n }) =>\n new QualitySelectorImpl({\n options: deps.options.pick('abr'),\n }),\n manifestTransformed: createDefaultDashManifestTransformer,\n mediaTimeline: (\n deps: BuildDashMediaTimelineDeps & {\n readonly manifestTransformed: ObservableValue<\n Promise<DashManifestData>\n >\n }\n ) =>\n deps.manifestTransformed.map(async (manifestPromise) => {\n const data = await manifestPromise\n return buildDashMediaTimeline(deps, data)\n }),\n mediaTimelineTransformed: createDefaultMediaTimelineTransformer,\n } as const) satisfies Factories<DashTrackDeps>\n }\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { Maybe } from '@amazon/vinyl-util'\nimport type { RequestInitOptions } from '@amazon/vinyl-util'\nimport type {\n MutableRequestParams,\n RequestInterceptor,\n} from '@amazon/vinyl-util'\nimport { noop } from '@amazon/vinyl-util'\nimport { clone, getLocation, resolveUrl } from '@amazon/vinyl-util'\nimport { requestWithRetry } from '@amazon/vinyl-util'\nimport { parseDashManifest } from '@amazon/vinyl-mpd-parser'\nimport type { DashManifestProvider } from './DashManifestProvider'\n\n/**\n * Creates a DashManifestProvider which performs a request to retrieve a dash manifest.\n * Can be a relative path.\n *\n * Usage example:\n *\n * ```createRequesterDashManifestProvider('https://example.com/manifest.mpd')```\n * @param input The resource location of the dash manifest.\n * @param init Optional request options such as headers.\n * @param requestInterceptor An optional transformer to mutate request parameters before the request is made.\n */\nexport function urlDashManifestProvider(\n input: string,\n init?: Maybe<RequestInitOptions>,\n requestInterceptor: RequestInterceptor = noop\n): DashManifestProvider {\n return async (abort) => {\n const params: MutableRequestParams = {\n input: resolveUrl(input, getLocation().href),\n init: clone(init) ?? {},\n }\n requestInterceptor(params)\n const response = await requestWithRetry(params.input, params.init, {\n abort,\n })\n const xml = await response.text()\n const manifest = parseDashManifest(xml)\n const baseInput = response.url || params.input\n return {\n manifest,\n baseUrl: resolveUrl('./', baseInput),\n }\n }\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { DashTrackLoadOptions } from './DashTrack'\nimport { urlDashManifestProvider } from './urlDashManifestProvider'\nimport type { RequestInterceptor } from '@amazon/vinyl-util'\n\n/**\n * Creates a DashManifestProvider which uses the manifestProvider set on the loadOptions, or a urlDashManifestProvider\n * if unset, which will use the loadOptions.uri as the manifest location.\n *\n * @param loadOptions\n */\nexport function createDashManifestProvider(loadOptions: DashTrackLoadOptions) {\n return (deps: { readonly requestInterceptor: RequestInterceptor }) => {\n return loadOptions.manifestProvider\n ? loadOptions.manifestProvider\n : urlDashManifestProvider(\n loadOptions.uri,\n loadOptions.requestInit,\n deps.requestInterceptor\n )\n }\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {\n createDisposer,\n type Disposable,\n EventHostImpl,\n type Maybe,\n type ReadonlyEventHost,\n type ReadonlyRanges,\n redispatchEvents,\n} from '@amazon/vinyl-util'\nimport type { StreamingEventMap } from './StreamingEventMap'\nimport type { SegmentController } from './SegmentController'\nimport type { BufferingController } from './buffering/BufferingController'\nimport type { ContentType, MediaQualityMetadata } from './MediaQualityMetadata'\nimport { createContainer, type Factories } from '@amazon/vinyl-di'\n\n/**\n * Creates a new ContentStream for the given content type.\n */\nexport type ContentStreamFactory = (contentType: ContentType) => ContentStream\n\nexport interface ContentStream\n extends ReadonlyEventHost<StreamingEventMap>, Disposable {\n /**\n * The content type for this stream.\n * E.g. 'audio' or 'video'\n */\n readonly contentType: ContentType\n\n /**\n * The prefetched time ranges.\n */\n readonly fetchedRanges: ReadonlyRanges\n\n /**\n * The quality currently being requested.\n */\n readonly streamingQuality: MediaQualityMetadata | null\n\n /**\n * The quality of the currently buffered media for this stream.\n */\n readonly bufferingQuality: MediaQualityMetadata | null\n\n /**\n * The quality for the currently buffered media at currentTime for this stream.\n */\n readonly playbackQuality: MediaQualityMetadata | null\n\n /**\n * The error, if in an error state.\n */\n readonly error: Error | null\n\n /**\n * True if the last segment has been appended.\n */\n readonly bufferingEnded: boolean\n\n /**\n * Starts prefetching with the given priority and prefetch start time.\n * @param options\n */\n preload(options: ContentStreamPreloadOptions): void\n\n clearPrefetch(): void\n\n /**\n * Resets the track to recover from error states.\n * Resets both the segment controller and buffering controller to clear failed segments and error conditions.\n */\n reset(): void\n\n /**\n * Activates the content stream, activating sub-controllers.\n */\n activate(options: ContentStreamActivateOptions): void\n\n /**\n * Deactivates the content stream, deactivating sub-controllers.\n */\n deactivate(): void\n}\n\nexport interface ContentStreamPreloadOptions {\n /**\n * Track priority for prefetching.\n * Higher values take precedence.\n */\n readonly prefetchPriority: number\n\n /**\n * The media presentation time (in seconds) to begin prefetching.\n */\n readonly startTime?: Maybe<number>\n}\n\nexport interface ContentStreamActivateOptions {\n /**\n * The media presentation time (in seconds) to seek to.\n */\n readonly startTime?: Maybe<number>\n}\n\nexport interface ContentStreamImplDeps {\n readonly bufferingController: BufferingController\n readonly segmentController: SegmentController\n}\n\nexport class ContentStreamImpl\n extends EventHostImpl<StreamingEventMap>\n implements ContentStream\n{\n private disposer = /* @__PURE__ */ createDisposer()\n private readonly segmentController: SegmentController\n private readonly bufferingController: BufferingController\n\n constructor(\n dependencyFactories: Factories<ContentStreamImplDeps>,\n readonly contentType: ContentType\n ) {\n super()\n const { add } = this.disposer\n const deps = add(createContainer(dependencyFactories)).dependencies\n\n this.segmentController = deps.segmentController\n redispatchEvents(this, this.segmentController, ['fetchedRangesChange'])\n\n this.bufferingController = deps.bufferingController\n redispatchEvents(this, this.segmentController, [\n 'streamingQualityChange',\n ])\n redispatchEvents(this, this.bufferingController, [\n 'bufferingQualityChange',\n 'playbackQualityChange',\n 'bufferingEnded',\n 'error',\n ])\n }\n\n preload(options: ContentStreamPreloadOptions) {\n this.segmentController.configure({\n startTime: options.startTime ?? 0,\n trackPrefetchPriority: options.prefetchPriority,\n })\n }\n\n get fetchedRanges(): ReadonlyRanges {\n return this.segmentController.fetchedRanges\n }\n\n get streamingQuality(): MediaQualityMetadata | null {\n return this.segmentController.streamingQuality ?? null\n }\n\n get bufferingQuality(): MediaQualityMetadata | null {\n return this.bufferingController.bufferingQuality ?? null\n }\n\n get playbackQuality(): MediaQualityMetadata | null {\n return this.bufferingController.playbackQuality ?? null\n }\n\n get bufferingEnded(): boolean {\n return this.bufferingController.bufferingEnded\n }\n\n get error(): Error | null {\n return this.bufferingController.error ?? this.segmentController.error\n }\n\n /**\n * Clears all fetched fragments and source buffers. Streaming will resume.\n * This should be called if a change has been made where the user would expect an immediate change,\n * for example, changing streaming quality from SD to HD.\n */\n clearPrefetch() {\n this.segmentController.clear()\n this.bufferingController.clear()\n }\n\n /**\n * Resets the track to recover from error states.\n * Resets both the segment controller and buffering controller to clear failed segments and error conditions.\n */\n reset(): void {\n this.segmentController.reset()\n this.bufferingController.reset()\n }\n\n activate(options: ContentStreamActivateOptions): void {\n this.segmentController.configure({\n startTime: options.startTime ?? 0,\n })\n this.segmentController.activate()\n this.bufferingController.activate()\n }\n\n deactivate(): void {\n this.segmentController.deactivate()\n this.bufferingController.deactivate()\n }\n\n dispose(): void {\n super.dispose()\n this.disposer.dispose()\n }\n}\n\n/**\n * The `Factory` to create a function which satisfies `ContentStreamFactory`.\n */\nexport function createContentStreamFactory(deps: {\n readonly createContentStreamFactories: (\n contentType: ContentType\n ) => Factories<ContentStreamImplDeps>\n}) {\n return ((contentType: ContentType) => {\n return new ContentStreamImpl(\n deps.createContentStreamFactories(contentType),\n contentType\n )\n }) satisfies ContentStreamFactory\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { DashManifestData } from './DashManifestProvider'\nimport type { DashMediaQualityMetadataResolver } from './DashMediaQualityMetadataResolver'\nimport { flattenRepresentations } from './util/mpd'\nimport type { ContentType } from '../../streaming/MediaQualityMetadata'\nimport type { ContentTypesValue } from '../../streaming/ContentTypesValue'\nimport type { ObservableValue } from '@amazon/vinyl-observable'\nimport type { DashManifest } from '@amazon/vinyl-mpd-parser'\n\nexport interface DashContentTypesValueDeps {\n readonly manifestTransformed: ObservableValue<Promise<DashManifestData>>\n readonly mediaQualityMetadataResolver: DashMediaQualityMetadataResolver\n}\n\n/**\n * Creates an ObservableValue for the types of streams that are available in the\n * filtered dash manifest.\n */\nexport function createDashContentTypesValue(\n deps: DashContentTypesValueDeps\n): ContentTypesValue {\n return deps.manifestTransformed.map(async (manifestAndPath) => {\n return getContentTypes(deps, (await manifestAndPath).manifest)\n })\n}\n\n/**\n * Determines the types of streams that are available in the filtered dash\n * manifest.\n *\n * Given a Dash manifest, this will resolve to the set of content types present.\n */\nfunction getContentTypes(\n deps: DashContentTypesValueDeps,\n manifest: DashManifest\n): Set<ContentType> {\n const contentTypes = new Set<ContentType>()\n for (const period of manifest.MPD.Period) {\n if (!period.AdaptationSet) continue\n const mediaMetadata = flattenRepresentations(period).map(\n deps.mediaQualityMetadataResolver\n )\n for (const { contentType } of mediaMetadata) {\n if (contentType) contentTypes.add(contentType)\n }\n }\n return contentTypes\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { Maybe, MaybePromise } from '@amazon/vinyl-util'\nimport {\n ErrorOrigin,\n getSidxSampleTimes,\n parseSidxBox,\n ValidationError,\n} from '@amazon/vinyl-util'\nimport type {\n ByteRange,\n MultipleSegmentBaseType,\n RepresentationType,\n SegmentBaseType,\n SegmentListType,\n SegmentTemplateType,\n SegmentTimelineType,\n} from '@amazon/vinyl-mpd-parser'\nimport {\n calculatePeriodTimeRange,\n getSegmentBase,\n getSegmentList,\n getSegmentTemplate,\n type PeriodRange,\n sampleToMpdTime,\n} from '../util/mpd'\nimport {\n type DashUriResolveDeps,\n resolveDashUri,\n segmentTemplateUrl,\n} from '../util/uriResolution'\nimport {\n createSegmentDataProvider,\n type CreateSegmentDataProviderDeps,\n} from '../../createSegmentDataProvider'\nimport { getSegmentAtTime } from '../../../streaming/util/segment'\nimport type {\n MediaSegmentReference,\n SegmentReference,\n} from '../../../streaming/SegmentReference'\nimport type { SegmentDataProvider } from '../../../streaming/SegmentDataSlot'\nimport type { MediaQualityMetadata } from '../../../streaming/MediaQualityMetadata'\nimport type { DashMediaQualityMetadataResolver } from '../DashMediaQualityMetadataResolver'\n\nexport interface DashSegmentProviderDeps\n extends DashUriResolveDeps, CreateSegmentDataProviderDeps {\n /**\n * Produces abstract metadata from a dash representation.\n */\n readonly mediaQualityMetadataResolver: DashMediaQualityMetadataResolver\n}\n\nexport interface DashRepresentationSegmentProvider {\n /**\n * Gets a segment reference within this representation for the given time, in seconds, relative to the period.\n *\n * @param time\n * @param affordance Forward-snap tolerance in seconds: if `time` falls just before a\n * segment's start (within `affordance`), that segment is returned. Defaults to `0`.\n */\n getSegment(\n time: number,\n affordance?: number\n ): Promise<SegmentReference<SegmentDataProvider> | null>\n}\n\ninterface GetTimelineOptions {\n readonly baseUrl: string\n readonly representation: RepresentationType\n readonly periodTimeRange: PeriodRange\n}\n\n/**\n * Metadata and a data provider for a segment.\n */\ntype DataSegmentRef = MediaSegmentReference<SegmentDataProvider>\n\n/**\n * Creates a representation timeline for the given representation.\n */\nexport function createDashRepresentationSegmentProvider(\n deps: DashSegmentProviderDeps,\n baseUrl: string,\n representation: RepresentationType\n): DashRepresentationSegmentProvider {\n const quality: MediaQualityMetadata =\n deps.mediaQualityMetadataResolver(representation)\n const options: GetTimelineOptions = {\n baseUrl,\n periodTimeRange: calculatePeriodTimeRange(representation.parent.parent),\n representation,\n }\n\n // 5.3.9.1 General\n // The elements SegmentBase, SegmentTemplate and SegmentList may be present in the\n // Representation element itself. In addition, to express default values, they may be present in the\n // Period and AdaptationSet element. At each level at most one of the three, SegmentBase,\n // SegmentTemplate and SegmentList, shall be present. Further, if SegmentTemplate or SegmentList is present on\n // one level of the hierarchy, then the other one shall not be present on any lower hierarchy level.\n\n const segmentTemplate = getSegmentTemplate(representation)\n const segmentList = getSegmentList(representation)\n const segmentBase = getSegmentBase(representation)\n\n let segmentsPromise: MaybePromise<\n readonly MediaSegmentReference<SegmentDataProvider>[]\n > | null = null\n\n let initUri: Maybe<string>\n let initRange: Maybe<ByteRange>\n\n if (segmentTemplate?.initialization) {\n initUri = segmentTemplateUrl(segmentTemplate.initialization, {\n representation,\n })\n }\n\n const commonSegmentBase = segmentTemplate ?? segmentList ?? segmentBase\n if (!commonSegmentBase)\n throw new ValidationError(\n 'Manifest must have one of SegmentList, SegmentTemplate, or SegmentBase',\n ErrorOrigin.MEDIA\n )\n\n if (commonSegmentBase.Initialization) {\n initUri = commonSegmentBase.Initialization.sourceURL\n initRange = commonSegmentBase.Initialization.range\n }\n\n if (!initUri && !initRange)\n throw new ValidationError(\n 'Missing initialization range',\n ErrorOrigin.MEDIA\n )\n\n const { url: initUrl, serviceLocation: initServiceLocation } =\n resolveDashUri(deps, { baseUrl, representation, uri: initUri })\n const initData = createSegmentDataProvider(deps, {\n url: initUrl,\n mediaRange: initRange,\n serviceId: initServiceLocation,\n reportDownlinkMetrics: false,\n })\n\n let getSegmentReferences: () => MaybePromise<\n readonly MediaSegmentReference<SegmentDataProvider>[]\n >\n\n // If an index range is present, use that to calculate segment data.\n // The index location may be defined in several locations:\n // SegmentBase.indexRange, SegmentBase.RepresentationIndex, or SegmentTemplate.index\n // One of segmentList, segmentTemplate, or segmentBase is guaranteed to be set.\n if (segmentList) {\n getSegmentReferences = () =>\n createSegmentsFromSegmentList(deps, {\n ...options,\n segmentList,\n })\n } else if (segmentTemplate) {\n getSegmentReferences = () =>\n createSegmentsFromSegmentTemplate(deps, {\n ...options,\n segmentTemplate,\n })\n } else if (segmentBase) {\n getSegmentReferences = () =>\n createSegmentsFromSegmentBase(deps, {\n ...options,\n segmentBase,\n })\n }\n\n return {\n async getSegment(\n time: number,\n affordance = 0\n ): Promise<SegmentReference<SegmentDataProvider> | null> {\n if (!segmentsPromise) segmentsPromise = getSegmentReferences()\n const segments = await Promise.resolve(segmentsPromise).catch(\n (error) => {\n // When the segments list fails (for example the sidx range request fails),\n // retry on the next request.\n segmentsPromise = null\n throw error\n }\n )\n const segment = getSegmentAtTime(time, segments, affordance)\n if (!segment) return null\n return {\n quality,\n ...segment,\n initData,\n }\n },\n }\n}\n\n/**\n * Creates a segment list when the representation has a SegmentList.\n */\nfunction createSegmentsFromSegmentList(\n deps: DashSegmentProviderDeps,\n options: GetTimelineOptions & {\n readonly segmentList: SegmentListType\n }\n): readonly DataSegmentRef[] {\n const { baseUrl, periodTimeRange, representation, segmentList } = options\n const segmentUrls = segmentList.SegmentURL\n if (segmentUrls) {\n // Fabricate a segment timeline from the segment duration.\n const timescale = getTimescale(segmentList)\n const sampleTimes = calculateSegmentSampleTimes({\n multipleSegmentBase: segmentList,\n periodTimeRange,\n numSegments: segmentUrls.length,\n })\n const presentationTimeOffset = segmentList.presentationTimeOffset ?? 0\n\n return createTimeline(\n {\n sampleTimes,\n presentationTimeOffset,\n periodTimeRange,\n timescale,\n },\n (i) => {\n const segmentUrl = segmentUrls[i]\n const { url, serviceLocation } = resolveDashUri(deps, {\n baseUrl,\n uri: segmentUrl.media,\n representation,\n })\n return createSegmentDataProvider(deps, {\n url,\n mediaRange: segmentUrl.mediaRange,\n serviceId: serviceLocation,\n reportDownlinkMetrics: true,\n })\n }\n )\n } else {\n if (segmentList.href) {\n throw new ValidationError(\n 'SegmentList.href currently unsupported',\n ErrorOrigin.MEDIA\n )\n } else {\n throw new ValidationError(\n 'could not determine segments from SegmentList',\n ErrorOrigin.MEDIA\n )\n }\n }\n}\n\n/**\n * SegmentTemplate contains URIs with template tokens, as defined in 5.3.9.4.4.\n *\n * @see segmentTemplateUrl\n */\nfunction createSegmentsFromSegmentTemplate(\n deps: DashSegmentProviderDeps,\n options: GetTimelineOptions & {\n readonly segmentTemplate: SegmentTemplateType\n }\n): readonly DataSegmentRef[] {\n const { baseUrl, periodTimeRange, representation, segmentTemplate } =\n options\n if (!segmentTemplate.media) {\n throw new ValidationError(\n 'SegmentTemplate.media required',\n ErrorOrigin.MEDIA\n )\n }\n const media = segmentTemplate.media\n const presentationTimeOffset = segmentTemplate.presentationTimeOffset ?? 0\n\n const sampleTimes = calculateSegmentSampleTimes({\n multipleSegmentBase: segmentTemplate,\n periodTimeRange,\n })\n\n const timescale = getTimescale(segmentTemplate)\n let segmentNumber = segmentTemplate.startNumber ?? 1\n return createTimeline(\n {\n timescale,\n presentationTimeOffset,\n periodTimeRange,\n sampleTimes,\n },\n (_, sampleTime) => {\n const uri = segmentTemplateUrl(media, {\n representation,\n sampleTime,\n segmentNumber: segmentNumber++,\n })\n const { url, serviceLocation } = resolveDashUri(deps, {\n baseUrl,\n uri,\n representation,\n })\n return createSegmentDataProvider(deps, {\n url,\n serviceId: serviceLocation,\n reportDownlinkMetrics: true,\n })\n }\n )\n}\n\n/**\n * When SegmentBase is provided, get the timeline from the index range.\n */\nasync function createSegmentsFromSegmentBase(\n deps: DashSegmentProviderDeps,\n options: GetTimelineOptions & {\n readonly segmentBase: SegmentBaseType\n }\n): Promise<readonly DataSegmentRef[]> {\n const { baseUrl, periodTimeRange, representation, segmentBase } = options\n if (segmentBase.indexRange) {\n // Load the sidx box from the mp4.\n const indexRange = segmentBase.indexRange\n const { url: indexUrl, serviceLocation: indexServiceLocation } =\n resolveDashUri(deps, { baseUrl, representation })\n const sidx = parseSidxBox(\n await createSegmentDataProvider(deps, {\n url: indexUrl,\n mediaRange: indexRange,\n serviceId: indexServiceLocation,\n reportDownlinkMetrics: false,\n })()\n )\n\n const sampleTimes = getSidxSampleTimes(sidx)\n let rangeStart = Number(sidx.firstOffset) + indexRange[1]! + 1\n return createTimeline(\n {\n sampleTimes,\n periodTimeRange,\n presentationTimeOffset: segmentBase.presentationTimeOffset ?? 0,\n timescale: sidx.timescale,\n },\n (i) => {\n const segmentReference = sidx.references[i]\n const size = segmentReference.referencedSize\n const provider = createSegmentDataProvider(deps, {\n url: indexUrl,\n mediaRange: [rangeStart, rangeStart + size - 1],\n serviceId: indexServiceLocation,\n reportDownlinkMetrics: true,\n })\n rangeStart += size\n return provider\n }\n )\n } else {\n throw new ValidationError('Manifest missing segments')\n }\n}\n\n/**\n * Returns an array of start times, in timescale units for the segments in the given multiple segment base.\n * The last time in the list will be the end time, in timescale units.\n */\nfunction calculateSegmentSampleTimes(options: {\n readonly multipleSegmentBase: MultipleSegmentBaseType\n readonly periodTimeRange: PeriodRange\n readonly numSegments?: Maybe<number>\n}): readonly number[] {\n const { multipleSegmentBase, periodTimeRange } = options\n const timescale = getTimescale(multipleSegmentBase)\n\n let startTimes: readonly number[]\n if (multipleSegmentBase.SegmentTimeline) {\n startTimes = calculateSampleTimesFromSegmentTimeline(\n multipleSegmentBase.SegmentTimeline\n )\n } else {\n // Fabricate a segment timeline from the segment duration.\n const sampleDuration = getSampleDuration(multipleSegmentBase) // The unscaled duration\n startTimes = calculateFixedSegmentSampleTimes({\n timescale,\n periodTimeRange,\n sampleDuration,\n numSegments: options.numSegments,\n })\n }\n return startTimes\n}\n\n/**\n * Given a SegmentTimeline element, calculates the sample start times of each segment, in timescale units.\n * The last time in the list will be the end time, in timescale units.\n */\nfunction calculateSampleTimesFromSegmentTimeline(\n segmentTimeline: SegmentTimelineType\n): readonly number[] {\n const out: number[] = new Array((segmentTimeline.S?.length ?? 0) + 1)\n let startTime = 0\n let c = 0\n\n segmentTimeline.S?.forEach((s) => {\n // If the start time 't' is defined, use it, otherwise use the calculated current time\n startTime = s.t != null ? s.t : startTime\n\n // Calculate segment details for the number of repeats\n for (let i = 0; i <= s.r; i++) {\n out[c++] = startTime\n startTime += s.d\n }\n })\n out[c++] = startTime\n return out\n}\n\n/**\n * Creates media segment sample start times, in timescale units, with a given duration.\n * The last time in the list will be the duration, in timescale units.\n *\n * @param options\n */\nfunction calculateFixedSegmentSampleTimes(options: {\n readonly sampleDuration: number\n readonly timescale: number\n readonly periodTimeRange: PeriodRange\n readonly numSegments?: Maybe<number>\n}): readonly number[] {\n const { sampleDuration, timescale } = options\n const [periodStart, periodEnd] = options.periodTimeRange\n if (periodEnd == null)\n throw new ValidationError(\n 'MPD.mediaPresentationDuration or Period.duration required',\n ErrorOrigin.MEDIA\n )\n const numSegments =\n options.numSegments ??\n Math.ceil((periodEnd - periodStart) / (sampleDuration / timescale))\n const out: number[] = new Array(numSegments + 1)\n let startTime = 0\n for (let i = 0; i < numSegments; i++) {\n out[i] = startTime\n startTime += sampleDuration\n }\n out[numSegments] = periodEnd * timescale\n return out\n}\n\n/**\n * Creates a timeline of DataSegmentRef objects from a sample timeline list and a data provider factory.\n *\n * @param sampleTimes The list of sample times, in timescale units, to convert into MPD presentation times.\n * @param periodTimeRange The time range of the period, in seconds.\n * @param presentationTimeOffset The presentation time offset, in samples per second.\n * @param timescale The timescale units, in samples per second.\n * @param dataProviderFactory Creates the data provider for the segment at the given index and sample start time.\n */\nfunction createTimeline(\n {\n sampleTimes,\n periodTimeRange,\n presentationTimeOffset,\n timescale,\n }: {\n sampleTimes: readonly number[]\n periodTimeRange: PeriodRange\n presentationTimeOffset: number\n timescale: number\n },\n dataProviderFactory: (i: number, sampleTime: number) => SegmentDataProvider\n): readonly DataSegmentRef[] {\n const [periodStart, periodEnd] = periodTimeRange\n const mpdTimes = sampleTimes.map((sampleTime) => {\n return sampleToMpdTime(\n sampleTime,\n periodStart,\n presentationTimeOffset,\n timescale\n )\n })\n const n = mpdTimes.length - 1\n const out = new Array<DataSegmentRef>(n)\n for (let i = 0; i < n; i++) {\n const startTime = mpdTimes[i]\n const endTime = mpdTimes[i + 1]\n out[i] = {\n data: dataProviderFactory(i, sampleTimes[i]),\n timestampOffset: startTime,\n startTime: Math.max(periodStart, startTime),\n endTime: periodEnd == null ? endTime : Math.min(periodEnd, endTime),\n }\n }\n return out\n}\n\n/**\n * Validates that timescale is set, returning it.\n *\n * @param multipleSegmentBase\n */\nfunction getTimescale(multipleSegmentBase: MultipleSegmentBaseType): number {\n if (!multipleSegmentBase.timescale)\n throw new ValidationError('invalid timescale', ErrorOrigin.MEDIA)\n return multipleSegmentBase.timescale\n}\n\n/**\n * Validates that duration is set, returning it.\n *\n * @param multipleSegmentBase\n */\nfunction getSampleDuration(\n multipleSegmentBase: MultipleSegmentBaseType\n): number {\n if (!multipleSegmentBase.duration)\n throw new ValidationError('invalid duration', ErrorOrigin.MEDIA)\n return multipleSegmentBase.duration\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type {\n Maybe,\n Mutable,\n MutableRequestParams,\n ReadonlyAbort,\n RequestInitOptions,\n RequestInterceptor,\n Timestamp,\n} from '@amazon/vinyl-util'\nimport {\n getHostname,\n last,\n networkMetricsController,\n normalizeHeadersInit,\n requestWithRetry,\n} from '@amazon/vinyl-util'\nimport { type ByteRange, stringifyByteRange } from '@amazon/vinyl-mpd-parser'\nimport type { SegmentDataProvider } from '../streaming/SegmentDataSlot'\n\nexport interface CreateSegmentDataProviderDeps {\n readonly requestInterceptor: RequestInterceptor\n readonly segmentRequestInit: Maybe<RequestInitOptions>\n}\n\nexport interface CreateSegmentDataProviderOptions {\n readonly url: string\n readonly mediaRange?: Maybe<ByteRange>\n readonly serviceId?: Maybe<string>\n /**\n * If true, reports downlink transfer speeds to network metrics.\n */\n readonly reportDownlinkMetrics: boolean\n}\n\nexport function createSegmentDataProvider(\n deps: CreateSegmentDataProviderDeps,\n options: CreateSegmentDataProviderOptions\n): SegmentDataProvider {\n return async (abort?: Maybe<ReadonlyAbort>) => {\n const init: Mutable<RequestInitOptions> = {\n ...deps.segmentRequestInit,\n }\n if (options.mediaRange) {\n init.headers = {\n ...normalizeHeadersInit(init.headers),\n Range: `bytes=${stringifyByteRange(options.mediaRange)}`,\n }\n }\n\n const params: MutableRequestParams = {\n input: options.url,\n init,\n }\n deps.requestInterceptor(params)\n\n const serviceId = options.serviceId ?? getHostname(options.url)\n const requestStart = Date.now()\n const response = await requestWithRetry(params.input, params.init, {\n serviceId,\n abort,\n })\n const responseEnd = Date.now()\n\n const arrayBuffer = await response.arrayBuffer()\n const contentEnd = Date.now()\n\n let responseStart: Timestamp | null = null\n if ('getEntriesByName' in performance) {\n const lastRequest: any = last(\n performance.getEntriesByName(params.input)\n )\n if (lastRequest) {\n // Resource timing information was available, use it to get a more accurate response start time. A\n // value of 0 means timing information was denied, likely due to a cross-origin request without\n // Timing-Allow-Origin response headers.\n if (lastRequest.responseStart) {\n responseStart =\n performance.timeOrigin + lastRequest.responseStart\n }\n }\n }\n\n if (options.reportDownlinkMetrics) {\n networkMetricsController.value.addDownlinkTransferEntry({\n bytes: arrayBuffer.byteLength,\n serviceId,\n requestStart,\n responseStart,\n responseEnd,\n contentEnd,\n })\n }\n return arrayBuffer\n }\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { DashManifestData } from './DashManifestProvider'\nimport type {\n MediaPeriod,\n MediaQualityData,\n MediaTimeline,\n} from '../../streaming/MediaTimeline'\nimport type { RepresentationType } from '@amazon/vinyl-mpd-parser'\nimport {\n calculateDuration,\n calculatePeriodEnd,\n calculatePeriodStart,\n flattenRepresentations,\n} from './util/mpd'\nimport {\n createDashRepresentationSegmentProvider,\n type DashSegmentProviderDeps,\n} from './timeline/DashRepresentationSegmentProvider'\n\nexport type BuildDashMediaTimelineDeps = DashSegmentProviderDeps\n\n/**\n * Builds a MediaTimeline from a Dash manifest.\n */\nexport function buildDashMediaTimeline(\n deps: BuildDashMediaTimelineDeps,\n data: DashManifestData\n): MediaTimeline {\n const { manifest, baseUrl } = data\n const periods: MediaPeriod[] = manifest.MPD.Period.map((period) => {\n const startTime = calculatePeriodStart(period)\n const endTime = calculatePeriodEnd(period) ?? Infinity\n const representations = flattenRepresentations(period)\n const qualities: MediaQualityData[] = representations.map(\n (representation: RepresentationType): MediaQualityData => {\n const metadata =\n deps.mediaQualityMetadataResolver(representation)\n const segmentProvider = createDashRepresentationSegmentProvider(\n deps,\n baseUrl,\n representation\n )\n return {\n metadata,\n getSegment: (time: number, affordance?: number) =>\n segmentProvider.getSegment(time, affordance),\n }\n }\n )\n return { startTime, endTime, qualities }\n })\n const duration = calculateDuration(manifest)\n return {\n periods,\n minBufferTime: manifest.MPD.minBufferTime,\n getDuration: () => Promise.resolve(duration),\n }\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { ObservableValue } from '@amazon/vinyl-observable'\nimport { combineData } from '@amazon/vinyl-observable'\nimport type { Capabilities } from '../client/Capabilities'\nimport type { DrmController } from '../drm/DrmController'\nimport type { MediaTimeline } from './MediaTimeline'\nimport {\n filterTimelineQualities,\n filterTimelineQualitiesAsync,\n} from './mediaTimelineFilter'\nimport { createLanguageFilter } from './mediaTimelineLanguageFilter'\nimport {\n canPlayMimeType,\n throwMimeTypesUnsupported,\n} from '../track/filters/resourceTypeFilter'\nimport {\n canPlayKeySystem,\n throwKeySystemsUnsupported,\n} from '../track/filters/keySystemFilter'\nimport {\n supportsAudioSamplingRate,\n throwSamplingRatesUnsupported,\n} from '../track/filters/sampleRateFilter'\nimport { throwLanguagesUnsupported } from '../track/filters/languageFilter'\n\nexport interface DefaultMediaTimelineTransformerDeps {\n readonly capabilities: Capabilities\n readonly drmController: DrmController\n readonly mediaTimeline: ObservableValue<Promise<MediaTimeline>>\n readonly options: ObservableValue<{\n readonly preferredAudioLanguage: string | null\n }>\n}\n\n/**\n * The default media timeline transformer filters out unplayable qualities\n * and applies language preferences. Shared by Dash and HLS.\n */\nexport function createDefaultMediaTimelineTransformer(\n deps: DefaultMediaTimelineTransformerDeps\n): ObservableValue<Promise<MediaTimeline>> {\n async function transformTimeline(\n timeline: MediaTimeline\n ): Promise<MediaTimeline> {\n let t = filterTimelineQualities(\n (quality) => canPlayMimeType(deps, quality),\n throwMimeTypesUnsupported,\n timeline\n )\n t = await filterTimelineQualitiesAsync(\n (quality) => canPlayKeySystem(deps, quality),\n throwKeySystemsUnsupported,\n t\n )\n t = filterTimelineQualities(\n (quality, index, array) =>\n supportsAudioSamplingRate(deps, quality, index, array),\n throwSamplingRatesUnsupported,\n t\n )\n t = filterTimelineQualities(\n createLanguageFilter(\n deps.options.value.preferredAudioLanguage,\n 'audio'\n ),\n throwLanguagesUnsupported,\n t\n )\n return t\n }\n\n return combineData({\n timeline: deps.mediaTimeline,\n preferredAudioLanguage: deps.options.pick('preferredAudioLanguage'),\n }).map(async ({ timeline }) => {\n return transformTimeline(await timeline)\n })\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type {\n MediaPeriod,\n MediaQualityData,\n MediaTimeline,\n} from './MediaTimeline'\nimport type { MediaQualityMetadata } from './MediaQualityMetadata'\nimport type {\n FilterPredicate,\n FilterPredicateAsync,\n Maybe,\n} from '@amazon/vinyl-util'\nimport { map, memoize } from '@amazon/vinyl-util'\n\n/**\n * Filters qualities in a MediaTimeline using a synchronous predicate.\n * If filtering would remove all qualities from any period, throws via `throwError`.\n */\nexport function filterTimelineQualities(\n filter: Maybe<FilterPredicate<MediaQualityMetadata>>,\n throwError: () => never,\n timeline: MediaTimeline\n): MediaTimeline {\n if (!filter) return timeline\n const mapMetadataArray = memoize(\n (qualities: readonly MediaQualityData[]) =>\n map(qualities, (q) => q.metadata),\n (qualities) => qualities,\n 1\n )\n\n const periods = timeline.periods.map((period) => {\n const filtered = period.qualities.filter((q, index) =>\n filter(q.metadata, index, mapMetadataArray(period.qualities))\n )\n return { ...period, qualities: filtered }\n })\n\n if (periods.some((p) => p.qualities.length === 0)) {\n throwError()\n }\n\n return { ...timeline, periods }\n}\n\n/**\n * Filters qualities in a MediaTimeline using an asynchronous predicate.\n * If filtering would remove all qualities from any period, throws via `throwError`.\n */\nexport async function filterTimelineQualitiesAsync(\n filter: FilterPredicateAsync<MediaQualityMetadata>,\n throwError: () => never,\n timeline: MediaTimeline\n): Promise<MediaTimeline> {\n const mapMetadataArray = memoize(\n (qualities: readonly MediaQualityData[]) =>\n map(qualities, (q) => q.metadata),\n (qualities) => qualities,\n 1\n )\n\n const periods: MediaPeriod[] = []\n for (const period of timeline.periods) {\n const filtered: MediaQualityData[] = []\n const metadataArray = mapMetadataArray(period.qualities)\n for (let i = 0; i < period.qualities.length; i++) {\n if (await filter(period.qualities[i].metadata, i, metadataArray)) {\n filtered.push(period.qualities[i])\n }\n }\n periods.push({ ...period, qualities: filtered })\n }\n\n if (periods.some((p) => p.qualities.length === 0)) {\n throwError()\n }\n\n return { ...timeline, periods }\n}\n\n/**\n * Creates a language filter predicate for use with filterTimelineQualities.\n */\nexport { createLanguageFilter } from './mediaTimelineLanguageFilter'\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { MediaQualityMetadata } from './MediaQualityMetadata'\nimport type { FilterPredicate } from '@amazon/vinyl-util'\nimport { memoize } from '@amazon/vinyl-util'\nimport {\n findBestLanguageMatch,\n languageRelatedness,\n} from '../track/filters/languageFilter'\n\n/**\n * Creates a filter predicate that keeps qualities matching the preferred language.\n * The best language match is computed per period (per unique array reference),\n * so periods with different available languages are handled independently.\n *\n * Qualities not matching the content type or without a language tag are always kept.\n *\n * @param preferredLanguage BCP 47 language tag, or null to keep all.\n * @param contentType Only filter qualities matching this content type (e.g. 'audio').\n */\nexport function createLanguageFilter(\n preferredLanguage: string | null,\n contentType: string\n): FilterPredicate<MediaQualityMetadata> | null {\n if (!preferredLanguage) return null\n\n // Finds the best language for the period by relevance.\n // If no languages are related, the first language will be chosen.\n const bestRelevanceForPeriod = memoize(\n (array: ArrayLike<MediaQualityMetadata>) => {\n const langs = Array.from(array)\n .filter((q) => q.contentType === contentType && q.lang)\n .map((q) => q.lang!)\n return languageRelatedness(\n preferredLanguage,\n findBestLanguageMatch(preferredLanguage, langs)!\n )\n },\n (array) => array,\n 1\n )\n\n return (quality, _index, array) => {\n if (quality.contentType !== contentType) return true\n if (!quality.lang) return true\n const bestScore = bestRelevanceForPeriod(array)\n return languageRelatedness(preferredLanguage, quality.lang) >= bestScore\n }\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { compareBy, max, MediaUnsupportedError } from '@amazon/vinyl-util'\n\nexport function throwLanguagesUnsupported(): never {\n throw new MediaUnsupportedError(\n 'No content matching preferred language',\n 'language'\n )\n}\n\n/**\n * Map from ISO 639-2 (3-letter) to ISO 639-1 (2-letter) codes.\n * Covers the most common languages encountered in streaming media.\n */\nconst iso3to2 = /* @__PURE__ */ new Map<string, string>([\n ['aar', 'aa'],\n ['abk', 'ab'],\n ['afr', 'af'],\n ['aka', 'ak'],\n ['amh', 'am'],\n ['ara', 'ar'],\n ['arg', 'an'],\n ['asm', 'as'],\n ['ava', 'av'],\n ['ave', 'ae'],\n ['aym', 'ay'],\n ['aze', 'az'],\n ['bak', 'ba'],\n ['bam', 'bm'],\n ['bel', 'be'],\n ['ben', 'bn'],\n ['bis', 'bi'],\n ['bod', 'bo'],\n ['bos', 'bs'],\n ['bre', 'br'],\n ['bul', 'bg'],\n ['cat', 'ca'],\n ['ces', 'cs'],\n ['cha', 'ch'],\n ['che', 'ce'],\n ['chu', 'cu'],\n ['chv', 'cv'],\n ['cor', 'kw'],\n ['cos', 'co'],\n ['cre', 'cr'],\n ['cym', 'cy'],\n ['dan', 'da'],\n ['deu', 'de'],\n ['div', 'dv'],\n ['dzo', 'dz'],\n ['ell', 'el'],\n ['eng', 'en'],\n ['epo', 'eo'],\n ['est', 'et'],\n ['eus', 'eu'],\n ['ewe', 'ee'],\n ['fao', 'fo'],\n ['fas', 'fa'],\n ['fij', 'fj'],\n ['fin', 'fi'],\n ['fra', 'fr'],\n ['fry', 'fy'],\n ['ful', 'ff'],\n ['gla', 'gd'],\n ['gle', 'ga'],\n ['glg', 'gl'],\n ['glv', 'gv'],\n ['grn', 'gn'],\n ['guj', 'gu'],\n ['hat', 'ht'],\n ['hau', 'ha'],\n ['heb', 'he'],\n ['her', 'hz'],\n ['hin', 'hi'],\n ['hmo', 'ho'],\n ['hrv', 'hr'],\n ['hun', 'hu'],\n ['hye', 'hy'],\n ['ibo', 'ig'],\n ['ido', 'io'],\n ['iii', 'ii'],\n ['iku', 'iu'],\n ['ile', 'ie'],\n ['ina', 'ia'],\n ['ind', 'id'],\n ['ipk', 'ik'],\n ['isl', 'is'],\n ['ita', 'it'],\n ['jav', 'jv'],\n ['jpn', 'ja'],\n ['kal', 'kl'],\n ['kan', 'kn'],\n ['kas', 'ks'],\n ['kat', 'ka'],\n ['kau', 'kr'],\n ['kaz', 'kk'],\n ['khm', 'km'],\n ['kik', 'ki'],\n ['kin', 'rw'],\n ['kir', 'ky'],\n ['kom', 'kv'],\n ['kon', 'kg'],\n ['kor', 'ko'],\n ['kua', 'kj'],\n ['kur', 'ku'],\n ['lao', 'lo'],\n ['lat', 'la'],\n ['lav', 'lv'],\n ['lim', 'li'],\n ['lin', 'ln'],\n ['lit', 'lt'],\n ['ltz', 'lb'],\n ['lub', 'lu'],\n ['lug', 'lg'],\n ['mah', 'mh'],\n ['mal', 'ml'],\n ['mar', 'mr'],\n ['mkd', 'mk'],\n ['mlg', 'mg'],\n ['mlt', 'mt'],\n ['mon', 'mn'],\n ['mri', 'mi'],\n ['msa', 'ms'],\n ['mya', 'my'],\n ['nau', 'na'],\n ['nav', 'nv'],\n ['nbl', 'nr'],\n ['nde', 'nd'],\n ['ndo', 'ng'],\n ['nep', 'ne'],\n ['nld', 'nl'],\n ['nno', 'nn'],\n ['nob', 'nb'],\n ['nor', 'no'],\n ['nya', 'ny'],\n ['oci', 'oc'],\n ['oji', 'oj'],\n ['ori', 'or'],\n ['orm', 'om'],\n ['oss', 'os'],\n ['pan', 'pa'],\n ['pli', 'pi'],\n ['pol', 'pl'],\n ['por', 'pt'],\n ['pus', 'ps'],\n ['que', 'qu'],\n ['roh', 'rm'],\n ['ron', 'ro'],\n ['run', 'rn'],\n ['rus', 'ru'],\n ['sag', 'sg'],\n ['san', 'sa'],\n ['sin', 'si'],\n ['slk', 'sk'],\n ['slv', 'sl'],\n ['sme', 'se'],\n ['smo', 'sm'],\n ['sna', 'sn'],\n ['snd', 'sd'],\n ['som', 'so'],\n ['sot', 'st'],\n ['spa', 'es'],\n ['sqi', 'sq'],\n ['srd', 'sc'],\n ['srp', 'sr'],\n ['ssw', 'ss'],\n ['sun', 'su'],\n ['swa', 'sw'],\n ['swe', 'sv'],\n ['tah', 'ty'],\n ['tam', 'ta'],\n ['tat', 'tt'],\n ['tel', 'te'],\n ['tgk', 'tg'],\n ['tgl', 'tl'],\n ['tha', 'th'],\n ['tir', 'ti'],\n ['ton', 'to'],\n ['tsn', 'tn'],\n ['tso', 'ts'],\n ['tuk', 'tk'],\n ['tur', 'tr'],\n ['twi', 'tw'],\n ['uig', 'ug'],\n ['ukr', 'uk'],\n ['urd', 'ur'],\n ['uzb', 'uz'],\n ['ven', 've'],\n ['vie', 'vi'],\n ['vol', 'vo'],\n ['wln', 'wa'],\n ['wol', 'wo'],\n ['xho', 'xh'],\n ['yid', 'yi'],\n ['yor', 'yo'],\n ['zha', 'za'],\n ['zho', 'zh'],\n ['zul', 'zu'],\n // Bibliographic codes (ISO 639-2/B) that differ from terminological codes\n ['alb', 'sq'],\n ['arm', 'hy'],\n ['baq', 'eu'],\n ['bur', 'my'],\n ['chi', 'zh'],\n ['cze', 'cs'],\n ['dut', 'nl'],\n ['fre', 'fr'],\n ['geo', 'ka'],\n ['ger', 'de'],\n ['gre', 'el'],\n ['ice', 'is'],\n ['mac', 'mk'],\n ['mao', 'mi'],\n ['may', 'ms'],\n ['per', 'fa'],\n ['rum', 'ro'],\n ['slo', 'sk'],\n ['tib', 'bo'],\n ['wel', 'cy'],\n])\n\n/**\n * Normalizes a BCP 47 / RFC 5646 language tag.\n *\n * - Converts ISO 639-2 (3-letter) codes to ISO 639-1 (2-letter)\n * - Forces language to lowercase, region to uppercase\n * - Discards script/dialect subtags beyond language-REGION\n *\n * Examples: `eng` \u2192 `en`, `en-us` \u2192 `en-US`, `fra-CA` \u2192 `fr-CA`\n */\nexport function normalizeLanguage(locale: string): string {\n const parts = locale.split('-')\n let language = (parts[0] || '').toLowerCase()\n language = iso3to2.get(language) || language\n const region = parts[1] ? parts[1].toUpperCase() : ''\n return region ? `${language}-${region}` : language\n}\n\n/**\n * Computes a relatedness score between two language codes.\n * Higher is better. 0 means unrelated.\n *\n * - 4: exact match after normalization (e.g. `en-US` vs `en-US`)\n * - 3: candidate is parent of target (e.g. `en` vs `en-US`)\n * - 2: candidate is sibling of target (e.g. `en-CA` vs `en-US`)\n * - 1: candidate is child of target (e.g. `en-US` vs `en`)\n * - 0: unrelated\n */\nexport function languageRelatedness(target: string, candidate: string): number {\n const t = normalizeLanguage(target)\n const c = normalizeLanguage(candidate)\n\n if (c === t) return 4\n\n const tParts = t.split('-')\n const cParts = c.split('-')\n\n if (tParts[0] !== cParts[0]) return 0\n\n // candidate is parent of target: candidate has no region, target does\n if (cParts.length === 1 && tParts.length === 2) return 3\n\n // candidate is sibling: both have regions (different, since exact match already checked)\n if (cParts.length === 2 && tParts.length === 2) return 2\n\n // candidate is child of target: target has no region, candidate does\n return 1 // tParts.length === 1 && cParts.length === 2\n}\n\n/**\n * Finds the best language match from a set of available languages.\n * Returns the best matching language, or undefined if the set is empty.\n * When no language is related, the first available language is returned.\n */\nexport function findBestLanguageMatch(\n target: string,\n available: ArrayLike<string>\n): string | undefined {\n return max(\n available,\n compareBy((lang) => languageRelatedness(target, lang))\n )\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { Capabilities } from '../../client/Capabilities'\nimport type { MediaFormatMetadata } from '../../streaming/MediaQualityMetadata'\nimport { MediaUnsupportedError } from '@amazon/vinyl-util'\n\nexport function throwMimeTypesUnsupported(): never {\n throw new MediaUnsupportedError(\n 'No resource type supported (container/codec).',\n 'resource-type'\n )\n}\n\n/**\n * Returns true when the media's codec and container is supported.\n */\nexport function canPlayMimeType(\n deps: { readonly capabilities: Capabilities },\n metadata: MediaFormatMetadata\n): boolean {\n if (!metadata.mimeType) return false\n return deps.capabilities.canPlayTypeMse(metadata.mimeType)\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { MediaQualityMetadata } from '../../streaming/MediaQualityMetadata'\nimport { type DrmController } from '../../drm/DrmController'\nimport { MediaUnsupportedError } from '@amazon/vinyl-util'\n\nexport function throwKeySystemsUnsupported(): never {\n throw new MediaUnsupportedError('No key system supported.', 'key-system')\n}\n\n/**\n * Returns true when the media's key system is supported or the representation has no content protection.\n */\nexport async function canPlayKeySystem(\n deps: { readonly drmController: DrmController },\n metadata: MediaQualityMetadata\n): Promise<boolean> {\n if (!metadata.contentProtections.length) return true // Is not content protected.\n return (await deps.drmController.isSupported(metadata)).supported\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { MediaQualityMetadata } from '../../streaming/MediaQualityMetadata'\nimport {\n hasBrowser,\n Browser,\n last,\n MediaUnsupportedError,\n every,\n map,\n min,\n} from '@amazon/vinyl-util'\nimport type { Capabilities } from '../../client/Capabilities'\n\nexport function throwSamplingRatesUnsupported(): never {\n throw new MediaUnsupportedError('No supported sample rate', 'sampling-rate')\n}\n\n/**\n * Returns true when the media's sampling rate is supported.\n * If Firefox (which does not support >48kHz), filter out all sampling rates above the supported sampling rate.\n * All other browsers filter out all sampling rates above the supported sampling rate unless this will filter all\n * and then do not filter the lowest sampling rate.\n */\nexport function supportsAudioSamplingRate(\n deps: { readonly capabilities: Capabilities },\n metadata: MediaQualityMetadata,\n _index: number,\n array: ArrayLike<MediaQualityMetadata>\n): boolean {\n const isFirefox = hasBrowser(Browser.FIREFOX)\n const maxSampleRate = deps.capabilities.sampleRate\n const samplingRate = last(metadata.audioSamplingRate)\n\n if (!samplingRate || !maxSampleRate) return true // sampling rate not set\n\n if (isFirefox) {\n // Firefox: filter out all sampling rates above 48_000 Hz\n return samplingRate <= 48_000\n }\n\n // Other browsers: filter out all sampling rates above supported unless this will filter all\n if (samplingRate <= maxSampleRate) return true\n\n // Check if filtering all would remove everything\n const allAboveMax = every(array, (item) => {\n const itemSamplingRate = last(item.audioSamplingRate)\n return itemSamplingRate != null && itemSamplingRate > maxSampleRate\n })\n\n if (allAboveMax) {\n // Find the lowest sampling rate and only allow that one\n const samplingRates = map(array, (item) =>\n last(item.audioSamplingRate)\n ).filter((rate): rate is number => rate != null)\n const lowestSamplingRate = min(samplingRates)\n return samplingRate === lowestSamplingRate\n }\n\n return false\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type {\n AlternativeRendition,\n VariantStream,\n} from '@amazon/vinyl-hls-parser'\nimport type { MediaQualityMetadata } from '../../streaming/MediaQualityMetadata'\nimport { codecToContentType, contentTypeToMimeType } from '../mse/codec'\n\nexport type HlsMediaQualityMetadataResolver = (\n variant: VariantStream,\n renditions: readonly AlternativeRendition[]\n) => MediaQualityMetadata\n\nexport function createDefaultHlsMediaQualityMetadataResolver(): HlsMediaQualityMetadataResolver {\n return (variant, renditions) => {\n const codecs = variant.codecs || null\n // Use the first codec to determine the primary content type.\n const contentType = codecs\n ? codecToContentType(codecs.split(',')[0])\n : null\n\n // Find matching audio rendition for language.\n const audioRendition = variant.audioGroup\n ? renditions.find(\n (r) => r.type === 'AUDIO' && r.groupId === variant.audioGroup\n )\n : undefined\n\n // Use the variant URI as the decoderId so each quality forces a decoder\n // re-initialization on switch.\n return {\n qualityId: `${variant.bandwidth}-${codecs ?? ''}`,\n decoderId: variant.uri,\n groupId: '0',\n switchingGroupIds: null,\n mimeType: contentType\n ? contentTypeToMimeType(contentType, codecs)\n : null,\n contentType,\n codecs,\n bandwidth: null,\n bandwidthTotal: variant.bandwidth,\n audioSamplingRate: null,\n width: variant.width ?? null,\n height: variant.height ?? null,\n frameRate: variant.frameRate\n ? ([variant.frameRate, 1] as const)\n : null,\n lang: audioRendition?.language ?? null,\n contentProtections: [],\n encryptionScheme: null,\n initDataType: null,\n supplementalProperties: {},\n }\n }\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { data } from '@amazon/vinyl-observable'\nimport { createAbortSlot, createDisposer, logDebug } from '@amazon/vinyl-util'\nimport type { ManifestController } from '../../streaming/ManifestController'\nimport type {\n HlsManifestData,\n HlsManifestProvider,\n} from './HlsManifestProvider'\n\nexport type HlsManifestController = ManifestController<Promise<HlsManifestData>>\n\nexport class HlsManifestControllerImpl implements HlsManifestController {\n get [Symbol.toStringTag](): string {\n return 'HlsManifestControllerImpl'\n }\n\n get logPrefix(): string {\n return 'HlsManifestControllerImpl'\n }\n\n private readonly _data = /* @__PURE__ */ data<Promise<HlsManifestData>>(\n /* @__PURE__ */ Promise.reject(/* @__PURE__ */ new Error('manifest not loaded'))\n )\n private _error: Error | null = null\n private readonly abortSlot = /* @__PURE__ */ createAbortSlot()\n private readonly disposer = /* @__PURE__ */ createDisposer()\n\n constructor(private readonly manifestProvider: HlsManifestProvider) {\n // Suppress unhandled rejection on the initial placeholder.\n this._data.value.catch(() => {})\n this.refresh()\n }\n\n /**\n * The most recent error from the manifest provider, or null.\n */\n get error(): Error | null {\n return this._error\n }\n\n refresh(): void {\n logDebug(this, 'refresh')\n this.abortSlot.abort()\n this._error = null\n const promise = this.manifestProvider(this.abortSlot.value)\n promise.catch((error: Error) => {\n this._error = error\n })\n this._data.value = promise\n }\n\n reset(): void {\n logDebug(this, 'reset')\n if (this._error) {\n this.refresh()\n }\n }\n\n get value(): Promise<HlsManifestData> {\n return this._data.value\n }\n\n get changeId(): number {\n return this._data.changeId\n }\n\n getValue(): Promise<HlsManifestData> {\n return this._data.getValue()\n }\n\n onData(\n callback: (\n value: Promise<HlsManifestData>,\n previous?: Promise<HlsManifestData>\n ) => void\n ): () => void {\n return this._data.onData(callback)\n }\n\n map<U>(fn: (value: Promise<HlsManifestData>) => U) {\n return this._data.map(fn)\n }\n\n pick<K extends keyof NonNullable<Promise<HlsManifestData>>>(key: K) {\n return this._data.pick(key)\n }\n\n get disposed(): boolean {\n return this.disposer.disposed\n }\n\n dispose(): void {\n this.abortSlot.abort()\n this.disposer.dispose()\n }\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { HlsTrackLoadOptions, HlsTrackDeps } from './HlsTrack'\nimport type { Maybe, RequestInterceptor } from '@amazon/vinyl-util'\nimport { createMediaSource } from '../../util/media/mediaSource'\nimport { createDefaultHlsMediaQualityMetadataResolver } from './HlsMediaQualityMetadataResolver'\nimport {\n MediaSourceControllerImpl,\n type MediaSourceControllerImplDeps,\n} from '../../streaming/buffering/MediaSourceController'\nimport { HlsManifestControllerImpl } from './HlsManifestController'\nimport {\n externalDependencies,\n type Factories,\n validateFactories,\n} from '@amazon/vinyl-di'\nimport { createUrlHlsManifestProvider } from './createUrlHlsManifestProvider'\nimport type { ContentStreamingOptions } from '../../streaming/ContentStreamingOptions'\nimport { createHlsContentTypesValue } from './createHlsContentTypesValue'\nimport { createHlsContentStreamFactories } from './createHlsContentStreamFactories'\nimport { createContentStreamFactory } from '../../streaming/ContentStream'\nimport type { ObservableValue } from '@amazon/vinyl-observable'\nimport type { PlaybackController } from '../../playback/PlaybackController'\nimport type { DrmKeySystemResolver } from '../../drm/DrmKeySystemResolver'\nimport type { DrmController } from '../../drm/DrmController'\nimport type { Capabilities } from '../../client/Capabilities'\nimport type { PlaybackSource } from '../../playback/PlaybackSource'\nimport type { QualitySelectorImplOptions } from '../../streaming/abr/QualitySelectorImpl'\nimport { QualitySelectorImpl } from '../../streaming/abr/QualitySelectorImpl'\nimport type { VinylOptions } from '../../vinyl/VinylOptions'\nimport { createDefaultHlsManifestTransformer } from './createDefaultHlsManifestTransformer'\nimport {\n buildHlsMediaTimeline,\n type BuildHlsMediaTimelineDeps,\n} from './buildHlsMediaTimeline'\nimport { createDefaultMediaTimelineTransformer } from '../../streaming/createDefaultMediaTimelineTransformer'\nimport type { HlsManifestData } from './HlsManifestProvider'\n\nexport interface HlsFactoryDeps {\n readonly options: ObservableValue<{\n readonly abr: QualitySelectorImplOptions\n readonly preferredAudioLanguage: string | null\n }>\n readonly playbackController: PlaybackController\n readonly playbackSource: PlaybackSource\n readonly drmKeySystemResolver: DrmKeySystemResolver\n readonly requestInterceptor: RequestInterceptor\n readonly drmController: DrmController\n readonly capabilities: Capabilities\n}\n\nexport type HlsInitOptions = {\n readonly streaming?: Maybe<ContentStreamingOptions>\n}\n\nexport function createHlsFactories(options: Maybe<HlsInitOptions>) {\n return (deps: HlsFactoryDeps) => {\n return (loadOptions: HlsTrackLoadOptions) => {\n const manifestProvider =\n loadOptions.manifestProvider ||\n createUrlHlsManifestProvider(\n loadOptions.uri,\n loadOptions.requestInit || undefined\n )\n\n return validateFactories({\n ...externalDependencies(deps),\n\n contentTypesValue: createHlsContentTypesValue,\n\n manifestController: () =>\n new HlsManifestControllerImpl(manifestProvider),\n\n manifestTransformed: createDefaultHlsManifestTransformer,\n\n mediaQualityMetadataResolver: () =>\n createDefaultHlsMediaQualityMetadataResolver(),\n\n mediaSourceFactory: () => createMediaSource,\n\n mediaSourceController: (deps: MediaSourceControllerImplDeps) =>\n new MediaSourceControllerImpl(deps),\n\n segmentRequestInit: () => loadOptions.segmentRequestInit,\n\n createContentStreamFactories: createHlsContentStreamFactories(\n options?.streaming\n ),\n contentStreamFactory: createContentStreamFactory,\n\n qualitySelector: (deps: {\n options: ObservableValue<Pick<VinylOptions, 'abr'>>\n }) =>\n new QualitySelectorImpl({\n options: deps.options.pick('abr'),\n }),\n\n mediaTimeline: (\n deps: BuildHlsMediaTimelineDeps & {\n readonly manifestTransformed: ObservableValue<\n Promise<HlsManifestData>\n >\n }\n ) =>\n deps.manifestTransformed.map(async (manifestPromise) => {\n const data = await manifestPromise\n return buildHlsMediaTimeline(deps, data)\n }),\n mediaTimelineTransformed: createDefaultMediaTimelineTransformer,\n } as const) satisfies Factories<HlsTrackDeps>\n }\n }\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { MainPlaylist, MediaPlaylist } from '@amazon/vinyl-hls-parser'\nimport { parseMainPlaylist, parseMediaPlaylist } from '@amazon/vinyl-hls-parser'\nimport type {\n Maybe,\n ReadonlyAbort,\n RequestInitOptions,\n} from '@amazon/vinyl-util'\nimport { memoize, requestWithRetry, resolveUrl } from '@amazon/vinyl-util'\nimport type {\n HlsManifestData,\n HlsManifestProvider,\n} from './HlsManifestProvider'\n\nexport function createUrlHlsManifestProvider(\n url: string,\n requestInit?: RequestInitOptions\n): HlsManifestProvider {\n return async (abort?: ReadonlyAbort): Promise<HlsManifestData> => {\n const mainResponse = await requestWithRetry(url, requestInit, {\n abort,\n })\n const mainText = await mainResponse.text()\n const mainPlaylist = parseMainPlaylist(mainText)\n\n // Use the response URL (after redirects) as the base for resolving\n // relative URIs in the manifest.\n const baseUrl = mainResponse.url || url\n\n const getMediaPlaylist = memoize(\n (uri: string) =>\n fetchMediaPlaylist({\n uri,\n baseUrl,\n defines: mainPlaylist.defines,\n requestInit,\n abort,\n }),\n (uri) => uri\n )\n\n return {\n mainPlaylist,\n baseUrl,\n getMediaPlaylist,\n }\n }\n}\n\nexport interface FetchMediaPlaylistOptions {\n /** The variant URI to resolve against the base URL. */\n readonly uri: string\n /** The base URL for resolving relative URIs. */\n readonly baseUrl: string\n /** Variable definitions from the main playlist. */\n readonly defines: MainPlaylist['defines']\n /** Optional request configuration. */\n readonly requestInit?: Maybe<RequestInitOptions>\n /** Optional abort signal. */\n readonly abort?: Maybe<ReadonlyAbort>\n}\n\n/**\n * Fetches and parses an HLS media playlist from a variant URI.\n */\nexport async function fetchMediaPlaylist(\n options: FetchMediaPlaylistOptions\n): Promise<MediaPlaylist> {\n const { uri, baseUrl, defines, requestInit, abort } = options\n const variantUrl = resolveUrl(uri, baseUrl)\n const response = await requestWithRetry(variantUrl, requestInit, { abort })\n const text = await response.text()\n return parseMediaPlaylist(text, defines)\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { ContentType } from '../../streaming/MediaQualityMetadata'\nimport type { ContentTypesValue } from '../../streaming/ContentTypesValue'\nimport type { ObservableValue } from '@amazon/vinyl-observable'\nimport type { HlsManifestData } from './HlsManifestProvider'\nimport type { MainPlaylist } from '@amazon/vinyl-hls-parser'\nimport { codecsToContentTypes } from '../mse/codec'\n\nexport interface HlsContentTypesValueDeps {\n readonly manifestTransformed: ObservableValue<Promise<HlsManifestData>>\n}\n\n/**\n * Creates an ObservableValue for the content types present in the HLS manifest.\n *\n * Per RFC 8216 \u00A74.3.4.2, content types are determined from:\n * 1. The CODECS attribute on EXT-X-STREAM-INF (variant streams)\n * 2. The TYPE attribute on EXT-X-MEDIA (alternative renditions)\n */\nexport function createHlsContentTypesValue(\n deps: HlsContentTypesValueDeps\n): ContentTypesValue {\n return deps.manifestTransformed.map(async (manifestData) => {\n return getContentTypes((await manifestData).mainPlaylist)\n })\n}\n\nfunction getContentTypes(mainPlaylist: MainPlaylist): Set<ContentType> {\n const contentTypes = new Set<ContentType>()\n\n // Derive content types from variant CODECS attributes.\n // Only audio and video are relevant for MSE; text (subtitles/CC) is not\n // appended via SourceBuffer in HLS.\n for (const variant of mainPlaylist.variants) {\n if (variant.codecs) {\n for (const type of codecsToContentTypes(variant.codecs)) {\n if (type === 'audio' || type === 'video') {\n contentTypes.add(type)\n }\n }\n }\n }\n\n // Add audio/video from separate renditions not already covered by variant codecs.\n for (const rendition of mainPlaylist.alternativeRenditions) {\n if (rendition.type === 'AUDIO') contentTypes.add('audio')\n if (rendition.type === 'VIDEO') contentTypes.add('video')\n }\n\n return contentTypes\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { MediaSourceController } from '../../streaming/buffering/MediaSourceController'\nimport type { PlaybackController } from '../../playback/PlaybackController'\nimport type { QualitySelector } from '../../streaming/abr/QualitySelector'\nimport type { ObservableValue } from '@amazon/vinyl-observable'\nimport { type ContentStreamImplDeps } from '../../streaming/ContentStream'\nimport type { ContentType } from '../../streaming/MediaQualityMetadata'\nimport {\n SourceBufferControllerImpl,\n type SourceBufferControllerImplDeps,\n} from '../../streaming/buffering/SourceBufferController'\nimport {\n BufferingControllerImpl,\n type BufferingControllerImplDeps,\n} from '../../streaming/buffering/BufferingController'\nimport {\n SegmentControllerImpl,\n type SegmentControllerImplDeps,\n} from '../../streaming/SegmentControllerImpl'\nimport { type Maybe, memoize } from '@amazon/vinyl-util'\nimport {\n externalDependencies,\n type Factories,\n validateFactories,\n} from '@amazon/vinyl-di'\nimport type { ContentStreamingOptions } from '../../streaming/ContentStreamingOptions'\nimport type { MediaTimeline } from '../../streaming/MediaTimeline'\n\nexport interface HlsContentStreamTrackDeps {\n readonly mediaSourceController: MediaSourceController\n readonly playbackController: PlaybackController\n readonly mediaTimelineTransformed: ObservableValue<Promise<MediaTimeline>>\n readonly qualitySelector: QualitySelector\n}\n\nexport function createHlsContentStreamFactories(\n options: Maybe<ContentStreamingOptions>\n) {\n return (deps: HlsContentStreamTrackDeps) =>\n memoize(\n (contentType: ContentType) => {\n return validateFactories({\n ...externalDependencies(deps),\n sourceBufferControllerFactory:\n (deps: SourceBufferControllerImplDeps) => () =>\n new SourceBufferControllerImpl(deps, contentType),\n bufferingController: (deps: BufferingControllerImplDeps) =>\n new BufferingControllerImpl(\n deps,\n contentType,\n options?.buffering\n ),\n segmentController: (deps: SegmentControllerImplDeps) =>\n new SegmentControllerImpl(\n deps,\n contentType,\n options?.segmentController\n ),\n } as const) satisfies Factories<ContentStreamImplDeps>\n },\n (contentType) => contentType\n )\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { ObservableValue } from '@amazon/vinyl-observable'\nimport type { HlsManifestData } from './HlsManifestProvider'\n\nexport interface HlsManifestTransformerDeps {\n readonly manifestController: ObservableValue<Promise<HlsManifestData>>\n}\n\n/**\n * The default HLS manifest transformer sorts variants by bandwidth descending (highest quality first).\n * Quality and language filtering is handled by the media timeline transformer.\n */\nexport function createDefaultHlsManifestTransformer(\n deps: HlsManifestTransformerDeps\n): ObservableValue<Promise<HlsManifestData>> {\n return deps.manifestController.map(async (v) => {\n const data = await v\n const sorted = [...data.mainPlaylist.variants].sort(\n (a, b) => b.bandwidth - a.bandwidth\n )\n return {\n ...data,\n mainPlaylist: {\n ...data.mainPlaylist,\n variants: sorted,\n },\n }\n })\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { ByteRange } from '@amazon/vinyl-mpd-parser'\nimport type { HlsByteRange } from '@amazon/vinyl-hls-parser'\n\n/** Converts an HLS byte range (`{offset, length}`) to a `ByteRange` (`[start, end]`). */\nexport function hlsByteRangeToMediaRange(byteRange: HlsByteRange): ByteRange {\n return [byteRange.offset, byteRange.offset + byteRange.length - 1]\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { HlsSegment } from '@amazon/vinyl-hls-parser'\nimport type { MediaSegmentReference } from '../../../streaming/SegmentReference'\nimport type { SegmentDataProvider } from '../../../streaming/SegmentDataSlot'\nimport {\n createSegmentDataProvider,\n type CreateSegmentDataProviderDeps,\n} from '../../createSegmentDataProvider'\nimport { hlsByteRangeToMediaRange } from './hlsByteRangeToMediaRange'\nimport { resolveUrl } from '@amazon/vinyl-util'\n\n/**\n * Builds a timeline of MediaSegmentReferences from an HLS media playlist's\n * segment list. Cumulative durations are used to compute start/end times.\n */\nexport function buildSegmentTimeline(\n deps: CreateSegmentDataProviderDeps,\n baseUrl: string,\n segments: readonly HlsSegment[]\n): readonly MediaSegmentReference<SegmentDataProvider>[] {\n const out: MediaSegmentReference<SegmentDataProvider>[] = new Array(\n segments.length\n )\n let time = 0\n for (let i = 0; i < segments.length; i++) {\n const seg = segments[i]\n const startTime = time\n const endTime = time + seg.duration\n const url = resolveUrl(seg.uri, baseUrl)\n out[i] = {\n timestampOffset: startTime,\n startTime,\n endTime,\n data: createSegmentDataProvider(deps, {\n url,\n mediaRange: seg.byteRange\n ? hlsByteRangeToMediaRange(seg.byteRange)\n : undefined,\n reportDownlinkMetrics: true,\n }),\n }\n time = endTime\n }\n return out\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { HlsManifestData } from './HlsManifestProvider'\nimport type { HlsMediaQualityMetadataResolver } from './HlsMediaQualityMetadataResolver'\nimport type {\n ContentType,\n MediaQualityMetadata,\n} from '../../streaming/MediaQualityMetadata'\nimport type {\n MediaPeriod,\n MediaQualityData,\n MediaTimeline,\n} from '../../streaming/MediaTimeline'\nimport type { SegmentReference } from '../../streaming/SegmentReference'\nimport type { SegmentDataProvider } from '../../streaming/SegmentDataSlot'\nimport { buildSegmentTimeline } from './util/hlsSegmentTime'\nimport { getSegmentAtTime } from '../../streaming/util/segment'\nimport { resolveUrl } from '@amazon/vinyl-util'\nimport { codecToContentType, contentTypeToMimeType } from '../mse/codec'\nimport {\n createSegmentDataProvider,\n type CreateSegmentDataProviderDeps,\n} from '../createSegmentDataProvider'\nimport { hlsByteRangeToMediaRange } from './util/hlsByteRangeToMediaRange'\nimport { createTransmuxer } from '@amazon/vinyl-transmux'\n\nexport interface BuildHlsMediaTimelineDeps extends CreateSegmentDataProviderDeps {\n readonly mediaQualityMetadataResolver: HlsMediaQualityMetadataResolver\n}\n\n/**\n * Builds a MediaTimeline from an HLS manifest.\n * HLS has a single implicit period spanning the full duration.\n */\nexport function buildHlsMediaTimeline(\n deps: BuildHlsMediaTimelineDeps,\n data: HlsManifestData\n): MediaTimeline {\n const { mainPlaylist, baseUrl } = data\n const renditions = mainPlaylist.alternativeRenditions\n\n // HLS duration requires fetching a media playlist, so compute it lazily.\n const DEFAULT_MIN_BUFFER_TIME = 10\n\n const qualities: MediaQualityData[] = mainPlaylist.variants.flatMap(\n (variant) => {\n const baseMetadata = deps.mediaQualityMetadataResolver(\n variant,\n renditions\n )\n\n // Determine which content types this variant carries.\n const codecs = variant.codecs?.split(',') ?? []\n const contentTypes = new Set(\n codecs\n .map((c) => codecToContentType(c))\n .filter((t): t is ContentType => t != null)\n )\n // If no codecs, default to audio (e.g. TS streams).\n if (contentTypes.size === 0) contentTypes.add('audio')\n\n // Create one quality per content type, with narrowed mimeType.\n return [...contentTypes].map((contentType) => {\n const codec =\n codecs.find((c) => codecToContentType(c) === contentType) ??\n null\n const metadata: MediaQualityMetadata = {\n ...baseMetadata,\n contentType,\n mimeType: contentTypeToMimeType(contentType, codec),\n codecs: codec,\n }\n const transmuxer = createTransmuxer()\n\n return {\n metadata,\n async getSegment(\n time: number,\n affordance = 0\n ): Promise<SegmentReference<SegmentDataProvider> | null> {\n // For an audio quality on a variant that also carries video,\n // the audio is delivered through a separate rendition group\n // (variant URI is video-only). Use the rendition URI in that\n // case. Otherwise the variant URI itself contains the audio.\n let playlistUri = variant.uri\n if (\n metadata.contentType === 'audio' &&\n variant.audioGroup &&\n contentTypes.has('video')\n ) {\n const rendition = renditions.find(\n (r) =>\n r.type === 'AUDIO' &&\n r.groupId === variant.audioGroup &&\n r.uri\n )\n if (rendition?.uri) playlistUri = rendition.uri\n }\n const playlist =\n await data.getMediaPlaylist(playlistUri)\n const playlistBaseUrl = resolveUrl(playlistUri, baseUrl)\n const segments = buildSegmentTimeline(\n deps,\n playlistBaseUrl,\n playlist.segments\n )\n const segment = getSegmentAtTime(\n time,\n segments,\n affordance\n )\n if (!segment) return null\n\n // fMP4: use #EXT-X-MAP init segment directly.\n const hlsMap = playlist.segments[0]?.map\n if (hlsMap) {\n return {\n quality: metadata,\n ...segment,\n initData: createSegmentDataProvider(deps, {\n url: resolveUrl(\n hlsMap.uri,\n playlistBaseUrl\n ),\n mediaRange: hlsMap.byteRange\n ? hlsByteRangeToMediaRange(\n hlsMap.byteRange\n )\n : undefined,\n reportDownlinkMetrics: false,\n }),\n }\n }\n\n // MPEG-TS/ADTS: transmux to fMP4.\n const transmuxedQuality: MediaQualityMetadata = {\n ...metadata,\n mimeType: contentTypeToMimeType(\n metadata.contentType!,\n metadata.codecs\n ),\n }\n const rawDataProvider = segment.data\n return {\n quality: transmuxedQuality,\n ...segment,\n data: async (abort) => {\n const raw = await rawDataProvider(abort)\n return transmuxer.transmux(raw).mediaSegment\n },\n initData: async (abort) => {\n const raw = await rawDataProvider(abort)\n return transmuxer.transmux(raw).initSegment\n },\n }\n },\n } satisfies MediaQualityData\n })\n }\n )\n\n const period: MediaPeriod = {\n startTime: 0,\n endTime: Infinity,\n qualities,\n }\n\n let cachedDuration: number | null = null\n\n return {\n periods: [period],\n minBufferTime: DEFAULT_MIN_BUFFER_TIME,\n async getDuration() {\n if (cachedDuration != null) return cachedDuration\n if (mainPlaylist.variants.length === 0) {\n throw new Error('Unable to determine HLS duration: no variants')\n }\n const playlist = await data.getMediaPlaylist(\n mainPlaylist.variants[0].uri\n )\n // Live playlists (no EXT-X-ENDLIST) have unbounded duration.\n if (!playlist.ended) return Infinity\n if (playlist.segments.length === 0) {\n throw new Error(\n 'Unable to determine HLS duration: no segments in media playlist'\n )\n }\n let total = 0\n for (const seg of playlist.segments) total += seg.duration\n cachedDuration = total\n return cachedDuration\n },\n }\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {\n bufferToByteArray,\n type Disposable,\n DisposedError,\n ErrorOrigin,\n EventHostImpl,\n type Unsubscribe,\n} from '@amazon/vinyl-util'\nimport {\n type CommonEme,\n type CommonMediaKeys,\n type CommonMediaKeySession,\n CommonMediaKeySessionError,\n type CommonMediaKeySessionEventMap,\n type CommonMediaKeySystemAccess,\n MediaKeySessionErrorType,\n} from './CommonEme'\nimport type { DrmKeySystem } from '../DrmKeySystem'\nimport { type EncryptedInitData } from './EncryptedInitData'\nimport type { MSMediaKeyMessageEvent } from '../dom/MSMediaKeys'\nimport { DrmError } from '../error/DrmError'\nimport type { DrmInitDataType } from '../../streaming/DrmInitDataType'\n\ndeclare global {\n interface HTMLMediaElementEventMap extends HTMLElementEventMap {\n readonly msneedkey: MSMediaKeyNeededEvent\n }\n\n interface MSMediaKeyNeededEvent extends Event {\n readonly initDataType: string\n readonly initData: Uint8Array<ArrayBuffer> | null\n }\n}\n\n/**\n * A CommonEme implementation of MS prefixed Encrypted Media Extensions as supported by IE11/Edge.\n */\nexport class MsCommonEme implements CommonEme {\n requestMediaKeySystemAccess(\n keySystem: DrmKeySystem,\n supportedConfigurations: readonly MediaKeySystemConfiguration[]\n ): Promise<CommonMediaKeySystemAccess> {\n for (const config of supportedConfigurations) {\n const capabilities = [\n ...(config.audioCapabilities ?? []),\n ...(config.videoCapabilities ?? []),\n ]\n for (const capability of capabilities) {\n if (\n MSMediaKeys.isTypeSupported(\n keySystem,\n capability.contentType\n )\n ) {\n return Promise.resolve(\n new MsCommonMediaKeySystemAccess(keySystem)\n )\n }\n }\n }\n return Promise.reject(\n new DrmError(\n `keySystem not supported: ${keySystem}`,\n { keySystem },\n ErrorOrigin.DRM\n )\n )\n }\n\n /**\n * Listens to the element for an encrypted event, returning a disposable handle.\n */\n addEncryptedListener(\n element: HTMLMediaElement,\n handler: (event: MediaEncryptedEvent) => void\n ): Unsubscribe {\n const event = 'msneedkey'\n element.addEventListener(event, handler as EventListener)\n return () =>\n element.removeEventListener(event, handler as EventListener)\n }\n}\n\nexport class MsCommonMediaKeySystemAccess implements CommonMediaKeySystemAccess {\n constructor(readonly keySystem: DrmKeySystem) {}\n\n createMediaKeys(): Promise<CommonMediaKeys> {\n const msMediaKeys = new MSMediaKeys(this.keySystem)\n return Promise.resolve(\n new MsCommonMediaKeys(this.keySystem, msMediaKeys)\n )\n }\n}\n\n/**\n * @private\n */\nexport class MsCommonMediaKeys implements CommonMediaKeys {\n constructor(\n public readonly keySystem: DrmKeySystem,\n public readonly mediaKeys: MSMediaKeys\n ) {}\n\n /**\n * Sets the media keys on the given element.\n */\n setOnElement(element: HTMLMediaElement): Promise<void> {\n element.msSetMediaKeys!(this.mediaKeys)\n return Promise.resolve()\n }\n\n /**\n * Clears the media keys from the given element.\n */\n clearFromElement(element: HTMLMediaElement): Promise<void> {\n element.msSetMediaKeys!(null)\n return Promise.resolve()\n }\n\n setServerCertificate(_certificate: BufferSource): Promise<boolean> {\n return Promise.resolve(false)\n }\n\n createSession(\n mimeType: string,\n initDataType: DrmInitDataType,\n initData: EncryptedInitData\n ): CommonMediaKeySession {\n const session = this.mediaKeys.createSession(\n mimeType,\n bufferToByteArray(initData)\n )\n return new MsCommonMediaKeySession(\n session,\n mimeType,\n initDataType,\n initData\n )\n }\n}\n\n/**\n * @private\n */\nexport class MsCommonMediaKeySession\n extends EventHostImpl<CommonMediaKeySessionEventMap>\n implements CommonMediaKeySession, Disposable\n{\n private _disposed: boolean = false\n\n constructor(\n private readonly session: MSMediaKeySession,\n readonly mimeType: string,\n readonly initDataType: DrmInitDataType,\n readonly initData: EncryptedInitData\n ) {\n super()\n session.addEventListener('mskeymessage', this.messageHandler)\n session.addEventListener('mskeyerror', this.errorHandler)\n }\n\n private readonly messageHandler = (event: MSMediaKeyMessageEvent) => {\n this.dispatch('message', {\n message: event.message.buffer as ArrayBuffer,\n })\n }\n\n private readonly errorHandler = (): void => {\n if (this.session.error) {\n const e = this.session.error\n const error = new CommonMediaKeySessionError(\n e.code,\n msErrorCodeToStr(e.code),\n e.systemCode,\n msErrorCodeToStr(e.systemCode)\n )\n this.dispatch('error', { error, target: this })\n }\n }\n\n update(key: ArrayBuffer): Promise<void> {\n if (this.disposed) return Promise.reject(new DisposedError())\n this.session.update(new Uint8Array(key))\n return Promise.resolve()\n }\n\n get disposed(): boolean {\n return this._disposed\n }\n\n dispose(): void {\n super.dispose()\n this._disposed = true\n this.session.close()\n this.session.removeEventListener('mskeymessage', this.messageHandler)\n this.session.removeEventListener('mskeyerror', this.errorHandler)\n }\n}\n\n/**\n * Returns a string for the WebKit media key error.\n */\nexport function msErrorCodeToStr(code: number): MediaKeySessionErrorType {\n switch (code) {\n case MSMediaKeyError.MS_MEDIA_KEYERR_CLIENT:\n return MediaKeySessionErrorType.CLIENT\n case MSMediaKeyError.MS_MEDIA_KEYERR_DOMAIN:\n return MediaKeySessionErrorType.DOMAIN\n case MSMediaKeyError.MS_MEDIA_KEYERR_HARDWARECHANGE:\n return MediaKeySessionErrorType.HARDWARECHANGE\n case MSMediaKeyError.MS_MEDIA_KEYERR_OUTPUT:\n return MediaKeySessionErrorType.OUTPUT\n case MSMediaKeyError.MS_MEDIA_KEYERR_SERVICE:\n return MediaKeySessionErrorType.SERVICE\n case MSMediaKeyError.MS_MEDIA_KEYERR_UNKNOWN:\n default:\n return MediaKeySessionErrorType.UNKNOWN\n }\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * An common interface to unify multiple EME implementations.\n * @module\n */\n\nimport type { DrmKeySystem } from '../DrmKeySystem'\nimport type { Json, ReadonlyEventHost, Unsubscribe } from '@amazon/vinyl-util'\nimport { ErrorLevel, ErrorOrigin, ReportableError } from '@amazon/vinyl-util'\nimport type { EncryptedInitData } from './EncryptedInitData'\nimport type { DrmInitDataType } from '../../streaming/DrmInitDataType'\nimport type { BasicErrorEvent } from '../../event/BasicErrorEvent'\n\n/**\n * Top-level Common EME methods for initiating encrypted audio session.\n *\n * Created to unify standard and non-standard EME interfaces.\n */\nexport interface CommonEme {\n requestMediaKeySystemAccess(\n keySystem: DrmKeySystem,\n supportedConfigurations: readonly MediaKeySystemConfiguration[]\n ): Promise<CommonMediaKeySystemAccess>\n\n addEncryptedListener(\n element: HTMLMediaElement,\n handler: (event: CommonMediaEncryptedEvent) => void\n ): Unsubscribe\n}\n\nexport interface CommonMediaEncryptedEvent {\n /**\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaEncryptedEvent/initData)\n */\n readonly initData: EncryptedInitData | null\n\n /**\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaEncryptedEvent/initDataType)\n */\n readonly initDataType: string\n}\n\n/**\n * This provides a common interface for MediaKeySystemAccess EME implementations.\n */\nexport interface CommonMediaKeySystemAccess {\n readonly keySystem: DrmKeySystem\n createMediaKeys(): Promise<CommonMediaKeys>\n}\n\n/**\n * This provides a common interface for MediaKeys EME implementations.\n */\nexport interface CommonMediaKeys {\n readonly keySystem: DrmKeySystem\n\n /**\n * Sets the media keys on the given element.\n * @param element\n */\n setOnElement(element: HTMLMediaElement): Promise<void>\n\n /**\n * Clears the media keys from the given element.\n * This is only allowed if the element's src isn't set.\n * https://bugs.chromium.org/p/chromium/issues/detail?id=462365#c7\n * @param element\n */\n clearFromElement(element: HTMLMediaElement): Promise<void>\n\n /**\n * Sets the server certificate on the media keys.\n *\n * A Promise that resolves to a boolean. If the Key System implementation\n * represented by this object's content decryption module's implementation\n * value does not support server certificates, return a promise resolved\n * with false.\n *\n * @param certificate The server certificate data.\n */\n setServerCertificate(certificate: BufferSource): Promise<boolean>\n\n /**\n * Creates the key session.\n *\n * @param mimeType\n * @param initDataType\n * @param initData The initialization data from the 'encrypted' event.\n */\n createSession(\n mimeType: string,\n initDataType: DrmInitDataType,\n initData: EncryptedInitData\n ): CommonMediaKeySession\n}\n\n/**\n * Common media key session events\n */\nexport interface CommonMediaKeySessionEventMap {\n /**\n * Dispatched when a message is generated by the content decryption module.\n */\n readonly message: CommonMediaKeyMessageEvent\n\n /**\n * Dispatched when an error occurs.\n */\n readonly error: BasicErrorEvent\n\n /**\n * Dispatched when the session is forcibly closed by the CDM.\n */\n readonly closed: CommonMediaKeySessionClosedEvent\n}\n\n/**\n * This provides a common interface for MediaKeySession EME implementations.\n */\nexport interface CommonMediaKeySession extends ReadonlyEventHost<CommonMediaKeySessionEventMap> {\n readonly mimeType: string\n readonly initDataType: DrmInitDataType\n readonly initData: EncryptedInitData\n\n /**\n * Updates the session with the license data.\n * @param key\n */\n update(key: ArrayBuffer): Promise<void>\n\n /**\n * Returns true if the session has been disposed.\n */\n get disposed(): boolean\n\n /**\n * Closes the session, and removes session handling and event listeners, freeing this session\n * handler for GC.\n *\n * Note: The audio source should be cleared first.\n */\n dispose(): void\n}\n\n/**\n * A media key session error, translated from the specific media key session implementation.\n */\nexport class CommonMediaKeySessionError extends ReportableError {\n get [Symbol.toStringTag](): string {\n return 'CommonMediaKeySessionError'\n }\n\n constructor(\n readonly code: number,\n readonly codeStr: MediaKeySessionErrorType,\n readonly systemCode: number,\n readonly systemCodeStr: MediaKeySessionErrorType\n ) {\n super(codeStr, ErrorOrigin.DRM, ErrorLevel.WARN)\n Object.setPrototypeOf(this, CommonMediaKeySessionError.prototype)\n }\n\n toJSON(): Json {\n return {\n ...super.toJSON(),\n code: this.code,\n codeStr: this.codeStr,\n systemCode: this.systemCode,\n systemCodeStr: this.systemCodeStr,\n }\n }\n}\n\n/**\n * Common media key message event body.\n */\nexport interface CommonMediaKeyMessageEvent {\n readonly message: ArrayBuffer\n}\n\nexport interface CommonMediaKeySessionClosedEvent {\n /**\n * The reason the session was closed.\n */\n readonly reason: MediaKeySessionClosedReason\n}\n\n/**\n * String representations of session error codes.\n */\nexport enum MediaKeySessionErrorType {\n CLIENT = 'CLIENT',\n DOMAIN = 'DOMAIN',\n HARDWARECHANGE = 'HARDWARECHANGE',\n OUTPUT = 'OUTPUT',\n SERVICE = 'SERVICE',\n UNKNOWN = 'UNKNOWN',\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { ErrorOrigin, type Json } from '@amazon/vinyl-util'\nimport { ErrorLevel, ReportableError } from '@amazon/vinyl-util'\n\n/**\n * An error originating from the DrmController.\n * If an error comes from a key session, `extra.error` will be set with the original error and origin will be DRM.\n */\nexport class DrmError<ExtraType = any> extends ReportableError {\n get [Symbol.toStringTag](): string {\n return 'DrmError'\n }\n\n constructor(\n readonly message: string,\n private readonly extra: ExtraType | null = null,\n readonly origin: string = ErrorOrigin.DRM,\n readonly level: ErrorLevel = ErrorLevel.FATAL\n ) {\n super(message, origin, level)\n Object.setPrototypeOf(this, DrmError.prototype)\n }\n\n toJSON(): Json {\n return { ...super.toJSON(), extra: this.extra }\n }\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {\n type Disposable,\n DisposedError,\n EventHostImpl,\n noop,\n type Unsubscribe,\n} from '@amazon/vinyl-util'\nimport type {\n CommonEme,\n CommonMediaEncryptedEvent,\n CommonMediaKeyMessageEvent,\n CommonMediaKeys,\n CommonMediaKeySession,\n CommonMediaKeySessionEventMap,\n CommonMediaKeySystemAccess,\n} from './CommonEme'\nimport type { DrmKeySystem } from '../DrmKeySystem'\nimport { type EncryptedInitData } from './EncryptedInitData'\nimport { createDrmErrorHandler } from './createDrmErrorHandler'\nimport type { DrmInitDataType } from '../../streaming/DrmInitDataType'\n\n/**\n * A CommonEme implementation of unprefixed Encrypted Media Extensions.\n */\nexport class StandardCommonEme implements CommonEme {\n async requestMediaKeySystemAccess(\n keySystem: DrmKeySystem,\n supportedConfigurations: readonly MediaKeySystemConfiguration[]\n ): Promise<CommonMediaKeySystemAccess> {\n const access = await navigator\n .requestMediaKeySystemAccess(keySystem, supportedConfigurations)\n .catch(createDrmErrorHandler())\n return new StandardCommonMediaKeySystemAccess(keySystem, access)\n }\n\n addEncryptedListener(\n element: HTMLMediaElement,\n handler: (event: CommonMediaEncryptedEvent) => void\n ): Unsubscribe {\n element.addEventListener('encrypted', handler)\n return () => element.removeEventListener('encrypted', handler)\n }\n}\n\n/**\n * CommonMediaKeySystemAccess for unprefixed EME implementations.\n */\nexport class StandardCommonMediaKeySystemAccess implements CommonMediaKeySystemAccess {\n constructor(\n public readonly keySystem: DrmKeySystem,\n private readonly access: MediaKeySystemAccess\n ) {}\n\n /**\n * @return {Promise<CommonMediaKeys>}\n */\n async createMediaKeys(): Promise<CommonMediaKeys> {\n const mediaKeys = await this.access\n .createMediaKeys()\n .catch(createDrmErrorHandler())\n return new StandardCommonMediaKeys(this.keySystem, mediaKeys)\n }\n}\n\n/**\n * CommonMediaKeys for unprefixed EME implementations.\n */\nexport class StandardCommonMediaKeys implements CommonMediaKeys {\n constructor(\n public readonly keySystem: DrmKeySystem,\n private readonly mediaKeys: MediaKeys\n ) {}\n\n setOnElement(element: HTMLMediaElement): Promise<void> {\n return element.setMediaKeys(this.mediaKeys)\n }\n\n clearFromElement(element: HTMLMediaElement): Promise<void> {\n return element.setMediaKeys(null)\n }\n\n async setServerCertificate(certificate: BufferSource): Promise<boolean> {\n return this.mediaKeys.setServerCertificate(certificate)\n }\n\n createSession(\n mimeType: string,\n initDataType: DrmInitDataType,\n initData: EncryptedInitData\n ): CommonMediaKeySession {\n return new StandardCommonMediaKeySession(\n this.mediaKeys.createSession('temporary'),\n mimeType,\n initDataType,\n initData\n )\n }\n}\n\n/**\n * CommonMediaKeySession for unprefixed EME implementations.\n */\nexport class StandardCommonMediaKeySession\n extends EventHostImpl<CommonMediaKeySessionEventMap>\n implements CommonMediaKeySession, Disposable\n{\n get [Symbol.toStringTag](): string {\n return 'StandardCommonMediaKeySession'\n }\n\n private _disposed = false\n\n private readonly messageHandler = (event: CommonMediaKeyMessageEvent) => {\n this.dispatch('message', {\n message: event.message,\n })\n }\n\n constructor(\n private readonly session: MediaKeySession,\n readonly mimeType: string,\n readonly initDataType: DrmInitDataType,\n readonly initData: EncryptedInitData\n ) {\n super()\n session.addEventListener('message', this.messageHandler)\n if ((session as any).closed) {\n // Compatibility: React Native MSE does not provide a 'closed' promise.\n session.closed\n .then((reason) => {\n this.dispatch('closed', {\n reason,\n })\n })\n .catch(noop)\n }\n this.generateRequest().catch((error) => {\n this.dispatch('error', {\n error,\n target: this,\n })\n })\n }\n\n private generateRequest(): Promise<void> {\n const initData = this.initData\n return this.session\n .generateRequest(\n this.initDataType,\n initData instanceof ArrayBuffer ? initData : initData.buffer\n )\n .catch(createDrmErrorHandler())\n }\n\n update(key: ArrayBufferLike): Promise<void> {\n if (this.disposed) throw new DisposedError()\n return this.session.update(key as ArrayBuffer)\n }\n\n get disposed(): boolean {\n return this._disposed\n }\n\n dispose(): void {\n super.dispose()\n this._disposed = true\n this.session.removeEventListener('message', this.messageHandler)\n this.session.close().catch(noop)\n }\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { DrmError } from '../error/DrmError'\nimport { ErrorLevel, ErrorOrigin, toJson } from '@amazon/vinyl-util'\n\nexport function createDrmErrorHandler(\n level: ErrorLevel = ErrorLevel.FATAL\n): (error: Error) => never {\n return (error) => {\n throw new DrmError(\n error.message,\n { error: toJson(error) },\n ErrorOrigin.DRM,\n level\n )\n }\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { Unsubscribe } from '@amazon/vinyl-util'\nimport {\n bufferToByteArray,\n type Disposable,\n DisposedError,\n ErrorOrigin,\n EventHostImpl,\n} from '@amazon/vinyl-util'\nimport type {\n CommonEme,\n CommonMediaEncryptedEvent,\n CommonMediaKeys,\n CommonMediaKeySession,\n CommonMediaKeySessionEventMap,\n CommonMediaKeySystemAccess,\n} from './CommonEme'\nimport {\n CommonMediaKeySessionError,\n MediaKeySessionErrorType,\n} from './CommonEme'\nimport type { WebKitMediaKeyMessageEvent } from '../dom/WebKitMediaKeys'\nimport type { DrmKeySystem } from '../DrmKeySystem'\nimport { DrmError } from '../error/DrmError'\nimport type { EncryptedInitData } from './EncryptedInitData'\nimport type { DrmInitDataType } from '../../streaming/DrmInitDataType'\n\ndeclare global {\n interface HTMLMediaElementEventMap extends HTMLElementEventMap {\n readonly webkitneedkey: WebKitMediaKeyNeededEvent\n }\n\n interface WebKitMediaKeyNeededEvent extends Event {\n readonly initDataType: string\n readonly initData: Uint8Array<ArrayBuffer> | null\n }\n}\n\n/**\n * A CommonEme implementation of WebKit-prefixed Encrypted Media Extensions.\n */\nexport class WebKitCommonEme implements CommonEme {\n requestMediaKeySystemAccess(\n keySystem: DrmKeySystem,\n supportedConfigurations: readonly MediaKeySystemConfiguration[]\n ): Promise<CommonMediaKeySystemAccess> {\n for (const config of supportedConfigurations) {\n const capabilities = [\n ...(config.audioCapabilities ?? []),\n ...(config.videoCapabilities ?? []),\n ]\n for (const capability of capabilities) {\n if (\n WebKitMediaKeys.isTypeSupported(\n keySystem,\n capability.contentType\n )\n ) {\n return Promise.resolve(\n new WebKitCommonMediaKeySystemAccess(keySystem)\n )\n }\n }\n }\n return Promise.reject(\n new DrmError(\n `keySystem not supported: ${keySystem}`,\n { keySystem },\n ErrorOrigin.DRM\n )\n )\n }\n\n addEncryptedListener(\n element: HTMLMediaElement,\n handler: (event: CommonMediaEncryptedEvent) => void\n ): Unsubscribe {\n element.addEventListener('webkitneedkey', handler)\n return () => element.removeEventListener('webkitneedkey', handler)\n }\n}\n\nexport class WebKitCommonMediaKeySystemAccess implements CommonMediaKeySystemAccess {\n constructor(public readonly keySystem: DrmKeySystem) {}\n\n createMediaKeys(): Promise<CommonMediaKeys> {\n const webKitMediaKeys = new WebKitMediaKeys(this.keySystem)\n const webkitCommonMediaKeys = new WebKitCommonMediaKeys(\n this.keySystem,\n webKitMediaKeys\n )\n return Promise.resolve(webkitCommonMediaKeys)\n }\n}\n\n/** @private */\nexport class WebKitCommonMediaKeys implements CommonMediaKeys {\n constructor(\n public readonly keySystem: DrmKeySystem,\n public readonly mediaKeys: WebKitMediaKeys\n ) {}\n\n /**\n * Sets the media keys on the given element.\n */\n setOnElement(element: HTMLMediaElement): Promise<void> {\n element.webkitSetMediaKeys!(this.mediaKeys)\n return Promise.resolve()\n }\n\n /**\n * Clears the media keys from the given element.\n */\n clearFromElement(element: HTMLMediaElement): Promise<void> {\n element.webkitSetMediaKeys!(null)\n return Promise.resolve()\n }\n\n setServerCertificate(_certificate: BufferSource): Promise<boolean> {\n return Promise.resolve(false)\n }\n\n createSession(\n mimeType: string,\n initDataType: DrmInitDataType,\n initData: EncryptedInitData\n ): CommonMediaKeySession {\n const session = this.mediaKeys.createSession(\n mimeType,\n bufferToByteArray(initData)\n )\n return new WebKitCommonMediaKeySession(\n session,\n mimeType,\n initDataType,\n initData\n )\n }\n}\n\n/** @private */\nexport class WebKitCommonMediaKeySession\n extends EventHostImpl<CommonMediaKeySessionEventMap>\n implements CommonMediaKeySession, Disposable\n{\n private _disposed: boolean = false\n\n constructor(\n private readonly session: WebKitMediaKeySession,\n readonly mimeType: string,\n readonly initDataType: DrmInitDataType,\n readonly initData: EncryptedInitData\n ) {\n super()\n session.addEventListener('webkitkeymessage', this.messageHandler)\n session.addEventListener('webkitkeyerror', this.errorHandler)\n }\n\n private readonly messageHandler = (event: WebKitMediaKeyMessageEvent) => {\n this.dispatch('message', {\n message: event.message.buffer as ArrayBuffer,\n })\n }\n\n private readonly errorHandler = () => {\n if (this.session.error) {\n const e = this.session.error\n const error = new CommonMediaKeySessionError(\n e.code,\n webkitErrorCodeToStr(e.code),\n e.systemCode,\n webkitErrorCodeToStr(e.systemCode)\n )\n this.dispatch('error', { error, target: this })\n }\n }\n\n update(key: ArrayBuffer): Promise<void> {\n if (this.disposed) return Promise.reject(new DisposedError())\n this.session.update(new Uint8Array(key))\n return Promise.resolve()\n }\n\n get disposed() {\n return this._disposed\n }\n\n dispose(): void {\n super.dispose()\n this._disposed = true\n this.session.removeEventListener(\n 'webkitkeymessage',\n this.messageHandler\n )\n this.session.removeEventListener('webkitkeyerror', this.errorHandler)\n // Do not wait on close, and ignore errors.\n this.session.close()\n }\n}\n\n/**\n * Returns a string for the WebKit media key error.\n */\nexport function webkitErrorCodeToStr(code: number): MediaKeySessionErrorType {\n switch (code) {\n case WebKitMediaKeyError.MEDIA_KEYERR_CLIENT:\n return MediaKeySessionErrorType.CLIENT\n case WebKitMediaKeyError.MEDIA_KEYERR_DOMAIN:\n return MediaKeySessionErrorType.DOMAIN\n case WebKitMediaKeyError.MEDIA_KEYERR_HARDWARECHANGE:\n return MediaKeySessionErrorType.HARDWARECHANGE\n case WebKitMediaKeyError.MEDIA_KEYERR_OUTPUT:\n return MediaKeySessionErrorType.OUTPUT\n case WebKitMediaKeyError.MEDIA_KEYERR_SERVICE:\n return MediaKeySessionErrorType.SERVICE\n case WebKitMediaKeyError.MEDIA_KEYERR_UNKNOWN:\n default:\n return MediaKeySessionErrorType.UNKNOWN\n }\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { MsCommonEme } from './MsCommonEme'\nimport { StandardCommonEme } from './StandardCommonEme'\nimport { WebKitCommonEme } from './WebKitCommonEme'\nimport type { CommonEme } from './CommonEme'\nimport { globalRef } from '@amazon/vinyl-util'\n\n/**\n * Common EME Factory provides the first supported implementation of CommonEme.\n * The priority is WebKit, Standard, then MS.\n *\n * Note: WebKit if present is currently prioritized over standard for legacy reasons. This may be an obsolete\n * requirement. https://jira.music.amazon.dev/browse/PLAYBACK-6072 ticket to investigate.\n */\nexport function commonEmeFactory(): CommonEme | null {\n if (supportsWebKitEme()) return new WebKitCommonEme()\n if (supportsStandardEme()) return new StandardCommonEme()\n if (supportsMsEme()) return new MsCommonEme()\n return null\n}\n\n/**\n * Tests for Standard Eme support.\n */\nexport function supportsStandardEme(): boolean {\n return mediaKeySupportRef.value.standardEme\n}\n\n/**\n * Tests for WebKitEme support.\n */\nexport function supportsWebKitEme(): boolean {\n return mediaKeySupportRef.value.webkitEme\n}\n\n/**\n * Tests for MsEme support.\n */\nexport function supportsMsEme(): boolean {\n return mediaKeySupportRef.value.msEme\n}\n\nexport type MediaKeySupport = {\n readonly standardEme: boolean\n readonly webkitEme: boolean\n readonly msEme: boolean\n}\n\nexport const mediaKeySupportRef = /* @__PURE__ */ globalRef<MediaKeySupport>(() => {\n return {\n standardEme: typeof MediaKeys !== 'undefined',\n webkitEme: typeof WebKitMediaKeys !== 'undefined',\n msEme: typeof (global as any).MSMediaKeys !== 'undefined',\n }\n})\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {\n AbortError,\n base64ToByteArray,\n buffersEqual,\n bufferToByteArray,\n clone,\n type Comparator,\n compareBy,\n createDisposer,\n ErrorOrigin,\n EventHostImpl,\n isSilentError,\n logDebug,\n logVerbose,\n type Maybe,\n memoize,\n noop,\n normalizeHeadersInit,\n type ReadonlyAbort,\n remove,\n resolveValueProvider,\n withTimeout,\n} from '@amazon/vinyl-util'\nimport { instanceOf, object, type ObjectSchema } from '@amazon/vinyl-validation'\nimport {\n type DrmMediaKeySystemOptions,\n type DrmOptions,\n DrmRobustness,\n type InitDataTransformer,\n} from './DrmOptions'\nimport type {\n DrmController,\n DrmControllerEventMap,\n DrmKeySystemSupport,\n} from './DrmController'\nimport type {\n CommonEme,\n CommonMediaEncryptedEvent,\n CommonMediaKeyMessageEvent,\n CommonMediaKeys,\n CommonMediaKeySession,\n CommonMediaKeySystemAccess,\n} from './commonEme/CommonEme'\nimport { DrmError } from './error/DrmError'\nimport type { EncryptedInitData } from './commonEme/EncryptedInitData'\nimport { DrmKeySystem, isPlayReady } from './DrmKeySystem'\nimport type { DrmInitDataType } from '../streaming/DrmInitDataType'\nimport type {\n ContentType,\n MediaFormatMetadata,\n} from '../streaming/MediaQualityMetadata'\nimport { unpackPlayReadyChallenge } from './util/unpackPlayReadyChallenge'\nimport type {\n LicenseProvider,\n ServerCertificate,\n} from './licenseProvider/LicenseProvider'\nimport { defaultLicenseProvider } from './licenseProvider/defaultLicenseProvider'\nimport { extractContentId } from './util/extractContentId'\nimport { createFairPlaySessionInitData } from './util/createFairPlaySessionInitData'\n\n/**\n * The number of seconds a license request will be allowed before timing out.\n * This should be higher than the network timeout.\n *\n * In practice, network requests will time out before this, and a license timeout\n * indicates a stalled promise result from the license provider.\n */\nexport const LICENSE_TIMEOUT = 90\nconst LICENSE_TIMEOUT_MESSAGE = 'License provider timed out after {time}s'\n\n/**\n * Dependencies for creating DrmController.\n */\nexport interface DrmControllerImplDeps {\n readonly media: HTMLMediaElement\n readonly commonEme: CommonEme | null\n}\n\nexport interface DrmControllerMessageProps {\n readonly mediaKeys: CommonMediaKeys\n readonly session: CommonMediaKeySession\n readonly event: CommonMediaKeyMessageEvent\n}\n\nexport class DrmControllerImpl\n extends EventHostImpl<DrmControllerEventMap>\n implements DrmController\n{\n get [Symbol.toStringTag](): string {\n return 'DrmControllerImpl'\n }\n\n private readonly optionsBase: DrmOptions\n private options: DrmOptions\n\n private mediaKeys: CommonMediaKeys | null = null\n private mediaKeysPromise: Promise<CommonMediaKeys> | null = null\n private readonly sessions: CommonMediaKeySession[] = []\n\n private _error: Error | null = null\n private drmInfo: MediaFormatMetadata | null = null\n private sessionAbort: ReadonlyAbort | null = null\n\n private pendingMessageProps: DrmControllerMessageProps | null = null\n private readonly disposer = /* @__PURE__ */ createDisposer()\n\n constructor(\n private readonly deps: DrmControllerImplDeps,\n options?: Maybe<Partial<DrmOptions>>\n ) {\n super()\n this.optionsBase = { keySystems: {}, ...options }\n this.options = this.optionsBase\n\n if (this.deps.commonEme) {\n this.disposer.add(\n this.deps.commonEme.addEncryptedListener(\n this.deps.media,\n this.handleEncryptedEvent\n )\n )\n }\n }\n\n configure(options: Maybe<Partial<DrmOptions>>): void {\n this.options = {\n ...this.optionsBase,\n ...options,\n keySystems: {\n ...this.optionsBase.keySystems,\n ...options?.keySystems,\n },\n }\n }\n\n private get licenseProvider(): LicenseProvider {\n return this.options.licenseProvider ?? defaultLicenseProvider\n }\n\n get error(): Error | null {\n return this._error\n }\n\n isEmeSupported(): boolean {\n return this.deps.commonEme != null\n }\n\n async isSupported(\n drmInfo: MediaFormatMetadata\n ): Promise<DrmKeySystemSupport> {\n const accessParamsList = this.createMediaKeySystemAccessParams(drmInfo)\n for (const params of accessParamsList) {\n const result = await this.checkIsSupportedCached(params)\n if (result.supported) return result\n }\n return { supported: false, persistentState: false }\n }\n\n private checkIsSupportedCached = /* @__PURE__ */ memoize(\n async (\n params: MediaKeySystemAccessParams\n ): Promise<DrmKeySystemSupport> => {\n try {\n await this.deps.commonEme!.requestMediaKeySystemAccess(\n params.keySystem,\n [params.config]\n )\n logVerbose(\n this,\n 'requestMediaKeySystemAccess supported',\n params\n )\n return {\n supported: true,\n persistentState:\n params.config.persistentState === 'required',\n }\n } catch (_) {\n logVerbose(this, 'requestMediaKeySystemAccess rejected', params)\n return { supported: false, persistentState: false }\n }\n },\n (options) => options.cacheKey,\n 20 // capacity\n )\n\n private readonly handleEncryptedEvent = (\n event: CommonMediaEncryptedEvent\n ) => {\n if (this.disposed) return\n ;(async () => {\n const { initData, initDataType } = event\n if (!initData) {\n // https://www.w3.org/TR/2014/WD-encrypted-media-20140218/#dom-mediakeyneededevent\n // https://www.w3.org/TR/encrypted-media/#initialization-data\n // Initialization data could not be obtained, possibly due to cross-origin policy issues.\n throw new DrmError(\n 'encrypted event provided null initData. Check CORS policies.'\n )\n }\n logDebug(\n this,\n `encrypted, initDataType: ${initDataType}, initData.byteLength: ${initData.byteLength}`\n )\n if (!this.drmInfo?.contentProtections.length) {\n throw new DrmError(\n 'Encrypted content not configured with content protections.'\n )\n }\n await this.maybeCreateSession(\n this.drmInfo,\n initDataType,\n initData,\n this.sessionAbort\n )\n })().catch(this.handleError)\n }\n\n /**\n * Resolves to media keys attached to the element.\n * The media keys will only be created and set once until `clearMediaKeys` is next called.\n */\n private async attachMediaKeys(\n drmInfo: MediaFormatMetadata\n ): Promise<CommonMediaKeys> {\n if (!this.mediaKeysPromise) {\n this.mediaKeysPromise = (async () => {\n logDebug(this, 'creating media keys')\n const access = await this.createAccess(drmInfo)\n const mediaKeys = await access.createMediaKeys()\n this.abortIfDisposed()\n this.mediaKeys = mediaKeys\n await mediaKeys.setOnElement(this.deps.media)\n logDebug(this, `set media keys on element`)\n this.dispatch('mediaKeysSet', {\n keySystem: mediaKeys.keySystem,\n })\n return mediaKeys\n })()\n }\n return this.mediaKeysPromise\n }\n\n /**\n * Creates a session for the given initialization data if none currently exists.\n * This will be done either after an 'encrypted' event or when drm metadata contains initialization data.\n * The new session will be added to the current sessions list.\n */\n private async maybeCreateSession(\n drmInfo: MediaFormatMetadata,\n initDataType: DrmInitDataType,\n initData: EncryptedInitData,\n abort?: Maybe<ReadonlyAbort>\n ): Promise<CommonMediaKeySession> {\n if (!hasMimeType(drmInfo)) {\n throw new DrmError('Encrypted content must have a mimeType.')\n }\n\n const mediaKeys = await this.attachMediaKeys(drmInfo)\n this.abortIfDisposed()\n\n // Resolve server certificate from configuration\n const keySystemOptions =\n this.options.keySystems[mediaKeys.keySystem] ??\n this.options.keySystems['*']\n const licenseServerOptionsProvider = keySystemOptions?.licenseServer\n const licenseServerOptions = await resolveValueProvider(\n licenseServerOptionsProvider ?? {}\n )\n this.abortIfDisposed()\n const existingSession = this.getSessionByInitData(initData)\n if (existingSession) {\n logDebug(this, 'reusing session')\n return existingSession\n } else {\n const newSession = await this.createNewSession(\n licenseServerOptions.serverCertificate,\n mediaKeys,\n initData,\n initDataType,\n drmInfo,\n keySystemOptions?.initDataTransformer\n )\n this.sessions.push(newSession)\n this.dispatch('sessionCreate', {\n initDataType: newSession.initDataType,\n mimeType: newSession.mimeType,\n })\n newSession.on('closed', () => this.closeSession(newSession))\n abort?.onAborted(() => {\n logDebug(this, 'abort session')\n this.closeSession(newSession)\n })\n return newSession\n }\n }\n\n initializeForPlayback(\n drmInfo: MediaFormatMetadata | null,\n abort?: ReadonlyAbort\n ): void {\n logDebug(this, 'initializeForPlayback', drmInfo)\n if (drmInfo?.contentProtections.length) {\n this.createSessionFromInitData(drmInfo, abort).catch(\n this.handleError\n )\n }\n }\n\n setBufferingDrmInfo(\n drmInfo: MediaFormatMetadata | null,\n abort?: ReadonlyAbort\n ): void {\n logDebug(this, 'setBufferingDrmInfo', drmInfo)\n // Reset 'encrypted' error reporting\n this.reset()\n this.drmInfo = drmInfo\n this.sessionAbort = abort ?? null\n }\n\n /**\n * If the drm metadata contains initialization data for the current key system, create a new session.\n * Otherwise, wait for the 'encrypted' event for the initialization data.\n */\n private async createSessionFromInitData(\n drmInfo: MediaFormatMetadata,\n abort?: ReadonlyAbort\n ) {\n if (!this.deps.commonEme) {\n this.handleError(new DrmError('DRM not supported.'))\n return\n }\n const mediaKeys = await this.attachMediaKeys(drmInfo)\n const drmProtection =\n drmInfo.contentProtections.find((cP) => {\n return cP.keySystem === mediaKeys.keySystem\n }) ?? null\n\n if (!drmProtection) {\n // Media keys have been initialized, but content is not encrypted with the current keySystem.\n throw new DrmError(\n `Encrypted content does not support set keySystem: '${mediaKeys.keySystem}'.`,\n { drmInfo }\n )\n }\n if (drmProtection.pssh) {\n await this.maybeCreateSession(\n drmInfo,\n drmInfo.initDataType ?? 'cenc',\n base64ToByteArray(drmProtection.pssh),\n abort\n )\n }\n }\n\n /**\n * Creates a CommonMediaKeySystemAccess object from the given content protection settings.\n */\n private async createAccess(\n drmInfo: MediaFormatMetadata\n ): Promise<CommonMediaKeySystemAccess> {\n const accessParamsList = this.createMediaKeySystemAccessParams(drmInfo)\n for (const { keySystem, config } of accessParamsList) {\n try {\n const access =\n await this.deps.commonEme!.requestMediaKeySystemAccess(\n keySystem,\n [config]\n )\n logDebug(\n this,\n `created media key system access for keySystem: ${access.keySystem}}`,\n config\n )\n return access\n } catch (_) {\n // ignore\n }\n }\n throw new DrmError(\n `No keySystem supported`,\n {\n contentProtections: drmInfo as any,\n attemptedKeySystems: accessParamsList.map(\n (arr) => arr.keySystem\n ),\n },\n ErrorOrigin.DRM\n )\n }\n\n /**\n * Creates a list of the MediaKeySystemAccess configurations to try for the given media format options.\n */\n private createMediaKeySystemAccessParams(\n drmInfo: MediaFormatMetadata\n ): readonly MediaKeySystemAccessParams[] {\n const keySystems = drmInfo.contentProtections\n .map((protection) => protection.keySystem)\n .sort(this.keySystemComparator)\n\n return keySystems.map((keySystem): MediaKeySystemAccessParams => {\n const mediaOptions = this.getMediaKeySystemOptions(\n keySystem,\n drmInfo.contentType\n )\n const capability: MediaKeySystemMediaCapability = {\n robustness:\n mediaOptions?.robustness ?? DrmRobustness.SW_SECURE_CRYPTO,\n encryptionScheme: drmInfo.encryptionScheme,\n }\n if (drmInfo.mimeType) {\n capability.contentType = drmInfo.mimeType\n }\n const config: MediaKeySystemConfiguration = {\n initDataTypes: [drmInfo.initDataType ?? 'cenc'],\n }\n const contentType = drmInfo.contentType\n if (contentType === 'video') {\n config.videoCapabilities = [capability]\n } else if (contentType === 'audio') {\n config.audioCapabilities = [capability]\n }\n return {\n keySystem,\n config,\n // Concatenate a list of inputs to use as a cache key for isSupported checks.\n cacheKey: [\n keySystem,\n drmInfo.mimeType,\n drmInfo.contentType,\n capability.robustness,\n drmInfo.encryptionScheme,\n drmInfo.initDataType,\n ]\n .map(String)\n .join('|'),\n }\n })\n }\n\n private getMediaKeySystemOptions(\n keySystem: DrmKeySystem,\n contentType: Maybe<ContentType>\n ): DrmMediaKeySystemOptions | undefined {\n const keySystems = this.options.keySystems\n const keySystemOptions = keySystems[keySystem] ?? keySystems['*']\n if (!keySystemOptions) return undefined\n switch (contentType) {\n case 'video':\n return keySystemOptions.video\n case 'audio':\n return keySystemOptions.audio\n default:\n return undefined\n }\n }\n\n /**\n * Creates a new key session and adds a message handler.\n */\n private async createNewSession(\n serverCertificate: Maybe<ServerCertificate>,\n mediaKeys: CommonMediaKeys,\n initData: EncryptedInitData,\n initDataType: DrmInitDataType,\n drmInfo: MediaFormatMetadata & { readonly mimeType: string },\n initDataTransformer?: InitDataTransformer\n ): Promise<CommonMediaKeySession> {\n const certBytes = serverCertificate\n ? typeof serverCertificate === 'string'\n ? base64ToByteArray(serverCertificate)\n : bufferToByteArray(serverCertificate)\n : null\n\n if (certBytes) {\n await mediaKeys.setServerCertificate(certBytes)\n }\n\n // Default initDataTransformer handles FAIR_PLAY_1_0 by packing the\n // skd init data with the content ID and server certificate.\n // FAIR_PLAY_1_0 always uses initDataType 'skd', so the default\n // does not need to explicitly check initDataType.\n const transform =\n initDataTransformer ??\n defaultInitDataTransformer(mediaKeys.keySystem, certBytes)\n initData = transform(bufferToByteArray(initData), initDataType, drmInfo)\n\n logDebug(this, 'createSession', drmInfo.mimeType, initDataType)\n const session = mediaKeys.createSession(\n drmInfo.mimeType,\n initDataType,\n initData\n )\n session.on('message', (event) => {\n withTimeout(\n this.messageHandler({\n mediaKeys: mediaKeys,\n session: session,\n event: event,\n }),\n LICENSE_TIMEOUT,\n LICENSE_TIMEOUT_MESSAGE\n ).catch(this.handleError)\n })\n session.on('error', (event) => {\n this.closeSession(session)\n this.handleError(event.error)\n })\n return session\n }\n\n /**\n * Invoked when the content decryption module needs to interact with the license server.\n */\n private async messageHandler(\n messageProps: DrmControllerMessageProps\n ): Promise<void> {\n const { mediaKeys, session, event } = messageProps\n messageEventValidator.assert(event)\n this.pendingMessageProps = messageProps\n\n const keySystem = mediaKeys.keySystem\n logDebug(this, 'message', keySystem, event.message.byteLength)\n\n const keySystemOptions = this.options.keySystems[keySystem]\n const licenseServerOptionsProvider = keySystemOptions?.licenseServer\n\n // Get the license server configuration for the current key system.\n const licenseServerOptions =\n clone(await resolveValueProvider(licenseServerOptionsProvider)) ??\n {}\n\n let challenge: BodyInit = event.message\n if (isPlayReady(keySystem)) {\n const unpacked = unpackPlayReadyChallenge(challenge)\n challenge = unpacked.challenge\n if (licenseServerOptions.init == null)\n licenseServerOptions.init = {}\n licenseServerOptions.init.headers = {\n ...normalizeHeadersInit(\n licenseServerOptions.init.headers ?? {}\n ),\n ...unpacked.headers,\n }\n }\n const key = await this.licenseProvider(\n keySystem,\n licenseServerOptions,\n challenge\n )\n this.pendingMessageProps = null\n if (session.disposed) return\n logDebug(this, 'update')\n await session.update(key)\n }\n\n //--------------------------------------------\n // Session management\n //--------------------------------------------\n\n /**\n * Closes all active DRM sessions.\n * This should not be called unless the audio source has been cleared.\n */\n closeSessions() {\n logDebug(this, `clearing ${this.sessions.length} sessions`)\n while (this.sessions.length) this.closeSession(this.sessions[0])\n }\n\n private closeSession(session: CommonMediaKeySession) {\n logDebug(this, 'closeSession')\n session.dispose()\n remove(this.sessions, session)\n this.dispatch('sessionClose', {\n initDataType: session.initDataType,\n mimeType: session.mimeType,\n })\n }\n\n /**\n * A handler which dispatches an error event.\n * Only one error event will be emitted per unique PSSH.\n * When track protections is set again, another error event may be emitted.\n */\n private readonly handleError = (error: Error) => {\n if (!this._error && !isSilentError(error)) {\n this._error = error\n this.dispatch('error', { error, target: this })\n }\n }\n\n /**\n * Returns the number of currently active sessions.\n */\n get activeSessions(): number {\n return this.sessions.length\n }\n\n /**\n * Clears the media keys from the element if they were set.\n */\n private clearMediaKeys() {\n this.closeSessions()\n if (this.mediaKeys) {\n logDebug(this, 'clearing media keys')\n this.mediaKeys.clearFromElement(this.deps.media).catch(noop)\n this.mediaKeys = null\n }\n this.mediaKeysPromise = null\n }\n\n protected abortIfDisposed() {\n if (this.disposed) throw new AbortError()\n }\n\n reset() {\n if (!this._error) {\n logDebug(this, 'reset no-op')\n return\n }\n logDebug(this, 'reset')\n this._error = null\n if (this.pendingMessageProps) {\n const mediaError = this.deps.media.error\n if (mediaError && mediaError.code === mediaError.MEDIA_ERR_DECODE) {\n // Media is in a failed decoding state, cannot recover from a failed license request.\n // The PlaybackController will attempt a reset.\n logDebug(\n this,\n 'media in an error state, will not retry failed license challenge'\n )\n this.pendingMessageProps = null\n } else {\n logDebug(this, 'retrying failed license challenge')\n this.messageHandler(this.pendingMessageProps).catch(\n this.handleError\n )\n }\n }\n this.dispatch('reset', {})\n }\n\n get disposed(): boolean {\n return this.disposer.disposed\n }\n\n dispose(): void {\n logDebug(this, 'dispose')\n super.dispose()\n this.clearMediaKeys()\n this.disposer.dispose()\n }\n\n private getSessionByInitData(\n initData: EncryptedInitData\n ): CommonMediaKeySession | null {\n return (\n this.sessions.find((session) => {\n return buffersEqual(session.initData, initData)\n }) ?? null\n )\n }\n\n /**\n * Sort the key systems first by their priority, then by the presence of a license uri.\n */\n private readonly keySystemComparator: Comparator<DrmKeySystem> = /* @__PURE__ */ compareBy(\n (keySystem: DrmKeySystem) => {\n return -(this.options.keySystems[keySystem]?.priority ?? 0)\n },\n (keySystem: DrmKeySystem) => {\n return this.options.keySystems[keySystem]?.licenseServer != null\n ? 0\n : 1\n }\n )\n}\n\ninterface MediaKeySystemAccessParams {\n readonly keySystem: DrmKeySystem\n readonly config: MediaKeySystemConfiguration\n readonly cacheKey: string\n}\n\nconst messageEventValidator: ObjectSchema<CommonMediaKeyMessageEvent> = /* @__PURE__ */ object({\n message: /* @__PURE__ */ instanceOf(ArrayBuffer),\n})\n\nfunction hasMimeType(\n drmInfo: MediaFormatMetadata\n): drmInfo is MediaFormatMetadata & { readonly mimeType: string } {\n return drmInfo.mimeType != null\n}\n\n/**\n * Default initDataTransformer. For FAIR_PLAY_1_0, packs the skd init data\n * with the extracted content ID and server certificate into the format\n * expected by WebKit-prefixed EME. FAIR_PLAY_1_0 always uses initDataType\n * 'skd', so we only need to check the key system.\n * For all other key systems, returns init data unchanged.\n */\nfunction defaultInitDataTransformer(\n keySystem: DrmKeySystem,\n certBytes: Uint8Array<ArrayBuffer> | null\n): InitDataTransformer {\n return (initData: Uint8Array<ArrayBuffer>): Uint8Array<ArrayBuffer> => {\n if (keySystem === DrmKeySystem.FAIR_PLAY_1_0) {\n if (!certBytes) {\n throw new DrmError('FairPlay requires certificate data')\n }\n const contentId = extractContentId(initData)\n return createFairPlaySessionInitData(initData, contentId, certBytes)\n }\n return initData\n }\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {\n base64ToByteArray,\n bufferToUtf16,\n logDebug,\n type LogTarget,\n type ReadonlyRecord,\n} from '@amazon/vinyl-util'\nimport type { XmlElement } from '@amazon/vinyl-xml'\nimport {\n attrInt,\n attrString,\n charactersString,\n element,\n elements,\n parseXml,\n parseXmlHandler,\n type XmlRules,\n} from '@amazon/vinyl-xml'\n\n/**\n * The final challenge buffer and headers for a playready license challenge.\n */\nexport interface UnpackedPlayReadyChallenge {\n readonly challenge: ArrayBuffer\n readonly headers: ReadonlyRecord<string, string>\n}\n\nconst logTarget: LogTarget = {\n logPrefix: 'unpackPlayReadyChallenge',\n}\n\n/**\n * IE and Edge wraps playready license challenges in PlayReadyKeyMessage xml.\n * Not all PlayReady clients do this.\n * Checks if the challenge is wrapped, and if so, returns the set headers and unwrapped challenge.\n * Otherwise, returns the challenge as-is with the required content type header.\n *\n * @param challenge The array buffer from the 'message' cdm event.\n */\nexport function unpackPlayReadyChallenge(\n challenge: ArrayBuffer\n): UnpackedPlayReadyChallenge {\n const xml = challenge.byteLength % 2 === 0 ? bufferToUtf16(challenge) : ''\n if (!xml.includes('PlayReadyKeyMessage')) {\n logDebug(logTarget, 'not wrapped')\n // A client that does not wrap the challenge.\n return {\n challenge,\n headers: {\n 'Content-Type': 'text/xml; charset=utf-8',\n },\n }\n }\n logDebug(logTarget, 'unpacking challenge')\n const message = parsePlayReadyKeyMessage(xml)\n const licenseAcquisition = message.PlayReadyKeyMessage.LicenseAcquisition\n const unpackedChallenge = base64ToByteArray(\n licenseAcquisition.Challenge._content\n ).buffer\n const headers: Record<string, string> = {}\n for (const element of licenseAcquisition.HttpHeaders.HttpHeader) {\n headers[element.name._content] = element.value._content\n }\n return {\n challenge: unpackedChallenge,\n headers,\n }\n}\n\ninterface PlayReadyMessage {\n readonly PlayReadyKeyMessage: PlayReadyKeyMessageType\n}\n\ninterface PlayReadyKeyMessageType {\n readonly type?: string\n readonly LicenseAcquisition: LicenseAcquisitionType\n}\n\ninterface LicenseAcquisitionType {\n readonly Version: number\n readonly Challenge: ChallengeType\n readonly HttpHeaders: HttpHeadersType\n}\n\ninterface ContentType {\n readonly _content: string\n}\n\ninterface ChallengeType extends ContentType {\n readonly encoding?: string\n}\n\ninterface HttpHeadersType {\n readonly HttpHeader: readonly HttpHeaderType[]\n}\n\ninterface HttpHeaderType {\n readonly name: ContentType\n readonly value: ContentType\n}\n\nconst challengeType: XmlRules<ChallengeType> = {\n _content: charactersString,\n encoding: attrString,\n}\n\nconst contentType: XmlRules<ContentType> = {\n _content: charactersString,\n}\n\nconst headerType: XmlRules<HttpHeaderType> = {\n name: /* @__PURE__ */ element(contentType, { required: true }),\n value: /* @__PURE__ */ element(contentType, { required: true }),\n}\n\nconst httpHeadersType: XmlRules<HttpHeadersType> = {\n HttpHeader: /* @__PURE__ */ elements(headerType, { useEmptyArrays: true }),\n}\n\nconst licenseAcquisitionType: XmlRules<LicenseAcquisitionType> = {\n Challenge: /* @__PURE__ */ element(challengeType, { required: true }),\n HttpHeaders: /* @__PURE__ */ element(httpHeadersType, { required: true }),\n Version: /* @__PURE__ */ attrInt({ required: true }),\n}\n\nconst playReadyKeyMessageType: XmlRules<PlayReadyKeyMessageType> = {\n LicenseAcquisition: /* @__PURE__ */ element(licenseAcquisitionType, { required: true }),\n type: /* @__PURE__ */ attrString(),\n}\n\nconst playReadyMessageRules: XmlRules<PlayReadyMessage> = {\n PlayReadyKeyMessage: /* @__PURE__ */ element(playReadyKeyMessageType, {\n required: true,\n }),\n}\n\n/**\n * A Content handler for a PlayReady SOAP message.\n */\nconst playReadyXmlHandler = /* @__PURE__ */ parseXmlHandler(playReadyMessageRules)\n\nexport function parsePlayReadyKeyMessage(\n xmlStr: string\n): PlayReadyMessage & XmlElement<PlayReadyMessage> {\n return parseXml(xmlStr, playReadyXmlHandler)\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { ReadonlyAbort } from '@amazon/vinyl-util'\nimport { requestWithRetry, ValidationError } from '@amazon/vinyl-util'\nimport type { DrmKeySystem } from '../DrmKeySystem'\nimport type { LicenseProvider, LicenseServerOptions } from './LicenseProvider'\n\n/**\n * A basic LicenseProvider which uses the configuration set for the current key system,\n * transmits a challenge as the body, and returns an array buffer.\n *\n * @param keySystem The key system for the current license challenge.\n * @param serverOptions The resolved configuration. The default DrmController\n * implementation provides this from the `drm` configuration set when creating\n * a new player.\n * @param challenge The license challenge, provided by the CDM (Content Decryption\n * Module)\n * @param abort (optional) When aborted, should cancel any active requests.\n */\nexport const defaultLicenseProvider: LicenseProvider = async (\n keySystem: DrmKeySystem,\n serverOptions: LicenseServerOptions,\n challenge: ArrayBuffer,\n abort?: ReadonlyAbort\n): Promise<ArrayBuffer> => {\n if (serverOptions.url == null) {\n throw new ValidationError(\n `Missing licenseServer url in DRM configuration for keySystem: ${keySystem}`\n )\n }\n const res = await requestWithRetry(\n serverOptions.url,\n {\n method: 'POST',\n ...serverOptions.init,\n body: challenge,\n },\n { abort }\n )\n return await res.arrayBuffer()\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { ValidationError } from '@amazon/vinyl-util'\nimport { ErrorOrigin } from '@amazon/vinyl-util'\nimport { bufferToUtf16 } from '@amazon/vinyl-util'\n\n/**\n * Extract contentId from event data encoded as UTF16.\n *\n * @param initData Expected byte array representing a UTF-16 string in the form\n * `skd://0b5689bb-4171-97e5-c280-99f7abe4004f`\n */\nexport function extractContentId(initData: Uint8Array<ArrayBuffer>): string {\n const bufferStr = bufferToUtf16(initData.buffer)\n const matches = bufferStr.match(/skd:\\/\\/(.+)$/)\n if (!matches) {\n throw new ValidationError('No contentId match', ErrorOrigin.MEDIA)\n }\n return matches[1]\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { utf16ToUint16Array } from '@amazon/vinyl-util'\n\n/**\n * Create the payload for EME media key session from `encrypted` / `*needkey` event data and DRM\n * certificate.\n * Note: This code is taken from the official FairPlay SDK example.\n *\n * @param initData\n * @param contentId\n * @param certificateData certificate data as a Uint8Array\n */\nexport function createFairPlaySessionInitData(\n initData: Uint8Array,\n contentId: string,\n certificateData: Uint8Array\n): Uint8Array<ArrayBuffer> {\n const contentIdUint16 = utf16ToUint16Array(contentId)\n const certificateDataUint8 = certificateData\n\n let offset = 0\n const buffer = new ArrayBuffer(\n initData.byteLength +\n 4 + // contentId length\n contentIdUint16.byteLength +\n 4 + // certificateDataUint8 length\n certificateDataUint8.byteLength\n )\n\n const initDataArray = new Uint8Array(buffer, offset, initData.byteLength)\n initDataArray.set(initData)\n offset += initData.byteLength\n\n const dataView = new DataView(buffer)\n dataView.setUint32(offset, contentIdUint16.byteLength, true)\n offset += 4\n\n const idArray = new Uint16Array(buffer, offset, contentIdUint16.length)\n idArray.set(contentIdUint16)\n offset += idArray.byteLength\n\n dataView.setUint32(offset, certificateDataUint8.byteLength, true)\n offset += 4\n\n const certArray = new Uint8Array(\n buffer,\n offset,\n certificateDataUint8.byteLength\n )\n certArray.set(certificateDataUint8)\n\n return new Uint8Array(buffer, 0, buffer.byteLength)\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { type ReadonlyRecord } from '@amazon/vinyl-util'\nimport {\n DrmKeySystem,\n FAIR_PLAY_KEY_SYSTEMS,\n PLAY_READY_KEY_SYSTEMS,\n} from './DrmKeySystem'\nimport { ContentProtectionScheme } from '@amazon/vinyl-mpd-parser'\n\n/**\n * Given a ContentProtection schemeIdUri, returns the {@link DrmKeySystem} it represents.\n * Not all scheme ids will match to a DrmKeySystem. If none are matched, null is returned.\n * For example, CENC 'urn:mpeg:dash:mp4protection:2011' has no key system and shouldn't be used\n * to create a key session.\n */\nexport type DrmKeySystemResolver = (\n schemeIdUri: string\n) => readonly DrmKeySystem[]\n\nlet _defaultSchemeToKeySystem: ReadonlyRecord<\n string,\n readonly DrmKeySystem[]\n> | null = null\n\nexport function getDefaultSchemeToKeySystem(): ReadonlyRecord<\n string,\n readonly DrmKeySystem[]\n> {\n if (_defaultSchemeToKeySystem == null) {\n _defaultSchemeToKeySystem = {\n [ContentProtectionScheme.CLEAR_KEY]: [DrmKeySystem.CLEAR_KEY],\n [ContentProtectionScheme.FAIR_PLAY]: FAIR_PLAY_KEY_SYSTEMS,\n [ContentProtectionScheme.PLAY_READY]: PLAY_READY_KEY_SYSTEMS,\n [ContentProtectionScheme.WIDEVINE]: [DrmKeySystem.WIDEVINE],\n } as const\n }\n return _defaultSchemeToKeySystem\n}\n\nexport const defaultDrmKeySystemResolver: DrmKeySystemResolver = (\n schemeIdUri: string\n) => {\n return getDefaultSchemeToKeySystem()[schemeIdUri.toLowerCase()] ?? []\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { createDisposer, type LogTarget } from '@amazon/vinyl-util'\nimport {\n logDebug,\n createLogPrefix,\n EventHostImpl,\n closeTo,\n} from '@amazon/vinyl-util'\nimport type {\n LoudnessNormalizationController,\n LoudnessNormalizationControllerEventMap,\n} from './LoudnessNormalizationController'\nimport {\n defaultLoudnessNormalizationControllerImplOptions,\n type LoudnessNormalizationControllerImplOptions,\n} from './LoudnessNormalizationControllerImplOptions'\nimport type { ObservableValue } from '@amazon/vinyl-observable'\n\nexport type LoudnessNormalizationControllerImplDeps = {\n readonly options: ObservableValue<LoudnessNormalizationControllerImplOptions>\n}\n\nconst DECIBEL_EXPONENT_BASE = /* @__PURE__ */ Math.pow(10, 1 / 10)\nconst MAX_GAIN_LEVEL = 1.0\n\n/**\n * Applies gain adjustment based on track loudness metadata from manifest.\n * This controller normalizes audio loudness to a target level for consistent playback volume.\n */\nexport class LoudnessNormalizationControllerImpl\n extends EventHostImpl<LoudnessNormalizationControllerEventMap>\n implements LoudnessNormalizationController, LogTarget\n{\n get [Symbol.toStringTag](): string {\n return 'LoudnessNormalizationControllerImpl'\n }\n readonly logPrefix = /* @__PURE__ */ createLogPrefix(this)\n\n private _gain: number = MAX_GAIN_LEVEL\n private readonly disposer = /* @__PURE__ */ createDisposer()\n\n private trackLoudness: number | null = null\n private _options: Required<LoudnessNormalizationControllerImplOptions> =\n defaultLoudnessNormalizationControllerImplOptions\n\n constructor(\n private readonly deps: LoudnessNormalizationControllerImplDeps\n ) {\n super()\n const { add } = this.disposer\n add(\n deps.options.onData((value) => {\n this._options = {\n ...defaultLoudnessNormalizationControllerImplOptions,\n ...value,\n }\n this.updateGain()\n })\n )\n }\n\n get options(): Required<LoudnessNormalizationControllerImplOptions> {\n return this._options\n }\n\n setTrackLoudness(value: number | null): void {\n this.trackLoudness = value\n this.updateGain()\n }\n\n /**\n * Returns the loudness gain value which needs to be applied, for current track playback.\n */\n public get gain(): number {\n return this._gain\n }\n\n /**\n * Sets the loudness gain value for current track playback.\n *\n * @param value New gain value to apply\n */\n private set gain(value: number) {\n const previousGain = this._gain\n // Emit change event if gain value changed\n if (!closeTo(previousGain, value)) {\n this._gain = value\n logDebug(this, 'loudness gain adjustment:', {\n trackLoudness: this.trackLoudness,\n targetLufs: this.options.targetLufs,\n gain: value,\n })\n this.dispatch('change', {})\n }\n }\n\n /**\n * Update gain value based on current track loudness and target loudness.\n */\n private updateGain(): void {\n const { targetLufs, maxGainDb, enabled } = this.options\n const trackLoudness = this.trackLoudness\n if (trackLoudness == null) {\n return\n }\n if (trackLoudness <= targetLufs || !enabled) {\n this.clear()\n return\n }\n // Calculate gain reduction for louder tracks\n const dbReduction = Math.min(trackLoudness - targetLufs, maxGainDb)\n this.gain =\n MAX_GAIN_LEVEL / Math.pow(DECIBEL_EXPONENT_BASE, dbReduction)\n }\n\n /**\n * Resets the loudness gain Value to max gain value.\n */\n clear(): void {\n this.gain = MAX_GAIN_LEVEL\n }\n\n dispose(): void {\n super.dispose()\n this.disposer.dispose()\n }\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { ObjectSchema } from '@amazon/vinyl-validation'\nimport { boolean, number, object } from '@amazon/vinyl-validation'\n\n/**\n * Options for configuring the loudness normalization controller.\n */\nexport interface LoudnessNormalizationControllerImplOptions {\n /**\n * If true, applies loudness Normalization to the current track played.\n * Default: false\n */\n readonly enabled: boolean\n\n /**\n * Target loudness level in LUFS (Loudness Units relative to Full Scale).\n * Default: -14.0 dB\n */\n readonly targetLufs?: number\n\n /**\n * Maximum gain reduction to apply in dB.\n * Default: 10 Db\n */\n readonly maxGainDb?: number\n}\n\nexport const defaultLoudnessNormalizationControllerImplOptions = {\n enabled: false,\n targetLufs: -14.0,\n maxGainDb: 10.0,\n} as const satisfies LoudnessNormalizationControllerImplOptions\n\nexport const loudnessNormalizationControllerImplOptionsValidator: ObjectSchema<LoudnessNormalizationControllerImplOptions> =\n /* @__PURE__ */ object({\n enabled: /* @__PURE__ */ boolean(),\n targetLufs: /* @__PURE__ */ /* @__PURE__ */ number().optional(),\n maxGainDb: /* @__PURE__ */ /* @__PURE__ */ number().optional(),\n })\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {\n type AnyRecord,\n type Clearable,\n createDisposer,\n type Disposable,\n EventHostImpl,\n getNetworkState,\n logDebug,\n onAny,\n type ReadonlyEventHost,\n RequestError,\n type Unsubscribe,\n} from '@amazon/vinyl-util'\nimport type { PlaybackController } from '../playback/PlaybackController'\nimport type { ChangeEvent } from '../event/ChangeEvent'\n\nexport interface AutoResetControllerEventMap {\n /**\n * Notifies that playback errors should be reset and retried.\n */\n readonly reset: AnyRecord\n\n /**\n * Dispatched when {@link AutoResetController.resetPending} changes.\n */\n readonly resetPendingChange: ChangeEvent<boolean>\n}\n\n/**\n * Notifies when playback should be reset and retried after a transient,\n * potentially-recoverable error.\n *\n * Once an eligible error is set, the controller watches for opportunities\n * to emit a `reset` event:\n * - Immediately when the network transitions back to online\n * - After a timeout interval, if online and retries are not exhausted\n * - Immediately on user playback actions (play, pause, seeking, playing)\n *\n * Each error triggers a single retry timeout. If another error occurs\n * after a reset, {@link AutoResetController.setError} should be called again\n * to schedule the next retry attempt.\n */\nexport interface AutoResetController\n extends ReadonlyEventHost<AutoResetControllerEventMap>, Clearable {\n /**\n * Sets the current playback error and, if eligible, begins watching for\n * retry opportunities.\n *\n * An error is eligible when it is a {@link RequestError} that did not\n * receive an HTTP response (i.e. `response == null`), indicating a\n * transient network failure such as connection loss or DNS failure.\n * All other errors \u2014 including HTTP failures with a response (4xx/5xx),\n * and non-RequestError errors \u2014 are ignored, since those are unlikely\n * to recover on their own.\n *\n * Subsequent calls while an error is already set are ignored until the\n * error is cleared via a reset emission or {@link Clearable.clear}.\n *\n * After a reset, if another eligible error occurs, this method should\n * be called again to schedule the next retry attempt.\n *\n * @param error The error to monitor for retry opportunities\n */\n setError(error: Error): void\n\n /**\n * True while an eligible error is being watched and a `reset` event\n * may still be emitted. Becomes false once the error is cleared, a\n * reset is emitted, or all retries are exhausted.\n *\n * Listen to `resetPendingChange` events for changes.\n */\n readonly resetPending: boolean\n}\n\nexport interface AutoResetControllerImplDeps {\n readonly playbackController: PlaybackController\n}\n\nexport interface AutoResetControllerImplOptions {\n /**\n * If false, disables auto reset behavior.\n * default: true\n */\n readonly enabled: boolean\n\n /**\n * The total number of times to reset when there has not been successful\n * playback.\n *\n * E.g. a retryInterval of 30 and maxRetries of 30 will retry for 15 minutes before stopping.\n *\n * default: 30\n */\n readonly maxRetries: number\n\n /**\n * The number of seconds between retries.\n *\n * When an error is set, a single timeout is scheduled for this interval.\n * If the retry limit hasn't been reached and the device is online, a reset\n * event is emitted. For subsequent errors after reset, setError() must be\n * called again to schedule the next retry timeout.\n */\n readonly retryInterval: number\n}\n\nexport const defaultResetControllerOptions = {\n enabled: true,\n maxRetries: 30,\n retryInterval: 30,\n} as const satisfies AutoResetControllerImplOptions\n\nexport class AutoResetControllerImpl\n extends EventHostImpl<AutoResetControllerEventMap>\n implements AutoResetController, Disposable\n{\n get [Symbol.toStringTag](): string {\n return 'AutoResetControllerImpl'\n }\n\n private readonly options: AutoResetControllerImplOptions\n private _error: Error | null = null\n private watchSub: Unsubscribe | null = null\n private currentRetry = 0\n private disposer = /* @__PURE__ */ createDisposer()\n\n constructor(\n readonly deps: AutoResetControllerImplDeps,\n options?: Partial<AutoResetControllerImplOptions>\n ) {\n super()\n logDebug(this, 'constructor')\n this.options = {\n ...defaultResetControllerOptions,\n ...options,\n }\n\n this.disposer.add(\n onAny(\n deps.playbackController,\n ['play', 'pause', 'seeking', 'playing'],\n (_event) => {\n // On certain user-initiated playback events, reset the currentRetry count and emit a reset event\n // if in an error state.\n this.currentRetry = 0\n this.reset()\n }\n )\n )\n }\n\n setError(error: Error): void {\n if (!this.options.enabled || this._error) return\n if (error instanceof RequestError && error.response == null) {\n this._error = error\n this.setResetPending(true)\n }\n }\n\n get resetPending(): boolean {\n return this.watchSub != null\n }\n\n private setResetPending(value: boolean): void {\n if (this.resetPending === value) {\n logDebug(this, 'setResetPending', value, 'no-op')\n return\n }\n logDebug(this, 'setResetPending', value)\n this.watchSub?.()\n this.watchSub = null\n if (value) {\n const networkState = getNetworkState()\n const { add, dispose: watchSub } = createDisposer()\n this.watchSub = watchSub\n add(\n networkState.on('online', () => {\n logDebug(this, 'online, emitting reset')\n this.reset()\n })\n )\n\n const intervalId = setTimeout(() => {\n if (this.currentRetry++ < this.options.maxRetries) {\n if (networkState.onLine) {\n logDebug(this, 'interval, emitting reset')\n this.reset()\n }\n } else {\n logDebug(this, 'max retries exhausted, pausing playback')\n this.setResetPending(false)\n }\n }, this.options.retryInterval * 1000)\n add(() => clearTimeout(intervalId))\n }\n this.dispatch('resetPendingChange', {\n previous: !value,\n current: value,\n })\n }\n\n private reset(): void {\n if (!this._error) return\n this.clear()\n this.dispatch('reset', {})\n }\n\n clear() {\n if (!this._error) return\n this._error = null\n this.setResetPending(false)\n }\n\n get disposed(): boolean {\n return this.disposer.disposed\n }\n\n dispose(): void {\n this.disposer.dispose()\n this.clear()\n }\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {\n defaultQualitySelectorImplOptions,\n type QualitySelectorImplOptions,\n qualitySelectorImplOptionsValidator,\n} from '../streaming/abr/QualitySelectorImpl'\nimport type { ObjectSchema } from '@amazon/vinyl-validation'\nimport { object, string } from '@amazon/vinyl-validation'\nimport {\n defaultLoudnessNormalizationControllerImplOptions,\n type LoudnessNormalizationControllerImplOptions,\n loudnessNormalizationControllerImplOptionsValidator,\n} from '../playback/loudness/LoudnessNormalizationControllerImplOptions'\n\nexport interface VinylOptions {\n /**\n * Configuration for the default adaptive bitrate selector.\n */\n readonly abr: QualitySelectorImplOptions\n\n readonly loudnessNormalization: LoudnessNormalizationControllerImplOptions\n\n /**\n * Preferred language for audio content, using a code as defined by RFC 5646 (e.g. 'en', 'ja').\n * When set, only adaptation sets / variants matching this language (or without a language tag)\n * are kept. Null means no language preference (all languages are kept).\n */\n readonly preferredAudioLanguage: string | null\n}\n\nexport const defaultVinylOptions: VinylOptions = {\n abr: defaultQualitySelectorImplOptions,\n loudnessNormalization: defaultLoudnessNormalizationControllerImplOptions,\n preferredAudioLanguage: null,\n}\n\nexport const vinylOptionsValidator: ObjectSchema<VinylOptions> = /* @__PURE__ */ object({\n abr: qualitySelectorImplOptionsValidator,\n loudnessNormalization: loudnessNormalizationControllerImplOptionsValidator,\n preferredAudioLanguage: /* @__PURE__ */ /* @__PURE__ */ string().orNull(),\n})\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { Client } from '../client/Client'\nimport {\n type AnyRecord,\n createDisposer,\n type Disposable,\n emptyRanges,\n equalDeep,\n EventHostImpl,\n logDebug,\n logInfo,\n type ReadonlyRanges,\n type ReadonlySet,\n redispatchEvents,\n type Unsubscribe,\n} from '@amazon/vinyl-util'\nimport {\n createContainer,\n type Factories,\n type ValidFactoryOverrides,\n} from '@amazon/vinyl-di'\nimport { playerRegistryRef } from '../global/PlayerRegistry'\nimport type { PlaybackController } from '../playback/PlaybackController'\nimport {\n ALL_PLAYBACK_STATE_EVENTS,\n type PlaybackControllerEventMap,\n type PlaybackNetworkState,\n type PlaybackReadyState,\n} from '../playback/ReadonlyPlaybackController'\nimport type { VinylTrackLoadOptions } from '../track/createVinylTrackFactories'\nimport { type ReadonlyTrack, type TrackUri } from '../track/Track'\nimport {\n ALL_TRACK_CONTROLLER_EVENTS,\n type TrackController,\n type TrackControllerEventMap,\n} from '../track/TrackController'\nimport type {\n InferLoadOptionsFromFactory,\n TrackLoadOptions,\n} from '../track/TrackFactory'\nimport type {\n DefaultVinylFactories,\n InferVinylOverrideDependencyType,\n VinylDependencyOptions,\n} from './createVinylFactories'\nimport { createVinylFactories } from './createVinylFactories'\nimport type { VinylDeps } from './VinylDeps'\nimport type { Capabilities } from '../client/Capabilities'\nimport { initializeVinylGlobal } from '../global/initializeVinylGlobal'\nimport {\n ALL_CONTENT_TYPES,\n type ContentType,\n type MediaQualityMetadata,\n} from '../streaming/MediaQualityMetadata'\nimport type { ReadonlyPlaybackStreamingState } from './ReadonlyPlaybackStreamingState'\nimport type { DrmController } from '../drm/DrmController'\nimport {\n ALL_STREAMING_EVENTS,\n type StreamingEventMap,\n} from '../streaming/StreamingEventMap'\nimport type {\n InferObservableValueType,\n MutableValue,\n} from '@amazon/vinyl-observable'\nimport type { VinylOptions } from './VinylOptions'\nimport type { AutoResetController } from '../track/AutoResetController'\nimport type { ChangeEvent } from '../event/ChangeEvent'\n\n/**\n * Events the Vinyl Player emits.\n */\nexport interface VinylPlayerEventMap<\n TrackLoadOptionsType extends TrackLoadOptions = VinylTrackLoadOptions,\n>\n extends\n PlaybackControllerEventMap,\n TrackControllerEventMap<TrackLoadOptionsType>,\n StreamingEventMap {\n /**\n * Dispatched when {@link VinylPlayer.resetPending} changes.\n *\n * `current` is true when the player has hit a transient, potentially\n * recoverable error (e.g. a network outage) and an automatic reset\n * attempt is scheduled. `current` is false once the pending reset is\n * emitted, the error is cleared, or all retries are exhausted.\n *\n * If `resetPending` becomes false while {@link VinylPlayer.error} is\n * still non-null, all automatic reset attempts have been exhausted\n * and playback will not recover without user action.\n */\n readonly resetPendingChange: ChangeEvent<boolean>\n}\n\n/**\n * A Vinyl Media Player.\n *\n * Unless custom dependencies need to be provided, use {@link createVinylPlayer} to construct\n * a new player implementation.\n */\nexport class VinylPlayer<\n TrackLoadOptionsType extends TrackLoadOptions = VinylTrackLoadOptions,\n OptionsType = VinylOptions,\n>\n extends EventHostImpl<VinylPlayerEventMap<TrackLoadOptionsType>>\n implements\n PlaybackController,\n TrackController<TrackLoadOptionsType>,\n ReadonlyPlaybackStreamingState,\n Disposable\n{\n get [Symbol.toStringTag](): string {\n return 'VinylPlayer'\n }\n\n protected readonly deps: VinylDeps<TrackLoadOptionsType, OptionsType>\n\n private get drmController(): DrmController {\n return this.deps.drmController\n }\n\n private get playbackController(): PlaybackController {\n return this.deps.playbackController\n }\n\n private get trackController(): TrackController<TrackLoadOptionsType> {\n return this.deps.trackController\n }\n\n private get autoResetController(): AutoResetController {\n return this.deps.autoResetController\n }\n\n /**\n * Provides information about the client, such as device and browser capabilities.\n */\n readonly client: Client\n\n private _error: Error | null = null\n\n protected readonly disposer = /* @__PURE__ */ createDisposer()\n\n /**\n * Constructs a new VinylPlayer with the given dependency factories.\n * This constructor is protected, use {@link createVinylPlayer} to construct a new player.\n *\n * @param factories\n * @see createVinylPlayer\n */\n protected constructor(\n factories: Factories<VinylDeps<TrackLoadOptionsType, OptionsType>>\n ) {\n initializeVinylGlobal()\n super()\n const add = this.disposer.add\n this.deps = add(createContainer(factories)).dependencies\n\n this.client = {\n capabilities: this.deps.capabilities,\n }\n playerRegistryRef.value.addPlayer(this)\n this.redispatchSubControllerEvents()\n this.redispatchCurrentTrackEvents()\n this.initializeAutoResetHandling()\n this.initializePreferredLanguageHandling()\n }\n\n protected redispatchSubControllerEvents(): void {\n const add = this.disposer.add\n add(\n redispatchEvents(\n this,\n this.playbackController,\n ALL_PLAYBACK_STATE_EVENTS.filter(notResetEvent)\n )\n )\n add(\n redispatchEvents(\n this,\n this.trackController,\n ALL_TRACK_CONTROLLER_EVENTS\n )\n )\n add(redispatchEvents(this, this.drmController, ['error']))\n\n this.on('error', (event) => {\n this._error = event.error\n })\n }\n\n /**\n * Certain track events are redispatched on the player for the current track.\n */\n protected redispatchCurrentTrackEvents() {\n let sub: Unsubscribe | null = null\n const add = this.disposer.add\n add(\n this.trackController.on('currentTrackChange', (event) => {\n sub?.()\n sub = null\n if (event.current) {\n sub = redispatchEvents(\n this,\n event.current,\n ALL_STREAMING_EVENTS.filter(notResetEvent)\n )\n }\n this.dispatch('fetchedRangesChange', {})\n\n // Emit a quality change event for every stream that has changed\n // for streaming, buffering, and playback\n for (const contentType of ALL_CONTENT_TYPES) {\n for (const [\n eventType,\n getterName,\n ] of qualityEventsAndGetters) {\n const previous =\n event.previous?.[getterName](contentType) ?? null\n const current =\n event.current?.[getterName](contentType) ?? null\n if (previous !== current) {\n this.dispatch(eventType, {\n previous,\n current,\n })\n }\n }\n }\n\n // Emit qualities change events on track switch\n const prevQualities = event.previous?.qualities ?? null\n const curQualities = event.current?.qualities ?? null\n if (prevQualities !== curQualities && curQualities) {\n this.dispatch('qualitiesChange', {\n previous: prevQualities ?? [],\n current: curQualities,\n })\n }\n const prevUnfiltered =\n event.previous?.qualitiesUnfiltered ?? null\n const curUnfiltered = event.current?.qualitiesUnfiltered ?? null\n if (prevUnfiltered !== curUnfiltered && curUnfiltered) {\n this.dispatch('qualitiesUnfilteredChange', {\n previous: prevUnfiltered ?? [],\n current: curUnfiltered,\n })\n }\n })\n )\n }\n\n private initializeAutoResetHandling() {\n // Initializes the binding between the player and the reset handler.\n // On an error, notify the auto reset controller which will\n // monitor network changes and periodically request a reset.\n const { add } = this.disposer\n this.on('error', (event) => {\n this.autoResetController.setError(event.error)\n })\n add(this.autoResetController.on('reset', () => this.reset()))\n add(\n this.autoResetController.on('resetPendingChange', (event) =>\n this.dispatch('resetPendingChange', event)\n )\n )\n }\n\n private initializePreferredLanguageHandling() {\n const { add } = this.disposer\n // When the preferred language changes, clear the prefetch to immediately switch.\n add(\n (this.deps.options as MutableValue<VinylOptions>)\n .pick('preferredAudioLanguage')\n .onData((_value, previous) => {\n if (previous !== undefined) this.clearPrefetch()\n })\n )\n }\n\n /**\n * Returns the current player options.\n * Use `configure` to set.\n */\n get options(): OptionsType {\n return this.deps.options.value\n }\n\n /**\n * Sets options on this player.\n * Options will be merged shallowly, for example,\n * `configure({ abr: { strategy: AbrStrategy.BEST }})` will replace all previous `abr` options, and not\n * change other options such as `loudnessNormalization`.\n *\n * @param options\n */\n configure(options: Partial<OptionsType>): void {\n logDebug(this, 'configure', options)\n const newValue = { ...this.options, ...options }\n if (!equalDeep(newValue, this.options)) {\n this.deps.options.value = newValue\n }\n }\n\n get capabilities(): Capabilities {\n return this.deps.capabilities\n }\n\n //----------------------------------------------------\n // PlaybackController delegate methods\n //----------------------------------------------------\n\n get buffered(): ReadonlyRanges {\n return this.playbackController.buffered\n }\n\n get canPlay(): boolean {\n return this.playbackController.canPlay\n }\n\n get canPlayThrough(): boolean {\n return this.playbackController.canPlayThrough\n }\n\n get currentTime(): number {\n return this.playbackController.currentTime\n }\n\n get currentTimePercent(): number {\n return this.playbackController.currentTimePercent\n }\n\n get defaultPlaybackRate(): number {\n return this.playbackController.defaultPlaybackRate\n }\n\n set defaultPlaybackRate(value: number) {\n this.playbackController.defaultPlaybackRate = value\n }\n\n get duration(): number {\n return this.playbackController.duration\n }\n\n get ended(): boolean {\n return this.playbackController.ended\n }\n\n /**\n * The last error reported.\n */\n get error(): Error | null {\n return this._error\n }\n\n /**\n * True when an error has interrupted playback and an automatic reset\n * is scheduled. This distinguishes transient, potentially recoverable\n * errors (such as a brief network outage) from terminal errors that\n * will not trigger a reset on their own.\n *\n * Listen to `resetPendingChange` events for changes.\n */\n get resetPending(): boolean {\n return this.autoResetController.resetPending\n }\n\n get hasMetadata(): boolean {\n return this.playbackController.hasMetadata\n }\n\n get loop(): boolean {\n return this.playbackController.loop\n }\n\n set loop(value: boolean) {\n this.playbackController.loop = value\n }\n\n get muted(): boolean {\n return this.playbackController.muted\n }\n\n set muted(value: boolean) {\n this.playbackController.muted = value\n }\n\n get networkState(): PlaybackNetworkState {\n return this.playbackController.networkState\n }\n\n get paused(): boolean {\n return this.playbackController.paused\n }\n\n get playbackRate(): number {\n return this.playbackController.playbackRate\n }\n\n set playbackRate(value: number) {\n this.playbackController.playbackRate = value\n }\n\n get playIsPending(): boolean {\n return this.playbackController.playIsPending\n }\n\n get playing(): boolean {\n return this.playbackController.playing\n }\n\n get preservesPitch(): boolean {\n return this.playbackController.preservesPitch\n }\n\n set preservesPitch(value: boolean) {\n this.playbackController.preservesPitch = value\n }\n\n get readyState(): PlaybackReadyState {\n return this.playbackController.readyState\n }\n\n get seekable(): ReadonlyRanges {\n return this.playbackController.seekable\n }\n\n get seeking(): boolean {\n return this.playbackController.seeking\n }\n\n get volume(): number {\n return this.playbackController.volume\n }\n\n set volume(value: number) {\n this.playbackController.volume = value\n }\n\n get waiting(): boolean {\n return this.playbackController.waiting\n }\n\n pause(): void {\n this.playbackController.pause()\n }\n\n play(): Promise<void> {\n return this.playbackController.play()\n }\n\n seekTo(time: number, tolerance?: number): Promise<void> {\n return this.playbackController.seekTo(time, tolerance)\n }\n\n reset() {\n if (!this._error) {\n logDebug(this, 'reset no-op')\n return\n }\n logDebug(this, 'reset')\n this._error = null\n this.drmController.reset()\n this.playbackController.reset()\n this.trackController.reset()\n this.autoResetController.clear()\n this.dispatch('reset', {})\n }\n\n //----------------------------------------------------\n // TrackController delegate methods\n //----------------------------------------------------\n\n get currentTrack(): ReadonlyTrack | null {\n return this.trackController.currentTrack\n }\n\n get queue(): readonly TrackLoadOptionsType[] {\n return this.trackController.queue\n }\n\n preload(...loadOptionsList: TrackLoadOptionsType[]): void {\n this.trackController.preload(...loadOptionsList)\n }\n\n load(...loadOptionsList: TrackLoadOptionsType[]): void {\n this.trackController.load(...loadOptionsList)\n }\n\n enqueue(...loadOptionsList: TrackLoadOptionsType[]): void {\n this.trackController.enqueue(...loadOptionsList)\n }\n\n unload(): void {\n this.trackController.unload()\n }\n\n hasNext(): boolean {\n return this.trackController.hasNext()\n }\n\n next(): void {\n return this.trackController.next()\n }\n\n isTrackCached(uri: TrackUri): boolean {\n return this.trackController.isTrackCached(uri)\n }\n\n getCachedTrack(uri: TrackUri): ReadonlyTrack | null {\n return this.trackController.getCachedTrack(uri)\n }\n\n getCachedTracks(): IterableIterator<ReadonlyTrack> {\n return this.trackController.getCachedTracks()\n }\n\n clearPrefetch(): void {\n this.trackController.clearPrefetch()\n }\n\n clearTrackCache(): void {\n this.trackController.clearTrackCache()\n }\n\n clearQueue(): void {\n this.trackController.clearQueue()\n }\n\n //----------------------------------------------------\n // CurrentTrackStreamingState methods\n //----------------------------------------------------\n\n /**\n * Returns the fetched ranges of the current track.\n * If there is no current track, empty ranges will be returned.\n *\n * Listen to {@link VinylPlayerEventMap.fetchedRangesChange} for changes.\n */\n get fetchedRanges(): ReadonlyRanges {\n return this.currentTrack?.fetchedRanges ?? emptyRanges\n }\n\n /**\n * Returns the time of the prefetch end.\n * If no data has been prefetched for the current track, 0 will be returned.\n *\n * The time given will be in seconds according to the media timeline.\n * It will represent the ending time of the continuous prefetch range from the current playhead time.\n */\n get fetchedTime(): number {\n const time = this.playbackController.currentTime\n const range = this.fetchedRanges.getRangeAt(time)\n if (!range) return 0\n return range[1]\n }\n\n /**\n * Returns current fetched time as a percent of the total duration.\n *\n * @return A number between 0-1\n */\n get fetchedTimePercent(): number {\n return this.duration > 0 ? this.fetchedTime / this.duration : 0\n }\n\n /**\n * Returns the current content types for active streams.\n */\n get contentTypes(): ReadonlySet<ContentType> {\n return this.currentTrack?.contentTypes ?? emptyContentTypes\n }\n\n /**\n * The available qualities for the current period of the current track, after filtering.\n * Null if no track is active or the timeline is not yet available.\n */\n get qualities(): readonly MediaQualityMetadata[] | null {\n return this.currentTrack?.qualities ?? null\n }\n\n /**\n * The available unfiltered qualities for the current period of the current track.\n * Null if no track is active or the timeline is not yet available.\n */\n get qualitiesUnfiltered(): readonly MediaQualityMetadata[] | null {\n return this.currentTrack?.qualitiesUnfiltered ?? null\n }\n\n /**\n * @deprecated Use `getStreamingQuality('audio')`\n */\n get streamingQuality(): MediaQualityMetadata | null {\n return this.getStreamingQuality('audio')\n }\n\n /**\n * @deprecated Use `getBufferingQuality('audio')\n */\n get bufferingQuality(): MediaQualityMetadata | null {\n return this.getStreamingQuality('audio')\n }\n\n /**\n * @deprecated Use `getPlaybackQuality('audio')\n */\n get playbackQuality(): MediaQualityMetadata | null {\n return this.getPlaybackQuality('audio')\n }\n\n /**\n * The streaming quality for the current track.\n * Note that this does not represent the quality of inactive preloading tracks.\n */\n getStreamingQuality(contentType: ContentType): MediaQualityMetadata | null {\n return this.currentTrack?.getStreamingQuality(contentType) ?? null\n }\n\n /**\n * The currently buffering quality, or null if no data is buffered.\n */\n getBufferingQuality(contentType: ContentType): MediaQualityMetadata | null {\n return this.currentTrack?.getBufferingQuality(contentType) ?? null\n }\n\n /**\n * The currently playing quality, or null if no media is playing.\n */\n getPlaybackQuality(contentType: ContentType): MediaQualityMetadata | null {\n return this.currentTrack?.getPlaybackQuality(contentType) ?? null\n }\n\n //----------------------------------------------------\n\n /**\n * Returns true if this player has been disposed.\n */\n get disposed(): boolean {\n return this.disposer.disposed\n }\n\n /**\n * Disposes this player and sub-systems.\n */\n dispose(): void {\n logDebug(this, 'dispose')\n super.dispose()\n this.disposer.dispose()\n playerRegistryRef.value.removePlayer(this)\n }\n}\n\n/**\n * Constructs a new {@link VinylPlayer}.\n *\n * @param options Configuration for default dependencies.\n * @param factoryOverrides Dependency factory overrides.\n */\nexport function createVinylPlayer<\n DependencyOverridesType extends Factories | undefined,\n>(\n options: VinylDependencyOptions,\n factoryOverrides?: ValidFactoryOverrides<\n VinylDeps<any, AnyRecord>,\n DefaultVinylFactories,\n DependencyOverridesType\n >\n): VinylPlayer<\n // The player will accept the load options for the track factories, accounting for overrides.\n InferLoadOptionsFromFactory<\n InferVinylOverrideDependencyType<\n NoInfer<DependencyOverridesType>,\n 'trackFactory'\n >\n >,\n // Infer the options type.\n InferObservableValueType<\n InferVinylOverrideDependencyType<\n NoInfer<DependencyOverridesType>,\n 'options'\n >\n >\n> {\n const player = new (VinylPlayer as any)({\n ...createVinylFactories(options),\n ...factoryOverrides,\n })\n logInfo(player, `VinylPlayer initialized`)\n return player\n}\n\n/**\n * Do not redispatch reset events, only emit the reset event when `player.reset` is called.\n * @param type\n */\nfunction notResetEvent<T extends string>(type: T): type is Exclude<T, 'reset'> {\n return type !== 'reset'\n}\n\nconst qualityEventsAndGetters = [\n ['streamingQualityChange', 'getStreamingQuality'],\n ['bufferingQualityChange', 'getBufferingQuality'],\n ['playbackQualityChange', 'getPlaybackQuality'],\n] as const\n\nconst emptyContentTypes = /* @__PURE__ */ new Set<ContentType>()\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { AnyRecord, Disposable } from '@amazon/vinyl-util'\nimport {\n globalRef,\n globalTarget,\n IllegalStateError,\n logWarn,\n remove,\n substitute,\n} from '@amazon/vinyl-util'\n\n/**\n * @private\n */\nconst locale = {\n maxPlayersWarning: `{count} Vinyl Players have been constructed without disposal. Check that player.dispose is properly being called, then increase the maxPlayersWarning option if this was intentional.`,\n} as const\n\n/**\n * A registry of all non-disposed Vinyl players.\n * Used for debugging and cleanup validation.\n */\nexport interface PlayerRegistry {\n /**\n * Returns the non-disposed Vinyl players.\n */\n readonly players: readonly AnyRecord[]\n\n /**\n * Adds a player reference. All players must be removed before disposing VinylGlobal.\n *\n * @param player\n */\n addPlayer(player: AnyRecord): void\n\n /**\n * Removes a player reference.\n *\n * @param player\n */\n removePlayer(player: AnyRecord): void\n}\n\nexport const DEFAULT_MAX_PLAYERS = 5\n\n/**\n * A registry of non-disposed players.\n * Used for leak detection and debugging diagnostics.\n */\nexport class PlayerRegistryImpl implements PlayerRegistry, Disposable {\n private _players: AnyRecord[] = []\n\n private gaveMaxPlayersWarning = false\n\n constructor(\n /**\n * The number of concurrent players before a warning is logged.\n * default: 5\n */\n public maxPlayersWarning: number = DEFAULT_MAX_PLAYERS\n ) {}\n\n get players(): readonly AnyRecord[] {\n return this._players\n }\n\n addPlayer(player: AnyRecord): void {\n this._players.push(player)\n const n = this._players.length\n if (n > this.maxPlayersWarning && !this.gaveMaxPlayersWarning) {\n this.gaveMaxPlayersWarning = true\n logWarn(\n globalTarget,\n substitute(locale.maxPlayersWarning, { count: n })\n )\n }\n }\n\n removePlayer(player: AnyRecord): void {\n remove(this._players, player)\n }\n\n /**\n * @throws An IllegalStateError if all players have not been removed.\n */\n dispose() {\n if (this._players.length)\n throw new IllegalStateError(\n 'All players must be removed before disposing VinylGlobal'\n )\n }\n}\n\nexport const playerRegistryRef = /* @__PURE__ */ globalRef<PlayerRegistry>(\n () => new PlayerRegistryImpl()\n)\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { initializeLogging } from '@amazon/vinyl-util'\nimport { vinylGlobalRef } from './globalRef'\n\nexport function initializeVinylGlobal() {\n initializeLogging()\n vinylGlobalRef.initialize()\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {\n type AnyRecord,\n getNetworkMetrics,\n getUserAgentInfo,\n globalRef,\n historyLogHandler,\n toDisposable,\n} from '@amazon/vinyl-util'\nimport { playerRegistryRef } from './PlayerRegistry'\nimport { vinylVersion } from './environment'\n\ndeclare global {\n /**\n * A reference to Vinyl's global state, easily accessible via console.\n */\n var vinylGlobal: any\n}\n\n/**\n * For console debugging, gives access to currently active players, logs, and client information.\n */\nexport class VinylGlobal {\n get players() {\n return playerRegistryRef.value.players\n }\n\n /**\n * Returns the first player.\n */\n get player() {\n return playerRegistryRef.value.players[0]\n }\n\n get logs() {\n return historyLogHandler.value?.history\n }\n\n get version() {\n return vinylVersion.str\n }\n\n get userAgentInfo() {\n return getUserAgentInfo()\n }\n\n get network() {\n return getNetworkMetrics()\n }\n\n /**\n * Returns the EWMA low estimate for the client's current bandwidth.\n */\n get bandwidth() {\n return this.network.estimatedDownlinkBandwidth.ewmaLow\n }\n}\n\n/**\n * Set the global vinylGlobal reference for easier console debugging.\n * Intentionally typed as AnyRecord to prevent API usage from code. This is\n * intended only for console debugging and the API may change at any time.\n */\nexport const vinylGlobalRef = /* @__PURE__ */ globalRef((): AnyRecord => {\n global.vinylGlobal = new VinylGlobal()\n return toDisposable(() => {\n delete global.vinylGlobal\n })\n})\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { parseVersion } from '@amazon/vinyl-util'\n\ndeclare global {\n var __VINYL_VERSION__: string | undefined\n}\n\n/**\n * `globalThis.__VINYL_VERSION__` is replaced at build time with the package.version via\n * esbuild's `define` option. In unit tests and unbundled dev builds the replacement does not\n * happen and the global is undefined, so we fall through to a placeholder version.\n */\nexport const vinylVersion = /* @__PURE__ */ parseVersion(\n /* istanbul ignore next */\n globalThis.__VINYL_VERSION__ ?? '0.0.0.0'\n)\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { ChangeEvent } from '../event/ChangeEvent'\nimport type { ContentType, MediaQualityMetadata } from './MediaQualityMetadata'\nimport type { BasicErrorEvent } from '../event/BasicErrorEvent'\nimport type { AnyRecord } from '@amazon/vinyl-util'\n\n/**\n * Events a track dispatches related to streaming quality and status.\n */\nexport interface StreamingEventMap {\n /**\n * The actively streamed content types have changed.\n */\n readonly contentTypesChange: ChangeEvent<ReadonlySet<ContentType>>\n\n /**\n * fetchedRanges have been updated.\n */\n readonly fetchedRangesChange: AnyRecord\n\n /**\n * Dispatched when the currently streaming quality changes.\n * This is dispatched when a new streaming quality has been requested.\n */\n readonly streamingQualityChange: ChangeEvent<MediaQualityMetadata | null>\n\n /**\n * Dispatched when the currently buffering quality changes.\n * This is dispatched before the segment is appended.\n */\n readonly bufferingQualityChange: ChangeEvent<MediaQualityMetadata | null>\n\n /**\n * The currently playing quality has changed.\n */\n readonly playbackQualityChange: ChangeEvent<MediaQualityMetadata | null>\n\n /**\n * The last segment has finished appending.\n */\n readonly bufferingEnded: AnyRecord\n\n /**\n * Dispatched when a streaming error occurs.\n */\n readonly error: BasicErrorEvent\n\n /**\n * Emitted when the error state has been reset.\n */\n readonly reset: AnyRecord\n\n /**\n * The available qualities for the current period have changed.\n */\n readonly qualitiesChange: ChangeEvent<readonly MediaQualityMetadata[]>\n\n /**\n * The available unfiltered qualities for the current period have changed.\n */\n readonly qualitiesUnfilteredChange: ChangeEvent<\n readonly MediaQualityMetadata[]\n >\n}\n\n/**\n * All streaming-related events a track may emit.\n * These will be bubbled by the player.\n */\nexport const ALL_STREAMING_EVENTS = [\n 'contentTypesChange',\n 'fetchedRangesChange',\n 'streamingQualityChange',\n 'bufferingQualityChange',\n 'playbackQualityChange',\n 'bufferingEnded',\n 'error',\n 'reset',\n 'qualitiesChange',\n 'qualitiesUnfilteredChange',\n] as const satisfies readonly (keyof StreamingEventMap)[]\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { ReadonlyPlaybackController } from '../../playback/ReadonlyPlaybackController'\nimport {\n SegmentControllerImpl,\n type SegmentControllerImplOptions,\n} from '../../streaming/SegmentControllerImpl'\nimport type { ContentType } from '../../streaming/MediaQualityMetadata'\nimport type { SegmentController } from '../../streaming/SegmentController'\nimport type { ObservableValue } from '@amazon/vinyl-observable'\nimport type { MediaTimeline } from '../../streaming/MediaTimeline'\nimport type { QualitySelector } from '../../streaming/abr/QualitySelector'\n\nexport type SegmentControllerFactory = (deps: {\n readonly mediaTimelineTransformed: ObservableValue<Promise<MediaTimeline>>\n readonly qualitySelector: QualitySelector\n}) => SegmentController\n\nexport interface SegmentControllerFactoryDeps {\n readonly playbackController: ReadonlyPlaybackController\n}\n\nexport function createSegmentControllerFactory(\n playerDeps: SegmentControllerFactoryDeps,\n contentType: ContentType,\n options?: Partial<SegmentControllerImplOptions>\n) {\n return (trackDeps: {\n readonly mediaTimelineTransformed: ObservableValue<\n Promise<MediaTimeline>\n >\n readonly qualitySelector: QualitySelector\n }) => {\n return new SegmentControllerImpl(\n {\n ...playerDeps,\n ...trackDeps,\n },\n contentType,\n options\n )\n }\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {\n consoleLogHandler,\n historyLogHandler,\n LogLevel,\n type PartialDeep,\n setLogLevel,\n} from '@amazon/vinyl-util'\nimport type { ValueSchema } from '@amazon/vinyl-validation'\nimport {\n isOneOf,\n number,\n object,\n type ObjectSchema,\n} from '@amazon/vinyl-validation'\nimport { PlayerRegistryImpl, playerRegistryRef } from './PlayerRegistry'\n\n/**\n * Configuration for VinylGlobal.\n */\nexport interface VinylGlobalOptions {\n /**\n * The number of concurrent players before a warning is logged.\n * default: 5\n */\n readonly maxPlayersWarning: number\n\n /**\n * Logging configuration\n */\n readonly logging: {\n readonly history: {\n /**\n * Limits the history log level.\n */\n readonly logLevel: LogLevel\n\n /**\n * Sets the logging history size.\n */\n readonly maxHistorySize: number\n }\n\n /**\n * Gates all log handlers to logs of at least this level.\n */\n readonly logLevel: LogLevel\n\n readonly console: {\n /**\n * Gates console logs\n */\n readonly logLevel: LogLevel\n }\n }\n}\n\nconst logLevelValidator: ValueSchema<LogLevel> = /* @__PURE__ */ (() =>\n isOneOf(\n LogLevel.VERBOSE,\n LogLevel.DEBUG,\n LogLevel.INFO,\n LogLevel.WARN,\n LogLevel.ERROR,\n LogLevel.NONE\n ))()\n\n/**\n * A validator for VinylGlobalOptions applications can set for Vinyl.\n */\nconst vinylGlobalOptionsValidator: ObjectSchema<VinylGlobalOptions> = /* @__PURE__ */ object({\n logging: /* @__PURE__ */ object({\n console: /* @__PURE__ */ object({\n logLevel: logLevelValidator,\n }),\n history: /* @__PURE__ */ object({\n logLevel: logLevelValidator,\n maxHistorySize: /* @__PURE__ */ number(),\n }),\n logLevel: logLevelValidator,\n }),\n maxPlayersWarning: /* @__PURE__ */ number(),\n})\n\nconst vinylGlobalOptionsPartialValidator: ObjectSchema<\n PartialDeep<VinylGlobalOptions>\n> = /* @__PURE__ */ vinylGlobalOptionsValidator.partialDeep()\n\n/**\n * Applies configuration to the current vinyl global options.\n *\n * @param options\n */\nexport function configureVinylGlobal(options: PartialDeep<VinylGlobalOptions>) {\n vinylGlobalOptionsPartialValidator.assert(options)\n // Logging configuration\n if (options.logging) {\n const logging = options.logging\n if (logging.logLevel != null) setLogLevel(logging.logLevel)\n if (logging.history) {\n const history = logging.history\n if (historyLogHandler.value) {\n if (history.maxHistorySize != null)\n historyLogHandler.value.maxHistorySize =\n history.maxHistorySize\n if (history.logLevel != null)\n historyLogHandler.value.logLevel = history.logLevel\n }\n }\n if (logging.console?.logLevel != null) {\n if (consoleLogHandler.value) {\n consoleLogHandler.value.logLevel = logging.console.logLevel\n }\n }\n }\n\n if (\n options.maxPlayersWarning != null &&\n playerRegistryRef.value instanceof PlayerRegistryImpl\n ) {\n playerRegistryRef.value.maxPlayersWarning = options.maxPlayersWarning\n }\n}\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA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,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC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",
6
- "names": ["data", "CanPlayTypeResult", "import_vinyl_util", "import_vinyl_util", "import_vinyl_util", "import_vinyl_util", "import_vinyl_util", "import_vinyl_util", "import_vinyl_util", "PlayedReason", "WaitedReason", "PlaybackReadyState", "PlaybackNetworkState", "import_vinyl_util", "import_vinyl_util", "import_vinyl_util", "import_vinyl_util", "import_vinyl_util", "import_vinyl_util", "import_vinyl_util", "import_vinyl_validation", "import_vinyl_validation", "import_vinyl_util", "import_vinyl_validation", "import_vinyl_validation", "DrmKeySystem", "import_vinyl_validation", "DrmRobustness", "import_vinyl_util", "contentType", "import_vinyl_util", "import_vinyl_util", "import_vinyl_validation", "import_vinyl_validation", "import_vinyl_util", "record", "src", "contentType", "import_vinyl_util", "import_vinyl_validation", "loadOptionsValidator", "import_vinyl_util", "import_vinyl_validation", "import_vinyl_util", "import_vinyl_util", "time", "period", "contentType", "loadOptionsValidator", "import_vinyl_util", "import_vinyl_validation", "loadOptionsValidator", "import_vinyl_util", "element", "import_vinyl_util", "import_vinyl_util", "import_vinyl_util", "time", "period", "_a", "import_vinyl_util", "import_vinyl_util", "import_vinyl_util", "_a", "import_vinyl_util", "contentType", "contentType", "fullMimeType", "import_vinyl_util", "contentType", "_a", "_b", "import_vinyl_util", "import_vinyl_util", "import_vinyl_util", "import_vinyl_util", "contentType", "import_vinyl_observable", "import_vinyl_util", "promise", "import_vinyl_util", "contentType", "data", "import_vinyl_util", "contentType", "onMediaSourceOpen", "import_vinyl_util", "import_vinyl_util", "SegmentStatus", "import_vinyl_util", "contentType", "import_vinyl_util", "time", "element", "contentType", "data", "cachedSegment", "import_vinyl_util", "import_vinyl_di", "contentType", "deps", "import_vinyl_util", "import_vinyl_validation", "AbrStrategy", "import_vinyl_di", "import_vinyl_util", "import_vinyl_mpd_parser", "import_vinyl_util", "import_vinyl_di", "contentType", "contentType", "import_vinyl_util", "import_vinyl_util", "import_vinyl_mpd_parser", "data", "import_vinyl_observable", "import_vinyl_util", "import_vinyl_util", "import_vinyl_util", "locale", "contentType", "array", "import_vinyl_util", "import_vinyl_util", "import_vinyl_util", "array", "array", "deps", "data", "contentType", "import_vinyl_observable", "import_vinyl_util", "promise", "import_vinyl_di", "import_vinyl_util", "getContentTypes", "import_vinyl_util", "import_vinyl_di", "contentType", "deps", "data", "import_vinyl_util", "import_vinyl_util", "data", "contentType", "_a", "deps", "data", "import_vinyl_util", "import_vinyl_util", "MediaKeySessionErrorType", "import_vinyl_util", "element", "import_vinyl_util", "import_vinyl_util", "element", "import_vinyl_util", "element", "import_vinyl_util", "import_vinyl_util", "import_vinyl_validation", "import_vinyl_util", "element", "import_vinyl_util", "import_vinyl_util", "import_vinyl_util", "contentType", "import_vinyl_mpd_parser", "import_vinyl_util", "import_vinyl_validation", "import_vinyl_util", "import_vinyl_di", "import_vinyl_validation", "import_vinyl_util", "import_vinyl_di", "import_vinyl_util", "locale", "import_vinyl_util", "import_vinyl_util", "import_vinyl_util", "contentType", "contentType", "import_vinyl_util", "import_vinyl_validation"]
3
+ "sources": ["../src/index.ts", "../src/ad/AdController.ts", "../src/ad/AdControllerImpl.ts", "../src/ad/AdError.ts", "../src/track/inferLoadOptionsFromUri.ts", "../src/ad/defaultAdLoadOptionsResolver.ts", "../src/ad/discoverHlsInterstitials.ts", "../src/client/Capabilities.ts", "../src/util/media/mediaSource.ts", "../src/util/media/getAudioContext.ts", "../src/client/CapabilitiesImpl.ts", "../src/drm/CencEncryptionScheme.ts", "../src/drm/commonEme/CommonEme.ts", "../src/drm/commonEme/MsCommonEme.ts", "../src/drm/error/DrmError.ts", "../src/drm/commonEme/StandardCommonEme.ts", "../src/drm/commonEme/createDrmErrorHandler.ts", "../src/drm/commonEme/WebKitCommonEme.ts", "../src/drm/commonEme/CommonEmeFactory.ts", "../src/drm/DrmControllerImpl.ts", "../src/drm/DrmOptions.ts", "../src/drm/DrmKeySystem.ts", "../src/drm/licenseProvider/LicenseProvider.ts", "../src/drm/util/unpackPlayReadyChallenge.ts", "../src/drm/licenseProvider/defaultLicenseProvider.ts", "../src/drm/util/extractContentId.ts", "../src/drm/util/createFairPlaySessionInitData.ts", "../src/drm/DrmKeySystemResolver.ts", "../src/event/ChangeEvent.ts", "../src/global/configureVinylGlobal.ts", "../src/global/PlayerRegistry.ts", "../src/global/environment.ts", "../src/global/globalRef.ts", "../src/global/initializeVinylGlobal.ts", "../src/patch/media/MediaElementPatchOptions.ts", "../src/patch/media/patches/createUnreliablePlaybackEventsPatch.ts", "../src/patch/media/patches/createPreventStallsPatch.ts", "../src/patch/media/patchMediaElement.ts", "../src/playback/error/InvalidSeekError.ts", "../src/playback/error/ReportableMediaError.ts", "../src/playback/logging/mediaErrorToJson.ts", "../src/playback/logging/playbackStateLoggingHandler.ts", "../src/playback/ReadonlyPlaybackController.ts", "../src/playback/loudness/LoudnessNormalizationControllerImpl.ts", "../src/playback/loudness/LoudnessNormalizationControllerImplOptions.ts", "../src/playback/nextHasMetadata.ts", "../src/playback/PlaybackController.ts", "../src/playback/PlaybackControllerImpl.ts", "../src/playback/PlaybackSourceImpl.ts", "../src/streaming/abr/QualitySelectorImpl.ts", "../src/streaming/buffering/BufferingController.ts", "../src/streaming/SegmentController.ts", "../src/streaming/buffering/error/SourceBufferError.ts", "../src/util/media/codecSupport.ts", "../src/streaming/buffering/codecDenylist.ts", "../src/streaming/buffering/MediaSourceController.ts", "../src/util/media/sourceBuffer.ts", "../src/streaming/buffering/SourceBufferController.ts", "../src/streaming/ContentStream.ts", "../src/streaming/createAllowedContentTypesValue.ts", "../src/streaming/createDefaultMediaTimelineTransformer.ts", "../src/streaming/mediaTimelineFilter.ts", "../src/streaming/mediaTimelineLanguageFilter.ts", "../src/track/filters/languageFilter.ts", "../src/streaming/mediaTimelineAccessibilityFilter.ts", "../src/track/filters/resourceTypeFilter.ts", "../src/track/filters/keySystemFilter.ts", "../src/track/filters/sampleRateFilter.ts", "../src/util/media/codecOverrides.ts", "../src/streaming/DescriptorRecord.ts", "../src/streaming/ManifestControllerImpl.ts", "../src/streaming/MediaQualityMetadata.ts", "../src/streaming/MediaTimeline.ts", "../src/streaming/SegmentControllerImpl.ts", "../src/streaming/SegmentDataSlot.ts", "../src/streaming/SegmentPrefetch.ts", "../src/streaming/util/segment.ts", "../src/streaming/StreamingEventMap.ts", "../src/text/discoverDashTextTracks.ts", "../src/text/discoverHlsTextTracks.ts", "../src/text/parseWebVtt.ts", "../src/text/pickPreferredTextTrack.ts", "../src/text/SidecarTextTrackController.ts", "../src/text/SidecarTextTrackLoader.ts", "../src/text/VttCueStyle.ts", "../src/text/TextTrack.ts", "../src/track/AutoResetController.ts", "../src/track/createSegmentDataProvider.ts", "../src/track/TrackFactory.ts", "../src/track/source/SourceObjectTrack.ts", "../src/track/TrackBase.ts", "../src/track/source/FixedPlaybackQuality.ts", "../src/track/source/SourceTrackBase.ts", "../src/track/source/SourceTrack.ts", "../src/track/dash/DashTrack.ts", "../src/track/mse/MseTrack.ts", "../src/track/hls/HlsTrack.ts", "../src/track/createVinylTrackFactories.ts", "../src/track/dash/util/mpd.ts", "../src/track/mse/codec.ts", "../src/track/dash/util/mimeType.ts", "../src/track/dash/timeline/DashRepresentationSegmentProvider.ts", "../src/track/dash/util/uriResolution.ts", "../src/track/dash/buildDashMediaTimeline.ts", "../src/track/dash/createDashContentStreamFactories.ts", "../src/track/dash/createDashContentTypesValue.ts", "../src/track/dash/createDefaultDashManifestTransformer.ts", "../src/track/dash/manifestTransformUtils.ts", "../src/track/dash/DashMediaQualityMetadataResolver.ts", "../src/track/dash/createDashFactories.ts", "../src/track/dash/urlDashManifestProvider.ts", "../src/track/dash/createDashManifestProvider.ts", "../src/track/dash/createSegmentControllerFactory.ts", "../src/track/hls/util/hlsByteRangeToMediaRange.ts", "../src/track/hls/util/hlsSegmentTime.ts", "../src/track/hls/buildHlsMediaTimeline.ts", "../src/track/hls/createDefaultHlsManifestTransformer.ts", "../src/track/hls/createHlsContentStreamFactories.ts", "../src/track/hls/createHlsContentTypesValue.ts", "../src/track/hls/HlsMediaQualityMetadataResolver.ts", "../src/track/hls/createHlsFactories.ts", "../src/track/hls/createUrlHlsManifestProvider.ts", "../src/track/hls/createHlsManifestProvider.ts", "../src/track/TrackController.ts", "../src/vinyl/createVinylFactories.ts", "../src/vinyl/VinylPatchOptions.ts", "../src/vinyl/VinylOptions.ts", "../src/vinyl/playerConfigFactory.ts", "../src/vinyl/VinylPlayer.ts"],
4
+ "sourcesContent": ["/** Auto-generated from build scripts */\nexport * from './ad/AdBreakInfo'\nexport * from './ad/AdController'\nexport * from './ad/AdControllerImpl'\nexport * from './ad/AdError'\nexport * from './ad/AdsProvider'\nexport * from './ad/defaultAdLoadOptionsResolver'\nexport * from './ad/discoverHlsInterstitials'\nexport * from './client/Capabilities'\nexport * from './client/CapabilitiesImpl'\nexport * from './client/Client'\nexport * from './drm/CencEncryptionScheme'\nexport * from './drm/commonEme/CommonEme'\nexport * from './drm/commonEme/CommonEmeFactory'\nexport * from './drm/commonEme/createDrmErrorHandler'\nexport * from './drm/commonEme/EncryptedInitData'\nexport * from './drm/commonEme/MsCommonEme'\nexport * from './drm/commonEme/StandardCommonEme'\nexport * from './drm/commonEme/WebKitCommonEme'\nexport * from './drm/dom/HTMLMediaElement'\nexport * from './drm/dom/MSMediaKeys'\nexport * from './drm/dom/WebKitMediaKeys'\nexport * from './drm/DrmController'\nexport * from './drm/DrmControllerImpl'\nexport * from './drm/DrmKeySystem'\nexport * from './drm/DrmKeySystemResolver'\nexport * from './drm/DrmOptions'\nexport * from './drm/error/DrmError'\nexport * from './drm/licenseProvider/defaultLicenseProvider'\nexport * from './drm/licenseProvider/LicenseProvider'\nexport * from './drm/util/createFairPlaySessionInitData'\nexport * from './drm/util/extractContentId'\nexport * from './drm/util/unpackPlayReadyChallenge'\nexport * from './event/BasicErrorEvent'\nexport * from './event/ChangeEvent'\nexport * from './global/configureVinylGlobal'\nexport * from './global/environment'\nexport * from './global/globalRef'\nexport * from './global/initializeVinylGlobal'\nexport * from './global/PlayerRegistry'\nexport * from './patch/media/HtmlMediaElementPatch'\nexport * from './patch/media/MediaElementPatchOptions'\nexport * from './patch/media/patches/createPreventStallsPatch'\nexport * from './patch/media/patches/createUnreliablePlaybackEventsPatch'\nexport * from './patch/media/patchMediaElement'\nexport * from './playback/error/InvalidSeekError'\nexport * from './playback/error/ReportableMediaError'\nexport * from './playback/logging/mediaErrorToJson'\nexport * from './playback/logging/playbackStateLoggingHandler'\nexport * from './playback/loudness/LoudnessNormalizationController'\nexport * from './playback/loudness/LoudnessNormalizationControllerImpl'\nexport * from './playback/loudness/LoudnessNormalizationControllerImplOptions'\nexport * from './playback/nextHasMetadata'\nexport * from './playback/PlaybackController'\nexport * from './playback/PlaybackControllerImpl'\nexport * from './playback/PlaybackSource'\nexport * from './playback/PlaybackSourceImpl'\nexport * from './playback/ReadonlyPlaybackController'\nexport * from './streaming/abr/QualitySelector'\nexport * from './streaming/abr/QualitySelectorImpl'\nexport * from './streaming/buffering/BufferingController'\nexport * from './streaming/buffering/codecDenylist'\nexport * from './streaming/buffering/error/SourceBufferError'\nexport * from './streaming/buffering/MediaSourceController'\nexport * from './streaming/buffering/SourceBufferController'\nexport * from './streaming/ContentStream'\nexport * from './streaming/ContentStreamingOptions'\nexport * from './streaming/ContentTypesValue'\nexport * from './streaming/createAllowedContentTypesValue'\nexport * from './streaming/createDefaultMediaTimelineTransformer'\nexport * from './streaming/DescriptorRecord'\nexport * from './streaming/DrmInitDataType'\nexport * from './streaming/LoadMetric'\nexport * from './streaming/ManifestController'\nexport * from './streaming/ManifestControllerImpl'\nexport * from './streaming/MediaQualityMetadata'\nexport * from './streaming/MediaTimeline'\nexport * from './streaming/mediaTimelineAccessibilityFilter'\nexport * from './streaming/mediaTimelineFilter'\nexport * from './streaming/mediaTimelineLanguageFilter'\nexport * from './streaming/SegmentController'\nexport * from './streaming/SegmentControllerImpl'\nexport * from './streaming/SegmentDataSlot'\nexport * from './streaming/SegmentPrefetch'\nexport * from './streaming/SegmentReference'\nexport * from './streaming/StreamingEventMap'\nexport * from './streaming/util/segment'\nexport * from './text/discoverDashTextTracks'\nexport * from './text/discoverHlsTextTracks'\nexport * from './text/parseWebVtt'\nexport * from './text/pickPreferredTextTrack'\nexport * from './text/SidecarTextTrackController'\nexport * from './text/SidecarTextTrackLoader'\nexport * from './text/TextTrack'\nexport * from './text/VttCueStyle'\nexport * from './track/AutoResetController'\nexport * from './track/createSegmentDataProvider'\nexport * from './track/createVinylTrackFactories'\nexport * from './track/dash/buildDashMediaTimeline'\nexport * from './track/dash/createDashContentStreamFactories'\nexport * from './track/dash/createDashContentTypesValue'\nexport * from './track/dash/createDashFactories'\nexport * from './track/dash/createDashManifestProvider'\nexport * from './track/dash/createDefaultDashManifestTransformer'\nexport * from './track/dash/createSegmentControllerFactory'\nexport * from './track/dash/DashManifestController'\nexport * from './track/dash/DashManifestProvider'\nexport * from './track/dash/DashMediaQualityMetadataResolver'\nexport * from './track/dash/DashTrack'\nexport * from './track/dash/manifestTransformUtils'\nexport * from './track/dash/timeline/DashRepresentationSegmentProvider'\nexport * from './track/dash/urlDashManifestProvider'\nexport * from './track/dash/util/mimeType'\nexport * from './track/dash/util/mpd'\nexport * from './track/dash/util/uriResolution'\nexport * from './track/filters/keySystemFilter'\nexport * from './track/filters/languageFilter'\nexport * from './track/filters/resourceTypeFilter'\nexport * from './track/filters/sampleRateFilter'\nexport * from './track/hls/buildHlsMediaTimeline'\nexport * from './track/hls/createDefaultHlsManifestTransformer'\nexport * from './track/hls/createHlsContentStreamFactories'\nexport * from './track/hls/createHlsContentTypesValue'\nexport * from './track/hls/createHlsFactories'\nexport * from './track/hls/createHlsManifestProvider'\nexport * from './track/hls/createUrlHlsManifestProvider'\nexport * from './track/hls/HlsManifestController'\nexport * from './track/hls/HlsManifestData'\nexport * from './track/hls/HlsMediaQualityMetadataResolver'\nexport * from './track/hls/HlsTrack'\nexport * from './track/hls/util/hlsByteRangeToMediaRange'\nexport * from './track/hls/util/hlsSegmentTime'\nexport * from './track/inferLoadOptionsFromUri'\nexport * from './track/mse/codec'\nexport * from './track/mse/MseTrack'\nexport * from './track/SeekRange'\nexport * from './track/source/FixedPlaybackQuality'\nexport * from './track/source/SourceObjectTrack'\nexport * from './track/source/SourceTrack'\nexport * from './track/source/SourceTrackBase'\nexport * from './track/Track'\nexport * from './track/TrackBase'\nexport * from './track/TrackController'\nexport * from './track/TrackFactory'\nexport * from './util/media/codecOverrides'\nexport * from './util/media/codecSupport'\nexport * from './util/media/getAudioContext'\nexport * from './util/media/mediaSource'\nexport * from './util/media/sourceBuffer'\nexport * from './vinyl/createVinylFactories'\nexport * from './vinyl/playerConfigFactory'\nexport * from './vinyl/ReadonlyPlaybackStreamingState'\nexport * from './vinyl/VinylDeps'\nexport * from './vinyl/VinylOptions'\nexport * from './vinyl/VinylPatchOptions'\nexport * from './vinyl/VinylPlayer'\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { ChangeEvent } from '../event/ChangeEvent'\nimport { type ReadonlyEventHost } from '@amazon/vinyl-util'\nimport { type AdBreakInfo, type AdInfo, type TrackAds } from './AdBreakInfo'\nimport type { AdsProvider } from './AdsProvider'\n\n/**\n * Events dispatched by an {@link AdController}. These are provider-agnostic:\n * an application listens once and receives the same events whether the ads\n * originate from HLS Interstitials or DASH SCTE-35.\n */\nexport interface AdEventMap {\n /**\n * Emitted when the set of known ad breaks for the current media changes,\n * for example when a live manifest reveals a new break.\n */\n readonly currentTrackAdsChange: ChangeEvent<TrackAds | null>\n\n /**\n * Dispatched when the playhead approaches a midroll or postroll break \u2014\n * within the break's resolution/preload window \u2014 so its ad assets can be\n * resolved and warmed ahead of entry. Fires once per break as it is\n * approached (again after a seek back re-arms a replayable break). Prerolls\n * are preloaded up front and do not emit this.\n */\n readonly adPreload: AdBreakEvent\n\n /**\n * Dispatched when an ad break has been entered \u2014 its ads may still be\n * resolving. An ad break may contain one or more ads.\n */\n readonly adBreakEntered: AdBreakEvent\n\n /**\n * Dispatched when the current ad break has completed: all of its ads\n * played, were skipped, it hit its playout limit, or it had no ads. Carries\n * the position at which primary content resumes.\n */\n readonly adBreakCompleted: AdBreakCompleteEvent\n\n /**\n * Dispatched when an ad region has been entered.\n */\n readonly adEntered: AdEvent\n\n /**\n * Dispatched when an ad has started playing.\n */\n readonly adPlaying: AdEvent\n\n /**\n * Dispatched on each playback progress tick while an ad is active, carrying\n * the elapsed and remaining time for both the current ad and the whole ad\n * break. Applications should prefer this over deriving ad timing from the\n * media element's duration.\n */\n readonly adTimeUpdate: AdTimeUpdateEvent\n\n /**\n * Dispatched when an ad has played through 25%.\n */\n readonly adFirstQuartile: AdProgressEvent\n\n /**\n * Dispatched when an ad has played through 50%.\n */\n readonly adMidpoint: AdProgressEvent\n\n /**\n * Dispatched when an ad has played through 75%.\n */\n readonly adThirdQuartile: AdProgressEvent\n\n /**\n * Dispatched when an ad has played through 100%.\n * Will be dispatched before adCompleted.\n */\n readonly adEnded: AdProgressEvent\n\n /**\n * Dispatched when an ad has stopped playing for any reason such as\n * ended, error, or skipped.\n */\n readonly adCompleted: AdCompleteEvent\n\n /**\n * An ad list or an individual ad failed to complete.\n */\n readonly adError: AdErrorEvent\n}\n\nexport interface AdErrorEvent {\n /**\n * The current ad break when the ad failed to load.\n */\n readonly adBreak: AdBreakInfo\n\n /**\n * If set, the error was from an individual ad.\n * If not set, the failure was in loading the ad list.\n */\n readonly currentAd: AdInfo | null\n\n /**\n * The source error.\n */\n readonly error: any\n}\n\nexport interface AdEvent {\n /** The parent ad break */\n readonly adBreak: AdBreakInfo\n\n /** The ad that triggered this event. */\n readonly ad: AdInfo\n\n /** The zero-based position of this ad within its break. */\n readonly index: number\n\n /** The total number of ads in this break. */\n readonly totalAds: number\n}\n\nexport interface AdProgressEvent extends AdEvent {\n /**\n * The average continuous playback rate for the quartile.\n * Typically, 1.0 unless playbackRate was altered.\n */\n readonly playbackRateAvg: number\n}\n\nexport interface AdTimeUpdateEvent extends AdEvent {\n /** Seconds the current ad has played. */\n readonly adCurrentTime: number\n\n /**\n * Seconds remaining in the current ad, or null when the ad's duration is\n * unknown.\n */\n readonly adTimeRemaining: number | null\n\n /**\n * Seconds the current ad break has played, summed across all of its ads so\n * far (including the current one).\n */\n readonly breakCurrentTime: number\n\n /**\n * Seconds remaining in the current ad break as a whole, or null when the\n * break's total duration is unknown.\n */\n readonly breakTimeRemaining: number | null\n\n /**\n * Whether the current ad may be skipped right now \u2014 false while skipping is\n * restricted or the break's skip window has not yet opened. Applications\n * should gate their skip control on this.\n */\n readonly canSkip: boolean\n\n /**\n * Seconds until the ad becomes skippable, or null when there is no pending\n * skip window (it is already skippable, or skipping is never offered).\n */\n readonly skipIn: number | null\n}\n\nexport interface AdCompleteEvent extends AdEvent {\n /** The current ad break. */\n readonly adBreak: AdBreakInfo\n\n /** The reason the ad changed, e.g. 'ended' for completed naturally, or 'skipped' */\n readonly reason: AdChangeReason\n}\n\nexport interface AdBreakEvent {\n /** The ad break. */\n readonly adBreak: AdBreakInfo\n}\n\nexport interface AdBreakCompleteEvent extends AdBreakEvent {\n /**\n * The absolute media-timeline position, in seconds, at which primary content\n * resumes after this break. The controller has already resolved the break's\n * resume offset and playout, so consumers use this position directly.\n */\n readonly resumePosition: number\n\n /** The reason the ad break changed, e.g. 'ended' for completed naturally, or 'skipped' */\n readonly reason: AdChangeReason\n}\n\nexport type AdChangeReason = 'ended' | 'skipped' | 'contentChange' | 'error'\n\nexport const ALL_AD_EVENTS = [\n 'currentTrackAdsChange',\n 'adPreload',\n 'adBreakEntered',\n 'adBreakCompleted',\n 'adFirstQuartile',\n 'adEntered',\n 'adPlaying',\n 'adTimeUpdate',\n 'adMidpoint',\n 'adThirdQuartile',\n 'adEnded',\n 'adCompleted',\n 'adError',\n] as const satisfies readonly (keyof AdEventMap)[]\n\n/**\n * Read-only view of the ad breaks for the current media and which break, if\n * any, currently contains the playhead.\n */\nexport interface ReadonlyAdController extends ReadonlyEventHost<AdEventMap> {\n /**\n * The ad breaks known for the current media.\n */\n readonly currentTrackAds: TrackAds | null\n\n /**\n * The ad break currently containing the playhead, or null when the\n * playhead is in primary content.\n */\n readonly currentAdBreak: AdBreakInfo | null\n\n /**\n * The ad currently playing within the active break, or null.\n */\n readonly currentAd: AdInfo | null\n}\n\n/**\n * Tracks the ad breaks for the current media and reports when the playhead\n * enters and exits them.\n *\n * The controller is deliberately agnostic of HLS/DASH discovery details: its\n * input is a list of {@link AdBreakInfo} sourced from an {@link AdsProvider}\n * (set via {@link setAdsProvider}); it derives the active break from the\n * playhead by observing the playback controller.\n */\nexport interface AdController extends ReadonlyAdController {\n /**\n * Sets the source of ad breaks, or null when no source is active. A\n * `ReadonlyTrack` satisfies {@link AdsProvider} directly, so the current\n * playing track can be passed as-is.\n */\n setAdsProvider(provider: AdsProvider | null): void\n\n /**\n * Skips the entire active ad break, advancing past all remaining ads.\n * No-op when no ad break is active.\n */\n skipAdBreak(): void\n\n /**\n * Skips the currently playing ad. If there are more ads in the break,\n * the next ad begins. If it's the last ad, the break ends.\n * No-op when no ad break is active.\n */\n skipAd(): void\n\n /**\n * Skips the current ad with 'error' for the completed reason.\n * Emits an 'adError' event.\n * If there are more ads in the break,\n * the next ad begins. If it's the last ad, the break ends.\n *\n * No-op when no ad break is active.\n */\n failAd(error: Error): void\n\n /**\n * Activates the preroll ads.\n * Does nothing if there is no preroll.\n * Resolves with the active preroll, or null if there wasn't one.\n */\n enterPreroll(): Promise<AdBreakInfo | null>\n\n /**\n * Activates the next postroll ad.\n * Does nothing if there is no postroll.\n * Resolves with the active postroll, or null if there wasn't one.\n */\n enterPostroll(): Promise<AdBreakInfo | null>\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {\n createDisposer,\n createLogPrefix,\n EventHostImpl,\n getElementOrDefault,\n lerp,\n logDebug,\n logError,\n type LogTarget,\n logVerbose,\n type Maybe,\n memoize,\n noop,\n resolveValueProvider,\n roundToNearest,\n sleep,\n sortedInsertionIndex,\n type Unsubscribe,\n} from '@amazon/vinyl-util'\nimport {\n type AdBreakInfo,\n type AdBreakList,\n type AdInfo,\n type TrackAds,\n} from './AdBreakInfo'\nimport type {\n AdChangeReason,\n AdController,\n AdEventMap,\n AdProgressEvent,\n} from './AdController'\nimport type { ReadonlyPlaybackController } from '../playback/ReadonlyPlaybackController'\nimport { AdError } from './AdError'\nimport type { AdsProvider } from './AdsProvider'\n\n/**\n * The % playhead start tolerance for playback progress when emitting ad progress events.\n */\nexport const AD_START_TOLERANCE = 0.05\n\nexport interface AdControllerImplDeps {\n readonly playbackController: ReadonlyPlaybackController\n}\n\nexport interface AdControllerImplOptions {\n /**\n * After an ad is set, the number of seconds to wait for playback to begin\n * before marking the ad as failed.\n * Default: 15\n */\n readonly adLoadTimeout: number\n\n /**\n * How many seconds ahead of a midroll or postroll break to emit `adPreload`\n * (so its ad assets can be warmed before the playhead reaches it). Used only\n * when the break itself carries no {@link AdBreakInfo.resolutionTimeOffset};\n * a break's own offset always takes precedence.\n * Default: 10\n */\n readonly preloadAheadTime: number\n}\n\nexport const defaultAdControllerImplOptions: AdControllerImplOptions = {\n adLoadTimeout: 15,\n preloadAheadTime: 10,\n}\n\ninterface Quartiles {\n first: boolean\n midpoint: boolean\n third: boolean\n}\n\ninterface AdBreakState {\n readonly adBreak: AdBreakInfo\n readonly adState: AdState | null\n\n completedReason: AdChangeReason | null\n\n playoutElapsed: number\n\n /**\n * Resolves the break's ad list (once, memoized) and advances to the next\n * ad in it, returning that ad's state \u2014 or null when the list is exhausted.\n */\n nextAd(): Promise<AdState | null>\n\n /**\n * Clears any pending and current ads.\n */\n clear(): void\n}\n\ninterface AdState {\n readonly parentBreak: AdBreakState\n readonly ad: AdInfo\n readonly index: number\n readonly totalAds: number\n started: boolean\n // The currentTime at the start of playback\n timeStart: number\n // The running playback rate average\n playbackRateAvg: number\n dataPoints: number\n readonly quartile: Quartiles\n completedReason: AdChangeReason | null\n}\n\n/**\n * Provider-agnostic {@link AdController}. Holds the discovered ad breaks and\n * derives enter/exit region events from playhead time updates.\n *\n * This controller is the *model* for ad playback: it knows which breaks exist,\n * which break contains the playhead, and which ad within that break is current.\n * It does NOT create, preload, or activate any tracks \u2014 that is the\n * responsibility of the {@link TrackController}.\n *\n * A break is considered active while `startTime <= currentTime < endTime`,\n * where `endTime` is `startTime + duration`. Breaks whose duration is unknown\n * (null) or breaks which restrict `jump` will become active at\n * `currentTime > startTime`\n *\n * This class contains no HLS- or DASH-specific logic; discovery code maps its\n * protocol's signals to {@link AdBreakInfo} exposed by an\n * {@link AdsProvider.getAds}, which this controller reads once the provider is\n * set via {@link AdController.setAdsProvider} (and re-reads on `adsChange`).\n */\nexport class AdControllerImpl\n extends EventHostImpl<AdEventMap>\n implements AdController\n{\n get [Symbol.toStringTag](): string {\n return 'AdControllerImpl'\n }\n\n private readonly options: AdControllerImplOptions\n private _trackAds: TrackAds | null = null\n private adsProviderSub: Unsubscribe | null = null\n private adsProvider: AdsProvider | null = null\n // The start times of the midroll ads, used for fast midroll break find\n private midrollAds: AdBreakList = []\n // Midroll and postroll breaks, sorted by start time \u2014 the breaks eligible\n // for the ahead-of-time `adPreload` signal (prerolls are preloaded up front).\n private preloadableBreaks: AdBreakList = []\n // Breaks for which `adPreload` has already been emitted on the current\n // approach; cleared on content change and when a break is re-armed by a\n // seek back, so a re-approached break preloads again.\n private readonly preloadedBreakIds = /* @__PURE__ */ new Set<AdBreakKey>()\n\n private lastPlaybackTime = 0\n private pendingAdBreaks: AdBreakInfo[] = []\n // Breaks permanently suppressed for this presentation (play-once breaks and\n // prerolls). Cleared only on a content change (clearCompletedAds).\n private readonly completeAdBreakIds = /* @__PURE__ */ new Set<AdBreakKey>()\n // Replayable (non-play-once) midroll breaks that have played and are \"spent\"\n // until the playhead moves back before their start, at which point they are\n // re-armed and replay on the next forward crossing.\n private readonly spentBreakIds = /* @__PURE__ */ new Set<AdBreakKey>()\n private readonly disposer = /* @__PURE__ */ createDisposer()\n private adBreakState: AdBreakState | null = null\n private loadingNext = false\n\n constructor(\n private readonly deps: AdControllerImplDeps,\n options?: Partial<AdControllerImplOptions>\n ) {\n super()\n this.options = { ...defaultAdControllerImplOptions, ...options }\n const { add } = this.disposer\n const { playbackController } = this.deps\n add(\n playbackController.on('playing', () => {\n if (this.adState) {\n const adState = this.adState\n if (!adState.started) {\n // The ad has started playing, initialize the state.\n adState.started = true\n adState.timeStart = playbackController.currentTime\n adState.playbackRateAvg =\n playbackController.playbackRate\n adState.dataPoints = 1\n }\n this.dispatch('adPlaying', {\n adBreak: adState.parentBreak.adBreak,\n ad: adState.ad,\n index: adState.index,\n totalAds: adState.totalAds,\n })\n }\n })\n )\n add(\n playbackController.on('seeked', (event) => {\n if (this.adState) {\n this.adState.timeStart = playbackController.currentTime\n return\n }\n // A genuine seek back before a break re-arms it: a spent\n // (replayable) break fires again on the next forward crossing,\n // and its preload signal re-arms so it warms again on approach.\n if (event.reason !== 'seeked') return\n const time = playbackController.currentTime\n for (const adBreak of this.preloadableBreaks) {\n if (time < adBreak.startTime) {\n const key = adBreakKey(adBreak)\n this.spentBreakIds.delete(key)\n this.preloadedBreakIds.delete(key)\n }\n }\n })\n )\n add(playbackController.on('timeUpdate', this.onTimeUpdate))\n add(\n playbackController.on('ended', () => {\n if (this.adState) this.endAd(this.adState)\n })\n )\n }\n\n clearCompletedAds(): void {\n this.completeAdBreakIds.clear()\n this.spentBreakIds.clear()\n this.preloadedBreakIds.clear()\n }\n\n private isBreakSuppressed(adBreak: AdBreakInfo): boolean {\n const key = adBreakKey(adBreak)\n return this.completeAdBreakIds.has(key) || this.spentBreakIds.has(key)\n }\n\n /** The media-time the current ad has actually played, or 0 if not playing. */\n private adElapsed(): number {\n const adState = this.adState\n return adState?.started\n ? Math.max(\n 0,\n this.deps.playbackController.currentTime - adState.timeStart\n )\n : 0\n }\n\n /**\n * Computes whether the current ad may be skipped and, when not yet, how many\n * seconds remain until it can. A `skip` restriction blocks it outright;\n * otherwise a resolved skip window gates it by the elapsed break playout, and\n * with no window the ad is freely skippable.\n */\n private async resolveSkipState(\n adBreakState: AdBreakState,\n breakPlayed: number\n ): Promise<{ readonly canSkip: boolean; readonly skipIn: number | null }> {\n const { adBreak } = adBreakState\n if (adBreak.restrict.skip === true) {\n return { canSkip: false, skipIn: null }\n }\n const skipControl = await resolveValueProvider(\n adBreak.skipControl\n ).catch((_v) => null)\n if (!skipControl) {\n return { canSkip: true, skipIn: null }\n }\n if (breakPlayed < skipControl.offset) {\n return { canSkip: false, skipIn: skipControl.offset - breakPlayed }\n }\n const end =\n skipControl.duration != null\n ? skipControl.offset + skipControl.duration\n : Infinity\n return { canSkip: breakPlayed < end, skipIn: null }\n }\n\n get currentTrackAds(): TrackAds | null {\n return this._trackAds\n }\n\n private setTrackAds(value: Maybe<TrackAds>): void {\n const previous = this._trackAds\n const current = value ?? null\n this._trackAds = current\n\n this.midrollAds = (value?.adBreaks ?? []).filter(\n (adBreak) => adBreak.placement === 'midroll'\n )\n // Midroll + postroll breaks are eligible for the ahead-of-time preload\n // signal. adBreaks are already sorted by start time, so this stays sorted.\n this.preloadableBreaks = (value?.adBreaks ?? []).filter(\n (adBreak) => adBreak.placement !== 'preroll'\n )\n\n logDebug(this, 'setTrackAds', value)\n this.dispatch('currentTrackAdsChange', {\n previous,\n current,\n })\n }\n\n /**\n * Returns a function that returns true if the ads provider has changed\n * since the callback was created.\n */\n private providerInterrupted(): () => boolean {\n const provider = this.adsProvider\n return () => provider !== this.adsProvider\n }\n\n setAdsProvider(provider: AdsProvider | null): void {\n if (this.adsProvider === provider) return\n this.pendingAdBreaks = []\n this.completeAdBreak(this.adBreakState, 'contentChange')\n\n this.adsProviderSub?.()\n const { add, dispose } = createDisposer()\n this.adsProviderSub = dispose\n this.adsProvider = provider\n const interrupted = this.providerInterrupted()\n this.clearCompletedAds()\n this.setTrackAds(null)\n\n if (!provider) return\n const refreshAds = () => {\n provider\n .getAds()\n .then((ads) => {\n if (interrupted()) return\n this.setTrackAds(ads)\n })\n .catch((error) => {\n // Ad discovery failed for the provider. There is no active\n // break to surface an adError against, so log it rather\n // than routing through failAd (which would no-op with no\n // active ad and swallow the failure silently).\n if (interrupted()) return\n logError(this, 'ad discovery failed', error)\n })\n }\n add(provider.on('adsChange', refreshAds))\n refreshAds()\n }\n\n async enterPreroll(): Promise<AdBreakInfo | null> {\n return this.enterRoll('preroll')\n }\n\n async enterPostroll(): Promise<AdBreakInfo | null> {\n return this.enterRoll('postroll')\n }\n\n private async enterRoll(\n placement: 'preroll' | 'postroll'\n ): Promise<AdBreakInfo | null> {\n if (!this.adsProvider) return null\n logVerbose(this, `checking for ${placement} ads`)\n this.lastPlaybackTime = this.deps.playbackController.currentTime\n const interrupted = this.providerInterrupted()\n return this.adsProvider\n .getAds()\n .then((ads) => {\n if (interrupted()) {\n logVerbose(\n this,\n `interrupted, no pending breaks set for ${placement}`\n )\n return null\n }\n this.setPendingBreaks(\n ads.adBreaks.filter(\n (adBreak) => adBreak.placement === placement\n )\n )\n return this.currentAdBreak\n })\n .catch(() => {\n return null\n })\n }\n\n // True when we have an ads provider set. Callers gate off this AND their\n // own \"no ad break in progress\" checks (currentAdBreak / pendingAdBreaks),\n // so this is only about \"a provider has committed\", not track activation.\n private get hasProvider(): boolean {\n return this.adsProvider != null\n }\n\n skipAdBreak(): void {\n const adBreakState = this.adBreakState\n if (!adBreakState) {\n logDebug(this, 'skipAdBreak, no-op')\n return\n }\n logDebug(this, 'skipAdBreak, active break id:', adBreakState.adBreak.id)\n this.completeAdBreak(adBreakState, 'skipped')\n this.nextAdOrBreak()\n }\n\n /**\n * Marks an ad break as completed (or 'spent' and replayable), emits an `adBreakCompleted` event.\n */\n private completeAdBreak(\n adBreakState: Maybe<AdBreakState>,\n reason: AdChangeReason\n ): void {\n if (!adBreakState || adBreakState.completedReason) {\n logDebug(this, 'completeAdBreak, no-op')\n return\n }\n const { adBreak } = adBreakState\n adBreakState.completedReason = reason\n const key = adBreakKey(adBreak)\n // A non-once midroll ad may be replayed if the region is re-entered\n // due to a back-seek.\n if (\n adBreak.once ||\n adBreak.placement === 'preroll' ||\n adBreak.placement === 'postroll'\n ) {\n this.completeAdBreakIds.add(key)\n } else {\n // Non-once midroll\n this.spentBreakIds.add(key)\n }\n\n // Interstitials play on a separate track, so the content timeline never\n // advances during the break: content resumes at the cue point plus any\n // explicit offset (default 0). max() keeps a forward seek from being\n // rewound.\n const resumePosition = Math.max(\n this.lastPlaybackTime,\n adBreak.startTime + (adBreak.resumeOffset ?? 0)\n )\n\n this.completeAd(adBreakState.adState, reason) // does nothing if no current ad\n logDebug(\n this,\n `adBreakCompleted, active break id:${adBreak.id} reason:${reason} resumePosition:${resumePosition}`\n )\n if (adBreakState === this.adBreakState) {\n this.adBreakState = null\n }\n this.dispatch('adBreakCompleted', { adBreak, resumePosition, reason })\n }\n\n get currentAdBreak(): AdBreakInfo | null {\n return this.adBreakState?.adBreak ?? null\n }\n\n /**\n * Marks an ad as completed and emits an `adCompleted` event.\n */\n private completeAd(adState: Maybe<AdState>, reason: AdChangeReason) {\n if (!adState || adState.completedReason) return // no-op\n logDebug(\n this,\n `adCompleted id=${adState.ad.id} reason=${reason} index=${adState.index} totalAds=${adState.totalAds}`\n )\n // Fold this ad's actual playout into the break total before clearing it.\n adState.parentBreak.playoutElapsed += this.adElapsed()\n adState.completedReason = reason\n this.dispatch('adCompleted', {\n adBreak: adState.parentBreak.adBreak,\n ad: adState.ad,\n reason,\n index: adState.index,\n totalAds: adState.totalAds,\n })\n if (adState.index >= adState.totalAds - 1) {\n this.completeAdBreak(adState.parentBreak, reason)\n }\n }\n\n /**\n * Polls the next pending ad and activates it.\n * When there are no remaining ads, activates the next ad break (if any).\n */\n private nextAdOrBreak() {\n if (this.disposed || this.loadingNext) return\n const adBreakState = this.adBreakState\n if (!adBreakState && !this.pendingAdBreaks.length) {\n logDebug(this, 'nextAdOrBreak no-op')\n return\n }\n logDebug(this, 'nextAdOrBreak')\n this.loadingNext = true\n\n const nextAd = async (adBreakState: AdBreakState) => {\n logVerbose(this, 'nextAd')\n try {\n const ad = await adBreakState.nextAd()\n // The break may have been completed or swapped out (a content\n // change, skip, or playout-limit) while its ads were resolving;\n // don't start an ad for an abandoned break.\n if (this.disposed || adBreakState.completedReason) return\n if (ad) {\n this.startAd(ad)\n } else {\n // No remaining ads in this break\n logVerbose(this, 'no remaining ads')\n this.completeAdBreak(adBreakState, 'ended')\n await nextBreak()\n }\n } catch (error) {\n if (this.disposed) return\n // The ad list failed to resolve: surface the error, complete\n // this break so content can resume, then advance to any pending\n // break. Re-calling nextAdOrBreak() here would no-op (loadingNext\n // is still held by this in-flight call) AND would leave the break\n // stuck non-null, permanently blocking midroll ingress.\n this.dispatch('adError', {\n adBreak: adBreakState.adBreak,\n currentAd: null,\n error,\n })\n this.completeAdBreak(adBreakState, 'error')\n await nextBreak()\n }\n }\n\n const nextBreak = async () => {\n logVerbose(this, 'nextBreak')\n if (this.pendingAdBreaks.length) {\n // There are pending breaks, take the next one and start its first ad.\n const adBreak = this.pendingAdBreaks.shift()!\n this.adBreakState = createAdBreakState(adBreak)\n logDebug(this, 'adBreakEntered', adBreak)\n this.dispatch('adBreakEntered', { adBreak })\n await nextAd(this.adBreakState)\n } else {\n logDebug(this, 'no remaining breaks')\n }\n }\n\n ;(async () => {\n if (adBreakState) {\n await nextAd(adBreakState)\n } else {\n await nextBreak().catch(noop)\n }\n })()\n .catch(noop)\n .finally(() => {\n this.loadingNext = false\n })\n }\n\n get currentAd(): AdInfo | null {\n return this.adState?.ad ?? null\n }\n\n private get adState(): AdState | null {\n return this.adBreakState?.adState ?? null\n }\n\n private startAd(adState: AdState): void {\n const { ad, index, totalAds } = adState\n logDebug(this, 'adEntered', adState.ad)\n this.dispatch('adEntered', {\n adBreak: adState.parentBreak.adBreak,\n ad,\n index,\n totalAds,\n })\n this.emitTimeUpdate(adState).catch(noop)\n sleep(this.options.adLoadTimeout)\n .then(() => {\n if (this.disposed) return\n if (this.adState === adState && !adState.started) {\n this.failAd(\n new AdError(\n `Ad failed to start after ${this.options.adLoadTimeout} seconds`\n )\n )\n }\n })\n .catch(noop)\n }\n\n /**\n * Checks if the playhead has entered a time to activate a midroll ad.\n */\n private onTimeUpdate = (): void => {\n const adBreak = this.currentAdBreak\n const adState = this.adState\n if (adBreak) {\n // Ad progress events\n if (adState && adState.completedReason == null) {\n this.emitAdProgressEvents(adState).catch(noop)\n this.enforcePlayoutLimits(adState)\n }\n return\n }\n const pC = this.deps.playbackController\n if (this.hasProvider && pC.playing && !this.pendingAdBreaks.length) {\n // Not an ad playing, main content.\n this.lastPlaybackTime = pC.currentTime\n this.checkAdPreload(pC.currentTime)\n this.checkMidrollIngress()\n }\n }\n\n /**\n * Emits `adPreload` once for each midroll/postroll break the playhead is\n * approaching \u2014 within (the break's {@link AdBreakInfo.resolutionTimeOffset}\n * or, when absent, the `preloadAheadTime` option) seconds before its start \u2014\n * so a consumer can resolve and warm the break's assets before entry.\n * Suppressed (played-once/spent) breaks are skipped.\n */\n private checkAdPreload(time: number): void {\n for (const adBreak of this.preloadableBreaks) {\n const key = adBreakKey(adBreak)\n if (this.preloadedBreakIds.has(key)) continue\n if (this.isBreakSuppressed(adBreak)) continue\n const offset =\n adBreak.resolutionTimeOffset ?? this.options.preloadAheadTime\n // Only ahead of the break; at/after its start, ingress takes over.\n if (\n time >= adBreak.startTime - offset &&\n time < adBreak.startTime\n ) {\n this.preloadedBreakIds.add(key)\n logDebug(this, 'adPreload', adBreak.id)\n this.dispatch('adPreload', { adBreak })\n }\n }\n }\n\n /**\n * Main content with ad breaks is playing, check if we have entered a midroll region.\n */\n private checkMidrollIngress(): void {\n const time = this.deps.playbackController.currentTime\n const midrolls = this.midrollAds\n // Upper bound: the first midroll whose startTime is strictly after the\n // playhead. Every candidate break is at an index before it.\n const upper = sortedInsertionIndex(\n midrolls,\n time,\n (time, ad) => time - ad.startTime\n )\n const newPending: AdBreakInfo[] = []\n // Scan every break at or before the playhead, ascending (timeline\n // order), so tied start times and an earlier still-open break that\n // contains the playhead (e.g. after a seek into or over it) are all\n // considered \u2014 not just the single nearest preceding break.\n for (let i = 0; i < upper; i++) {\n const midroll = midrolls[i]\n if (this.isBreakSuppressed(midroll)) continue\n const duration =\n midroll.duration == null || midroll.restrict.jump\n ? Number.MAX_VALUE\n : midroll.duration\n if (time < midroll.startTime + duration) {\n newPending.push(midroll)\n }\n }\n if (newPending.length) {\n logVerbose(this, 'setting midrolls')\n this.setPendingBreaks(newPending)\n }\n }\n\n /**\n * Emits events for `adTimeUpdate`, `adFirstQuartile`, `adMidpoint`, and\n * `adThirdQuartile`.\n * (Does not emit `adCompleted`)\n */\n private async emitAdProgressEvents(adState: AdState): Promise<void> {\n const pC = this.deps.playbackController\n await this.emitTimeUpdate(adState)\n if (isFinite(pC.duration) && pC.duration > 0) {\n // Take a running average of the playback rate. Applications can\n // use this to detect tampering when emitting metrics.\n adState.dataPoints++\n adState.playbackRateAvg = lerp(\n adState.playbackRateAvg,\n pC.playbackRate,\n 1 / adState.dataPoints\n )\n\n // If the ad's duration is set, take the shorter of the ad duration\n const currProgress = pC.currentTimePercent\n const progressStart = adState.timeStart / pC.duration\n if (\n !adState.quartile.first &&\n currProgress > 0.25 &&\n progressStart < AD_START_TOLERANCE\n ) {\n this.dispatch('adFirstQuartile', createAdProgressEvent(adState))\n }\n if (\n !adState.quartile.midpoint &&\n currProgress > 0.5 &&\n progressStart < 0.25 + AD_START_TOLERANCE\n ) {\n this.dispatch('adMidpoint', createAdProgressEvent(adState))\n }\n if (\n !adState.quartile.third &&\n currProgress > 0.75 &&\n progressStart < 0.5 + AD_START_TOLERANCE\n ) {\n this.dispatch('adThirdQuartile', createAdProgressEvent(adState))\n }\n // adEnded is not on progress but on a call to `endAd()`.\n }\n }\n\n private async emitTimeUpdate(adState: AdState): Promise<void> {\n const pC = this.deps.playbackController\n const { ad, parentBreak } = adState\n // Surface elapsed/remaining time for the ad and the break as a\n // whole so applications don't derive it from the media duration.\n const adPlayed = this.adElapsed()\n const adBreak = parentBreak.adBreak\n const naturalAdTotal =\n ad.duration ?? (isFinite(pC.duration) ? pC.duration : null)\n // The break's playout limit is a budget shared across all its ads, so\n // the current ad can run no longer than the budget left after the ads\n // that already played. Cap its reported total by that remainder \u2014\n // matching enforcePlayoutLimits, which cuts the ad (and break) off at\n // exactly this point. Without the cap adTimeRemaining over-reports (the\n // full asset duration) while the ad is actually stopped at the limit.\n const limit = adBreak.playoutLimit\n const adTotal =\n limit != null\n ? Math.min(\n naturalAdTotal ?? Infinity,\n Math.max(0, limit - parentBreak.playoutElapsed)\n )\n : naturalAdTotal\n const breakPlayed = parentBreak.playoutElapsed + adPlayed\n const breakTotal = limit ?? adBreak.duration\n const { canSkip, skipIn } = await this.resolveSkipState(\n parentBreak,\n breakPlayed\n )\n this.dispatch('adTimeUpdate', {\n adBreak: adState.parentBreak.adBreak,\n ad,\n index: adState.index,\n totalAds: adState.totalAds,\n adCurrentTime: adPlayed,\n adTimeRemaining:\n adTotal != null ? Math.max(0, adTotal - adPlayed) : null,\n breakCurrentTime: breakPlayed,\n breakTimeRemaining:\n breakTotal != null\n ? Math.max(0, breakTotal - breakPlayed)\n : null,\n canSkip,\n skipIn,\n })\n }\n\n /**\n * Ads breaks can have a playout limit that may cut off ad playback.\n * End the ad if that limit is reached.\n */\n private enforcePlayoutLimits(adState: AdState): void {\n const pC = this.deps.playbackController\n const { ad, parentBreak } = adState\n // Enforce playout limits independent of a finite content duration so\n // live ads with a declared playout limit are still bounded.\n if (adState.started) {\n const elapsed = Math.max(0, pC.currentTime - adState.timeStart)\n const adBreak = parentBreak.adBreak\n const limit = adBreak.playoutLimit\n if (\n limit != null &&\n parentBreak.playoutElapsed + elapsed >= limit\n ) {\n // The break's total playout limit is reached: end the whole\n // break, dropping any ads that have not started.\n parentBreak.clear()\n this.endAd(adState)\n } else if (ad.duration != null && elapsed >= ad.duration) {\n // This ad reached its declared duration: advance to the next.\n this.endAd(adState)\n }\n }\n }\n\n private setPendingBreaks(newPending: AdBreakList): void {\n this.pendingAdBreaks = newPending.filter(\n (adBreak) => !this.isBreakSuppressed(adBreak)\n )\n const n = this.pendingAdBreaks.length\n logDebug(\n this,\n `setPendingBreaks len=${n}, suppressed=${newPending.length - n}`\n )\n this.nextAdOrBreak()\n }\n\n skipAd(): void {\n this.completeAd(this.adState, 'skipped')\n this.nextAdOrBreak()\n }\n\n failAd(error: Error): void {\n const adState = this.adState\n if (adState) {\n // Capture the failing ad before completeAd() clears it, so the\n // adError event can distinguish an individual-ad failure from an\n // ad-list load failure (currentAd == null).\n this.completeAd(adState, 'error')\n this.dispatch('adError', {\n error,\n adBreak: adState.parentBreak.adBreak,\n currentAd: adState.ad,\n })\n }\n this.nextAdOrBreak()\n }\n\n private endAd(adState: AdState): void {\n this.completeAd(adState, 'ended')\n this.dispatch('adEnded', createAdProgressEvent(adState))\n this.nextAdOrBreak()\n }\n\n get disposed(): boolean {\n return this.disposer.disposed\n }\n\n /**\n * Disposes this controller, removes all listeners.\n */\n dispose(): void {\n super.dispose()\n this.disposer.dispose()\n // Detach any active break so currentAd/currentAdBreak read null after\n // dispose, even if a break's ad list resolves late (startAd is already\n // guarded by the disposed check, so no adEntered/adPlaying fires).\n this.adBreakState = null\n }\n}\n\nfunction createAdProgressEvent(adState: AdState): AdProgressEvent {\n return {\n adBreak: adState.parentBreak.adBreak,\n ad: adState.ad,\n // Snapped to nearest 0.1 to avoid ~1.0\n playbackRateAvg: roundToNearest(adState.playbackRateAvg, 0.1),\n index: adState.index,\n totalAds: adState.totalAds,\n }\n}\n\nfunction createAdBreakState(adBreak: AdBreakInfo): AdBreakState {\n let _currentIndex = -1\n let _adState: AdState | null = null\n const logTarget: LogTarget = {\n logPrefix: createLogPrefix('AdBreakState'),\n }\n\n const adBreakState: AdBreakState = {\n adBreak,\n playoutElapsed: 0,\n completedReason: null,\n get adState(): AdState | null {\n return _adState\n },\n\n async nextAd(): Promise<AdState | null> {\n const ads = await getAds()\n if (_currentIndex >= ads.length) return null\n _adState = getElementOrDefault(ads, ++_currentIndex, null)\n return _adState\n },\n\n clear() {\n _adState = null\n _currentIndex = Number.MAX_VALUE\n },\n }\n\n const getAds = memoize(() => {\n logVerbose(\n logTarget,\n `requesting ads for break ${adBreak.placement} ${adBreak.id}`\n )\n return resolveValueProvider(adBreak.ads).then((ads) => {\n logVerbose(logTarget, 'ads resolved', ads)\n return ads.map((adInfo, index) => {\n return createAdState({\n adBreakState: adBreakState,\n ad: adInfo,\n totalAds: ads.length,\n index: index,\n })\n })\n })\n })\n\n return adBreakState\n}\n\nfunction createAdState({\n adBreakState,\n ad,\n totalAds,\n index,\n}: {\n adBreakState: AdBreakState\n ad: AdInfo\n totalAds: number\n index: number\n}): AdState {\n return {\n parentBreak: adBreakState,\n ad,\n index,\n totalAds,\n started: false,\n timeStart: 0,\n playbackRateAvg: 0,\n dataPoints: 0,\n quartile: {\n first: false,\n midpoint: false,\n third: false,\n },\n completedReason: null,\n }\n}\n\ntype AdBreakKey = string & { readonly __adBreakKey: unique symbol }\n\n/** Combines the placement and id of the break for unique reference by placement */\nfunction adBreakKey(adBreak: AdBreakInfo): AdBreakKey {\n return `${adBreak.placement}_${adBreak.id}` as AdBreakKey\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { ErrorLevel, ErrorOrigin, ReportableError } from '@amazon/vinyl-util'\n\nexport class AdError extends ReportableError {\n get [Symbol.toStringTag](): string {\n return 'AdError'\n }\n\n constructor(\n message: string,\n origin: string = ErrorOrigin.MEDIA,\n level: ErrorLevel = ErrorLevel.FATAL\n ) {\n super(message, origin, level)\n Object.setPrototypeOf(this, AdError.prototype)\n }\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { VinylTrackLoadOptions } from './createVinylTrackFactories'\nimport { memoize, requestWithRetry } from '@amazon/vinyl-util'\n\n/**\n * The built-in track types Vinyl can infer from a URI.\n */\nexport type TrackType = 'hls' | 'dash' | 'src'\n\n/**\n * Infers the track type from a URI based first on its file extension\n * then mime type.\n *\n * Returns null if the type cannot be determined.\n */\nexport async function inferTrackTypeFromUrl(\n url: string\n): Promise<TrackType | null> {\n return inferTrackTypeFromUrlPath(url) ?? (await probeType(url))\n}\n\nexport function inferTrackTypeFromUrlPath(url: string): TrackType | null {\n if (url.endsWith('.m3u8') || url.includes('.m3u8?')) return 'hls'\n if (url.endsWith('.mpd') || url.includes('.mpd?')) return 'dash'\n if (/\\.(mp3|mp4|m4a|m4v|aac|ogg|opus|wav|webm)(\\?|$)/i.test(url))\n return 'src'\n return null\n}\n\nexport async function createTrackLoadOptionsFromUrl(\n url: string\n): Promise<VinylTrackLoadOptions | null> {\n if (!url) return null\n const type = await inferTrackTypeFromUrl(url)\n if (!type) return null\n return { uri: url, type }\n}\n\n/**\n * Performs a HEAD request on the given URL to determine its track type by its\n * content-type response.\n * The result is cached.\n */\nconst probeType = /* @__PURE__ */ memoize(\n async (url: string): Promise<TrackType | null> => {\n try {\n const res = await requestWithRetry(url, { method: 'HEAD' })\n if (!res.ok) return null\n const mime = (res.headers.get('content-type') ?? '').toLowerCase()\n if (mime.includes('dash+xml')) return 'dash'\n if (mime.includes('mpegurl')) return 'hls'\n if (mime.startsWith('video/') || mime.startsWith('audio/'))\n return 'src'\n return null\n } catch {\n return null\n }\n },\n (url) => url,\n /* capacity */ 30\n)\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { AdInfo } from './AdBreakInfo'\nimport { createTrackLoadOptionsFromUrl } from '../track/inferLoadOptionsFromUri'\nimport type { VinylTrackLoadOptions } from '../track/createVinylTrackFactories'\nimport { ErrorOrigin, ReportableError } from '@amazon/vinyl-util'\n\nexport async function defaultAdLoadOptionsResolver(\n adInfo: AdInfo\n): Promise<VinylTrackLoadOptions> {\n if (!adInfo.uri)\n throw new UnresolvableAdError('Ad with no URI cannot be played')\n const loadOptions = await createTrackLoadOptionsFromUrl(adInfo.uri)\n if (!loadOptions)\n throw new UnresolvableAdError(\n `could not infer ad track type from uri ${adInfo.uri}`\n )\n return loadOptions\n}\n\n/**\n * An error indicating that a method was called with illegal arguments.\n */\nexport class UnresolvableAdError extends ReportableError {\n get [Symbol.toStringTag](): string {\n return 'UnresolvableAdError'\n }\n\n constructor(message: string) {\n super(message, ErrorOrigin.MEDIA)\n Object.setPrototypeOf(this, UnresolvableAdError.prototype)\n }\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { HlsDateRange, HlsMediaPlaylist } from '@amazon/vinyl-hls-parser'\nimport { HLS_INTERSTITIAL_CLASS } from '@amazon/vinyl-hls-parser'\nimport {\n type Maybe,\n type MaybePromise,\n memoize,\n requestWithRetry,\n resolveUrl,\n} from '@amazon/vinyl-util'\nimport type {\n AdBreakInfo,\n AdBreakList,\n AdBreakPlacement,\n AdInfo,\n AdList,\n AdRestriction,\n SkipControl,\n} from './AdBreakInfo'\n\n/** The ads and skip window resolved from a break's asset source. */\ninterface AssetContent {\n readonly ads: AdList\n readonly skipControl: SkipControl | null\n}\n\n/**\n * How close to the start or end of content a break must be to be classified as\n * a pre-roll or post-roll rather than a mid-roll, in seconds.\n */\nconst ROLL_EPSILON = 0.5\n\n/**\n * Discovers HLS Interstitial ad breaks from a parsed media playlist and maps\n * them to the provider-agnostic {@link AdBreakInfo} model.\n *\n * HLS Interstitials (Apple's SGAI primitive) are carried as EXT-X-DATERANGE\n * tags with `CLASS=\"com.apple.hls.interstitial\"`. Each such range is anchored\n * to a wall-clock `START-DATE`; this function converts that to a media-timeline\n * start time by correlating it with the playlist's EXT-X-PROGRAM-DATE-TIME\n * anchor. When the playlist carries no program date-time, and the range's\n * start-date is not otherwise resolvable, the break is anchored to the start of\n * the timeline (pre-roll) as a best effort.\n *\n * @param playlist The parsed HLS media playlist.\n * @param baseUrl The URL of the media playlist, used to resolve relative\n * `X-ASSET-URI` values.\n * @param contentDuration The total content duration in seconds, if known, used\n * to classify post-rolls. Pass null/undefined for live or unknown durations.\n */\nexport function discoverHlsInterstitials(\n playlist: HlsMediaPlaylist,\n baseUrl: string,\n contentDuration?: number | null\n): Promise<AdBreakList> {\n const anchor = findProgramDateTimeAnchor(playlist)\n\n const breaks: AdBreakInfo[] = []\n for (const range of playlist.dateRanges) {\n if (range.classId !== HLS_INTERSTITIAL_CLASS) continue\n\n const startTime = resolveStartTime(range, anchor)\n if (startTime == null) continue\n\n const playoutLimit = resolvePlayoutLimit(range)\n let duration = resolveDuration(range)\n if (playoutLimit != null && duration != null)\n duration = Math.min(playoutLimit, duration)\n const cues = parseCues(range)\n const placement = classifyPlacement(startTime, contentDuration, cues)\n const effectiveStartTime = placement === 'preroll' ? 0 : startTime\n\n const restrictStr = range.clientAttributes['X-RESTRICT'] ?? ''\n const restrict = parseRestrict(restrictStr)\n\n // The ads and skip window share one (memoized) asset-list resolution.\n const resolveContent = memoize(() =>\n resolveHlsAssetContent({\n range,\n startTime: effectiveStartTime,\n duration,\n baseUrl,\n })\n )\n\n breaks.push({\n id: range.id,\n startTime: effectiveStartTime,\n duration,\n placement,\n once: cues.has('ONCE'),\n resumeOffset: parseResumeOffset(range),\n resolutionTimeOffset: parseResolutionTimeOffset(range),\n playoutLimit,\n ads: async () => (await resolveContent()).ads,\n skipControl: async () => (await resolveContent()).skipControl,\n restrict,\n })\n }\n\n breaks.sort((a, b) => a.startTime - b.startTime)\n // Discovery is synchronous; ad assets resolve lazily via each break's\n // `ads` ValueProvider. The Promise return keeps the provider-agnostic\n // contract stable for future async discovery (e.g. DASH).\n return Promise.resolve(breaks)\n}\n\n/**\n * The media-timeline anchor derived from the first segment carrying an\n * EXT-X-PROGRAM-DATE-TIME: the wall-clock epoch millis of that segment and the\n * media-timeline start time it corresponds to.\n */\ninterface ProgramDateTimeAnchor {\n readonly epochMs: number\n readonly mediaTime: number\n}\n\nfunction findProgramDateTimeAnchor(\n playlist: HlsMediaPlaylist\n): ProgramDateTimeAnchor | null {\n let mediaTime = 0\n for (const seg of playlist.segments) {\n if (seg.programDateTime) {\n const epochMs = Date.parse(seg.programDateTime)\n if (!Number.isNaN(epochMs)) {\n return { epochMs, mediaTime }\n }\n }\n mediaTime += seg.duration\n }\n return null\n}\n\n/**\n * Converts a range's wall-clock START-DATE to a media-timeline start time.\n * Returns 0 when there is no program-date-time anchor but the start-date is\n * present (best-effort pre-roll), or null when the start-date is unusable.\n */\nfunction resolveStartTime(\n range: HlsDateRange,\n anchor: ProgramDateTimeAnchor | null\n): number | null {\n if (!range.startDate) {\n // END-ON-NEXT ranges may omit START-DATE; without an anchor we cannot\n // place them, so skip.\n return null\n }\n const epochMs = Date.parse(range.startDate)\n if (Number.isNaN(epochMs)) return null\n if (!anchor) {\n // No program-date-time to correlate against. Treat as a pre-roll.\n return 0\n }\n const startTime = anchor.mediaTime + (epochMs - anchor.epochMs) / 1000\n // Clamp tiny negatives from clock rounding to 0.\n return startTime < 0 && startTime > -ROLL_EPSILON ? 0 : startTime\n}\n\n/**\n * Determines a break's duration in seconds. Uses DURATION, else END-DATE span, else\n * PLANNED-DURATION, else null.\n */\nfunction resolveDuration(range: HlsDateRange): number | null {\n if (range.duration != null && !Number.isNaN(range.duration)) {\n return range.duration\n }\n if (range.endDate && range.startDate) {\n const start = Date.parse(range.startDate)\n const end = Date.parse(range.endDate)\n if (!Number.isNaN(start) && !Number.isNaN(end) && end >= start) {\n return (end - start) / 1000\n }\n }\n if (range.plannedDuration != null && !Number.isNaN(range.plannedDuration)) {\n return range.plannedDuration\n }\n return null\n}\n\nfunction resolvePlayoutLimit(range: HlsDateRange): number | null {\n const playoutLimit = parseFloat(\n range.clientAttributes['X-PLAYOUT-LIMIT'] ?? ''\n )\n if (Number.isFinite(playoutLimit) && playoutLimit > 0) {\n return playoutLimit\n }\n return null\n}\n\n/**\n * Tokenizes the DATERANGE `CUE` attribute, an enumerated-string list of trigger\n * identifiers (e.g. `\"PRE,ONCE\"`), into an uppercased, trimmed Set. Unknown\n * tokens are preserved but ignored by callers.\n */\nfunction parseCues(range: HlsDateRange): ReadonlySet<string> {\n return new Set(\n (range.clientAttributes['CUE'] ?? '')\n .split(',')\n .map((token) => token.trim().toUpperCase())\n .filter(Boolean)\n )\n}\n\n/**\n * Parses the signed `X-RESUME-OFFSET` (seconds). Returns null when the attribute\n * is absent (so the controller substitutes the actual playout duration) \u2014 a\n * present value of 0 is distinct from absent and is returned as 0.\n */\nfunction parseResumeOffset(range: HlsDateRange): number | null {\n if (!('X-RESUME-OFFSET' in range.clientAttributes)) return null\n const value = parseFloat(range.clientAttributes['X-RESUME-OFFSET'])\n return Number.isFinite(value) ? value : null\n}\n\n/**\n * Parses the `X-RESOLUTION-TIME-OFFSET` (seconds) \u2014 how far ahead of the break\n * the client should resolve/preload its assets. Returns null when absent or not\n * a finite non-negative number, so the controller falls back to its configured\n * `preloadAheadTime`.\n */\nfunction parseResolutionTimeOffset(range: HlsDateRange): number | null {\n if (!('X-RESOLUTION-TIME-OFFSET' in range.clientAttributes)) return null\n const value = parseFloat(range.clientAttributes['X-RESOLUTION-TIME-OFFSET'])\n return Number.isFinite(value) && value >= 0 ? value : null\n}\n\nfunction classifyPlacement(\n startTime: number,\n contentDuration: Maybe<number>,\n cues: ReadonlySet<string>\n): AdBreakPlacement {\n // PRE/POST trigger identifiers are authoritative over the proximity\n // heuristic (they may fire outside the range's START-DATE/duration). PRE\n // wins the illegal PRE+POST combination.\n if (cues.has('PRE')) return 'preroll'\n if (cues.has('POST')) return 'postroll'\n if (startTime <= ROLL_EPSILON) return 'preroll'\n if (\n contentDuration != null &&\n Number.isFinite(contentDuration) &&\n startTime >= contentDuration - ROLL_EPSILON\n ) {\n return 'postroll'\n }\n return 'midroll'\n}\n\n/**\n * The JSON shape of an HLS interstitial `X-ASSET-LIST` document.\n */\ninterface AssetListDocument {\n readonly ASSETS?: readonly {\n readonly URI: string\n readonly DURATION?: number\n }[]\n readonly ['SKIP-CONTROL']?: {\n readonly OFFSET?: number\n readonly DURATION?: number\n }\n}\n\nfunction resolveHlsAssetContent({\n range,\n startTime,\n duration,\n baseUrl,\n}: {\n readonly range: HlsDateRange\n readonly startTime: number\n readonly duration: number | null\n readonly baseUrl: string\n}): MaybePromise<AssetContent> {\n const assetUri = range.clientAttributes['X-ASSET-URI']\n if (assetUri) {\n // A single inline asset carries no skip window.\n return {\n ads: [\n {\n id: `${range.id}-0`,\n startTime,\n duration,\n uri: resolveUrl(assetUri, baseUrl),\n },\n ],\n skipControl: null,\n }\n }\n const assetListUrl = range.clientAttributes['X-ASSET-LIST']\n if (assetListUrl) {\n return resolveHlsAssetList({\n assetListUrl,\n rangeId: range.id,\n startTime,\n baseUrl,\n })\n }\n return { ads: [], skipControl: null }\n}\n\nasync function resolveHlsAssetList({\n assetListUrl,\n rangeId,\n startTime,\n baseUrl,\n}: {\n readonly assetListUrl: string\n readonly rangeId: string\n readonly startTime: number\n readonly baseUrl: string\n}): Promise<AssetContent> {\n const url = resolveUrl(assetListUrl, baseUrl)\n const response = await requestWithRetry(url)\n const json: AssetListDocument = await response.json()\n const assets = json.ASSETS ?? []\n const ads = assets.map((asset, i): AdInfo => {\n return {\n id: `${rangeId}-${i}`,\n startTime,\n duration: asset.DURATION ?? null,\n uri: resolveUrl(asset.URI, baseUrl),\n }\n })\n return { ads, skipControl: parseSkipControl(json['SKIP-CONTROL']) }\n}\n\n/**\n * Maps an X-ASSET-LIST `SKIP-CONTROL` object to a {@link SkipControl}, or null\n * when absent or missing a usable offset.\n */\nfunction parseSkipControl(\n control: AssetListDocument['SKIP-CONTROL']\n): SkipControl | null {\n if (!control) return null\n const offset = Number(control.OFFSET)\n if (!Number.isFinite(offset) || offset < 0) return null\n return { offset, duration: control.DURATION ?? null }\n}\n\nfunction parseRestrict(str: string): AdRestriction {\n const skip = str.includes('SKIP')\n const jump = str.includes('JUMP')\n return { skip, jump }\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { DrmKeySystem } from '../drm/DrmKeySystem'\nimport type { DrmKeySystemSupport } from '../drm/DrmController'\n\nexport enum CanPlayTypeResult {\n /**\n * The media cannot be played on the current device.\n */\n NO = 'no',\n\n /**\n * There is not enough information to determine whether the media can play.\n */\n MAYBE = 'maybe',\n\n /**\n * The media is probably playable on this device.\n */\n PROBABLY = 'probably',\n}\n\n/**\n * Detected capabilities of the device.\n */\nexport interface Capabilities {\n /**\n * Returns true if Media Source Extensions are supported.\n *\n * Note that this does not test DRM or any DRM key systems.\n */\n readonly mse: boolean\n\n /**\n * Returns true if Encrypted Media Extensions are supported.\n */\n readonly eme: boolean\n\n /**\n * Returns true if native Dynamic Adaptive Streaming is supported.\n *\n * (Legacy Edge 12-18 and XBox One)\n * Note that this is not the same as supporting a dash track.\n */\n readonly dash: boolean\n\n /**\n * Returns true if native HTTP Live Streaming is supported.\n *\n * iOS 7.0+, Safari 8.0+\n * Note that this does not do FairPlay detection.\n */\n readonly hls: boolean\n\n /**\n * Returns the sample rate, in samples per second, that this platform supports.\n * Returns null if the sample rate cannot be determined.\n */\n readonly sampleRate: number | null\n\n /**\n * Returns a string that specifies whether the client can play a given media resource type for progressive\n * content.\n *\n * @param type A string specifying the MIME type of the media and (optionally) a codecs\n * parameter containing a comma-separated list of the supported codecs.\n */\n canPlayType(type: string): CanPlayTypeResult\n\n /**\n * Returns a boolean that specifies whether the client can play a given media resource type for streaming\n * content with media source extensions.\n *\n * @param type A string specifying the MIME type of the media and (optionally) a codecs\n * parameter containing a comma-separated list of the supported codecs.\n */\n canPlayTypeMse(type: string): boolean\n\n /**\n * Returns a promise describing support for the given key system.\n *\n * @param keySystem\n */\n supportsKeySystem(keySystem: DrmKeySystem): Promise<DrmKeySystemSupport>\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { MediaUnsupportedError } from '@amazon/vinyl-util'\nimport type { Unsubscribe } from '@amazon/vinyl-util'\nimport type { SignalOptions } from '@amazon/vinyl-util'\nimport { withTimeout } from '@amazon/vinyl-util'\n\ndeclare global {\n var ManagedMediaSource: typeof MediaSource | undefined\n}\n\n/**\n * Returns true if the UA supports media source extensions.\n */\nexport function supportsMse(): boolean {\n return (\n typeof ManagedMediaSource === 'function' ||\n typeof MediaSource === 'function'\n )\n}\n\n/**\n * Returns ManagedMediaSource or MediaSource.\n */\nfunction getMediaSourceCtor(): typeof MediaSource {\n if (typeof ManagedMediaSource === 'function') return ManagedMediaSource\n else return MediaSource\n}\n\n/**\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaSource/isTypeSupported_static)\n *\n * Delegates to the browser's native support check. False-positive codecs\n * (where the browser reports support but decode fails at runtime) are handled\n * by the decode-failure recovery path rather than a static denylist, so this\n * function reflects the browser's own answer.\n */\nexport function isTypeSupported(type: string): boolean {\n assertMseSupported()\n return getMediaSourceCtor().isTypeSupported(type)\n}\n\n/**\n * Constructs a new ManagedMediaSource or MediaSource.\n */\nexport function createMediaSource(): MediaSource {\n assertMseSupported()\n return new (getMediaSourceCtor())()\n}\n\n/**\n * Throws a MediaUnsupportedError if MSE is not supported.\n */\nexport function assertMseSupported(): void {\n if (!supportsMse())\n throw new MediaUnsupportedError(\n 'Media Source Extensions not supported',\n 'mse-unsupported'\n )\n}\n\n/**\n * Invokes a callback when the media source is open.\n * The callback will be invoked immediately if already open.\n */\nexport function onMediaSourceOpen(\n mediaSource: MediaSource,\n callback: () => void,\n options?: SignalOptions\n): Unsubscribe {\n const open = mediaSource.readyState === 'open'\n if (open) callback()\n const handler = () => callback()\n if (!options?.once || !open) {\n // compatibility note: MediaSource.addEventListener is more widely supported than onsourceopen\n // https://caniuse.com/mdn-api_mediasource_sourceopen_event\n mediaSource.addEventListener('sourceopen', handler, options)\n return () => mediaSource.removeEventListener('sourceopen', handler)\n } else {\n return () => {}\n }\n}\n\n/**\n * Invokes a callback when the media source is next ended.\n * The callback will be invoked immediately if already ended.\n */\nexport function onMediaSourceEnded(\n mediaSource: MediaSource,\n callback: () => void,\n options?: SignalOptions\n): Unsubscribe {\n const ended = mediaSource.readyState === 'ended'\n if (ended) callback()\n const handler = () => callback()\n if (!options?.once || !ended) {\n mediaSource.addEventListener('sourceended', handler, options)\n return () => mediaSource.removeEventListener('sourceended', handler)\n } else {\n return () => {}\n }\n}\n\n/**\n * Returns a Promise that resolves when the media source is next in an 'ended' state.\n *\n * @param mediaSource\n * @param timeout The number of seconds before rejecting with a TimeoutError.\n * @param timeoutMessage\n */\nexport function nextMediaSourceEnded(\n mediaSource: MediaSource,\n timeout: number = 5,\n timeoutMessage?: string\n): Promise<void> {\n return withTimeout(\n new Promise((resolve) => {\n onMediaSourceEnded(mediaSource, resolve, { once: true })\n }),\n timeout,\n { message: timeoutMessage }\n )\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { globalRef, lazy } from '@amazon/vinyl-util'\n\ntype MaybeAudioContext = typeof AudioContext | undefined\n\ndeclare global {\n var webkitAudioContext: MaybeAudioContext\n}\n\n/**\n * Creates a new AudioContext.\n * Returns null if not supported on this platform.\n */\nexport function createAudioContext(): AudioContext | null {\n const ctor =\n (global.AudioContext as MaybeAudioContext) ?? global.webkitAudioContext\n return ctor ? new ctor() : null\n}\n\n/**\n * Some devices have a hard limit to how many audio context objects can be created.\n * Uses a lazy instance to ensure only one context is created, even within integ tests.\n */\nconst audioContextSingleton = /* @__PURE__ */ lazy(createAudioContext)\n\n/**\n * The audio context global reference.\n */\nexport const audioContextRef = /* @__PURE__ */ globalRef<AudioContext | null>(\n () => audioContextSingleton.value\n)\n\n/**\n * Returns an AudioContext singleton, or returns null if not supported on this platform.\n *\n * If the first time this is called is outside a user gesture, the AudioContext will be unable to start in a\n * running state.\n */\nexport function getAudioContext(): AudioContext | null {\n return audioContextRef.value\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { type DrmKeySystem } from '../drm/DrmKeySystem'\nimport type { Capabilities } from './Capabilities'\nimport { CanPlayTypeResult } from './Capabilities'\nimport { isTypeSupported, supportsMse } from '../util/media/mediaSource'\nimport { getAudioContext } from '../util/media/getAudioContext'\nimport type { DrmController, DrmKeySystemSupport } from '../drm/DrmController'\n\n/**\n * Dependencies for CapabilitiesImpl.\n */\nexport interface CapabilitiesImplDeps {\n readonly media: HTMLMediaElement\n readonly drmController: DrmController\n}\n\n/**\n * Client support detection.\n */\nexport class CapabilitiesImpl implements Capabilities {\n constructor(private readonly deps: CapabilitiesImplDeps) {}\n\n get mse(): boolean {\n return supportsMse()\n }\n\n get dash(): boolean {\n return this.canPlayType('application/dash+xml') !== CanPlayTypeResult.NO\n }\n\n get hls(): boolean {\n return (\n this.canPlayType('application/vnd.apple.mpegurl') !==\n CanPlayTypeResult.NO\n )\n }\n\n get eme(): boolean {\n return this.deps.drmController.isEmeSupported()\n }\n\n get sampleRate(): number | null {\n return getAudioContext()?.sampleRate ?? null\n }\n\n canPlayType(type: string): CanPlayTypeResult {\n const media: HTMLMediaElement = this.deps.media\n if (typeof media.canPlayType === 'undefined')\n return CanPlayTypeResult.NO\n const str = media.canPlayType(type)\n switch (str) {\n case '':\n return CanPlayTypeResult.NO\n case 'maybe':\n return CanPlayTypeResult.MAYBE\n case 'probably':\n return CanPlayTypeResult.PROBABLY\n }\n }\n\n canPlayTypeMse(type: string): boolean {\n return isTypeSupported(type)\n }\n\n async supportsKeySystem(\n keySystem: DrmKeySystem\n ): Promise<DrmKeySystemSupport> {\n // Take the most commonly supported codec and media format, check the DrmController if\n // it is supported with the given key system.\n return this.deps.drmController.isSupported({\n initDataType: 'cenc',\n encryptionScheme: 'cenc',\n contentType: 'audio',\n mimeType: 'audio/mp4; codecs=\"mp4a.40.2\"',\n contentProtections: [{ keySystem }],\n })\n }\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {\n type Maybe,\n parseIntSafe,\n type ReadonlyRecord,\n} from '@amazon/vinyl-util'\n\n/**\n * https://www.w3.org/TR/encrypted-media-2/#dom-mediakeysystemmediacapability-encryptionscheme\n */\nexport type CencEncryptionScheme =\n /**\n * AES-CTR mode full sample and video NAL subsample encryption.\n */\n | 'cenc'\n\n /**\n * AES-CBC mode partial video NAL pattern encryption. For video, the spec allows various encryption patterns.\n */\n | 'cbcs'\n\n /**\n * The same as \"cbcs\" mode, but with a specific encrypt:skip pattern of 1:9 for video.\n */\n | 'cbcs-1-9'\n | string\n\nexport interface CencEncryptionSchemeAndVersion {\n readonly scheme: CencEncryptionScheme\n readonly version: number | null\n}\n\nconst encryptionSchemeRegex = /([a-z]{4})(?::([\\da-f]{1,8}))?/\n\nconst protectionSchemeCodes: ReadonlyRecord<\n string,\n CencEncryptionScheme | undefined\n> = {\n ['cbcs']: 'cbcs',\n ['cenc']: 'cenc',\n}\n\n/**\n * 5.8.5.2.2 The MP4 Protection Scheme\n *\n * For Representations based on ISO/IEC 14496-12, the following URI is defined to indicate protection\n * schemes identified by the Scheme Type within the Scheme Type Box of the Protection Scheme\n * Information Box of the file:\n * urn:mpeg:dash:mp4protection:2011\n * In this scheme, the `value` attribute shall present and shall be the 4CC contained in the Scheme Type\n * Box, suitably percent-encoded according to IETF RFC 8141, and may include the version number. The\n * 4CC and the version number, if present, shall be separated by a \":\". The version number shall be encoded\n * as up to 8 hexadecimal digits, where the leading '0's may be omitted.\n *\n * @param value\n */\nexport function parseCencEncryptionScheme(\n value: Maybe<string>\n): CencEncryptionSchemeAndVersion | null {\n if (!value) return null\n const match = encryptionSchemeRegex.exec(value)\n if (!match) return null\n const version = parseIntSafe(match[2], 16)\n const scheme = protectionSchemeCodes[match[1]]\n if (!scheme) return null\n return {\n scheme,\n version,\n }\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * An common interface to unify multiple EME implementations.\n * @module\n */\n\nimport type { DrmKeySystem } from '../DrmKeySystem'\nimport type { Json, ReadonlyEventHost, Unsubscribe } from '@amazon/vinyl-util'\nimport { ErrorLevel, ErrorOrigin, ReportableError } from '@amazon/vinyl-util'\nimport type { EncryptedInitData } from './EncryptedInitData'\nimport type { DrmInitDataType } from '../../streaming/DrmInitDataType'\nimport type { BasicErrorEvent } from '../../event/BasicErrorEvent'\n\n/**\n * Top-level Common EME methods for initiating encrypted audio session.\n *\n * Created to unify standard and non-standard EME interfaces.\n */\nexport interface CommonEme {\n requestMediaKeySystemAccess(\n keySystem: DrmKeySystem,\n supportedConfigurations: readonly MediaKeySystemConfiguration[]\n ): Promise<CommonMediaKeySystemAccess>\n\n addEncryptedListener(\n element: HTMLMediaElement,\n handler: (event: CommonMediaEncryptedEvent) => void\n ): Unsubscribe\n}\n\nexport interface CommonMediaEncryptedEvent {\n /**\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaEncryptedEvent/initData)\n */\n readonly initData: EncryptedInitData | null\n\n /**\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaEncryptedEvent/initDataType)\n */\n readonly initDataType: string\n}\n\n/**\n * This provides a common interface for MediaKeySystemAccess EME implementations.\n */\nexport interface CommonMediaKeySystemAccess {\n readonly keySystem: DrmKeySystem\n createMediaKeys(): Promise<CommonMediaKeys>\n}\n\n/**\n * This provides a common interface for MediaKeys EME implementations.\n */\nexport interface CommonMediaKeys {\n readonly keySystem: DrmKeySystem\n\n /**\n * Sets the media keys on the given element.\n * @param element\n */\n setOnElement(element: HTMLMediaElement): Promise<void>\n\n /**\n * Clears the media keys from the given element.\n * This is only allowed if the element's src isn't set.\n * https://bugs.chromium.org/p/chromium/issues/detail?id=462365#c7\n * @param element\n */\n clearFromElement(element: HTMLMediaElement): Promise<void>\n\n /**\n * Sets the server certificate on the media keys.\n *\n * A Promise that resolves to a boolean. If the Key System implementation\n * represented by this object's content decryption module's implementation\n * value does not support server certificates, return a promise resolved\n * with false.\n *\n * @param certificate The server certificate data.\n */\n setServerCertificate(certificate: BufferSource): Promise<boolean>\n\n /**\n * Creates the key session.\n *\n * @param mimeType\n * @param initDataType\n * @param initData The initialization data from the 'encrypted' event.\n */\n createSession(\n mimeType: string,\n initDataType: DrmInitDataType,\n initData: EncryptedInitData\n ): CommonMediaKeySession\n}\n\n/**\n * Common media key session events\n */\nexport interface CommonMediaKeySessionEventMap {\n /**\n * Dispatched when a message is generated by the content decryption module.\n */\n readonly message: CommonMediaKeyMessageEvent\n\n /**\n * Dispatched when an error occurs.\n */\n readonly error: BasicErrorEvent\n\n /**\n * Dispatched when the session is forcibly closed by the CDM.\n */\n readonly closed: CommonMediaKeySessionClosedEvent\n}\n\n/**\n * This provides a common interface for MediaKeySession EME implementations.\n */\nexport interface CommonMediaKeySession extends ReadonlyEventHost<CommonMediaKeySessionEventMap> {\n readonly mimeType: string\n readonly initDataType: DrmInitDataType\n readonly initData: EncryptedInitData\n\n /**\n * Updates the session with the license data.\n * @param key\n */\n update(key: ArrayBuffer): Promise<void>\n\n /**\n * Returns true if the session has been disposed.\n */\n get disposed(): boolean\n\n /**\n * Closes the session, and removes session handling and event listeners, freeing this session\n * handler for GC.\n *\n * Note: The audio source should be cleared first.\n */\n dispose(): void\n}\n\n/**\n * A media key session error, translated from the specific media key session implementation.\n */\nexport class CommonMediaKeySessionError extends ReportableError {\n get [Symbol.toStringTag](): string {\n return 'CommonMediaKeySessionError'\n }\n\n constructor(\n readonly code: number,\n readonly codeStr: MediaKeySessionErrorType,\n readonly systemCode: number,\n readonly systemCodeStr: MediaKeySessionErrorType\n ) {\n super(codeStr, ErrorOrigin.DRM, ErrorLevel.WARN)\n Object.setPrototypeOf(this, CommonMediaKeySessionError.prototype)\n }\n\n toJSON(): Json {\n return {\n ...super.toJSON(),\n code: this.code,\n codeStr: this.codeStr,\n systemCode: this.systemCode,\n systemCodeStr: this.systemCodeStr,\n }\n }\n}\n\n/**\n * Common media key message event body.\n */\nexport interface CommonMediaKeyMessageEvent {\n readonly message: ArrayBuffer\n}\n\nexport interface CommonMediaKeySessionClosedEvent {\n /**\n * The reason the session was closed.\n */\n readonly reason: MediaKeySessionClosedReason\n}\n\n/**\n * String representations of session error codes.\n */\nexport enum MediaKeySessionErrorType {\n CLIENT = 'CLIENT',\n DOMAIN = 'DOMAIN',\n HARDWARECHANGE = 'HARDWARECHANGE',\n OUTPUT = 'OUTPUT',\n SERVICE = 'SERVICE',\n UNKNOWN = 'UNKNOWN',\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {\n bufferToByteArray,\n type Disposable,\n DisposedError,\n ErrorOrigin,\n EventHostImpl,\n type Unsubscribe,\n} from '@amazon/vinyl-util'\nimport {\n type CommonEme,\n type CommonMediaKeys,\n type CommonMediaKeySession,\n CommonMediaKeySessionError,\n type CommonMediaKeySessionEventMap,\n type CommonMediaKeySystemAccess,\n MediaKeySessionErrorType,\n} from './CommonEme'\nimport type { DrmKeySystem } from '../DrmKeySystem'\nimport { type EncryptedInitData } from './EncryptedInitData'\nimport type { MSMediaKeyMessageEvent } from '../dom/MSMediaKeys'\nimport { DrmError } from '../error/DrmError'\nimport type { DrmInitDataType } from '../../streaming/DrmInitDataType'\n\ndeclare global {\n interface HTMLMediaElementEventMap extends HTMLElementEventMap {\n readonly msneedkey: MSMediaKeyNeededEvent\n }\n\n interface MSMediaKeyNeededEvent extends Event {\n readonly initDataType: string\n readonly initData: Uint8Array<ArrayBuffer> | null\n }\n}\n\n/**\n * A CommonEme implementation of MS prefixed Encrypted Media Extensions as supported by IE11/Edge.\n */\nexport class MsCommonEme implements CommonEme {\n requestMediaKeySystemAccess(\n keySystem: DrmKeySystem,\n supportedConfigurations: readonly MediaKeySystemConfiguration[]\n ): Promise<CommonMediaKeySystemAccess> {\n for (const config of supportedConfigurations) {\n const capabilities = [\n ...(config.audioCapabilities ?? []),\n ...(config.videoCapabilities ?? []),\n ]\n for (const capability of capabilities) {\n if (\n MSMediaKeys.isTypeSupported(\n keySystem,\n capability.contentType\n )\n ) {\n return Promise.resolve(\n new MsCommonMediaKeySystemAccess(keySystem)\n )\n }\n }\n }\n return Promise.reject(\n new DrmError(\n `keySystem not supported: ${keySystem}`,\n { keySystem },\n ErrorOrigin.DRM\n )\n )\n }\n\n /**\n * Listens to the element for an encrypted event, returning a disposable handle.\n */\n addEncryptedListener(\n element: HTMLMediaElement,\n handler: (event: MediaEncryptedEvent) => void\n ): Unsubscribe {\n const event = 'msneedkey'\n element.addEventListener(event, handler as EventListener)\n return () =>\n element.removeEventListener(event, handler as EventListener)\n }\n}\n\nexport class MsCommonMediaKeySystemAccess implements CommonMediaKeySystemAccess {\n constructor(readonly keySystem: DrmKeySystem) {}\n\n createMediaKeys(): Promise<CommonMediaKeys> {\n const msMediaKeys = new MSMediaKeys(this.keySystem)\n return Promise.resolve(\n new MsCommonMediaKeys(this.keySystem, msMediaKeys)\n )\n }\n}\n\n/**\n * @private\n */\nexport class MsCommonMediaKeys implements CommonMediaKeys {\n constructor(\n public readonly keySystem: DrmKeySystem,\n public readonly mediaKeys: MSMediaKeys\n ) {}\n\n /**\n * Sets the media keys on the given element.\n */\n setOnElement(element: HTMLMediaElement): Promise<void> {\n element.msSetMediaKeys!(this.mediaKeys)\n return Promise.resolve()\n }\n\n /**\n * Clears the media keys from the given element.\n */\n clearFromElement(element: HTMLMediaElement): Promise<void> {\n element.msSetMediaKeys!(null)\n return Promise.resolve()\n }\n\n setServerCertificate(_certificate: BufferSource): Promise<boolean> {\n return Promise.resolve(false)\n }\n\n createSession(\n mimeType: string,\n initDataType: DrmInitDataType,\n initData: EncryptedInitData\n ): CommonMediaKeySession {\n const session = this.mediaKeys.createSession(\n mimeType,\n bufferToByteArray(initData)\n )\n return new MsCommonMediaKeySession(\n session,\n mimeType,\n initDataType,\n initData\n )\n }\n}\n\n/**\n * @private\n */\nexport class MsCommonMediaKeySession\n extends EventHostImpl<CommonMediaKeySessionEventMap>\n implements CommonMediaKeySession, Disposable\n{\n private _disposed: boolean = false\n\n constructor(\n private readonly session: MSMediaKeySession,\n readonly mimeType: string,\n readonly initDataType: DrmInitDataType,\n readonly initData: EncryptedInitData\n ) {\n super()\n session.addEventListener('mskeymessage', this.messageHandler)\n session.addEventListener('mskeyerror', this.errorHandler)\n }\n\n private readonly messageHandler = (event: MSMediaKeyMessageEvent) => {\n this.dispatch('message', {\n message: event.message.buffer as ArrayBuffer,\n })\n }\n\n private readonly errorHandler = (): void => {\n if (this.session.error) {\n const e = this.session.error\n const error = new CommonMediaKeySessionError(\n e.code,\n msErrorCodeToStr(e.code),\n e.systemCode,\n msErrorCodeToStr(e.systemCode)\n )\n this.dispatch('error', { error, target: this })\n }\n }\n\n update(key: ArrayBuffer): Promise<void> {\n if (this.disposed) return Promise.reject(new DisposedError())\n this.session.update(new Uint8Array(key))\n return Promise.resolve()\n }\n\n get disposed(): boolean {\n return this._disposed\n }\n\n dispose(): void {\n super.dispose()\n this._disposed = true\n this.session.close()\n this.session.removeEventListener('mskeymessage', this.messageHandler)\n this.session.removeEventListener('mskeyerror', this.errorHandler)\n }\n}\n\n/**\n * Returns a string for the WebKit media key error.\n */\nexport function msErrorCodeToStr(code: number): MediaKeySessionErrorType {\n switch (code) {\n case MSMediaKeyError.MS_MEDIA_KEYERR_CLIENT:\n return MediaKeySessionErrorType.CLIENT\n case MSMediaKeyError.MS_MEDIA_KEYERR_DOMAIN:\n return MediaKeySessionErrorType.DOMAIN\n case MSMediaKeyError.MS_MEDIA_KEYERR_HARDWARECHANGE:\n return MediaKeySessionErrorType.HARDWARECHANGE\n case MSMediaKeyError.MS_MEDIA_KEYERR_OUTPUT:\n return MediaKeySessionErrorType.OUTPUT\n case MSMediaKeyError.MS_MEDIA_KEYERR_SERVICE:\n return MediaKeySessionErrorType.SERVICE\n case MSMediaKeyError.MS_MEDIA_KEYERR_UNKNOWN:\n default:\n return MediaKeySessionErrorType.UNKNOWN\n }\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { ErrorOrigin, type Json } from '@amazon/vinyl-util'\nimport { ErrorLevel, ReportableError } from '@amazon/vinyl-util'\n\n/**\n * An error originating from the DrmController.\n * If an error comes from a key session, `extra.error` will be set with the original error and origin will be DRM.\n */\nexport class DrmError<ExtraType = any> extends ReportableError {\n get [Symbol.toStringTag](): string {\n return 'DrmError'\n }\n\n constructor(\n readonly message: string,\n private readonly extra: ExtraType | null = null,\n readonly origin: string = ErrorOrigin.DRM,\n readonly level: ErrorLevel = ErrorLevel.FATAL\n ) {\n super(message, origin, level)\n Object.setPrototypeOf(this, DrmError.prototype)\n }\n\n toJSON(): Json {\n return { ...super.toJSON(), extra: this.extra }\n }\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {\n type Disposable,\n DisposedError,\n EventHostImpl,\n noop,\n type Unsubscribe,\n} from '@amazon/vinyl-util'\nimport type {\n CommonEme,\n CommonMediaEncryptedEvent,\n CommonMediaKeyMessageEvent,\n CommonMediaKeys,\n CommonMediaKeySession,\n CommonMediaKeySessionEventMap,\n CommonMediaKeySystemAccess,\n} from './CommonEme'\nimport type { DrmKeySystem } from '../DrmKeySystem'\nimport { type EncryptedInitData } from './EncryptedInitData'\nimport { createDrmErrorHandler } from './createDrmErrorHandler'\nimport type { DrmInitDataType } from '../../streaming/DrmInitDataType'\n\n/**\n * A CommonEme implementation of unprefixed Encrypted Media Extensions.\n */\nexport class StandardCommonEme implements CommonEme {\n async requestMediaKeySystemAccess(\n keySystem: DrmKeySystem,\n supportedConfigurations: readonly MediaKeySystemConfiguration[]\n ): Promise<CommonMediaKeySystemAccess> {\n const access = await navigator\n .requestMediaKeySystemAccess(keySystem, supportedConfigurations)\n .catch(createDrmErrorHandler())\n return new StandardCommonMediaKeySystemAccess(keySystem, access)\n }\n\n addEncryptedListener(\n element: HTMLMediaElement,\n handler: (event: CommonMediaEncryptedEvent) => void\n ): Unsubscribe {\n element.addEventListener('encrypted', handler)\n return () => element.removeEventListener('encrypted', handler)\n }\n}\n\n/**\n * CommonMediaKeySystemAccess for unprefixed EME implementations.\n */\nexport class StandardCommonMediaKeySystemAccess implements CommonMediaKeySystemAccess {\n constructor(\n public readonly keySystem: DrmKeySystem,\n private readonly access: MediaKeySystemAccess\n ) {}\n\n /**\n * @return {Promise<CommonMediaKeys>}\n */\n async createMediaKeys(): Promise<CommonMediaKeys> {\n const mediaKeys = await this.access\n .createMediaKeys()\n .catch(createDrmErrorHandler())\n return new StandardCommonMediaKeys(this.keySystem, mediaKeys)\n }\n}\n\n/**\n * CommonMediaKeys for unprefixed EME implementations.\n */\nexport class StandardCommonMediaKeys implements CommonMediaKeys {\n constructor(\n public readonly keySystem: DrmKeySystem,\n private readonly mediaKeys: MediaKeys\n ) {}\n\n setOnElement(element: HTMLMediaElement): Promise<void> {\n return element.setMediaKeys(this.mediaKeys)\n }\n\n clearFromElement(element: HTMLMediaElement): Promise<void> {\n return element.setMediaKeys(null)\n }\n\n async setServerCertificate(certificate: BufferSource): Promise<boolean> {\n return this.mediaKeys.setServerCertificate(certificate)\n }\n\n createSession(\n mimeType: string,\n initDataType: DrmInitDataType,\n initData: EncryptedInitData\n ): CommonMediaKeySession {\n return new StandardCommonMediaKeySession(\n this.mediaKeys.createSession('temporary'),\n mimeType,\n initDataType,\n initData\n )\n }\n}\n\n/**\n * CommonMediaKeySession for unprefixed EME implementations.\n */\nexport class StandardCommonMediaKeySession\n extends EventHostImpl<CommonMediaKeySessionEventMap>\n implements CommonMediaKeySession, Disposable\n{\n get [Symbol.toStringTag](): string {\n return 'StandardCommonMediaKeySession'\n }\n\n private _disposed = false\n\n private readonly messageHandler = (event: CommonMediaKeyMessageEvent) => {\n this.dispatch('message', {\n message: event.message,\n })\n }\n\n constructor(\n private readonly session: MediaKeySession,\n readonly mimeType: string,\n readonly initDataType: DrmInitDataType,\n readonly initData: EncryptedInitData\n ) {\n super()\n session.addEventListener('message', this.messageHandler)\n if ((session as any).closed) {\n // Compatibility: React Native MSE does not provide a 'closed' promise.\n session.closed\n .then((reason) => {\n this.dispatch('closed', {\n reason,\n })\n })\n .catch(noop)\n }\n this.generateRequest().catch((error) => {\n this.dispatch('error', {\n error,\n target: this,\n })\n })\n }\n\n private generateRequest(): Promise<void> {\n const initData = this.initData\n return this.session\n .generateRequest(\n this.initDataType,\n initData instanceof ArrayBuffer ? initData : initData.buffer\n )\n .catch(createDrmErrorHandler())\n }\n\n update(key: ArrayBufferLike): Promise<void> {\n if (this.disposed) throw new DisposedError()\n return this.session.update(key as ArrayBuffer)\n }\n\n get disposed(): boolean {\n return this._disposed\n }\n\n dispose(): void {\n super.dispose()\n this._disposed = true\n this.session.removeEventListener('message', this.messageHandler)\n this.session.close().catch(noop)\n }\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { DrmError } from '../error/DrmError'\nimport { ErrorLevel, ErrorOrigin, toJson } from '@amazon/vinyl-util'\n\nexport function createDrmErrorHandler(\n level: ErrorLevel = ErrorLevel.FATAL\n): (error: Error) => never {\n return (error) => {\n throw new DrmError(\n error.message,\n { error: toJson(error) },\n ErrorOrigin.DRM,\n level\n )\n }\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { Unsubscribe } from '@amazon/vinyl-util'\nimport {\n bufferToByteArray,\n type Disposable,\n DisposedError,\n ErrorOrigin,\n EventHostImpl,\n} from '@amazon/vinyl-util'\nimport type {\n CommonEme,\n CommonMediaEncryptedEvent,\n CommonMediaKeys,\n CommonMediaKeySession,\n CommonMediaKeySessionEventMap,\n CommonMediaKeySystemAccess,\n} from './CommonEme'\nimport {\n CommonMediaKeySessionError,\n MediaKeySessionErrorType,\n} from './CommonEme'\nimport type { WebKitMediaKeyMessageEvent } from '../dom/WebKitMediaKeys'\nimport type { DrmKeySystem } from '../DrmKeySystem'\nimport { DrmError } from '../error/DrmError'\nimport type { EncryptedInitData } from './EncryptedInitData'\nimport type { DrmInitDataType } from '../../streaming/DrmInitDataType'\n\ndeclare global {\n interface HTMLMediaElementEventMap extends HTMLElementEventMap {\n readonly webkitneedkey: WebKitMediaKeyNeededEvent\n }\n\n interface WebKitMediaKeyNeededEvent extends Event {\n readonly initDataType: string\n readonly initData: Uint8Array<ArrayBuffer> | null\n }\n}\n\n/**\n * A CommonEme implementation of WebKit-prefixed Encrypted Media Extensions.\n */\nexport class WebKitCommonEme implements CommonEme {\n requestMediaKeySystemAccess(\n keySystem: DrmKeySystem,\n supportedConfigurations: readonly MediaKeySystemConfiguration[]\n ): Promise<CommonMediaKeySystemAccess> {\n for (const config of supportedConfigurations) {\n const capabilities = [\n ...(config.audioCapabilities ?? []),\n ...(config.videoCapabilities ?? []),\n ]\n for (const capability of capabilities) {\n if (\n WebKitMediaKeys.isTypeSupported(\n keySystem,\n capability.contentType\n )\n ) {\n return Promise.resolve(\n new WebKitCommonMediaKeySystemAccess(keySystem)\n )\n }\n }\n }\n return Promise.reject(\n new DrmError(\n `keySystem not supported: ${keySystem}`,\n { keySystem },\n ErrorOrigin.DRM\n )\n )\n }\n\n addEncryptedListener(\n element: HTMLMediaElement,\n handler: (event: CommonMediaEncryptedEvent) => void\n ): Unsubscribe {\n element.addEventListener('webkitneedkey', handler)\n return () => element.removeEventListener('webkitneedkey', handler)\n }\n}\n\nexport class WebKitCommonMediaKeySystemAccess implements CommonMediaKeySystemAccess {\n constructor(public readonly keySystem: DrmKeySystem) {}\n\n createMediaKeys(): Promise<CommonMediaKeys> {\n const webKitMediaKeys = new WebKitMediaKeys(this.keySystem)\n const webkitCommonMediaKeys = new WebKitCommonMediaKeys(\n this.keySystem,\n webKitMediaKeys\n )\n return Promise.resolve(webkitCommonMediaKeys)\n }\n}\n\n/** @private */\nexport class WebKitCommonMediaKeys implements CommonMediaKeys {\n constructor(\n public readonly keySystem: DrmKeySystem,\n public readonly mediaKeys: WebKitMediaKeys\n ) {}\n\n /**\n * Sets the media keys on the given element.\n */\n setOnElement(element: HTMLMediaElement): Promise<void> {\n element.webkitSetMediaKeys!(this.mediaKeys)\n return Promise.resolve()\n }\n\n /**\n * Clears the media keys from the given element.\n */\n clearFromElement(element: HTMLMediaElement): Promise<void> {\n element.webkitSetMediaKeys!(null)\n return Promise.resolve()\n }\n\n setServerCertificate(_certificate: BufferSource): Promise<boolean> {\n return Promise.resolve(false)\n }\n\n createSession(\n mimeType: string,\n initDataType: DrmInitDataType,\n initData: EncryptedInitData\n ): CommonMediaKeySession {\n const session = this.mediaKeys.createSession(\n mimeType,\n bufferToByteArray(initData)\n )\n return new WebKitCommonMediaKeySession(\n session,\n mimeType,\n initDataType,\n initData\n )\n }\n}\n\n/** @private */\nexport class WebKitCommonMediaKeySession\n extends EventHostImpl<CommonMediaKeySessionEventMap>\n implements CommonMediaKeySession, Disposable\n{\n private _disposed: boolean = false\n\n constructor(\n private readonly session: WebKitMediaKeySession,\n readonly mimeType: string,\n readonly initDataType: DrmInitDataType,\n readonly initData: EncryptedInitData\n ) {\n super()\n session.addEventListener('webkitkeymessage', this.messageHandler)\n session.addEventListener('webkitkeyerror', this.errorHandler)\n }\n\n private readonly messageHandler = (event: WebKitMediaKeyMessageEvent) => {\n this.dispatch('message', {\n message: event.message.buffer as ArrayBuffer,\n })\n }\n\n private readonly errorHandler = () => {\n if (this.session.error) {\n const e = this.session.error\n const error = new CommonMediaKeySessionError(\n e.code,\n webkitErrorCodeToStr(e.code),\n e.systemCode,\n webkitErrorCodeToStr(e.systemCode)\n )\n this.dispatch('error', { error, target: this })\n }\n }\n\n update(key: ArrayBuffer): Promise<void> {\n if (this.disposed) return Promise.reject(new DisposedError())\n this.session.update(new Uint8Array(key))\n return Promise.resolve()\n }\n\n get disposed() {\n return this._disposed\n }\n\n dispose(): void {\n super.dispose()\n this._disposed = true\n this.session.removeEventListener(\n 'webkitkeymessage',\n this.messageHandler\n )\n this.session.removeEventListener('webkitkeyerror', this.errorHandler)\n // Do not wait on close, and ignore errors.\n this.session.close()\n }\n}\n\n/**\n * Returns a string for the WebKit media key error.\n */\nexport function webkitErrorCodeToStr(code: number): MediaKeySessionErrorType {\n switch (code) {\n case WebKitMediaKeyError.MEDIA_KEYERR_CLIENT:\n return MediaKeySessionErrorType.CLIENT\n case WebKitMediaKeyError.MEDIA_KEYERR_DOMAIN:\n return MediaKeySessionErrorType.DOMAIN\n case WebKitMediaKeyError.MEDIA_KEYERR_HARDWARECHANGE:\n return MediaKeySessionErrorType.HARDWARECHANGE\n case WebKitMediaKeyError.MEDIA_KEYERR_OUTPUT:\n return MediaKeySessionErrorType.OUTPUT\n case WebKitMediaKeyError.MEDIA_KEYERR_SERVICE:\n return MediaKeySessionErrorType.SERVICE\n case WebKitMediaKeyError.MEDIA_KEYERR_UNKNOWN:\n default:\n return MediaKeySessionErrorType.UNKNOWN\n }\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { MsCommonEme } from './MsCommonEme'\nimport { StandardCommonEme } from './StandardCommonEme'\nimport { WebKitCommonEme } from './WebKitCommonEme'\nimport type { CommonEme } from './CommonEme'\nimport { globalRef } from '@amazon/vinyl-util'\n\n/**\n * Common EME Factory provides the first supported implementation of CommonEme.\n * The priority is WebKit, Standard, then MS.\n *\n * Note: WebKit if present is currently prioritized over standard for legacy reasons. This may be an obsolete\n * requirement. https://jira.music.amazon.dev/browse/PLAYBACK-6072 ticket to investigate.\n */\nexport function commonEmeFactory(): CommonEme | null {\n if (supportsWebKitEme()) return new WebKitCommonEme()\n if (supportsStandardEme()) return new StandardCommonEme()\n if (supportsMsEme()) return new MsCommonEme()\n return null\n}\n\n/**\n * Tests for Standard Eme support.\n */\nexport function supportsStandardEme(): boolean {\n return mediaKeySupportRef.value.standardEme\n}\n\n/**\n * Tests for WebKitEme support.\n */\nexport function supportsWebKitEme(): boolean {\n return mediaKeySupportRef.value.webkitEme\n}\n\n/**\n * Tests for MsEme support.\n */\nexport function supportsMsEme(): boolean {\n return mediaKeySupportRef.value.msEme\n}\n\nexport type MediaKeySupport = {\n readonly standardEme: boolean\n readonly webkitEme: boolean\n readonly msEme: boolean\n}\n\nexport const mediaKeySupportRef = /* @__PURE__ */ globalRef<MediaKeySupport>(() => {\n return {\n standardEme: typeof MediaKeys !== 'undefined',\n webkitEme: typeof WebKitMediaKeys !== 'undefined',\n msEme: typeof (global as any).MSMediaKeys !== 'undefined',\n }\n})\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {\n AbortError,\n base64ToByteArray,\n buffersEqual,\n bufferToByteArray,\n clone,\n type Comparator,\n compareBy,\n createDisposer,\n ErrorOrigin,\n EventHostImpl,\n getUserAgentInfo,\n isSilentError,\n logDebug,\n logError,\n logVerbose,\n type Maybe,\n memoize,\n noop,\n normalizeHeadersInit,\n Os,\n type ReadonlyAbort,\n remove,\n resolveValueProvider,\n withTimeout,\n} from '@amazon/vinyl-util'\nimport { instanceOf, object, type ObjectSchema } from '@amazon/vinyl-validation'\nimport {\n type DrmMediaKeySystemOptions,\n type DrmOptions,\n DrmRobustness,\n type InitDataTransformer,\n} from './DrmOptions'\nimport type {\n DrmController,\n DrmControllerEventMap,\n DrmKeySystemSupport,\n DrmPlaybackOptions,\n} from './DrmController'\nimport type {\n CommonEme,\n CommonMediaEncryptedEvent,\n CommonMediaKeyMessageEvent,\n CommonMediaKeys,\n CommonMediaKeySession,\n CommonMediaKeySystemAccess,\n} from './commonEme/CommonEme'\nimport { DrmError } from './error/DrmError'\nimport type { EncryptedInitData } from './commonEme/EncryptedInitData'\nimport { DrmKeySystem, isPlayReady } from './DrmKeySystem'\nimport type { DrmInitDataType } from '../streaming/DrmInitDataType'\nimport type {\n ContentType,\n MediaFormatMetadata,\n} from '../streaming/MediaQualityMetadata'\nimport { unpackPlayReadyChallenge } from './util/unpackPlayReadyChallenge'\nimport type {\n LicenseProvider,\n ServerCertificate,\n} from './licenseProvider/LicenseProvider'\nimport { defaultLicenseProvider } from './licenseProvider/defaultLicenseProvider'\nimport { extractContentId } from './util/extractContentId'\nimport { createFairPlaySessionInitData } from './util/createFairPlaySessionInitData'\nimport type { TrackUri } from '../track/Track'\n\n/**\n * The number of seconds a license request will be allowed before timing out.\n * This should be higher than the network timeout.\n *\n * In practice, network requests will time out before this, and a license timeout\n * indicates a stalled promise result from the license provider.\n */\nexport const LICENSE_TIMEOUT = 90\nconst LICENSE_TIMEOUT_MESSAGE = 'License provider timed out after {time}s'\n\n/**\n * Dependencies for creating DrmController.\n */\nexport interface DrmControllerImplDeps {\n readonly media: HTMLMediaElement\n readonly commonEme: CommonEme | null\n}\n\nexport interface DrmControllerMessageProps {\n readonly mediaKeys: CommonMediaKeys\n readonly session: CommonMediaKeySession\n readonly event: CommonMediaKeyMessageEvent\n /**\n * The track that initiated this session, captured when the session was\n * created. Carried on the props (not read from controller state at message\n * time) so concurrent license exchanges for different tracks each attribute\n * to their own track.\n */\n readonly trackUri: TrackUri | null\n}\n\n/**\n * Options for {@link DrmControllerImpl.maybeCreateSession}.\n */\ninterface MaybeCreateSessionOptions {\n readonly drmInfo: MediaFormatMetadata\n readonly initDataType: DrmInitDataType\n readonly initData: EncryptedInitData\n readonly trackUri: TrackUri | null\n readonly abort?: Maybe<ReadonlyAbort>\n}\n\n/**\n * Options for {@link DrmControllerImpl.createNewSession}.\n */\ninterface CreateNewSessionOptions {\n readonly serverCertificate: Maybe<ServerCertificate>\n readonly mediaKeys: CommonMediaKeys\n readonly initData: EncryptedInitData\n readonly initDataType: DrmInitDataType\n readonly drmInfo: MediaFormatMetadata & { readonly mimeType: string }\n readonly trackUri: TrackUri | null\n readonly initDataTransformer?: InitDataTransformer | undefined\n}\n\nexport class DrmControllerImpl\n extends EventHostImpl<DrmControllerEventMap>\n implements DrmController\n{\n get [Symbol.toStringTag](): string {\n return 'DrmControllerImpl'\n }\n\n private readonly optionsBase: DrmOptions\n private options: DrmOptions\n\n private mediaKeys: CommonMediaKeys | null = null\n private mediaKeysPromise: Promise<CommonMediaKeys> | null = null\n private readonly sessions: CommonMediaKeySession[] = []\n\n private _error: Error | null = null\n private drmInfo: MediaFormatMetadata | null = null\n private bufferingTrackUri: TrackUri | null = null\n private sessionAbort: ReadonlyAbort | null = null\n\n private pendingMessageProps: DrmControllerMessageProps | null = null\n private readonly disposer = /* @__PURE__ */ createDisposer()\n\n constructor(\n private readonly deps: DrmControllerImplDeps,\n options?: Maybe<Partial<DrmOptions>>\n ) {\n super()\n this.optionsBase = { keySystems: {}, ...options }\n this.options = this.optionsBase\n\n if (this.deps.commonEme) {\n this.disposer.add(\n this.deps.commonEme.addEncryptedListener(\n this.deps.media,\n this.handleEncryptedEvent\n )\n )\n }\n }\n\n configure(options: Maybe<Partial<DrmOptions>>): void {\n this.options = {\n ...this.optionsBase,\n ...options,\n keySystems: {\n ...this.optionsBase.keySystems,\n ...options?.keySystems,\n },\n }\n }\n\n private get licenseProvider(): LicenseProvider {\n return this.options.licenseProvider ?? defaultLicenseProvider\n }\n\n get error(): Error | null {\n return this._error\n }\n\n isEmeSupported(): boolean {\n return this.deps.commonEme != null\n }\n\n async isSupported(\n drmInfo: MediaFormatMetadata\n ): Promise<DrmKeySystemSupport> {\n const accessParamsList = this.createMediaKeySystemAccessParams(drmInfo)\n for (const params of accessParamsList) {\n const result = await this.checkIsSupportedCached(params)\n if (result.supported) return result\n }\n return { supported: false, persistentState: false }\n }\n\n private checkIsSupportedCached = /* @__PURE__ */ memoize(\n async (\n params: MediaKeySystemAccessParams\n ): Promise<DrmKeySystemSupport> => {\n try {\n await this.deps.commonEme!.requestMediaKeySystemAccess(\n params.keySystem,\n [params.config]\n )\n this.abortIfDisposed()\n logVerbose(\n this,\n 'requestMediaKeySystemAccess supported',\n params\n )\n return {\n supported: true,\n persistentState:\n params.config.persistentState === 'required',\n }\n } catch (_) {\n if (!this.disposed)\n logVerbose(\n this,\n 'requestMediaKeySystemAccess rejected',\n params\n )\n return { supported: false, persistentState: false }\n }\n },\n (options) => options.cacheKey,\n 20 // capacity\n )\n\n private readonly handleEncryptedEvent = (\n event: CommonMediaEncryptedEvent\n ) => {\n if (this.disposed) return\n ;(async () => {\n const { initData, initDataType } = event\n if (!initData) {\n // https://www.w3.org/TR/2014/WD-encrypted-media-20140218/#dom-mediakeyneededevent\n // https://www.w3.org/TR/encrypted-media/#initialization-data\n // Initialization data could not be obtained, possibly due to cross-origin policy issues.\n throw new DrmError(\n 'encrypted event provided null initData. Check CORS policies.'\n )\n }\n logDebug(\n this,\n `encrypted, initDataType: ${initDataType}, initData.byteLength: ${initData.byteLength}`\n )\n // A session may already cover this initData (e.g. another stream\n // created it, or buffering info was transiently cleared). Reuse it\n // before treating the event as unconfigured content.\n if (this.getSessionByInitData(initData)) {\n logDebug(this, 'reusing session')\n return\n }\n if (!this.drmInfo?.contentProtections.length) {\n throw new DrmError(\n 'Encrypted content not configured with content protections.'\n )\n }\n await this.maybeCreateSession({\n drmInfo: this.drmInfo,\n initDataType,\n initData,\n trackUri: this.bufferingTrackUri,\n abort: this.sessionAbort,\n })\n })().catch(this.handleError)\n }\n\n /**\n * Resolves to media keys attached to the element.\n * The media keys will only be created and set once until `clearMediaKeys` is next called.\n */\n private async attachMediaKeys(\n drmInfo: MediaFormatMetadata\n ): Promise<CommonMediaKeys> {\n if (!this.mediaKeysPromise) {\n this.mediaKeysPromise = (async () => {\n logDebug(this, 'creating media keys')\n const access = await this.createAccess(drmInfo)\n const mediaKeys = await access.createMediaKeys()\n this.abortIfDisposed()\n this.mediaKeys = mediaKeys\n await mediaKeys.setOnElement(this.deps.media)\n this.abortIfDisposed()\n logDebug(this, `set media keys on element`)\n this.dispatch('mediaKeysSet', {\n keySystem: mediaKeys.keySystem,\n })\n return mediaKeys\n })()\n }\n return this.mediaKeysPromise\n }\n\n /**\n * Creates a session for the given initialization data if none currently exists.\n * This will be done either after an 'encrypted' event or when drm metadata contains initialization data.\n * The new session will be added to the current sessions list.\n */\n private async maybeCreateSession(\n options: MaybeCreateSessionOptions\n ): Promise<CommonMediaKeySession> {\n const { drmInfo, initDataType, initData, trackUri, abort } = options\n if (!hasMimeType(drmInfo)) {\n throw new DrmError('Encrypted content must have a mimeType.')\n }\n\n const mediaKeys = await this.attachMediaKeys(drmInfo)\n this.abortIfDisposed()\n\n // Resolve server certificate from configuration\n const keySystemOptions =\n this.options.keySystems[mediaKeys.keySystem] ??\n this.options.keySystems['*']\n const licenseServerOptionsProvider = keySystemOptions?.licenseServer\n const licenseServerOptions = await resolveValueProvider(\n licenseServerOptionsProvider ?? {}\n )\n this.abortIfDisposed()\n const existingSession = this.getSessionByInitData(initData)\n if (existingSession) {\n logDebug(this, 'reusing session')\n return existingSession\n } else {\n const newSession = await this.createNewSession({\n serverCertificate: licenseServerOptions.serverCertificate,\n mediaKeys,\n initData,\n initDataType,\n drmInfo,\n trackUri,\n initDataTransformer: keySystemOptions?.initDataTransformer,\n })\n this.sessions.push(newSession)\n this.dispatch('sessionCreate', {\n initDataType: newSession.initDataType,\n mimeType: newSession.mimeType,\n })\n newSession.on('closed', () => this.closeSession(newSession))\n abort?.onAborted(() => {\n if (this.disposed) return\n logDebug(this, 'abort session')\n this.closeSession(newSession)\n })\n return newSession\n }\n }\n\n initializeForPlayback(\n drmInfo: MediaFormatMetadata | null,\n options?: DrmPlaybackOptions\n ): void {\n logDebug(this, 'initializeForPlayback', drmInfo)\n if (drmInfo?.contentProtections.length) {\n this.createSessionFromInitData(\n drmInfo,\n options?.trackUri ?? null,\n options?.abort\n ).catch(this.handleError)\n }\n }\n\n setBufferingDrmInfo(\n drmInfo: MediaFormatMetadata | null,\n options?: DrmPlaybackOptions\n ): void {\n logDebug(this, 'setBufferingDrmInfo', drmInfo)\n // Reset 'encrypted' error reporting\n this.reset()\n this.drmInfo = drmInfo\n this.bufferingTrackUri = options?.trackUri ?? null\n this.sessionAbort = options?.abort ?? null\n }\n\n /**\n * If the drm metadata contains initialization data for the current key system, create a new session.\n * Otherwise, wait for the 'encrypted' event for the initialization data.\n */\n private async createSessionFromInitData(\n drmInfo: MediaFormatMetadata,\n trackUri: TrackUri | null,\n abort?: ReadonlyAbort\n ) {\n if (!this.deps.commonEme) {\n this.handleError(new DrmError('DRM not supported.'))\n return\n }\n const mediaKeys = await this.attachMediaKeys(drmInfo)\n const drmProtection =\n drmInfo.contentProtections.find((cP) => {\n return cP.keySystem === mediaKeys.keySystem\n }) ?? null\n\n if (!drmProtection) {\n // Media keys have been initialized, but content is not encrypted with the current keySystem.\n throw new DrmError(\n `Encrypted content does not support set keySystem: '${mediaKeys.keySystem}'.`,\n { drmInfo }\n )\n }\n if (drmProtection.pssh) {\n await this.maybeCreateSession({\n drmInfo,\n initDataType: drmInfo.initDataType ?? 'cenc',\n initData: base64ToByteArray(drmProtection.pssh),\n trackUri,\n abort,\n })\n }\n }\n\n /**\n * Creates a CommonMediaKeySystemAccess object from the given content protection settings.\n */\n private async createAccess(\n drmInfo: MediaFormatMetadata\n ): Promise<CommonMediaKeySystemAccess> {\n const accessParamsList = this.createMediaKeySystemAccessParams(drmInfo)\n for (const { keySystem, config } of accessParamsList) {\n try {\n const access =\n await this.deps.commonEme!.requestMediaKeySystemAccess(\n keySystem,\n [config]\n )\n if (!this.disposed) {\n logDebug(\n this,\n `created media key system access for keySystem: ${access.keySystem}}`,\n config\n )\n }\n return access\n } catch (_) {\n // ignore\n }\n }\n throw new DrmError(\n `No keySystem supported`,\n {\n contentProtections: drmInfo as any,\n attemptedKeySystems: accessParamsList.map(\n (arr) => arr.keySystem\n ),\n },\n ErrorOrigin.DRM\n )\n }\n\n /**\n * Creates a list of the MediaKeySystemAccess configurations to try for the given media format options.\n */\n private createMediaKeySystemAccessParams(\n drmInfo: MediaFormatMetadata\n ): readonly MediaKeySystemAccessParams[] {\n const keySystems = drmInfo.contentProtections\n .map((protection) => protection.keySystem)\n .sort(this.keySystemComparator)\n\n return keySystems.map((keySystem): MediaKeySystemAccessParams => {\n const mediaOptions = this.getMediaKeySystemOptions(\n keySystem,\n drmInfo.contentType\n )\n const capability: MediaKeySystemMediaCapability = {\n robustness:\n mediaOptions?.robustness ?? DrmRobustness.SW_SECURE_CRYPTO,\n encryptionScheme: drmInfo.encryptionScheme,\n }\n if (drmInfo.mimeType) {\n capability.contentType = drmInfo.mimeType\n }\n const config: MediaKeySystemConfiguration = {\n initDataTypes: [drmInfo.initDataType ?? 'cenc'],\n }\n const contentType = drmInfo.contentType\n if (contentType === 'video') {\n config.videoCapabilities = [capability]\n } else if (contentType === 'audio') {\n config.audioCapabilities = [capability]\n if (getUserAgentInfo().os?.name === Os.CHROME_OS) {\n // Add videoCapabilities to get ChromeOS to enable verified media path\n logDebug(this, 'Adding video avc1 drm capabilities for VMP')\n config.videoCapabilities = [\n {\n contentType: `video/mp4; codecs=\"avc1.4d401f\"`,\n robustness: 'SW_SECURE_DECODE',\n },\n ]\n }\n }\n return {\n keySystem,\n config,\n // Concatenate a list of inputs to use as a cache key for isSupported checks.\n cacheKey: [\n keySystem,\n drmInfo.mimeType,\n drmInfo.contentType,\n capability.robustness,\n drmInfo.encryptionScheme,\n drmInfo.initDataType,\n ]\n .map(String)\n .join('|'),\n }\n })\n }\n\n private getMediaKeySystemOptions(\n keySystem: DrmKeySystem,\n contentType: Maybe<ContentType>\n ): DrmMediaKeySystemOptions | undefined {\n const keySystems = this.options.keySystems\n const keySystemOptions = keySystems[keySystem] ?? keySystems['*']\n if (!keySystemOptions) return undefined\n switch (contentType) {\n case 'video':\n return keySystemOptions.video\n case 'audio':\n return keySystemOptions.audio\n default:\n return undefined\n }\n }\n\n /**\n * Creates a new key session and adds a message handler.\n */\n private async createNewSession(\n options: CreateNewSessionOptions\n ): Promise<CommonMediaKeySession> {\n const {\n serverCertificate,\n mediaKeys,\n initDataType,\n drmInfo,\n trackUri,\n initDataTransformer,\n } = options\n let initData = options.initData\n const certBytes = serverCertificate\n ? typeof serverCertificate === 'string'\n ? base64ToByteArray(serverCertificate)\n : bufferToByteArray(serverCertificate)\n : null\n\n if (certBytes) {\n await mediaKeys.setServerCertificate(certBytes)\n }\n\n // Default initDataTransformer handles FAIR_PLAY_1_0 by packing the\n // skd init data with the content ID and server certificate.\n // FAIR_PLAY_1_0 always uses initDataType 'skd', so the default\n // does not need to explicitly check initDataType.\n const transform =\n initDataTransformer ??\n defaultInitDataTransformer(mediaKeys.keySystem, certBytes)\n initData = transform(bufferToByteArray(initData), initDataType, drmInfo)\n\n this.abortIfDisposed()\n logDebug(this, 'createSession', drmInfo.mimeType, initDataType)\n const session = mediaKeys.createSession(\n drmInfo.mimeType,\n initDataType,\n initData\n )\n session.on('message', (event) => {\n withTimeout(\n this.messageHandler({\n mediaKeys: mediaKeys,\n session: session,\n event: event,\n // Captured per session, so a concurrent preloaded track's\n // license exchange keeps its own attribution.\n trackUri: trackUri,\n }),\n LICENSE_TIMEOUT,\n { message: LICENSE_TIMEOUT_MESSAGE }\n ).catch(this.handleError)\n })\n session.on('error', (event) => {\n this.closeSession(session)\n this.handleError(event.error)\n })\n return session\n }\n\n /**\n * Invoked when the content decryption module needs to interact with the license server.\n */\n private async messageHandler(\n messageProps: DrmControllerMessageProps\n ): Promise<void> {\n const { mediaKeys, session, event } = messageProps\n messageEventValidator.assert(event)\n this.pendingMessageProps = messageProps\n\n const keySystem = mediaKeys.keySystem\n logDebug(this, 'message', keySystem, event.message.byteLength)\n\n const keySystemOptions = this.options.keySystems[keySystem]\n const licenseServerOptionsProvider = keySystemOptions?.licenseServer\n\n // Get the license server configuration for the current key system.\n const licenseServerOptions =\n clone(await resolveValueProvider(licenseServerOptionsProvider)) ??\n {}\n this.abortIfDisposed()\n\n let challenge: BodyInit = event.message\n if (isPlayReady(keySystem)) {\n const unpacked = unpackPlayReadyChallenge(challenge)\n challenge = unpacked.challenge\n if (licenseServerOptions.init == null)\n licenseServerOptions.init = {}\n licenseServerOptions.init.headers = {\n ...normalizeHeadersInit(\n licenseServerOptions.init.headers ?? {}\n ),\n ...unpacked.headers,\n }\n }\n const licenseSpanStart = Date.now()\n const key = await this.licenseProvider(\n keySystem,\n licenseServerOptions,\n challenge\n )\n this.dispatch('loadSpanMeasured', {\n kind: 'license',\n startTime: licenseSpanStart,\n endTime: Date.now(),\n // Attributed at the source to the session's track; omitted (not set\n // to undefined) when unknown, per exactOptionalPropertyTypes.\n ...(messageProps.trackUri != null && {\n trackUri: messageProps.trackUri,\n }),\n })\n this.pendingMessageProps = null\n if (session.disposed) return\n logDebug(this, 'update')\n await session.update(key)\n }\n\n //--------------------------------------------\n // Session management\n //--------------------------------------------\n\n /**\n * Closes all active DRM sessions.\n * This should not be called unless the audio source has been cleared.\n */\n closeSessions() {\n logDebug(this, `clearing ${this.sessions.length} sessions`)\n while (this.sessions.length) this.closeSession(this.sessions[0])\n }\n\n private closeSession(session: CommonMediaKeySession) {\n // Sessions are closed synchronously during dispose() (before the\n // disposer flips `disposed`), but a session's own async 'closed'/'error'\n // can arrive after teardown.\n if (this.disposed) return\n logDebug(this, 'closeSession')\n session.dispose()\n remove(this.sessions, session)\n this.dispatch('sessionClose', {\n initDataType: session.initDataType,\n mimeType: session.mimeType,\n })\n }\n\n /**\n * A handler which dispatches an error event.\n * Only one error event will be emitted per unique PSSH.\n * When track protections is set again, another error event may be emitted.\n */\n private readonly handleError = (error: Error) => {\n if (!this._error && !isSilentError(error)) {\n logError(this, error)\n this._error = error\n this.dispatch('error', { error, target: this })\n }\n }\n\n /**\n * Returns the number of currently active sessions.\n */\n get activeSessions(): number {\n return this.sessions.length\n }\n\n /**\n * Clears the media keys from the element if they were set.\n */\n private clearMediaKeys() {\n this.closeSessions()\n if (this.mediaKeys) {\n logDebug(this, 'clearing media keys')\n this.mediaKeys.clearFromElement(this.deps.media).catch(noop)\n this.mediaKeys = null\n }\n this.mediaKeysPromise = null\n }\n\n protected abortIfDisposed() {\n if (this.disposed) throw new AbortError()\n }\n\n reset() {\n if (!this._error) {\n logDebug(this, 'reset no-op')\n return\n }\n logDebug(this, 'reset')\n this._error = null\n if (this.pendingMessageProps) {\n const mediaError = this.deps.media.error\n if (mediaError && mediaError.code === mediaError.MEDIA_ERR_DECODE) {\n // Media is in a failed decoding state, cannot recover from a failed license request.\n // The PlaybackController will attempt a reset.\n logDebug(\n this,\n 'media in an error state, will not retry failed license challenge'\n )\n this.pendingMessageProps = null\n } else {\n logDebug(this, 'retrying failed license challenge')\n this.messageHandler(this.pendingMessageProps).catch(\n this.handleError\n )\n }\n }\n this.dispatch('reset', {})\n }\n\n get disposed(): boolean {\n return this.disposer.disposed\n }\n\n dispose(): void {\n logDebug(this, 'dispose')\n super.dispose()\n this.clearMediaKeys()\n this.disposer.dispose()\n }\n\n private getSessionByInitData(\n initData: EncryptedInitData\n ): CommonMediaKeySession | null {\n return (\n this.sessions.find((session) => {\n return buffersEqual(session.initData, initData)\n }) ?? null\n )\n }\n\n /**\n * Sort the key systems first by their priority, then by the presence of a license uri.\n */\n private readonly keySystemComparator: Comparator<DrmKeySystem> = /* @__PURE__ */ compareBy(\n (keySystem: DrmKeySystem) => {\n return -(this.options.keySystems[keySystem]?.priority ?? 0)\n },\n (keySystem: DrmKeySystem) => {\n return this.options.keySystems[keySystem]?.licenseServer != null\n ? 0\n : 1\n }\n )\n}\n\ninterface MediaKeySystemAccessParams {\n readonly keySystem: DrmKeySystem\n readonly config: MediaKeySystemConfiguration\n readonly cacheKey: string\n}\n\nconst messageEventValidator: ObjectSchema<CommonMediaKeyMessageEvent> = /* @__PURE__ */ object({\n message: /* @__PURE__ */ instanceOf(ArrayBuffer),\n})\n\nfunction hasMimeType(\n drmInfo: MediaFormatMetadata\n): drmInfo is MediaFormatMetadata & { readonly mimeType: string } {\n return drmInfo.mimeType != null\n}\n\n/**\n * Default initDataTransformer. For FAIR_PLAY_1_0, packs the skd init data\n * with the extracted content ID and server certificate into the format\n * expected by WebKit-prefixed EME. FAIR_PLAY_1_0 always uses initDataType\n * 'skd', so we only need to check the key system.\n * For all other key systems, returns init data unchanged.\n */\nfunction defaultInitDataTransformer(\n keySystem: DrmKeySystem,\n certBytes: Uint8Array<ArrayBuffer> | null\n): InitDataTransformer {\n return (initData: Uint8Array<ArrayBuffer>): Uint8Array<ArrayBuffer> => {\n if (keySystem === DrmKeySystem.FAIR_PLAY_1_0) {\n if (!certBytes) {\n throw new DrmError('FairPlay requires certificate data')\n }\n const contentId = extractContentId(initData)\n return createFairPlaySessionInitData(initData, contentId, certBytes)\n }\n return initData\n }\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { ReadonlyRecord, ValueProvider } from '@amazon/vinyl-util'\nimport type { DrmInitDataType } from '../streaming/DrmInitDataType'\nimport type { MediaFormatMetadata } from '../streaming/MediaQualityMetadata'\nimport {\n enumOf,\n func,\n isOneOf,\n number,\n object,\n type ObjectSchema,\n record,\n recordValues,\n string,\n type ValueSchema,\n} from '@amazon/vinyl-validation'\nimport { DrmKeySystem, drmKeySystemValidator } from './DrmKeySystem'\nimport {\n type LicenseProvider,\n type LicenseServerOptions,\n licenseServerOptionsValidator,\n} from './licenseProvider/LicenseProvider'\n\n/**\n * DrmRobustness is the requested security level for audio or video decryption.\n */\nexport enum DrmRobustness {\n SW_SECURE_CRYPTO = 'SW_SECURE_CRYPTO',\n SW_SECURE_DECODE = 'SW_SECURE_DECODE',\n HW_SECURE_CRYPTO = 'HW_SECURE_CRYPTO',\n HW_SECURE_DECODE = 'HW_SECURE_DECODE',\n HW_SECURE_ALL = 'HW_SECURE_ALL',\n}\n\n/**\n * DrmConfig configures DrmController and LicenseProvider.\n */\nexport interface DrmOptions {\n readonly keySystems: {\n readonly [p in DrmKeySystem]?: DrmKeySystemOptions\n } & {\n readonly [DrmKeySystem.CLEAR_KEY]?: DrmClearKeySystemOptions\n } & {\n /**\n * A wildcard to match any key system when there wasn't a match.\n */\n readonly ['*']?: DrmKeySystemOptions\n }\n\n /**\n *\n * If not set, the license provider from the player dependencies will\n * be used.\n */\n readonly licenseProvider?: LicenseProvider\n}\n\n/**\n * Clear key system options that extend base DRM key system options with clear\n * key mappings. Used for unencrypted content or testing scenarios where keys\n * are provided in plain text.\n */\nexport type DrmClearKeySystemOptions = DrmKeySystemOptions & {\n readonly keys: ReadonlyRecord<string, string>\n}\n\nexport interface DrmKeySystemOptions {\n /**\n * License server configuration used to make license requests.\n */\n readonly licenseServer?: ValueProvider<LicenseServerOptions>\n\n /**\n * Audio-specific DRM configuration.\n */\n readonly audio?: DrmMediaKeySystemOptions\n\n /**\n * Video-specific DRM configuration.\n */\n readonly video?: DrmMediaKeySystemOptions\n\n /**\n * Key systems with a higher priority take precedence.\n * If two key systems have equal priority, the order will be as it appears\n * in DrmInfo (provided by the manifest).\n */\n readonly priority?: number\n\n /**\n * Transform applied to init data before session creation.\n * Always invoked for every key system. The default implementation\n * handles {@link DrmKeySystem.FAIR_PLAY_1_0} by packing the init data,\n * content ID, and server certificate into the format expected by\n * WebKit-prefixed EME. For all other key systems, returns init data\n * unchanged.\n */\n readonly initDataTransformer?: InitDataTransformer\n}\n\n/**\n * Transforms raw init data before it is passed to the CDM for session creation.\n *\n * @param initData - The raw initialization data.\n * @param initDataType - The initialization data type (e.g. 'cenc', 'skd').\n * @param drmInfo - The media format metadata for the current content.\n * @returns The transformed init data to pass to the CDM.\n */\nexport type InitDataTransformer = (\n initData: Uint8Array<ArrayBuffer>,\n initDataType: DrmInitDataType,\n drmInfo: MediaFormatMetadata\n) => Uint8Array<ArrayBuffer>\n\nexport interface DrmMediaKeySystemOptions {\n readonly robustness?: DrmRobustness\n}\n\nexport const drmRobustnessValidator: ValueSchema<DrmRobustness> =\n /* @__PURE__ */ enumOf(DrmRobustness)\n\nexport const drmMediaKeySystemOptionsValidator: ObjectSchema<DrmMediaKeySystemOptions> =\n /* @__PURE__ */ object({\n robustness: /* @__PURE__ */ drmRobustnessValidator.optional(),\n })\n\nexport const drmKeySystemOptionsValidator: ObjectSchema<DrmKeySystemOptions> =\n /* @__PURE__ */ object({\n licenseServer: /* @__PURE__ */ /* @__PURE__ */ /* @__PURE__ */ func().or(licenseServerOptionsValidator).optional(),\n audio: /* @__PURE__ */ drmMediaKeySystemOptionsValidator.optional(),\n video: /* @__PURE__ */ drmMediaKeySystemOptionsValidator.optional(),\n priority: /* @__PURE__ */ /* @__PURE__ */ number().optional(),\n initDataTransformer: /* @__PURE__ */ /* @__PURE__ */ func().optional(),\n })\n\nexport const drmClearKeySystemOptionsValidator: ObjectSchema<DrmClearKeySystemOptions> =\n /* @__PURE__ */ drmKeySystemOptionsValidator.extend({\n keys: /* @__PURE__ */ recordValues(/* @__PURE__ */ string()),\n })\n\nexport const drmOptionsValidator: ObjectSchema<DrmOptions> = /* @__PURE__ */ object({\n keySystems: /* @__PURE__ */ /* @__PURE__ */ record(\n /* @__PURE__ */ drmKeySystemValidator.or(/* @__PURE__ */ isOneOf('*')),\n /* @__PURE__ */ drmKeySystemOptionsValidator.optional()\n ).and(\n /* @__PURE__ */ object<{\n readonly [DrmKeySystem.CLEAR_KEY]?: DrmClearKeySystemOptions\n }>({\n [DrmKeySystem.CLEAR_KEY]:\n /* @__PURE__ */ drmClearKeySystemOptionsValidator.optional(),\n })\n ),\n\n licenseProvider: /* @__PURE__ */ /* @__PURE__ */ func().optional(),\n})\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { ValueSchema } from '@amazon/vinyl-validation'\nimport { string } from '@amazon/vinyl-validation'\n\nexport enum DrmKeySystem {\n /**\n * Plain text encryption.\n */\n CLEAR_KEY = 'org.w3.clearkey',\n\n /**\n * Google's Widevine.\n */\n WIDEVINE = 'com.widevine.alpha',\n\n /**\n * Microsoft's PlayReady.\n *\n * - Deprecated.\n * - Will be removed in a future release.\n * - Non-compliant with any version of the EME specification.\n */\n PLAY_READY = 'com.microsoft.playready',\n\n /**\n * Microsoft's PlayReady for Chromecast.\n *\n * - Deprecated.\n * - Will be removed in a future release.\n * - Non-compliant with any version of the EME specification.\n */\n PLAY_READY_CHROMECAST = 'com.chromecast.playready',\n\n /**\n * Microsoft's PlayReady.\n *\n * - Security Level 2000.\n * - Best effort compliance with latest EME specification.\n */\n PLAY_READY_RECOMMENDATION = 'com.microsoft.playready.recommendation',\n\n /**\n * Microsoft's PlayReady.\n *\n * - Supported on devices with required hardware.\n * - Security Level 3000.\n * - Best effort compliance with latest EME specification.\n */\n PLAY_READY_3000 = 'com.microsoft.playready.recommendation.3000',\n\n /**\n * Apple's Fairplay for modern EME.\n */\n FAIR_PLAY = 'com.apple.fps',\n\n /**\n * Apple's Fairplay for legacy Apple Media Keys.\n */\n FAIR_PLAY_1_0 = 'com.apple.fps.1_0',\n}\n\n/**\n * Validates that the key system value is a string.\n * While DrmKeySystem is an enum to be useful for providing known key systems,\n * avoid strict validation to allow for unknown key systems.\n */\nexport const drmKeySystemValidator =\n /* @__PURE__ */ /* @__PURE__ */ string().notEmpty() as ValueSchema<DrmKeySystem>\n\nexport const PLAY_READY_KEY_SYSTEMS: readonly DrmKeySystem[] = [\n DrmKeySystem.PLAY_READY,\n DrmKeySystem.PLAY_READY_CHROMECAST,\n DrmKeySystem.PLAY_READY_RECOMMENDATION,\n DrmKeySystem.PLAY_READY_3000,\n] as const\n\nexport function isPlayReady(keySystem: DrmKeySystem): boolean {\n return PLAY_READY_KEY_SYSTEMS.includes(keySystem)\n}\n\nexport const FAIR_PLAY_KEY_SYSTEMS: readonly DrmKeySystem[] = [\n DrmKeySystem.FAIR_PLAY,\n DrmKeySystem.FAIR_PLAY_1_0,\n] as const\n\nexport function isFairPlay(keySystem: DrmKeySystem): boolean {\n return FAIR_PLAY_KEY_SYSTEMS.includes(keySystem)\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { type Maybe, type ReadonlyAbort } from '@amazon/vinyl-util'\nimport type { DrmKeySystem } from '../DrmKeySystem'\nimport {\n any,\n instanceOf,\n object,\n type ObjectSchema,\n string,\n} from '@amazon/vinyl-validation'\n\n/**\n * LicenseProvider handles requesting DRM licenses for specific key systems.\n */\nexport type LicenseProvider = (\n keySystem: DrmKeySystem,\n serverOptions: LicenseServerOptions,\n challenge: ArrayBuffer,\n abort?: ReadonlyAbort\n) => Promise<ArrayBuffer>\n\n/**\n * Basic license server configuration.\n * The license provider is given the matching configuration for the selected\n * key system.\n */\nexport interface LicenseServerOptions {\n /**\n * The license server URL.\n * This is required when using the default license provider.\n */\n readonly url?: Maybe<string | URL>\n\n /**\n * License request init options.\n */\n readonly init?: Maybe<RequestInit>\n\n /**\n * If set, provides the server certificate.\n * An ArrayBufferLike object containing the server certificate.\n * The contents are Key System-specific.\n * If a `string` is provided, the value will be considered to be Base 64.\n */\n readonly serverCertificate?: Maybe<ServerCertificate>\n}\n\n/**\n * An ArrayBufferLike object containing the server certificate.\n * The contents are Key System-specific.\n * If a `string` is provided, the value will be considered to be Base 64.\n */\nexport type ServerCertificate = ArrayBuffer | string\n\nexport const licenseServerOptionsValidator: ObjectSchema<LicenseServerOptions> =\n /* @__PURE__ */ object({\n url: /* @__PURE__ */ /* @__PURE__ */ /* @__PURE__ */ /* @__PURE__ */ string().or(/* @__PURE__ */ instanceOf(URL)).maybe().optional(),\n init: /* @__PURE__ */ /* @__PURE__ */ /* @__PURE__ */ /* @__PURE__ */ object({}).cast<RequestInit>().maybe().optional(),\n serverCertificate: /* @__PURE__ */ /* @__PURE__ */ any().optional(),\n })\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {\n base64ToByteArray,\n bufferToUtf16,\n logDebug,\n type LogTarget,\n type ReadonlyRecord,\n} from '@amazon/vinyl-util'\nimport type { XmlElement } from '@amazon/vinyl-xml'\nimport {\n attrInt,\n attrString,\n charactersString,\n element,\n elements,\n parseXml,\n parseXmlHandler,\n type XmlRules,\n} from '@amazon/vinyl-xml'\n\n/**\n * The final challenge buffer and headers for a playready license challenge.\n */\nexport interface UnpackedPlayReadyChallenge {\n readonly challenge: ArrayBuffer\n readonly headers: ReadonlyRecord<string, string>\n}\n\nconst logTarget: LogTarget = {\n logPrefix: 'unpackPlayReadyChallenge',\n}\n\n/**\n * IE and Edge wraps playready license challenges in PlayReadyKeyMessage xml.\n * Not all PlayReady clients do this.\n * Checks if the challenge is wrapped, and if so, returns the set headers and unwrapped challenge.\n * Otherwise, returns the challenge as-is with the required content type header.\n *\n * @param challenge The array buffer from the 'message' cdm event.\n */\nexport function unpackPlayReadyChallenge(\n challenge: ArrayBuffer\n): UnpackedPlayReadyChallenge {\n const xml = challenge.byteLength % 2 === 0 ? bufferToUtf16(challenge) : ''\n if (!xml.includes('PlayReadyKeyMessage')) {\n logDebug(logTarget, 'not wrapped')\n // A client that does not wrap the challenge.\n return {\n challenge,\n headers: {\n 'Content-Type': 'text/xml; charset=utf-8',\n },\n }\n }\n logDebug(logTarget, 'unpacking challenge')\n const message = parsePlayReadyKeyMessage(xml)\n const licenseAcquisition = message.PlayReadyKeyMessage.LicenseAcquisition\n const unpackedChallenge = base64ToByteArray(\n licenseAcquisition.Challenge._content\n ).buffer\n const headers: Record<string, string> = {}\n for (const element of licenseAcquisition.HttpHeaders.HttpHeader) {\n headers[element.name._content] = element.value._content\n }\n return {\n challenge: unpackedChallenge,\n headers,\n }\n}\n\ninterface PlayReadyMessage {\n readonly PlayReadyKeyMessage: PlayReadyKeyMessageType\n}\n\ninterface PlayReadyKeyMessageType {\n readonly type?: string\n readonly LicenseAcquisition: LicenseAcquisitionType\n}\n\ninterface LicenseAcquisitionType {\n readonly Version: number\n readonly Challenge: ChallengeType\n readonly HttpHeaders: HttpHeadersType\n}\n\ninterface ContentType {\n readonly _content: string\n}\n\ninterface ChallengeType extends ContentType {\n readonly encoding?: string\n}\n\ninterface HttpHeadersType {\n readonly HttpHeader: readonly HttpHeaderType[]\n}\n\ninterface HttpHeaderType {\n readonly name: ContentType\n readonly value: ContentType\n}\n\nconst challengeType: XmlRules<ChallengeType> = {\n _content: charactersString,\n encoding: attrString,\n}\n\nconst contentType: XmlRules<ContentType> = {\n _content: charactersString,\n}\n\nconst headerType: XmlRules<HttpHeaderType> = {\n name: /* @__PURE__ */ element(contentType, { required: true }),\n value: /* @__PURE__ */ element(contentType, { required: true }),\n}\n\nconst httpHeadersType: XmlRules<HttpHeadersType> = {\n HttpHeader: /* @__PURE__ */ elements(headerType, { useEmptyArrays: true }),\n}\n\nconst licenseAcquisitionType: XmlRules<LicenseAcquisitionType> = {\n Challenge: /* @__PURE__ */ element(challengeType, { required: true }),\n HttpHeaders: /* @__PURE__ */ element(httpHeadersType, { required: true }),\n Version: /* @__PURE__ */ attrInt({ required: true }),\n}\n\nconst playReadyKeyMessageType: XmlRules<PlayReadyKeyMessageType> = {\n LicenseAcquisition: /* @__PURE__ */ element(licenseAcquisitionType, { required: true }),\n type: /* @__PURE__ */ attrString(),\n}\n\nconst playReadyMessageRules: XmlRules<PlayReadyMessage> = {\n PlayReadyKeyMessage: /* @__PURE__ */ element(playReadyKeyMessageType, {\n required: true,\n }),\n}\n\n/**\n * A Content handler for a PlayReady SOAP message.\n */\nconst playReadyXmlHandler = /* @__PURE__ */ parseXmlHandler(playReadyMessageRules)\n\n/**\n * Parses a PlayReady SOAP key message.\n *\n * @internal Exported for unit testing; not part of the public API.\n */\nexport function parsePlayReadyKeyMessage(\n xmlStr: string\n): PlayReadyMessage & XmlElement<PlayReadyMessage> {\n return parseXml(xmlStr, playReadyXmlHandler)\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { ReadonlyAbort } from '@amazon/vinyl-util'\nimport { requestWithRetry, ValidationError } from '@amazon/vinyl-util'\nimport type { DrmKeySystem } from '../DrmKeySystem'\nimport type { LicenseProvider, LicenseServerOptions } from './LicenseProvider'\n\n/**\n * A basic LicenseProvider which uses the configuration set for the current key system,\n * transmits a challenge as the body, and returns an array buffer.\n *\n * @param keySystem The key system for the current license challenge.\n * @param serverOptions The resolved configuration. The default DrmController\n * implementation provides this from the `drm` configuration set when creating\n * a new player.\n * @param challenge The license challenge, provided by the CDM (Content Decryption\n * Module)\n * @param abort (optional) When aborted, should cancel any active requests.\n */\nexport const defaultLicenseProvider: LicenseProvider = async (\n keySystem: DrmKeySystem,\n serverOptions: LicenseServerOptions,\n challenge: ArrayBuffer,\n abort?: ReadonlyAbort\n): Promise<ArrayBuffer> => {\n if (serverOptions.url == null) {\n throw new ValidationError(\n `Missing licenseServer url in DRM configuration for keySystem: ${keySystem}`\n )\n }\n const res = await requestWithRetry(\n serverOptions.url,\n {\n method: 'POST',\n ...serverOptions.init,\n body: challenge,\n },\n { abort }\n )\n return await res.arrayBuffer()\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { ValidationError } from '@amazon/vinyl-util'\nimport { ErrorOrigin } from '@amazon/vinyl-util'\nimport { bufferToUtf16 } from '@amazon/vinyl-util'\n\n/**\n * Extract contentId from event data encoded as UTF16.\n *\n * @param initData Expected byte array representing a UTF-16 string in the form\n * `skd://0b5689bb-4171-97e5-c280-99f7abe4004f`\n */\nexport function extractContentId(initData: Uint8Array<ArrayBuffer>): string {\n const bufferStr = bufferToUtf16(initData.buffer)\n const matches = bufferStr.match(/skd:\\/\\/(.+)$/)\n if (!matches) {\n throw new ValidationError('No contentId match', ErrorOrigin.MEDIA)\n }\n return matches[1]\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { utf16ToUint16Array } from '@amazon/vinyl-util'\n\n/**\n * Create the payload for EME media key session from `encrypted` / `*needkey` event data and DRM\n * certificate.\n * Note: This code is taken from the official FairPlay SDK example.\n *\n * @param initData\n * @param contentId\n * @param certificateData certificate data as a Uint8Array\n */\nexport function createFairPlaySessionInitData(\n initData: Uint8Array,\n contentId: string,\n certificateData: Uint8Array\n): Uint8Array<ArrayBuffer> {\n const contentIdUint16 = utf16ToUint16Array(contentId)\n const certificateDataUint8 = certificateData\n\n let offset = 0\n const buffer = new ArrayBuffer(\n initData.byteLength +\n 4 + // contentId length\n contentIdUint16.byteLength +\n 4 + // certificateDataUint8 length\n certificateDataUint8.byteLength\n )\n\n const initDataArray = new Uint8Array(buffer, offset, initData.byteLength)\n initDataArray.set(initData)\n offset += initData.byteLength\n\n const dataView = new DataView(buffer)\n dataView.setUint32(offset, contentIdUint16.byteLength, true)\n offset += 4\n\n const idArray = new Uint16Array(buffer, offset, contentIdUint16.length)\n idArray.set(contentIdUint16)\n offset += idArray.byteLength\n\n dataView.setUint32(offset, certificateDataUint8.byteLength, true)\n offset += 4\n\n const certArray = new Uint8Array(\n buffer,\n offset,\n certificateDataUint8.byteLength\n )\n certArray.set(certificateDataUint8)\n\n return new Uint8Array(buffer, 0, buffer.byteLength)\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { type ReadonlyRecord } from '@amazon/vinyl-util'\nimport {\n DrmKeySystem,\n FAIR_PLAY_KEY_SYSTEMS,\n PLAY_READY_KEY_SYSTEMS,\n} from './DrmKeySystem'\nimport { ContentProtectionScheme } from '@amazon/vinyl-mpd-parser'\n\n/**\n * Given a ContentProtection schemeIdUri, returns the {@link DrmKeySystem} it represents.\n * Not all scheme ids will match to a DrmKeySystem. If none are matched, null is returned.\n * For example, CENC 'urn:mpeg:dash:mp4protection:2011' has no key system and shouldn't be used\n * to create a key session.\n */\nexport type DrmKeySystemResolver = (\n schemeIdUri: string\n) => readonly DrmKeySystem[]\n\nlet _defaultSchemeToKeySystem: ReadonlyRecord<\n string,\n readonly DrmKeySystem[]\n> | null = null\n\nexport function getDefaultSchemeToKeySystem(): ReadonlyRecord<\n string,\n readonly DrmKeySystem[]\n> {\n if (_defaultSchemeToKeySystem == null) {\n _defaultSchemeToKeySystem = {\n [ContentProtectionScheme.CLEAR_KEY]: [DrmKeySystem.CLEAR_KEY],\n [ContentProtectionScheme.FAIR_PLAY]: FAIR_PLAY_KEY_SYSTEMS,\n [ContentProtectionScheme.PLAY_READY]: PLAY_READY_KEY_SYSTEMS,\n [ContentProtectionScheme.WIDEVINE]: [DrmKeySystem.WIDEVINE],\n } as const\n }\n return _defaultSchemeToKeySystem\n}\n\nexport const defaultDrmKeySystemResolver: DrmKeySystemResolver = (\n schemeIdUri: string\n) => {\n return getDefaultSchemeToKeySystem()[schemeIdUri.toLowerCase()] ?? []\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nexport interface ChangeEvent<T> {\n readonly previous: T | null\n readonly current: T\n}\n\n/**\n * Creates a function, which when invoked, will call `inner` with a new ChangeEvent.\n *\n * @param getter\n * @param inner\n */\nexport function createChangeEventTrigger<T>(\n getter: () => T,\n inner: (event: ChangeEvent<T>) => void\n): () => void {\n let current = getter()\n return () => {\n const event: ChangeEvent<T> = {\n previous: current,\n current: getter(),\n }\n current = event.current\n inner(event)\n }\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {\n consoleLogHandler,\n historyLogHandler,\n LogLevel,\n type PartialDeep,\n setLogLevel,\n} from '@amazon/vinyl-util'\nimport type { ValueSchema } from '@amazon/vinyl-validation'\nimport {\n isOneOf,\n number,\n object,\n type ObjectSchema,\n} from '@amazon/vinyl-validation'\nimport { PlayerRegistryImpl, playerRegistryRef } from './PlayerRegistry'\n\n/**\n * Configuration for VinylGlobal.\n */\nexport interface VinylGlobalOptions {\n /**\n * The number of concurrent players before a warning is logged.\n * default: 5\n */\n readonly maxPlayersWarning: number\n\n /**\n * Logging configuration\n */\n readonly logging: {\n readonly history: {\n /**\n * Limits the history log level.\n */\n readonly logLevel: LogLevel\n\n /**\n * Sets the logging history size.\n */\n readonly maxHistorySize: number\n }\n\n /**\n * Gates all log handlers to logs of at least this level.\n */\n readonly logLevel: LogLevel\n\n readonly console: {\n /**\n * Gates console logs\n */\n readonly logLevel: LogLevel\n }\n }\n}\n\nconst logLevelValidator: ValueSchema<LogLevel> = /* @__PURE__ */ (() =>\n isOneOf(\n LogLevel.VERBOSE,\n LogLevel.DEBUG,\n LogLevel.INFO,\n LogLevel.WARN,\n LogLevel.ERROR,\n LogLevel.NONE\n ))()\n\n/**\n * A validator for VinylGlobalOptions applications can set for Vinyl.\n */\nconst vinylGlobalOptionsValidator: ObjectSchema<VinylGlobalOptions> = /* @__PURE__ */ object({\n logging: /* @__PURE__ */ object({\n console: /* @__PURE__ */ object({\n logLevel: logLevelValidator,\n }),\n history: /* @__PURE__ */ object({\n logLevel: logLevelValidator,\n maxHistorySize: /* @__PURE__ */ number(),\n }),\n logLevel: logLevelValidator,\n }),\n maxPlayersWarning: /* @__PURE__ */ number(),\n})\n\nconst vinylGlobalOptionsPartialValidator: ObjectSchema<\n PartialDeep<VinylGlobalOptions>\n> = /* @__PURE__ */ vinylGlobalOptionsValidator.partialDeep()\n\n/**\n * Applies configuration to the current vinyl global options.\n *\n * @param options\n */\nexport function configureVinylGlobal(options: PartialDeep<VinylGlobalOptions>) {\n vinylGlobalOptionsPartialValidator.assert(options)\n // Logging configuration\n if (options.logging) {\n const logging = options.logging\n if (logging.logLevel != null) setLogLevel(logging.logLevel)\n if (logging.history) {\n const history = logging.history\n if (historyLogHandler.value) {\n if (history.maxHistorySize != null)\n historyLogHandler.value.maxHistorySize =\n history.maxHistorySize\n if (history.logLevel != null)\n historyLogHandler.value.logLevel = history.logLevel\n }\n }\n if (logging.console?.logLevel != null) {\n if (consoleLogHandler.value) {\n consoleLogHandler.value.logLevel = logging.console.logLevel\n }\n }\n }\n\n if (\n options.maxPlayersWarning != null &&\n playerRegistryRef.value instanceof PlayerRegistryImpl\n ) {\n playerRegistryRef.value.maxPlayersWarning = options.maxPlayersWarning\n }\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { AnyRecord, Disposable } from '@amazon/vinyl-util'\nimport {\n globalRef,\n globalTarget,\n IllegalStateError,\n logWarn,\n remove,\n substitute,\n} from '@amazon/vinyl-util'\n\n/**\n * @private\n */\nconst locale = {\n maxPlayersWarning: `{count} Vinyl Players have been constructed without disposal. Check that player.dispose is properly being called, then increase the maxPlayersWarning option if this was intentional.`,\n} as const\n\n/**\n * A registry of all non-disposed Vinyl players.\n * Used for debugging and cleanup validation.\n */\nexport interface PlayerRegistry {\n /**\n * Returns the non-disposed Vinyl players.\n */\n readonly players: readonly AnyRecord[]\n\n /**\n * Adds a player reference. All players must be removed before disposing VinylGlobal.\n *\n * @param player\n */\n addPlayer(player: AnyRecord): void\n\n /**\n * Removes a player reference.\n *\n * @param player\n */\n removePlayer(player: AnyRecord): void\n}\n\nexport const DEFAULT_MAX_PLAYERS = 5\n\n/**\n * A registry of non-disposed players.\n * Used for leak detection and debugging diagnostics.\n */\nexport class PlayerRegistryImpl implements PlayerRegistry, Disposable {\n private _players: AnyRecord[] = []\n\n private gaveMaxPlayersWarning = false\n\n constructor(\n /**\n * The number of concurrent players before a warning is logged.\n * default: 5\n */\n public maxPlayersWarning: number = DEFAULT_MAX_PLAYERS\n ) {}\n\n get players(): readonly AnyRecord[] {\n return this._players\n }\n\n addPlayer(player: AnyRecord): void {\n this._players.push(player)\n const n = this._players.length\n if (n > this.maxPlayersWarning && !this.gaveMaxPlayersWarning) {\n this.gaveMaxPlayersWarning = true\n logWarn(\n globalTarget,\n substitute(locale.maxPlayersWarning, { count: n })\n )\n }\n }\n\n removePlayer(player: AnyRecord): void {\n remove(this._players, player)\n }\n\n /**\n * @throws An IllegalStateError if all players have not been removed.\n */\n dispose() {\n if (this._players.length)\n throw new IllegalStateError(\n 'All players must be removed before disposing VinylGlobal'\n )\n }\n}\n\nexport const playerRegistryRef = /* @__PURE__ */ globalRef<PlayerRegistry>(\n () => new PlayerRegistryImpl()\n)\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { parseVersion } from '@amazon/vinyl-util'\n\ndeclare global {\n var __VINYL_VERSION__: string | undefined\n}\n\n/**\n * `globalThis.__VINYL_VERSION__` is replaced at build time with the package.version via\n * esbuild's `define` option. In unit tests and unbundled dev builds the replacement does not\n * happen and the global is undefined, so we fall through to a placeholder version.\n */\nexport const vinylVersion = /* @__PURE__ */ parseVersion(\n /* istanbul ignore next */\n globalThis.__VINYL_VERSION__ ?? '0.0.0.0'\n)\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {\n type AnyRecord,\n getNetworkMetrics,\n getUserAgentInfo,\n globalRef,\n historyLogHandler,\n toDisposable,\n} from '@amazon/vinyl-util'\nimport { playerRegistryRef } from './PlayerRegistry'\nimport { vinylVersion } from './environment'\n\ndeclare global {\n /**\n * A reference to Vinyl's global state, easily accessible via console.\n */\n var vinylGlobal: any\n}\n\n/**\n * For console debugging, gives access to currently active players, logs, and client information.\n */\nexport class VinylGlobal {\n get players() {\n return playerRegistryRef.value.players\n }\n\n /**\n * Returns the first player.\n */\n get player() {\n return playerRegistryRef.value.players[0]\n }\n\n get logs() {\n return historyLogHandler.value?.history\n }\n\n get version() {\n return vinylVersion.str\n }\n\n get userAgentInfo() {\n return getUserAgentInfo()\n }\n\n get network() {\n return getNetworkMetrics()\n }\n\n /**\n * Returns the EWMA low estimate for the client's current bandwidth.\n */\n get bandwidth() {\n return this.network.estimatedDownlinkBandwidth.ewmaLow\n }\n}\n\n/**\n * Set the global vinylGlobal reference for easier console debugging.\n * Intentionally typed as AnyRecord to prevent API usage from code. This is\n * intended only for console debugging and the API may change at any time.\n */\nexport const vinylGlobalRef = /* @__PURE__ */ globalRef((): AnyRecord => {\n global.vinylGlobal = new VinylGlobal()\n return toDisposable(() => {\n delete global.vinylGlobal\n })\n})\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { initializeLogging } from '@amazon/vinyl-util'\nimport { vinylGlobalRef } from './globalRef'\n\nexport function initializeVinylGlobal() {\n initializeLogging()\n vinylGlobalRef.initialize()\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { lazy } from '@amazon/vinyl-util'\nimport { requiresUnreliablePlaybackEventsPatch } from './patches/createUnreliablePlaybackEventsPatch'\nimport { requiresPreventStallsPatch } from './patches/createPreventStallsPatch'\n\nexport interface MediaElementPatchOptions {\n /**\n * Playback events 'playing' and 'waiting' are unreliable after seeking.\n *\n * Risks for false positive: LOW. Timing of emitted playing events may be subtly\n * different, but they will not be duplicated.\n * Risks for false negative: MEDIUM. Certain playback events on affected platforms will be missed.\n */\n readonly unreliablePlaybackEvents?: boolean\n\n /**\n * The affected user agent gets into a state where playback can become stalled and needs help getting unstuck.\n */\n readonly preventStalls?: boolean\n}\n\n/**\n * Aggregates flags for toggling patches.\n */\nexport const defaultMediaElementPatchOptions = /* @__PURE__ */ lazy<\n Required<MediaElementPatchOptions>\n>(() => {\n return {\n unreliablePlaybackEvents: requiresUnreliablePlaybackEventsPatch(),\n preventStalls: requiresPreventStallsPatch(),\n } as const satisfies Required<MediaElementPatchOptions>\n})\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { Browser, hasBrowser, type Timestamp } from '@amazon/vinyl-util'\nimport {\n closeTo,\n createDisposer,\n DomEventHost,\n onAny,\n SignalImpl,\n} from '@amazon/vinyl-util'\nimport type { HtmlMediaElementPatch } from '../HtmlMediaElementPatch'\n\n/**\n * The interval (in seconds) to poll for time progress in a media element.\n *\n * @private\n */\nexport const UNRELIABLE_EVENTS_POLL_INTERVAL = 0.2\n\n/**\n * Minimum amount of time playback must be stalled before fabricating a waiting event.\n */\nexport const MIN_STALLED_BEFORE_FAB = 0.8\n\n/**\n * Minimum amount of time playback must be progressing before fabricating a playing event.\n */\nexport const MIN_PLAYING_BEFORE_FAB = 0.4\n\n/**\n * If currentTime does not change larger than this value, it will be considered to be stalled.\n */\nconst MIN_PLAYING_DELTA = 0.05\n\n/**\n * If currentTime changes beyond this tolerance the apparent state will be considered to be seeking.\n */\nconst MIN_SEEKING_DELTA = 0.5\n\nenum PlayHeadState {\n /**\n * The last time update was an increment from the previous.\n */\n PLAYING,\n\n /**\n * The last time update was close to the previous.\n */\n STOPPED,\n\n /**\n * The last time update was a non-incremental change.\n */\n SEEKING,\n}\n\n/**\n * Playback events such as playing, canPlay, and waiting are unreliable on this platform.\n * Watch playback state and fabricate events when necessary.\n */\nexport function createUnreliablePlaybackEventsPatch(\n media: HTMLMediaElement\n): HtmlMediaElementPatch {\n const { add, dispose } = createDisposer()\n const domEvents = add(new DomEventHost<HTMLMediaElementEventMap>(media))\n const eventFabricated = add(new SignalImpl<Event>())\n\n // The timestamp of the last change.\n let stateChangedAt: Timestamp = Date.now()\n\n // The current observed state based on the play head progress.\n let currentApparentState: PlayHeadState = PlayHeadState.STOPPED\n\n /**\n * @param state The new apparent state.\n * @param changedAt The timestamp the apparent state was changed.\n */\n function setApparentState(\n state: PlayHeadState,\n changedAt: Timestamp = Date.now()\n ) {\n if (currentApparentState !== state) {\n currentApparentState = state\n stateChangedAt = changedAt\n }\n }\n\n /**\n * Returns the number of seconds since the last state change.\n */\n function elapsedStateTime(): number {\n return (Date.now() - stateChangedAt) / 1000\n }\n\n let lastTimestamp: Timestamp = Date.now()\n let lastTime = media.currentTime\n\n let waiting = false\n let seeking = false\n\n onAny(\n domEvents,\n ['emptied', 'ended', 'pause', 'playing', 'seeking'],\n () => {\n waiting = false\n }\n )\n\n let playing = false\n onAny(\n domEvents,\n ['emptied', 'ended', 'pause', 'seeking', 'waiting'],\n () => {\n playing = false\n }\n )\n\n domEvents.on('seeking', () => {\n seeking = true\n })\n domEvents.on('seeked', () => {\n seeking = false\n setApparentState(PlayHeadState.SEEKING)\n })\n domEvents.on('play', () => {\n // Resets the timer so that the !paused state does not immediately trigger a 'waiting' event.\n stateChangedAt = Date.now()\n })\n\n // All events that can affect the ready state.\n // canplay and canplaythrough are handled in the overridden events map.\n const readyStateEvents = [\n 'emptied',\n 'loadeddata',\n 'loadedmetadata',\n 'waiting',\n ] as const\n let lastReadyStateEvent = 'emptied'\n add(\n onAny(domEvents, readyStateEvents, (_, type) => {\n lastReadyStateEvent = type\n })\n )\n\n const checkApparentState = () => {\n const progressed = (media.currentTime - lastTime) / media.playbackRate\n const now = Date.now()\n if (Math.abs(progressed) > MIN_SEEKING_DELTA) {\n setApparentState(PlayHeadState.SEEKING, lastTimestamp)\n } else if (progressed >= MIN_PLAYING_DELTA) {\n setApparentState(PlayHeadState.PLAYING, lastTimestamp)\n } else if (closeTo(progressed, 0, MIN_PLAYING_DELTA)) {\n setApparentState(PlayHeadState.STOPPED, lastTimestamp)\n }\n lastTime = media.currentTime\n lastTimestamp = now\n\n if (\n !playing &&\n !seeking &&\n !media.paused &&\n !media.ended &&\n media.readyState >= media.HAVE_FUTURE_DATA &&\n currentApparentState === PlayHeadState.PLAYING &&\n elapsedStateTime() >= MIN_PLAYING_BEFORE_FAB\n ) {\n // The play head is progressing but a playing event was never observed.\n waiting = false\n playing = true\n\n if (\n lastReadyStateEvent !== 'canplay' &&\n lastReadyStateEvent !== 'canplaythrough'\n ) {\n lastReadyStateEvent = 'canplay'\n eventFabricated.dispatch(new CustomEvent('canplay'))\n }\n if (media.readyState >= media.HAVE_ENOUGH_DATA) {\n if (lastReadyStateEvent !== 'canplaythrough') {\n lastReadyStateEvent = 'canplaythrough'\n eventFabricated.dispatch(new CustomEvent('canplaythrough'))\n }\n }\n eventFabricated.dispatch(new CustomEvent('playing'))\n }\n if (\n !waiting &&\n !media.paused &&\n !media.ended &&\n currentApparentState === PlayHeadState.STOPPED &&\n elapsedStateTime() >= MIN_STALLED_BEFORE_FAB\n ) {\n waiting = true\n playing = false\n // currentTime is not changing; playback has stopped but no 'waiting' event\n // was observed.\n eventFabricated.dispatch(new CustomEvent('waiting'))\n }\n }\n\n const playbackWatchIntervalId = setInterval(\n checkApparentState,\n UNRELIABLE_EVENTS_POLL_INTERVAL * 1000\n )\n add(() => {\n clearInterval(playbackWatchIntervalId)\n })\n return {\n eventFabricated,\n properties: {\n /**\n * Platforms that have unreliable waiting events, also have unreliable ready state\n * when the end of buffered data has been reached. If the media is in a waiting state,\n * the highest ready state that is possible is HAVE_METADATA.\n */\n readyState: {\n get() {\n return waiting\n ? Math.min(media.readyState, media.HAVE_METADATA)\n : media.readyState\n },\n },\n },\n events: {\n canplay(event) {\n // Do not emit the canplay event if one was fabricated.\n const eventOrNull =\n lastReadyStateEvent === 'canplay' ? null : event\n lastReadyStateEvent = 'canplay'\n return eventOrNull\n },\n\n canplaythrough(event) {\n // Do not emit the canplaythrough event if one was fabricated.\n const eventOrNull =\n lastReadyStateEvent === 'canplaythrough' ? null : event\n lastReadyStateEvent = 'canplaythrough'\n return eventOrNull\n },\n\n playing(event) {\n if (playing) {\n // Do not emit the playing event if one was fabricated.\n return null\n }\n setApparentState(PlayHeadState.PLAYING)\n playing = true\n return event\n },\n\n waiting(event) {\n if (waiting) {\n // Do not emit the waiting event if one was fabricated.\n return null\n }\n waiting = true\n setApparentState(PlayHeadState.STOPPED)\n return event\n },\n },\n\n dispose,\n }\n}\n\n/**\n * Chrome <= 53 has unreliable waiting events.\n * Safari, and Edge Legacy miss playing events after seeking.\n */\nexport function requiresUnreliablePlaybackEventsPatch(): boolean {\n return (\n hasBrowser(Browser.SAFARI) ||\n hasBrowser(Browser.EDGE_LEGACY) ||\n hasBrowser(Browser.CHROMIUM, null, '53')\n )\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {\n Browser,\n closeTo,\n createDisposer,\n createLogPrefix,\n DomEventHost,\n hasBrowser,\n logInfo,\n type LogTarget,\n logWarn,\n noop,\n} from '@amazon/vinyl-util'\nimport type { HtmlMediaElementPatch } from '../HtmlMediaElementPatch'\n\n/**\n * The number of timeupdate events stuck at the same position before attempting to jiggle the playhead.\n * @private\n */\nexport const MAX_UNCHANGED_COUNT = 10\n\n/**\n * On affected UAs, playback can become stuck. timeupdate events are observed but playback position is never changing.\n * This patch applies a workaround which will pause and play again after max number of timeupdate events with no\n * actual time progression.\n */\nexport function createPreventStallsPatch(\n media: HTMLMediaElement\n): HtmlMediaElementPatch {\n const { add, dispose } = createDisposer()\n const domEvents = add(new DomEventHost<HTMLMediaElementEventMap>(media))\n const pathTarget: LogTarget = {\n logPrefix: createLogPrefix('createPreventStallsPatch'),\n }\n let unchangedCount = 0\n let attemptedFix = false\n let previousTime = media.currentTime\n domEvents.on('timeupdate', () => {\n if (media.paused) return\n if (closeTo(media.currentTime, previousTime, 0.01)) {\n if (++unchangedCount >= MAX_UNCHANGED_COUNT && !attemptedFix) {\n logWarn(\n pathTarget,\n `Detected stall at time ${media.currentTime}, attempting fix`\n )\n attemptedFix = true\n unchangedCount = 0\n media.pause()\n media.play().catch(noop)\n }\n } else {\n if (attemptedFix) {\n logInfo(pathTarget, 'stall ended')\n attemptedFix = false\n } // Unstuck\n unchangedCount = 0\n previousTime = media.currentTime\n }\n })\n\n return {\n dispose,\n }\n}\n\n/**\n * Returns true if stall detection should be enabled for the current user agent.\n */\nexport function requiresPreventStallsPatch(): boolean {\n return hasBrowser(Browser.EDGE_LEGACY)\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { type PatchedRef, patchTargetFromFlags } from '@amazon/vinyl-util'\nimport type { MediaElementPatchOptions } from './MediaElementPatchOptions'\nimport { createUnreliablePlaybackEventsPatch } from './patches/createUnreliablePlaybackEventsPatch'\nimport { createPreventStallsPatch } from './patches/createPreventStallsPatch'\n\n/**\n * Applies patches corresponding to the patch flags on the given media element.\n *\n * Adds logging for fabricated or squelched events.\n */\nexport function patchMediaElement<\n T extends HTMLMediaElement = HTMLMediaElement,\n>(media: T, options: MediaElementPatchOptions): PatchedRef<T> {\n return patchTargetFromFlags(\n media,\n options,\n ['unreliablePlaybackEvents', createUnreliablePlaybackEventsPatch],\n ['preventStalls', createPreventStallsPatch]\n )\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { ErrorLevel, type Json, ReportableError } from '@amazon/vinyl-util'\nimport { ErrorOrigin } from '@amazon/vinyl-util'\nimport type { ReadonlyRanges } from '@amazon/vinyl-util'\n\n/**\n * An error indicating a seek was out of range.\n * This will have an error level of `ErrorLevel.WARN`.\n * This indicates a bad seek request, but is recoverable.\n */\nexport class InvalidSeekError extends ReportableError {\n get [Symbol.toStringTag](): string {\n return 'InvalidSeekError'\n }\n\n constructor(\n readonly time: number,\n readonly seekable: ReadonlyRanges,\n readonly tolerance: number\n ) {\n super(\n `Could not seek to time: ${time}, outside of seekable ranges ${seekable} with tolerance ${tolerance}`,\n ErrorOrigin.API,\n ErrorLevel.WARN\n )\n Object.setPrototypeOf(this, InvalidSeekError.prototype)\n }\n\n toJSON(): Json {\n return {\n ...super.toJSON(),\n time: this.time,\n seekable: Array.from(this.seekable),\n }\n }\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {\n ErrorLevel,\n ErrorOrigin,\n type Json,\n type Maybe,\n ReportableError,\n} from '@amazon/vinyl-util'\nimport { mediaErrorToJson } from '../logging/mediaErrorToJson'\n\n/**\n * An error from the media element\n */\nexport class ReportableMediaError extends ReportableError {\n // Copied from MediaError to ensure compatibility in Node\n static readonly MEDIA_ERR_ABORTED = 1\n static readonly MEDIA_ERR_NETWORK = 2\n static readonly MEDIA_ERR_DECODE = 3\n static readonly MEDIA_ERR_SRC_NOT_SUPPORTED = 4\n\n get [Symbol.toStringTag](): string {\n return 'ReportableMediaError'\n }\n\n readonly reason: string\n readonly code: number\n\n constructor(error: Maybe<MediaError>) {\n const { name, code, message } = mediaErrorToJson(error)\n const level =\n error == null || code === ReportableMediaError.MEDIA_ERR_ABORTED\n ? ErrorLevel.SILENT\n : ErrorLevel.FATAL\n super(message, ErrorOrigin.MEDIA, level)\n this.reason = name\n this.code = code\n Object.setPrototypeOf(this, ReportableMediaError.prototype)\n }\n\n toJSON(): Json {\n return {\n ...super.toJSON(),\n reason: this.reason,\n code: this.code,\n }\n }\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { Maybe } from '@amazon/vinyl-util'\n\nexport function mediaErrorToJson(error: Maybe<MediaError>): {\n readonly name: string\n readonly message: string\n readonly code: number\n} {\n let message: string = 'An unknown media error has occurred.'\n let name: string = 'UNKNOWN_MEDIA_ERROR'\n let code = -1\n if (error) {\n code = error.code\n switch (error.code) {\n case error.MEDIA_ERR_ABORTED: {\n message = `The requesting of the associated resource was aborted by the user's request.`\n name = 'MEDIA_ERR_ABORTED'\n break\n }\n case error.MEDIA_ERR_NETWORK: {\n message = 'A network error occurred.'\n name = 'MEDIA_ERR_NETWORK'\n break\n }\n case error.MEDIA_ERR_DECODE: {\n name = 'MEDIA_ERR_DECODE'\n message =\n 'An error occurred while trying to decode the media resource.'\n break\n }\n case error.MEDIA_ERR_SRC_NOT_SUPPORTED: {\n name = 'MEDIA_ERR_SRC_NOT_SUPPORTED'\n message = 'The associated resource was not supported.'\n break\n }\n }\n }\n return {\n name,\n message,\n code,\n }\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { Disposable } from '@amazon/vinyl-util'\nimport { createDisposer } from '@amazon/vinyl-util'\nimport { logDebug } from '@amazon/vinyl-util'\nimport type { ReadonlyPlaybackController } from '../ReadonlyPlaybackController'\nimport { ALL_PLAYBACK_STATE_EVENTS } from '../ReadonlyPlaybackController'\nimport { throttle } from '@amazon/vinyl-util'\nimport { substitute } from '@amazon/vinyl-util'\nimport { createLogPrefix, type LogTarget } from '@amazon/vinyl-util'\n\n/**\n * The number of seconds to throttle timeupdate logs.\n * Logs will not be emitted for timeupdate events less than this interval.\n */\nexport const TIMEUPDATE_THROTTLE = 5\n\n/**\n * @private\n */\nconst locale = {\n /**\n * The timeupdate log message when grouping several updates together.\n *\n * Param start - start time\n * Param end - end time\n * Param count - number of events\n */\n timeupdateLogBatch: 'timeUpdate {start}-{end} x{count}',\n} as const\n\n/**\n * Logs all playback state events.\n *\n * @param playbackState The event host with playback events to observe.\n * @return Returns a disposable handle to remove all added handlers.\n */\nexport function playbackStateLoggingHandler(\n playbackState: ReadonlyPlaybackController\n): Disposable {\n const target: LogTarget = {\n logPrefix: createLogPrefix('Playback'),\n }\n const disposer = createDisposer()\n const { add } = disposer\n\n // Log time update events so that sequential time updates are debounced.\n let timeUpdateCount = 0\n let startTime: number | null = null\n\n /**\n * Logs the cumulated timeupdate event counts, resetting the window.\n */\n const logTimeupdateBatch = () => {\n if (startTime == null) return\n const currentTime = playbackState.currentTime\n logDebug(\n target,\n substitute(locale.timeupdateLogBatch, {\n start: startTime.toFixed(1),\n end: currentTime.toFixed(1),\n count: timeUpdateCount,\n })\n )\n timeUpdateCount = 0\n startTime = null\n }\n\n /**\n * Throttles timeupdate logs to the given interval.\n */\n const logTimeupdateBatchThrottled = add(\n throttle(logTimeupdateBatch, TIMEUPDATE_THROTTLE, { trailing: true })\n )\n\n add(\n playbackState.on('timeUpdate', () => {\n timeUpdateCount++\n if (startTime == null) startTime = playbackState.currentTime\n logTimeupdateBatchThrottled()\n })\n )\n\n for (const type of ALL_PLAYBACK_STATE_EVENTS) {\n if (type === 'timeUpdate') continue\n add(\n playbackState.on(type, (event) => {\n logTimeupdateBatch()\n logDebug(target, type, event)\n })\n )\n }\n\n return disposer\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type {\n AnyRecord,\n ReadonlyEventHost,\n ReadonlyRanges,\n Timestamp,\n} from '@amazon/vinyl-util'\nimport type { ChangeEvent } from '../event/ChangeEvent'\nimport type { BasicErrorEvent } from '../event/BasicErrorEvent'\n\nexport interface ProgressEvent {\n readonly loaded: number\n readonly total: number\n}\n\nexport interface OperationCompletedEvent<K> {\n /**\n * The timestamp the operation began.\n */\n readonly started: Timestamp\n\n /**\n * The timestamp the operation completed.\n */\n readonly ended: Timestamp\n\n /**\n * The total number of seconds the operation took.\n */\n readonly duration: number\n\n /**\n * The reason the operation completed.\n */\n readonly reason: K\n}\n\nexport interface PlayedEvent extends OperationCompletedEvent<PlayedReason> {\n /**\n * The total number of seconds elapsed for the track (using `currentTime`).\n */\n readonly playbackTime: number\n}\n\n/**\n * The reason playback has stopped.\n * These are source event types from the media element that all indicate playback has stopped.\n * @see PlaybackControllerEventMap\n */\nexport enum PlayedReason {\n EMPTIED = 'emptied',\n /**\n * Note - 'ended' reason is generally unused, however it is not part of the w3c spec to guarantee a 'pause' event\n * before 'ended'.\n */\n ENDED = 'ended',\n PAUSE = 'pause',\n SEEKING = 'seeking',\n WAITING = 'waiting',\n}\n\n/**\n * A list of all events that cause the 2nd-order 'played' event.\n */\nexport const playedReasons = [\n PlayedReason.EMPTIED,\n PlayedReason.ENDED,\n PlayedReason.PAUSE,\n PlayedReason.SEEKING,\n PlayedReason.WAITING,\n] as const satisfies readonly PlayedReason[]\n\nexport interface PlayRejectedEvent {\n /**\n * The reason for the play() rejection.\n *\n * @see #isNotAllowedError\n */\n reason: any\n}\n\nexport interface PlaybackControllerEventMap {\n /**\n * Fired when the resource was not fully loaded, but not as the result of an error.\n */\n readonly abort: AnyRecord\n\n /**\n * Fired when the user agent can play the media, but estimates that not enough data has been\n * loaded to play the media up to its end without having to stop for further buffering of\n * content.\n *\n * readyState will be at least {@link PlaybackReadyState.HAVE_FUTURE_DATA}\n */\n readonly canPlay: AnyRecord\n\n /**\n * Fired when the user agent can play the media, and estimates that enough data has been\n * loaded to play the media up to its end without having to stop for further buffering of content.\n *\n * readyState will be at least {@link PlaybackReadyState.HAVE_ENOUGH_DATA}\n */\n readonly canPlayThrough: AnyRecord\n\n /**\n * Fired when the duration attribute has been updated.\n */\n readonly durationChange: ChangeEvent<number>\n\n /**\n * Fired when the media has become empty; for example, this event is sent if the media has\n * already been loaded (or partially loaded), and the load() method is called to reload it.\n *\n * readyState will be {@link PlaybackReadyState.HAVE_NOTHING}\n */\n readonly emptied: AnyRecord\n\n /**\n * Fired when playback or streaming has stopped because the end of the media was reached or\n * because no further data is available.\n */\n readonly ended: AnyRecord\n\n /**\n * Dispatched when the media element dispatches an error.\n */\n readonly error: BasicErrorEvent\n\n /**\n * Fired when {@link ReadonlyPlaybackController.playIsPending} has changed.\n */\n readonly playIsPendingChange: ChangeEvent<boolean>\n\n /**\n * Fired when the frame at the current playback position of the media has finished loading;\n * often the first frame.\n *\n * readyState will be at least {@link PlaybackReadyState.HAVE_CURRENT_DATA}\n */\n readonly loadedData: AnyRecord\n\n /**\n * Fired when the metadata has been loaded.\n *\n * readyState will be at least {@link PlaybackReadyState.HAVE_METADATA}\n */\n readonly loadedMetadata: AnyRecord\n\n /**\n * Fired when the browser has started to load a resource.\n */\n readonly loadStart: AnyRecord\n\n /**\n * Fired when {@link ReadonlyPlaybackController.loop} is true and playback has looped to track beginning.\n */\n readonly looped: AnyRecord\n\n /**\n * Fired when the mute status has changed.\n */\n readonly mutedChange: ChangeEvent<boolean>\n\n /**\n * Fired when a request to pause an activity is handled and the activity has entered its paused\n * state, most commonly after the media has been paused through a call to the element's\n * pause() method.\n */\n readonly pause: AnyRecord\n\n /**\n * Fired when the paused property is changed from true to false, as a result of the play\n * method, or the autoplay attribute.\n */\n readonly play: AnyRecord\n\n /**\n * Fired if play() has been attempted, but rejected.\n */\n readonly playRejected: PlayRejectedEvent\n\n /**\n * Fired when playback has stopped, for any reason.\n *\n * When media begins playing, a `playing` event is emitted. If playback stops due to 'pause',\n * 'seeking', 'emptied', 'waiting', or 'ended', then `played` will be fired.\n */\n readonly played: PlayedEvent\n\n /**\n * Fired after playback is first started, and whenever it is restarted. For example, it is\n * fired when playback resumes after having been paused or delayed due to lack of data.\n */\n readonly playing: AnyRecord\n\n /**\n * Fired periodically as the browser loads a resource.\n */\n readonly progress: ProgressEvent\n\n /**\n * Fired when the intrinsic dimensions of the media (e.g. a video's width or\n * height) change, including once they first become known.\n */\n readonly resize: AnyRecord\n\n /**\n * Fired when the playback rate has changed.\n */\n readonly rateChange: ChangeEvent<number>\n\n /**\n * Fired when {@link ReadonlyPlaybackController.readyState} has changed.\n *\n * This is fired when any of the following events have fired:\n * {@link loadedData},\n * {@link loadedMetadata}\n * {@link canPlay}\n * {@link canPlayThrough}\n * {@link emptied}\n * {@link waiting}\n */\n readonly readyStateChange: ChangeEvent<PlaybackReadyState>\n\n /**\n * Fired when a seek operation completed, the current playback position has changed, and the\n * Boolean seeking attribute is changed to false.\n */\n readonly seeked: OperationCompletedEvent<'seeked' | 'playing' | 'emptied'>\n\n /**\n * Fired when a seek operation starts, meaning the Boolean seeking attribute has changed to\n * true and the media is seeking a new position.\n */\n readonly seeking: AnyRecord\n\n /**\n * Fired when the time indicated by the currentTime attribute has been updated.\n */\n readonly timeUpdate: ChangeEvent<number>\n\n /**\n * Fired when the volume has changed.\n */\n readonly volumeChange: ChangeEvent<number>\n\n /**\n * Fired when playback has stopped because of a temporary lack of data.\n *\n * Note: this includes during initial loading or after a seek and data is needed to buffer.\n * Will not be emitted when paused.\n */\n readonly waiting: AnyRecord\n\n /**\n * Fired when waiting has completed.\n * This will be emitted after a waiting event when playback has resumed, paused, or unloaded.\n */\n readonly waited: OperationCompletedEvent<WaitedReason>\n\n /**\n * Playback is blocked waiting for a key.\n */\n readonly waitingForKey: AnyRecord\n\n /**\n * Emitted when the error state has been reset.\n */\n readonly reset: AnyRecord\n}\n\n/**\n * Reasons why a 'waiting' operation has ended.\n */\nexport enum WaitedReason {\n PLAYING = 'playing',\n PAUSE = 'pause',\n EMPTIED = 'emptied',\n SEEKING = 'seeking',\n}\n\n/**\n * A list of all events that cause the 2nd-order 'waited' event.\n */\nexport const waitedReasons = [\n WaitedReason.PLAYING,\n WaitedReason.PAUSE,\n WaitedReason.EMPTIED,\n WaitedReason.SEEKING,\n] as const satisfies readonly WaitedReason[]\n\nexport const ALL_PLAYBACK_STATE_EVENTS = [\n 'abort',\n 'canPlay',\n 'canPlayThrough',\n 'durationChange',\n 'emptied',\n 'ended',\n 'error',\n 'playIsPendingChange',\n 'loadedData',\n 'loadedMetadata',\n 'loadStart',\n 'looped',\n 'mutedChange',\n 'pause',\n 'play',\n 'playRejected',\n 'played',\n 'playing',\n 'progress',\n 'rateChange',\n 'readyStateChange',\n 'reset',\n 'resize',\n 'seeked',\n 'seeking',\n 'timeUpdate',\n 'volumeChange',\n 'waited',\n 'waiting',\n 'waitingForKey',\n] as const satisfies readonly (keyof PlaybackControllerEventMap)[]\n\nexport enum PlaybackReadyState {\n /**\n * No information is available about the media resource.\n *\n * readyState will be this after `emptied`\n */\n HAVE_NOTHING = 0,\n\n /**\n * Enough of the media resource has been retrieved that the metadata attributes are initialized\n * Seeking will no longer raise an exception.\n *\n * readyState will be at least this after `loadedMetadata`\n */\n HAVE_METADATA = 1,\n\n /**\n * Data is available for the current playback position, but not enough to actually play more\n * than one frame.\n *\n * readyState will be at least this after `loadedData`\n */\n HAVE_CURRENT_DATA = 2,\n\n /**\n * Data for the current playback position as well as for at least a little bit of time into the\n * future is available (in other words, at least two frames of video, for example).\n *\n * readyState will be at least this after `canPlay`\n */\n HAVE_FUTURE_DATA = 3,\n\n /**\n * Enough data is available\u2014and the download rate is high enough\u2014that the media can be played\n * through to the end without interruption.\n *\n * readyState will be at least this after `canPlayThrough`\n */\n HAVE_ENOUGH_DATA = 4,\n}\n\n/**\n * An enumeration of possible networkState values on a media element.\n */\nexport enum PlaybackNetworkState {\n /**\n * There is no data yet. Also, readyState is HAVE_NOTHING.\n */\n NETWORK_EMPTY = 0,\n\n /**\n * HTMLMediaElement is active and has selected a resource, but is not using the network.\n */\n NETWORK_IDLE = 1,\n\n /**\n * The browser is downloading HTMLMediaElement data.\n */\n NETWORK_LOADING = 2,\n\n /**\n * No HTMLMediaElement src found.\n */\n NETWORK_NO_SOURCE = 3,\n}\n\nexport interface ReadonlyPlaybackController extends ReadonlyEventHost<PlaybackControllerEventMap> {\n /**\n * Returns a new static normalized ReadonlyRanges object that represents the ranges of the\n * media resource, if any, that the user agent has buffered at the moment the buffered\n * property is accessed.\n *\n * Note: `ReadonlyRanges` is a view to the DOM `TimeRanges` object.\n */\n readonly buffered: ReadonlyRanges\n\n /**\n * True if the {@link readyState} is {@link PlaybackReadyState.HAVE_FUTURE_DATA}\n * This will be true after a {@link PlaybackControllerEventMap.canPlay} event.\n *\n * Note that security permissions may not allow a track to load past metadata before there has\n * been a user interaction. This should not be relied upon before invoking\n * {@link PlaybackController.play}.\n */\n readonly canPlay: boolean\n\n /**\n * True if the {@link readyState} is {@link PlaybackReadyState.HAVE_ENOUGH_DATA}\n * This will be true after a {@link PlaybackControllerEventMap.canPlayThrough} event.\n *\n * Note that security permissions may not allow a track to load past metadata before there has\n * been a user interaction. This should not be relied upon before invoking\n * {@link PlaybackController.play}.\n */\n readonly canPlayThrough: boolean\n\n /**\n * The current playback time in seconds.\n * When changed, a 'timeUpdate' event is emitted.\n */\n readonly currentTime: number\n\n /**\n * Returns current time as a percent of the total duration.\n *\n * @return A number between 0-1\n */\n readonly currentTimePercent: number\n\n /**\n * The default playback rate when the user is not using fast forward or reverse for a\n * video or audio resource.\n */\n readonly defaultPlaybackRate: number\n\n /**\n * The length of the element's media in seconds.\n * Observe changes with `durationChange` events.\n */\n readonly duration: number\n\n /**\n * Indicates whether the media element has ended playback.\n */\n readonly ended: boolean\n\n /**\n * The Error object for the most recent error, or null if there has not been an error.\n * When an error event is received by the element, you can determine details about what\n * happened by examining this object.\n */\n readonly error: Error | null\n\n /**\n * True if the {@link readyState} is at least {@link PlaybackReadyState.HAVE_METADATA}\n *\n * This will be true after a {@link PlaybackControllerEventMap.loadedMetadata} event and\n * false after an {@link PlaybackControllerEventMap.emptied} event.\n */\n readonly hasMetadata: boolean\n\n /**\n * Controls whether the media element should start over when it reaches the end.\n */\n readonly loop: boolean\n\n /**\n * Indicates whether the media element muted.\n * Observe changes with `mutedChange` events.\n */\n readonly muted: boolean\n\n /**\n * Indicates the current state of the fetching of media over the network.\n */\n readonly networkState: PlaybackNetworkState\n\n /**\n * Indicates whether the media element is paused.\n * Observe changes with `play` and `pause` events.\n */\n readonly paused: boolean\n\n /**\n * Sets the rate at which the media is being played back. This is used to implement user\n * controls for fast-forward, slow motion, and so forth. The normal playback rate is\n * multiplied by this value to obtain the current rate, so a value of 1.0 indicates normal\n * speed.\n */\n readonly playbackRate: number\n\n /**\n * True if playback has started, is not paused, stalled, or seeking.\n * Observe changes with 'playing' and 'played' events.\n */\n readonly playing: boolean\n\n /**\n * True if `play` has been called and the returned promise is currently in a pending state.\n * Observe changes with {@link PlaybackControllerEventMap.playIsPendingChange} events.\n */\n readonly playIsPending: boolean\n\n /**\n * Determines whether the browser should adjust the pitch of the audio to compensate\n * for changes to the playback rate.\n * Default: true\n */\n readonly preservesPitch: boolean\n\n /**\n * Indicates the readiness state of the media.\n * Observe changes with {@link PlaybackControllerEventMap.readyStateChange} events.\n */\n readonly readyState: PlaybackReadyState\n\n /**\n * Returns a new static normalized `ReadonlyRanges` object that represents the ranges of the\n * media resource, if any, that the user agent is able to seek to at the time seekable\n * property is accessed.\n *\n * Note: `ReadonlyRanges` is a view to the DOM `TimeRanges` object.\n */\n readonly seekable: ReadonlyRanges\n\n /**\n * True if the element is currently seeking.\n * Observe changes with `seeking` and `seeked` events.\n */\n readonly seeking: boolean\n\n /**\n * The volume level for audio portions of the media element.\n * Observe changes with `volumeChange` events.\n */\n readonly volume: number\n\n /**\n * True if playback is stopped due to waiting for data.\n * Observe changes with `waiting` and `waited` events.\n */\n readonly waiting: boolean\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { createDisposer, type LogTarget } from '@amazon/vinyl-util'\nimport {\n logDebug,\n createLogPrefix,\n EventHostImpl,\n closeTo,\n} from '@amazon/vinyl-util'\nimport type {\n LoudnessNormalizationController,\n LoudnessNormalizationControllerEventMap,\n} from './LoudnessNormalizationController'\nimport {\n defaultLoudnessNormalizationControllerImplOptions,\n type LoudnessNormalizationControllerImplOptions,\n} from './LoudnessNormalizationControllerImplOptions'\nimport type { ObservableValue } from '@amazon/vinyl-observable'\n\nexport type LoudnessNormalizationControllerImplDeps = {\n readonly options: ObservableValue<LoudnessNormalizationControllerImplOptions>\n}\n\nconst DECIBEL_EXPONENT_BASE = /* @__PURE__ */ Math.pow(10, 1 / 10)\nconst MAX_GAIN_LEVEL = 1.0\n\n/**\n * Applies gain adjustment based on track loudness metadata from manifest.\n * This controller normalizes audio loudness to a target level for consistent playback volume.\n */\nexport class LoudnessNormalizationControllerImpl\n extends EventHostImpl<LoudnessNormalizationControllerEventMap>\n implements LoudnessNormalizationController, LogTarget\n{\n get [Symbol.toStringTag](): string {\n return 'LoudnessNormalizationControllerImpl'\n }\n readonly logPrefix = /* @__PURE__ */ createLogPrefix(this)\n\n private _gain: number = MAX_GAIN_LEVEL\n private readonly disposer = /* @__PURE__ */ createDisposer()\n\n private trackLoudness: number | null = null\n private _options: Required<LoudnessNormalizationControllerImplOptions> =\n defaultLoudnessNormalizationControllerImplOptions\n\n constructor(\n private readonly deps: LoudnessNormalizationControllerImplDeps\n ) {\n super()\n const { add } = this.disposer\n add(\n deps.options.onData((value) => {\n this._options = {\n ...defaultLoudnessNormalizationControllerImplOptions,\n ...value,\n }\n this.updateGain()\n })\n )\n }\n\n get options(): Required<LoudnessNormalizationControllerImplOptions> {\n return this._options\n }\n\n setTrackLoudness(value: number | null): void {\n this.trackLoudness = value\n this.updateGain()\n }\n\n /**\n * Returns the loudness gain value which needs to be applied, for current track playback.\n */\n public get gain(): number {\n return this._gain\n }\n\n /**\n * Sets the loudness gain value for current track playback.\n *\n * @param value New gain value to apply\n */\n private set gain(value: number) {\n const previousGain = this._gain\n // Emit change event if gain value changed\n if (!closeTo(previousGain, value)) {\n this._gain = value\n logDebug(this, 'loudness gain adjustment:', {\n trackLoudness: this.trackLoudness,\n targetLufs: this.options.targetLufs,\n gain: value,\n })\n this.dispatch('change', {})\n }\n }\n\n /**\n * Update gain value based on current track loudness and target loudness.\n */\n private updateGain(): void {\n const { targetLufs, maxGainDb, enabled } = this.options\n const trackLoudness = this.trackLoudness\n if (trackLoudness == null) {\n return\n }\n if (trackLoudness <= targetLufs || !enabled) {\n this.clear()\n return\n }\n // Calculate gain reduction for louder tracks\n const dbReduction = Math.min(trackLoudness - targetLufs, maxGainDb)\n this.gain =\n MAX_GAIN_LEVEL / Math.pow(DECIBEL_EXPONENT_BASE, dbReduction)\n }\n\n /**\n * Resets the loudness gain Value to max gain value.\n */\n clear(): void {\n this.gain = MAX_GAIN_LEVEL\n }\n\n dispose(): void {\n super.dispose()\n this.disposer.dispose()\n }\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { ObjectSchema } from '@amazon/vinyl-validation'\nimport { boolean, number, object } from '@amazon/vinyl-validation'\n\n/**\n * Options for configuring the loudness normalization controller.\n */\nexport interface LoudnessNormalizationControllerImplOptions {\n /**\n * If true, applies loudness Normalization to the current track played.\n * Default: false\n */\n readonly enabled: boolean\n\n /**\n * Target loudness level in LUFS (Loudness Units relative to Full Scale).\n * Default: -14.0 dB\n */\n readonly targetLufs?: number\n\n /**\n * Maximum gain reduction to apply in dB.\n * Default: 10 Db\n */\n readonly maxGainDb?: number\n}\n\nexport const defaultLoudnessNormalizationControllerImplOptions = {\n enabled: false,\n targetLufs: -14.0,\n maxGainDb: 10.0,\n} as const satisfies LoudnessNormalizationControllerImplOptions\n\nexport const loudnessNormalizationControllerImplOptionsValidator: ObjectSchema<LoudnessNormalizationControllerImplOptions> =\n /* @__PURE__ */ object({\n enabled: /* @__PURE__ */ boolean(),\n targetLufs: /* @__PURE__ */ /* @__PURE__ */ number().optional(),\n maxGainDb: /* @__PURE__ */ /* @__PURE__ */ number().optional(),\n })\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type {\n PlaybackControllerEventMap,\n ReadonlyPlaybackController,\n} from './ReadonlyPlaybackController'\nimport {\n type AnyRecord,\n nextEventAsPromise,\n type NextEventAsPromiseOptions,\n} from '@amazon/vinyl-util'\n\nexport function nextHasMetadata(\n controller: ReadonlyPlaybackController,\n options?: NextEventAsPromiseOptions<\n PlaybackControllerEventMap,\n 'loadedMetadata'\n >\n): Promise<AnyRecord> {\n if (controller.hasMetadata) return Promise.resolve({})\n return nextEventAsPromise(controller, 'loadedMetadata', options)\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { ReadonlyPlaybackController } from './ReadonlyPlaybackController'\n\nexport interface PlaybackController extends ReadonlyPlaybackController {\n defaultPlaybackRate: number\n loop: boolean\n muted: boolean\n playbackRate: number\n preservesPitch: boolean\n volume: number\n\n /**\n * Pauses playback of the media, if the media is already in a paused state\n * this method will have no effect.\n * If a play is pending, the play will be aborted and the promise returned by play() will be\n * rejected.\n *\n * @see pendingPlay\n * @see play\n */\n pause(): void\n\n /**\n * Attempts to begin playback of the media. It returns a Promise which is resolved when\n * playback has been successfully started.\n *\n * Failure to begin playback for any reason, such as permission issues or interruption via\n * pause, results in the promise being rejected.\n *\n * The first time play() is invoked, except muted video, should be in response to a user\n * interaction such as a button click.\n *\n * @see isNotAllowedError\n */\n play(): Promise<void>\n\n /**\n * Safely seeks to the given time.\n * The seek will begin only after {@link readyState} is at least\n * {@link PlaybackReadyState.HAVE_METADATA}.\n * If a previous seek was still pending, the previous seek will be ignored.\n * Returns a Promise that resolves when the seek has completed. If the seek is interrupted\n * by another seek, the promise will be rejected with an `AbortError`.\n * If the seek is not to a seekable range, the promise will reject with an {@link InvalidSeekError}.\n *\n * @param time The value, in seconds, to set the playback time.\n * @param tolerance The amount of tolerance to have when the time is outside the seekable\n * ranges to snap, in seconds. If time is outside all seekable ranges beyond this tolerance,\n * the seek will be ignored. Default: 0.5\n */\n seekTo(time: number, tolerance?: number): Promise<void>\n\n /**\n * Resets the error state.\n */\n reset(): void\n}\n\n/**\n * The maximum duration media can be before it is considered 'live'.\n */\nexport const LIVE_DURATION = 4294967296 // 2 ** 32\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {\n Abort,\n AbortError,\n Browser,\n clamp,\n closeTo,\n createDisposer,\n createTimeRangesReader,\n DomEventHost,\n ErrorLevel,\n ErrorOrigin,\n EventHostImpl,\n getUserAgentInfo,\n hasBrowser,\n logDebug,\n logInfo,\n logWarn,\n nextEventAsPromise,\n onAny,\n ownKeys,\n type ReadonlyEventHost,\n type ReadonlyRanges,\n TimeoutSlot,\n toLowerCase,\n withAbort,\n withTimeout,\n} from '@amazon/vinyl-util'\nimport { LIVE_DURATION, type PlaybackController } from './PlaybackController'\nimport {\n type PlaybackControllerEventMap,\n PlaybackReadyState,\n playedReasons,\n waitedReasons,\n} from './ReadonlyPlaybackController'\nimport { InvalidSeekError } from './error/InvalidSeekError'\nimport { playbackStateLoggingHandler } from './logging/playbackStateLoggingHandler'\nimport { createChangeEventTrigger } from '../event/ChangeEvent'\nimport { nextHasMetadata } from './nextHasMetadata'\nimport type { LoudnessNormalizationController } from './loudness/LoudnessNormalizationController'\nimport { ReportableMediaError } from './error/ReportableMediaError'\n\nexport interface PlaybackControllerImplOptions {\n /**\n * An affordance when comparing the last currentTime and the new currentTime after a seek.\n * Most browsers have around 30-40 time updates per second, but some constrained devices only\n * have a few. This value needs to be large enough where the last timeupdate in a looping track\n * is at currentTime >= duration - LOOP_TIME_AFFORDANCE.\n * Default: 2\n */\n readonly loopTimeAffordance: number\n\n /**\n * The minimum number of seconds before the end of the next seekable range allowed for a seek\n * operation. Some browsers will never complete a seek operation if the seek is too close to\n * this end range.\n * Default: getMinSeekableBufferDefault() which is between 0.5 and 5, browser dependent.\n */\n readonly minSeekableBuffer: number\n\n /**\n * The number of seconds before the promise returned by play() is rejected regardless whether\n * the media element response has settled.\n * Default: 30\n */\n readonly playTimeout: number\n\n /**\n * The number of seconds before the promise returned by seek() is rejected.\n * Default: 30\n */\n readonly seekTimeout: number\n}\n\nexport const defaultPlaybackControllerImplOptions = {\n loopTimeAffordance: 2,\n minSeekableBuffer: -1, // Default comes from getMinSeekableBufferDefault()\n playTimeout: 30,\n seekTimeout: 30,\n} as const satisfies PlaybackControllerImplOptions\n\n/**\n * Safari and Edge Legacy cannot reliably seek close to the end of a seekable range.\n * Firefox can but if the playhead reaches the end of track before the media stream is closed, an 'ended' event\n * will never fire.\n */\nexport function getMinSeekableBufferDefault() {\n return !hasBrowser(Browser.CHROMIUM) ? 5 : 2\n}\n\nexport interface PlaybackControllerImplDeps {\n readonly media: HTMLMediaElement\n readonly loudnessNormalizationController: LoudnessNormalizationController\n}\n\nexport class PlaybackControllerImpl\n extends EventHostImpl<PlaybackControllerEventMap>\n implements PlaybackController\n{\n private readonly loudnessNormalizationController: LoudnessNormalizationController\n get [Symbol.toStringTag](): string {\n return 'PlaybackControllerImpl'\n }\n\n private _error: Error | null = null\n private readonly media: HTMLMediaElement\n private readonly domEvents: DomEventHost<HTMLMediaElementEventMap>\n private readonly disposer = /* @__PURE__ */ createDisposer()\n private _playing = false\n private _seeking = false\n private _waiting = false\n\n // Monotonic counter identifying the most recent seekTo call.\n private _seekId = 0\n\n // default user volume (0.0 to 1.0 scale)\n private userVolume: number = 1.0\n private _pendingPlay: Promise<void> | null = null\n private playAbort: Abort | null = null\n private disposeAbort = /* @__PURE__ */ new Abort()\n\n readonly options: PlaybackControllerImplOptions\n\n constructor(\n deps: PlaybackControllerImplDeps,\n options?: Partial<PlaybackControllerImplOptions>\n ) {\n super()\n this.options = {\n ...defaultPlaybackControllerImplOptions,\n minSeekableBuffer: getMinSeekableBufferDefault(),\n ...options,\n }\n this.loudnessNormalizationController =\n deps.loudnessNormalizationController\n logInfo(this, 'constructed', this.options)\n this.media = deps.media\n\n const { add } = this.disposer\n add(() => {\n this.disposeAbort.abort()\n this.disposeAbort.dispose()\n })\n\n this.domEvents = add(\n new DomEventHost<HTMLMediaElementEventMap>(deps.media)\n )\n\n // Log media events.\n add(playbackStateLoggingHandler(this))\n\n // Reports media errors\n this.domEvents.on('error', (_) => {\n const error = new ReportableMediaError(this.media.error)\n if (error.level === ErrorLevel.SILENT) {\n // Not a fatal error, log and ignore\n logInfo(this, error.message)\n return\n }\n this._error = error\n this.dispatch('error', {\n target: this,\n error,\n })\n })\n\n this.initializeEvents()\n\n // Listen for loudness normalization changes\n add(\n this.loudnessNormalizationController.on('change', () => {\n this.refreshVolume()\n })\n )\n }\n\n /**\n * Updates volume with loudness gain, on the mediaElement.\n * @private\n */\n private refreshVolume(): void {\n const effectiveVolume =\n this.userVolume * this.loudnessNormalizationController.gain\n this.media.volume = Math.min(1.0, effectiveVolume) // valid range (0-1)\n logDebug(this, 'refreshVolume', {\n userVolume: this.userVolume,\n lnGain: this.loudnessNormalizationController.gain,\n effectiveVolume: this.media.volume,\n })\n }\n\n /**\n * Listens to select events on the media element, redispatching as playback state events.\n * @private\n */\n private initializeEvents() {\n this.initializePlainEvents()\n this.initializeChangeEvents()\n this.initializeOperationEvents()\n this.initializeMutedEvent()\n this.initializeLoopedEvent()\n this.initializeReadyStateChangeEvent()\n }\n\n /**\n * Re-dispatches the plain DOM events without extra information.\n *\n * @private\n */\n private initializePlainEvents() {\n // Re-dispatch html media element events exposed on the playback controller as empty events.\n for (const key of [\n 'abort',\n 'canPlay',\n 'canPlayThrough',\n 'emptied',\n 'ended',\n 'loadStart',\n 'loadedData',\n 'loadedMetadata',\n 'pause',\n 'play',\n 'playing',\n 'resize',\n 'seeking',\n 'waiting',\n 'waitingForKey',\n ] as const) {\n this.domEvents.on(toLowerCase(key), () => this.dispatch(key, {}))\n }\n\n // Keep specific event information for progress events.\n\n this.domEvents.on('progress', (e) => {\n this.dispatch('progress', { loaded: e.loaded, total: e.total })\n })\n }\n\n /**\n * Delegates the DOM events with additional information about what the previous and current\n * values are.\n * @private\n */\n private initializeChangeEvents() {\n const changeEventGetters = {\n durationChange: () => this.duration,\n timeUpdate: () => this.currentTime,\n volumeChange: () => this.volume,\n rateChange: () => this.playbackRate,\n } as const\n for (const key of ownKeys(changeEventGetters)) {\n this.domEvents.on(\n toLowerCase(key),\n createChangeEventTrigger(changeEventGetters[key], (event) => {\n this.dispatch(key, event)\n })\n )\n }\n }\n\n /**\n * Operation events provide an easy way to listen for the terminus of a state.\n * For example after a 'waiting' event, there are several different events that indicate that\n * the waiting has finished, and this API provides those events conflated into a single\n * 'waited' event.\n * @private\n */\n private initializeOperationEvents() {\n // seeking state + seeked event\n // media element has a seeked event, add operation details and set state.\n this.operationEvent(\n this.domEvents,\n 'seeking',\n // A seeked event may not be emitted in certain cases such as changing tracks before the seek can finish.\n ['seeked', 'emptied'],\n () => (this._seeking = true),\n (info) => {\n this._seeking = false\n this.dispatch('seeked', info)\n }\n )\n\n // waiting state + waited event\n this.operationEvent(\n this,\n 'waiting',\n waitedReasons,\n () => (this._waiting = true),\n (info) => {\n this._waiting = false\n this.dispatch('waited', info)\n }\n )\n\n // Only advance the observed position forward; a backward timeUpdate\n // (e.g. one arriving just before a backward seek) must not shrink a\n // play's measured progress.\n let lastKnownTime = this.currentTime\n this.on('timeUpdate', () => {\n if (this.currentTime > lastKnownTime)\n lastKnownTime = this.currentTime\n })\n\n // playing state + played event\n let startedTime = 0\n this.operationEvent(\n this,\n 'playing',\n playedReasons,\n () => {\n this._playing = true\n startedTime = this.currentTime\n lastKnownTime = startedTime\n },\n (info) => {\n this._playing = false\n this.dispatch('played', {\n ...info,\n playbackTime: lastKnownTime - startedTime,\n })\n }\n )\n }\n\n /**\n * When going into a state from a beginEvent, dispatches endEvent when any of the endEvents\n * is dispatched.\n *\n * This allows consumers of the playback state to listen for the exit of a state without\n * needing to know every event that ends that state.\n *\n * @param host The event host emitting the primary events.\n * @param beginEvent The event that enters a state.\n * @param endEvents A list of events that exits the entered state.\n * @param onBegin Invoked when the operation has begun.\n * @param onEnd Invoked when the operation has completed.\n */\n private operationEvent<EventMap, const EndEvent extends keyof EventMap>(\n host: ReadonlyEventHost<EventMap>,\n beginEvent: keyof EventMap,\n endEvents: readonly EndEvent[],\n onBegin: () => void,\n onEnd: (info: {\n started: number\n ended: number\n duration: number\n reason: EndEvent\n }) => void\n ) {\n let startedAt = 0\n let started = false\n host.on(beginEvent, () => {\n onBegin()\n started = true\n startedAt = Date.now()\n })\n onAny(host, endEvents, (_, event) => {\n if (started) {\n started = false\n const now = Date.now()\n onEnd({\n started: startedAt,\n ended: now,\n duration: (now - startedAt) / 1000,\n reason: event,\n })\n }\n })\n }\n\n /**\n * Dispatches a 'mutedChange' event when 'muted' state has changed.\n *\n * The DOM element only provides a 'volumeChange' event, which is filtered to watch when\n * muted has changed.\n *\n * @private\n */\n private initializeMutedEvent() {\n const { add } = this.disposer\n let previousMuted = this.muted\n\n // Dispatches a mutedChange event if the muted property changed since the last check.\n const maybeDispatchMutedChange = () => {\n if (this.muted === previousMuted) return\n previousMuted = this.muted\n this.dispatch('mutedChange', {\n previous: !this.muted,\n current: this.muted,\n })\n }\n const mutedTimeoutSlot = add(new TimeoutSlot())\n this.on('volumeChange', () => {\n maybeDispatchMutedChange()\n // The volumechange event may be emitted before the muted property change.\n // This has been observed on legacy edge and as a rare occurrence for Chrome.\n mutedTimeoutSlot.set(maybeDispatchMutedChange, 0.2)\n })\n }\n\n /**\n * Dispatches a looped event if loop is true and playback wraps back to the start.\n * Safari emits timeupdate events at duration and then 0 before the seeking event\n * Other browsers emit the seeking before the timeupdate near zero.\n * Firefox timeupdate after the loop is near zero, not exactly.\n *\n * @private\n */\n private initializeLoopedEvent() {\n let lastTime = 0\n this.on('timeUpdate', () => {\n if (\n this.loop &&\n !this.paused &&\n this.currentTime <= this.options.loopTimeAffordance &&\n lastTime >= this.duration - this.options.loopTimeAffordance\n ) {\n if (getUserAgentInfo().browserLike?.name === Browser.FIREFOX) {\n // Firefox does not emit a 'playing' event after a loop, fabricate one.\n logDebug(this, 'fabricating Firefox playing event on loop')\n this.dispatch('playing', {})\n }\n this.dispatch('looped', {})\n }\n lastTime = this.currentTime\n })\n }\n\n get buffered(): ReadonlyRanges {\n return createTimeRangesReader(this.media.buffered)\n }\n\n get currentTime(): number {\n return this.media.currentTime\n }\n\n get currentTimePercent(): number {\n return this.duration > 0 ? this.currentTime / this.duration : 0\n }\n\n get defaultPlaybackRate(): number {\n return this.media.defaultPlaybackRate\n }\n\n set defaultPlaybackRate(value: number) {\n logDebug(this, `defaultPlaybackRate set to ${value}`)\n this.media.defaultPlaybackRate = value\n }\n\n get duration(): number {\n if (this.media.duration >= LIVE_DURATION)\n return Number.POSITIVE_INFINITY\n return this.media.duration\n }\n\n get ended(): boolean {\n return this.media.ended\n }\n\n get error(): Error | null {\n return this._error\n }\n\n get loop(): boolean {\n return this.media.loop\n }\n\n set loop(value: boolean) {\n logDebug(this, `loop set to ${value}`)\n this.media.loop = value\n }\n\n get muted(): boolean {\n return this.media.muted\n }\n\n set muted(value: boolean) {\n logDebug(this, `muted set to ${value}`)\n this.media.muted = value\n }\n\n get networkState(): number {\n return this.media.networkState\n }\n\n get paused(): boolean {\n return this.media.paused\n }\n\n get playbackRate(): number {\n return this.media.playbackRate\n }\n\n set playbackRate(value: number) {\n logDebug(this, `playbackRate set to ${value}`)\n this.media.playbackRate = value\n }\n\n get playing(): boolean {\n return this._playing\n }\n\n get preservesPitch(): boolean {\n return this.media.preservesPitch\n }\n\n set preservesPitch(value: boolean) {\n logDebug(this, `preservesPitch set to ${value}`)\n this.media.preservesPitch = value\n }\n\n get readyState(): PlaybackReadyState {\n return this.media.readyState\n }\n\n get seekable(): ReadonlyRanges {\n return createTimeRangesReader(this.media.seekable)\n }\n\n get seeking(): boolean {\n return this._seeking\n }\n\n get volume(): number {\n return this.userVolume\n }\n\n set volume(value: number) {\n logDebug(this, `volume set to ${value}`)\n this.userVolume = value\n this.refreshVolume()\n }\n\n get waiting(): boolean {\n return this._waiting\n }\n\n pause(): void {\n logDebug(this, 'pause')\n this.playAbort?.abort(\n new AbortError(\n 'The play() request was interrupted by a call to pause().'\n )\n )\n this.pendingPlay = null\n this.media.pause()\n }\n\n private get pendingPlay(): Promise<void> | null {\n return this._pendingPlay\n }\n\n private set pendingPlay(value: Promise<void> | null) {\n this._pendingPlay = value\n this.dispatch('playIsPendingChange', {\n previous: value == null,\n current: value != null,\n })\n }\n\n play(): Promise<void> {\n logDebug(this, 'play')\n if (!this.pendingPlay) {\n const playAbort = new Abort()\n this.playAbort = playAbort\n this.pendingPlay = withAbort(\n (async () => {\n await nextHasMetadata(this)\n playAbort.throwIfAborted()\n await withTimeout(\n this.media.play(),\n this.options.playTimeout,\n {\n message: 'play() timed out after {time}s',\n origin: ErrorOrigin.INTERNAL,\n level: ErrorLevel.SILENT,\n }\n )\n })(),\n playAbort\n )\n .catch((reason) => {\n this.dispatch('playRejected', { reason })\n throw reason\n })\n .finally(() => {\n this.pendingPlay = null\n this.playAbort = null\n })\n }\n return this.pendingPlay\n }\n\n get canPlay(): boolean {\n return this.readyState >= PlaybackReadyState.HAVE_FUTURE_DATA\n }\n\n get canPlayThrough(): boolean {\n return this.readyState >= PlaybackReadyState.HAVE_ENOUGH_DATA\n }\n\n get hasMetadata(): boolean {\n return this.readyState >= PlaybackReadyState.HAVE_METADATA\n }\n\n get playIsPending(): boolean {\n return this.pendingPlay != null\n }\n\n async seekTo(time: number, tolerance = 0.5): Promise<void> {\n logDebug(this, `seekTo: ${time}`)\n // Claim this seek as the newest. A seek that parks on an await (e.g. waiting for loadedMetadata) can resume\n // AFTER a later-issued seek has already applied its target.\n const seekId = ++this._seekId\n const superseded = (): boolean => {\n if (this._seekId === seekId) return false\n logDebug(this, `seekTo: ${time} superseded by a newer seek`)\n return true\n }\n const nextEvent = <K extends keyof PlaybackControllerEventMap>(\n type: K\n ): Promise<PlaybackControllerEventMap[K]> => {\n return nextEventAsPromise(this, type, {\n timeout: this.options.seekTimeout,\n timeoutMessage: `seek timed out on ${type} event after {time}s`,\n timeoutOrigin: ErrorOrigin.INTERNAL,\n timeoutLevel: ErrorLevel.WARN,\n abort: this.disposeAbort,\n })\n }\n\n // Cannot seek until there are seekable ranges.\n if (!this.hasMetadata) {\n await nextEvent('loadedMetadata')\n // A newer seek was issued while we waited \u2014 it already applied (or\n // will apply) its target. Don't overwrite it with this stale one.\n if (superseded()) return\n }\n\n const seekable = this.seekable\n const range = seekable.getRangeAt(\n clamp(time, 0, this.duration),\n tolerance\n )\n if (range == null) {\n logWarn(\n this,\n `seekTo: seek outside of seekable ranges, seek ignored`,\n seekable.ranges\n )\n throw new InvalidSeekError(time, seekable, tolerance)\n }\n // The end-of-range buffer exists only so playback can resume near the\n // end; when paused there's nothing to keep playing, so allow seeking\n // right up to the range end.\n const seekableBuffer = this.paused ? 0 : this.options.minSeekableBuffer\n const clampedTime = Math.max(\n Math.min(time, range[1] - seekableBuffer),\n range[0]\n )\n\n // No-op check\n\n logDebug(\n this,\n `seekTo operation, requested: ${time}, actual: ${clampedTime}`\n )\n\n if (closeTo(clampedTime, this.currentTime, tolerance)) {\n // Within tolerance of the currentTime, no seek needed.\n logDebug(\n this,\n `seekTo: requested: ${time}, actual: ${clampedTime} no-op`\n )\n } else {\n const seeking = nextEvent('seeking')\n this.media.currentTime = clampedTime\n await seeking\n const seekedEvent = await nextEvent('seeked')\n if (seekedEvent.reason === 'emptied') {\n // Seek finished due to track unloading. Abort any pending seek.\n throw new AbortError()\n }\n }\n }\n\n /**\n * Dispatches a readyStateChange event when {@link readyState} changes.\n * @private\n */\n private initializeReadyStateChangeEvent() {\n let previous = this.readyState\n onAny(\n this,\n [\n 'canPlay',\n 'canPlayThrough',\n 'emptied',\n 'loadedData',\n 'loadedMetadata',\n 'waiting',\n ],\n () => {\n const current = this.readyState\n if (previous !== current) {\n this.dispatch('readyStateChange', {\n previous,\n current,\n })\n previous = this.readyState\n }\n }\n )\n }\n\n reset() {\n if (this._error == null) {\n logDebug(this, 'reset no-op')\n return\n }\n logDebug(this, 'reset')\n this._error = null\n this.dispatch('reset', {})\n }\n\n /**\n * True if this controller has been disposed.\n */\n get disposed(): boolean {\n return this.disposer.disposed\n }\n\n dispose() {\n this.disposer.dispose()\n }\n}\n\n/**\n * Returns true if the play rejection reason is a not allowed error. This indicates that play\n * should be retried within a user interaction stack.\n * @param reason\n */\nexport function isNotAllowedError(\n reason: any\n): reason is { name: 'NotAllowedError' } {\n return reason?.name === 'NotAllowedError'\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { CrossOrigin, PlaybackSource } from './PlaybackSource'\n\nexport interface PlaybackSourceImplDeps {\n readonly media: HTMLMediaElement\n}\n\nexport class PlaybackSourceImpl implements PlaybackSource {\n protected readonly media: HTMLMediaElement\n\n constructor(deps: PlaybackSourceImplDeps) {\n this.media = deps.media\n }\n\n get crossOrigin(): CrossOrigin {\n return this.media.crossOrigin as CrossOrigin\n }\n\n set crossOrigin(value: CrossOrigin) {\n this.media.crossOrigin = value\n }\n\n get currentSrc(): string {\n return this.media.currentSrc\n }\n\n load(): void {\n this.media.load()\n }\n\n get src(): string {\n return this.media.src\n }\n\n set src(value: string | null) {\n if (!value) this.media.removeAttribute('src')\n else this.media.src = value\n }\n\n get srcObject(): MediaStream | null {\n return this.media.srcObject as MediaStream | null\n }\n\n set srcObject(value: MediaStream | null) {\n this.media.srcObject = value\n }\n\n get disableRemotePlayback(): boolean {\n return this.media.disableRemotePlayback\n }\n\n set disableRemotePlayback(value: boolean) {\n this.media.disableRemotePlayback = value\n }\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { PrefetchState, QualitySelector } from './QualitySelector'\nimport {\n clamp,\n createDisposer,\n createLogPrefix,\n type Disposable,\n getNetworkMetrics,\n type LogTarget,\n lerp,\n type Maybe,\n} from '@amazon/vinyl-util'\nimport {\n boolean,\n enumOf,\n number,\n object,\n type ObjectSchema,\n} from '@amazon/vinyl-validation'\nimport type { MediaQualityMetadata } from '../MediaQualityMetadata'\nimport type { ObservableValue } from '@amazon/vinyl-observable'\n\nexport interface QualitySelectorImplOptions {\n /**\n * If at least this amount of time (in seconds) is currently fetched, don't consider an ABR-down.\n * Also used as the upper bound for interpolating between {@link bandwidthMultiplierLow} and\n * {@link bandwidthMultiplierHigh} based on the current fetched time.\n * Default: 15\n */\n readonly highBufferThreshold?: number\n\n /**\n * If less than this amount of time (in seconds) is currently fetched, don't consider an ABR-up.\n * Default: 4\n */\n readonly lowBufferThreshold?: number\n\n /**\n * Defines the strategy used for quality selection.\n *\n * Default: BEST (ABR will be enabled)\n */\n readonly strategy?: AbrStrategy\n\n /**\n * A multiplier applied to the estimated bandwidth when the fetched buffer is empty (0 seconds).\n * Lower values are more conservative (reduce the bandwidth used for quality selection) and help\n * avoid rebuffers when the buffer is low.\n *\n * As the fetched buffer fills toward {@link highBufferThreshold}, the effective multiplier\n * linearly interpolates between this value and {@link bandwidthMultiplierHigh}.\n *\n * Default: 0.4\n */\n readonly bandwidthMultiplierLow?: number\n\n /**\n * A multiplier applied to the estimated bandwidth when the fetched buffer is at or above\n * {@link highBufferThreshold}. Higher values are more optimistic and allow selection of higher\n * qualities once enough data is buffered to absorb short-term bandwidth dips.\n *\n * As the fetched buffer fills from 0 toward {@link highBufferThreshold}, the effective multiplier\n * linearly interpolates between {@link bandwidthMultiplierLow} and this value.\n *\n * Default: 0.9\n */\n readonly bandwidthMultiplierHigh?: number\n\n /**\n * When true, avoids changing codecs when considering choosing a higher audio bitrate\n * than what is currently playing. A decoder re-initialization is often an audible change,\n * so consumers that prefer to avoid audible artifacts may enable this. ABR-down is still\n * allowed across decoders because the subtle audio artifact is more desirable than a rebuffer.\n * Default: false\n */\n readonly restrictDecoderChangeOnAudioAbrUp?: boolean\n\n /**\n * Maximum bandwidth in bits per second a quality may use to be selectable.\n *\n * Soft cap: if no qualities fit within the limit (including when set to 0),\n * the quality with the lowest bandwidth is selected so playback is still\n * possible.\n *\n * Has no effect when {@link strategy} is {@link AbrStrategy.LOWEST} or\n * {@link AbrStrategy.HIGHEST}, since those strategies pin the selection\n * regardless of bandwidth.\n *\n * Default: null (no limit).\n */\n readonly maxBandwidth?: Maybe<number>\n\n /**\n * Maximum video height, in pixels, a quality may have to be selectable.\n * Mirrors Shaka's `restrictions.maxHeight`.\n *\n * Only affects video qualities; audio (and other non-video) qualities are\n * never restricted by resolution. Qualities with an unknown height (null)\n * are treated as within the cap.\n *\n * Soft cap: if no video quality fits within the resolution limit, the\n * quality with the smallest bandwidth is selected so video still plays.\n *\n * Has no effect when {@link strategy} is {@link AbrStrategy.LOWEST} or\n * {@link AbrStrategy.HIGHEST}, since those strategies pin the selection\n * regardless of resolution.\n *\n * Default: null (no limit).\n */\n readonly maxHeight?: Maybe<number>\n\n /**\n * Maximum video width, in pixels, a quality may have to be selectable.\n * Mirrors Shaka's `restrictions.maxWidth`. Behaves like {@link maxHeight}\n * but constrains the width dimension.\n *\n * Default: null (no limit).\n */\n readonly maxWidth?: Maybe<number>\n}\n\nexport enum AbrStrategy {\n /**\n * Selects lowest quality, regardless of bandwidth conditions.\n */\n LOWEST = 'lowest',\n\n /**\n * Selects highest quality, regardless of bandwidth conditions.\n */\n HIGHEST = 'highest',\n\n /**\n * Selects the best quality based on user bandwidth data.\n * Uses an EWMA estimation.\n */\n BEST = 'best',\n\n /**\n * Selects the initial quality based on bandwidth information, but will not change qualities mid-stream.\n *\n * May choose new quality after streaming clear, such as after a seek.\n */\n FIXED = 'fixed',\n}\n\nexport const qualitySelectorImplOptionsValidator: ObjectSchema<QualitySelectorImplOptions> =\n /* @__PURE__ */ object({\n highBufferThreshold: /* @__PURE__ */ /* @__PURE__ */ number().optional(),\n lowBufferThreshold: /* @__PURE__ */ /* @__PURE__ */ number().optional(),\n strategy: /* @__PURE__ */ /* @__PURE__ */ enumOf(AbrStrategy).optional(),\n bandwidthMultiplierLow: /* @__PURE__ */ /* @__PURE__ */ number().optional(),\n bandwidthMultiplierHigh: /* @__PURE__ */ /* @__PURE__ */ number().optional(),\n restrictDecoderChangeOnAudioAbrUp: /* @__PURE__ */ /* @__PURE__ */ boolean().optional(),\n maxBandwidth: /* @__PURE__ */ /* @__PURE__ */ /* @__PURE__ */ number().maybe().optional(),\n maxHeight: /* @__PURE__ */ /* @__PURE__ */ /* @__PURE__ */ number().maybe().optional(),\n maxWidth: /* @__PURE__ */ /* @__PURE__ */ /* @__PURE__ */ number().maybe().optional(),\n })\n\nexport const defaultQualitySelectorImplOptions = {\n highBufferThreshold: 15,\n lowBufferThreshold: 4,\n strategy: AbrStrategy.BEST,\n bandwidthMultiplierLow: 0.4,\n bandwidthMultiplierHigh: 0.9,\n restrictDecoderChangeOnAudioAbrUp: false,\n maxBandwidth: null,\n maxHeight: null,\n maxWidth: null,\n} as const satisfies QualitySelectorImplOptions\n\nexport interface QualitySelectorImplDeps {\n readonly options: ObservableValue<QualitySelectorImplOptions>\n}\n\nexport class QualitySelectorImpl\n implements QualitySelector, LogTarget, Disposable\n{\n get [Symbol.toStringTag](): string {\n return 'QualitySelectorImpl'\n }\n\n readonly logPrefix = /* @__PURE__ */ createLogPrefix(this)\n private _options: Required<QualitySelectorImplOptions> =\n defaultQualitySelectorImplOptions\n\n private disposer = /* @__PURE__ */ createDisposer()\n\n constructor(deps: QualitySelectorImplDeps) {\n const { add } = this.disposer\n add(\n deps.options.onData((v) => {\n this._options = { ...defaultQualitySelectorImplOptions, ...v }\n })\n )\n }\n\n get options(): Required<QualitySelectorImplOptions> {\n return this._options\n }\n\n selectQuality(\n qualities: readonly MediaQualityMetadata[],\n prefetchState: PrefetchState\n ): number {\n const {\n strategy,\n highBufferThreshold,\n lowBufferThreshold,\n bandwidthMultiplierLow,\n bandwidthMultiplierHigh,\n restrictDecoderChangeOnAudioAbrUp,\n maxBandwidth,\n maxHeight,\n maxWidth,\n } = this.options\n\n // A video quality is within the resolution cap when both its width and\n // height are at or below the configured maxima. Non-video qualities and\n // qualities with an unknown dimension are never restricted, mirroring\n // Shaka's restrictions.maxWidth/maxHeight (which only apply to video).\n const withinResolution = (quality: MediaQualityMetadata): boolean =>\n quality.contentType !== 'video' ||\n ((maxHeight == null ||\n quality.height == null ||\n quality.height <= maxHeight) &&\n (maxWidth == null ||\n quality.width == null ||\n quality.width <= maxWidth))\n const previousQuality = prefetchState.previousQuality\n // previousIndex will be -1 if the previously playing quality is not within the current qualities list.\n const previousIndex =\n previousQuality == null\n ? -1\n : qualities.findIndex(\n (quality) =>\n quality.qualityId === previousQuality.qualityId\n )\n\n if (strategy === AbrStrategy.LOWEST) {\n return qualities.length - 1\n } else if (strategy === AbrStrategy.HIGHEST) {\n return 0\n } else if (strategy === AbrStrategy.FIXED) {\n if (previousIndex >= 0) return previousIndex\n }\n\n const fetchedTime = prefetchState.fetchedTime\n const bandwidthEstimate = getNetworkMetrics().estimatedDownlinkBandwidth\n // Interpolate the bandwidth multiplier between the low and high values based on how much\n // buffer is currently fetched. An empty buffer uses bandwidthMultiplierLow (conservative)\n // to reduce rebuffer risk; a buffer at or above highBufferThreshold uses\n // bandwidthMultiplierHigh (optimistic) since buffered data can absorb short-term dips.\n // The interpolation is linear with respect to the buffer ratio.\n // If the track is not active (i.e. prefetch), always use the high multiplier.\n const bufferRatio =\n highBufferThreshold > 0\n ? clamp(fetchedTime / highBufferThreshold, 0, 1)\n : 1\n const bandwidthMultiplier = prefetchState.active\n ? lerp(bandwidthMultiplierLow, bandwidthMultiplierHigh, bufferRatio)\n : bandwidthMultiplierHigh\n\n // Choose bandwidth based on pessimistic network information.\n // If the track is active, take the lesser of the latest recorded bandwidth stat and the weighted\n // average to allow for fast ABR-down in variable conditions.\n let bandwidth =\n (prefetchState.active\n ? Math.min(bandwidthEstimate.ewmaLow, bandwidthEstimate.latest)\n : bandwidthEstimate.ewmaLow) * bandwidthMultiplier\n\n // Apply the maxBandwidth cap as a soft upper bound on the bandwidth budget.\n if (maxBandwidth != null && maxBandwidth < bandwidth) {\n bandwidth = maxBandwidth\n }\n\n let restrictDecoderId: string | null = null\n let restrictSwitchingGroupIds: readonly string[] | null = null\n if (previousQuality && previousIndex >= 0) {\n // Restrict to qualities whose groupId is in the previous quality's switching group.\n // Null switchingGroupIds means no switching constraint.\n if (previousQuality.switchingGroupIds != null) {\n restrictSwitchingGroupIds = previousQuality.switchingGroupIds\n }\n\n // Intra-track ABR rules\n if (\n previousQuality.bandwidthTotal &&\n bandwidth < previousQuality.bandwidthTotal\n ) {\n // Measured bandwidth lower than current streaming bandwidth.\n if (\n fetchedTime >= highBufferThreshold &&\n withinResolution(previousQuality)\n ) {\n // Do not ABR-down inter-track when there is ample fetched data.\n // Skipped if the previous quality now exceeds the resolution\n // cap, so a lowered cap takes effect promptly.\n return previousIndex\n }\n } else {\n if (\n fetchedTime < lowBufferThreshold &&\n withinResolution(previousQuality)\n ) {\n // Do not ABR-up inter-track when there is not enough fetched data.\n // Skipped if the previous quality now exceeds the resolution\n // cap, so a lowered cap takes effect promptly.\n return previousIndex\n }\n\n // Measured bandwidth is at least current streaming bandwidth.\n // Restrict to the previous decoder id for audio to avoid an audible artifact\n // from decoder re-initialization.\n if (\n restrictDecoderChangeOnAudioAbrUp &&\n previousQuality.contentType === 'audio'\n ) {\n restrictDecoderId = previousQuality.decoderId\n }\n }\n }\n const index = qualities.findIndex((quality) => {\n if (\n restrictSwitchingGroupIds != null &&\n !restrictSwitchingGroupIds.includes(quality.groupId)\n )\n return false\n if (\n restrictDecoderId != null &&\n quality.decoderId !== restrictDecoderId\n )\n return false\n // Exclude video qualities above the resolution cap.\n if (!withinResolution(quality)) return false\n return (\n quality.bandwidthTotal == null ||\n quality.bandwidthTotal <= bandwidth\n )\n })\n if (index !== -1) return index\n // No quality fit the bandwidth budget (and resolution cap). Prefer the\n // smallest quality that still satisfies the resolution cap so a video\n // above the cap is never selected while a compliant option exists; if\n // none satisfy the cap, fall back to the overall smallest so video\n // still plays.\n for (let i = qualities.length - 1; i >= 0; i--) {\n if (withinResolution(qualities[i])) return i\n }\n return qualities.length - 1\n }\n\n get disposed(): boolean {\n return this.disposer.disposed\n }\n\n dispose() {\n this.disposer.dispose()\n }\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {\n type AnyRecord,\n type Clearable,\n createAbortSlot,\n createDisposer,\n createLogPrefix,\n createTaskQueue,\n type Disposable,\n type Disposer,\n EventHostImpl,\n getLogLevel,\n isSilentError,\n LinkedList,\n logDebug,\n LogLevel,\n logVerbose,\n logWarn,\n type ReadonlyEventHost,\n throttle,\n} from '@amazon/vinyl-util'\nimport type { ReadonlyPlaybackController } from '../../playback/ReadonlyPlaybackController'\nimport type { SourceBufferController } from './SourceBufferController'\nimport type { ReadonlySegmentController } from '../SegmentController'\nimport type { SegmentReference } from '../SegmentReference'\nimport type { BasicErrorEvent } from '../../event/BasicErrorEvent'\nimport type { ChangeEvent } from '../../event/ChangeEvent'\nimport type { ContentType, MediaQualityMetadata } from '../MediaQualityMetadata'\nimport type { CodecUnsupportedEvent } from '../StreamingEventMap'\nimport { type MediaSourceController } from './MediaSourceController'\nimport { SEGMENT_START_AFFORDANCE } from '../SegmentController'\nimport { SourceBufferError } from './error/SourceBufferError'\nimport { denylistCodecsFromMimeType } from './codecDenylist'\n\n/**\n * The interval to throttle polling the buffer.\n * Reset after a seek.\n * @private\n */\nexport const POLL_BUFFER_THROTTLE = 0.1\n\n/**\n * If segments are too large to append, reduces the max append size.\n */\nexport const QUOTA_REACHED_SCALE = 0.8\n\n/**\n * If quota exceeded errors are hit, the max append size will not be reduced below this value and the buffering\n * controller will be set to an erred state.\n */\nexport const MIN_APPEND_SIZE = 524288 // 512 * 1024\n\n/**\n * If the content type does not match a config setting.\n */\nexport const DEFAULT_MAX_APPEND_SIZE = 10485760 // 10 * 1024 * 1024\n\nexport interface BufferingControllerEventMap {\n /**\n * Dispatched when an error of severity warning or fatal occurred while buffering.\n */\n readonly error: BasicErrorEvent\n\n /**\n * Dispatched when the currently playing media encoding has changed.\n */\n readonly playbackQualityChange: ChangeEvent<MediaQualityMetadata | null>\n\n /**\n * Dispatched when the currently buffering quality changes.\n * This is dispatched before the segment is appended.\n */\n readonly bufferingQualityChange: ChangeEvent<MediaQualityMetadata | null>\n\n /**\n * The last segment has finished appending.\n */\n readonly bufferingEnded: AnyRecord\n\n /**\n * The buffer went from empty to holding data, or back to empty.\n */\n readonly hasDataChange: ChangeEvent<boolean>\n\n /**\n * A codec the browser reported as supported failed to decode on append and\n * has been denylisted. Dispatched instead of `error` so the media can be\n * reloaded and fall back to a codec that decodes.\n */\n readonly codecUnsupported: CodecUnsupportedEvent\n}\n\nexport interface BufferingController\n extends\n ReadonlyEventHost<BufferingControllerEventMap>,\n Clearable,\n Disposable {\n /**\n * The last error emitted.\n * Buffering will halt if this controller is in an error state.\n * Deactivating this controller will reset the error state.\n */\n readonly error: Error | null\n\n /**\n * The currently buffering media quality.\n * This is set immediately before a segment of a new quality is appended.\n *\n * Listen to {@link BufferingControllerEventMap.bufferingQualityChange} events for changes.\n */\n readonly bufferingQuality: MediaQualityMetadata | null\n\n /**\n * The currently playing media quality.\n *\n * Listen to {@link BufferingControllerEventMap.playbackQualityChange} events for changes.\n */\n readonly playbackQuality: MediaQualityMetadata | null\n\n /**\n * True if this buffering controller is active.\n */\n readonly active: boolean\n\n /**\n * True if the stream has buffered the last segment.\n */\n readonly bufferingEnded: boolean\n\n /**\n * True while the buffer holds any data (false when empty or cleared).\n */\n readonly hasData: boolean\n\n /**\n * Begins buffering.\n */\n activate(): void\n\n /**\n * Stops buffering.\n */\n deactivate(): void\n\n /**\n * If this controller is in an error state, resets and tries again.\n */\n reset(): void\n}\n\n/**\n * The measured source buffer quotas.\n */\nconst sourceBufferQuotas = /* @__PURE__ */ new Map<string, number>()\n\n/**\n * Clears the current estimated source buffer quota.\n * @private\n */\nexport function clearSourceBufferQuota() {\n sourceBufferQuotas.clear()\n}\n\n/**\n * Returns the measured source buffer quota for the given content type.\n * Will return null if the quota was never reached.\n *\n * @param contentType\n */\nexport function getSourceBufferQuota(contentType: ContentType): number | null {\n return sourceBufferQuotas.get(contentType) ?? null\n}\n\nexport interface BufferingControllerImplDeps {\n readonly mediaSourceController: MediaSourceController\n readonly segmentController: ReadonlySegmentController\n readonly playbackController: ReadonlyPlaybackController\n readonly sourceBufferControllerFactory: () => SourceBufferController\n}\nexport interface BufferingControllerImplOptions {\n /**\n * When the buffer falls below this time threshold, the next segment will be requested from the\n * segment controller and appended.\n * Default: 4s\n */\n readonly minBuffer: number\n\n /**\n * The maximum number of bytes to append at a time per content type.\n * Default: { audio: 1MiB, video: 15MiB }\n */\n readonly maxAppendSize: Partial<Record<ContentType, number>>\n}\n\nconst defaultBufferingControllerOptions = {\n minBuffer: 4.0,\n maxAppendSize: {\n audio: 10485760, // 10 * 1024 * 1024\n video: 157286400, // 150 * 1024 * 1024\n },\n} as const satisfies BufferingControllerImplOptions\n\n/**\n * The buffering controller is responsible for requesting and appending segments to the source\n * buffer controller.\n */\nexport class BufferingControllerImpl\n extends EventHostImpl<BufferingControllerEventMap>\n implements BufferingController, Disposable\n{\n get [Symbol.toStringTag](): string {\n return `Buffering_${this.contentType}`\n }\n\n // Assigned in the constructor body: a field initializer runs before the\n // contentType param-property, so it would capture `undefined`.\n readonly logPrefix: string\n\n readonly options: BufferingControllerImplOptions\n private readonly mediaSourceController: MediaSourceController\n private readonly playbackController: ReadonlyPlaybackController\n private readonly segmentController: ReadonlySegmentController\n\n private sourceBufferController: SourceBufferController | null = null\n private decoderId: string | null = null\n\n /**\n * The currently buffered segments.\n */\n private buffered = /* @__PURE__ */ new LinkedList<SegmentReference<ArrayBuffer>>()\n private appendOffset = 0\n\n /**\n * The currently buffering quality.\n */\n private _bufferingQuality: MediaQualityMetadata | null = null\n\n /**\n * If true and in a bufferingEnded state, the segment provider will be queried again.\n * This will be set to true after the segment controller reports a change event, indicating that there may be new\n * segments to append.\n */\n private reopen = false\n private _error: Error | null = null\n private _bufferingEnded = false\n private _hasData = false\n\n private readonly queue = /* @__PURE__ */ createTaskQueue()\n\n private disposer = /* @__PURE__ */ createDisposer()\n private _active = false\n private activateDisposer: Disposer | null = null\n\n private readonly segmentAbort = /* @__PURE__ */ createAbortSlot()\n\n constructor(\n readonly deps: BufferingControllerImplDeps,\n readonly contentType: ContentType,\n options?: Partial<BufferingControllerImplOptions>\n ) {\n super()\n this.logPrefix = createLogPrefix(`Buffering_${contentType}`)\n this.options = {\n ...defaultBufferingControllerOptions,\n ...options,\n }\n logDebug(this, 'constructed', this.options)\n this.mediaSourceController = deps.mediaSourceController\n this.playbackController = deps.playbackController\n this.segmentController = deps.segmentController\n }\n\n get active(): boolean {\n return this._active\n }\n\n /**\n * Activates the buffering controller, watching the playhead and segment controller.\n */\n activate() {\n if (this._active) return\n this._active = true\n logDebug(this, 'activate')\n this.activateDisposer = createDisposer()\n const { add } = this.activateDisposer\n this.sourceBufferController = add(\n this.deps.sourceBufferControllerFactory()\n )\n add(this.playbackController.on('timeUpdate', this.pollBuffer))\n add(\n this.playbackController.on('seeking', () => {\n this.reopen = true // prevents a no-op when 'ended'\n this.pollBufferImmediate()\n })\n )\n\n const onMediaSourceOpen = () => {\n logDebug(this, 'media source opened')\n this.pollBufferImmediate()\n }\n if (this.mediaSourceOpen) {\n onMediaSourceOpen()\n } else {\n add(this.mediaSourceController.on('sourceOpen', onMediaSourceOpen))\n }\n add(\n this.segmentController.on('change', () => {\n this.reopen = true\n this.pollBufferImmediate()\n })\n )\n }\n\n deactivate() {\n if (!this._active) return\n logDebug(this, 'deactivate')\n this.abortCurrentSegment()\n this.resetBufferedState()\n this.activateDisposer!.dispose()\n this.activateDisposer = null\n this.sourceBufferController = null\n this._active = false\n }\n\n reset(): void {\n if (!this._error) {\n logDebug(this, 'reset no-op')\n return\n }\n logDebug(this, 'reset')\n this._error = null\n this.pollBufferImmediate()\n }\n\n /**\n * Returns true if there are active operations.\n */\n get busy(): boolean {\n return this.queue.running > 0\n }\n\n /**\n * Resets the throttle and polls the buffer on the next frame.\n */\n private pollBufferImmediate = () => {\n if (!this.active) return\n this.pollBuffer.reset()\n setTimeout(() => {\n if (this.active) this.pollBuffer()\n })\n }\n\n /**\n * If buffered time reaches below minBuffer, request the segment for the next unbuffered\n * time and append.\n * @private\n */\n private readonly pollBuffer = /* @__PURE__ */ this.disposer.add(\n /* @__PURE__ */ throttle(\n () => {\n const time = this.playbackController.currentTime\n if (getLogLevel() === LogLevel.VERBOSE) {\n logVerbose(\n this,\n `pollBuffer time: ${time}, bufferedTime: ${this.getBufferedTime()}, busy: ${this.busy}, error: ${this.error != null}, readyState: ${this.mediaSourceController.readyState}`\n )\n }\n this.refreshHead()\n if (!this.shouldAppend()) return\n this.reopen = false\n if (this.needsBufferClear()) {\n this.clear() // After the clear, the buffer state will reset and re-poll.\n return\n }\n this.queue\n .enqueue(() => this.appendNext())\n .catch(this.handleError)\n // An append has finished. Poll again on the next frame.\n // The append either completed successfully, erred fatally (setting an error state),\n // or erred silently (an abort).\n .finally(this.pollBufferImmediate)\n },\n POLL_BUFFER_THROTTLE,\n {\n leading: true,\n trailing: true,\n }\n )\n )\n\n private shouldAppend(): boolean {\n return (\n this.active &&\n !this.busy &&\n !this.error &&\n !this.mediaSourceClosed &&\n (!this.bufferingEnded || this.reopen) &&\n // Return true if the current buffer is less than the minimum buffer and the playhead has not reached duration.\n this.getBufferedTime() <= this.options.minBuffer\n )\n }\n\n /**\n * The buffered segment at the playhead.\n */\n private get head(): SegmentReference<ArrayBuffer> | undefined {\n return this.buffered.head?.value\n }\n\n /**\n * The most recently buffered segment.\n */\n private get tail(): SegmentReference<ArrayBuffer> | undefined {\n return this.buffered.tail?.value\n }\n\n protected async appendNext(): Promise<void> {\n logVerbose(this, 'appendNext')\n const sourceBufferController = this.sourceBufferController!\n const time = this.playbackController.currentTime\n\n const tail = this.tail\n let streamingSegment: SegmentReference<ArrayBuffer> | null\n // If appendOffset is less than the last buffered segment size, this indicates a partial append, continue\n // buffering the last segment.\n if (tail && this.appendOffset < tail.data.byteLength) {\n streamingSegment = tail\n } else {\n streamingSegment = await this.segmentController.getSegment(\n // If buffering is a continuation from the previous segment, use its end time.\n // Otherwise, start streaming from slightly behind the playhead.\n tail?.endTime ?? time - SEGMENT_START_AFFORDANCE,\n this.segmentAbort.value\n )\n logVerbose(this, 'streamingSegment', streamingSegment)\n if (streamingSegment) this.appendOffset = 0\n }\n if (!streamingSegment) {\n await sourceBufferController.enqueue(() => {\n if (this.mediaSourceOpen) this.endBuffering()\n })\n return\n }\n this.bufferingQuality = streamingSegment.quality\n if (this.decoderId !== streamingSegment.quality.decoderId) {\n // Append the initialization segment before the media segment if the decoder\n // needs (re)-initialization.\n this.decoderId = null\n await sourceBufferController.appendInit(\n streamingSegment.initData,\n streamingSegment.quality.mimeType!\n )\n this.decoderId = streamingSegment.quality.decoderId\n }\n // Set the timestamp offset only if appending from an unbuffered position.\n if (!tail) {\n await sourceBufferController.setTimestampOffset(\n streamingSegment.timestampOffset\n )\n }\n\n const maxAppendSize = this.getMaxAppendSize(\n streamingSegment.quality.contentType!\n )\n\n const currentBitrate =\n streamingSegment.data.byteLength /\n (streamingSegment.endTime - streamingSegment.startTime)\n const appendSize =\n maxAppendSize - currentBitrate * this.getBufferedTime()\n if (appendSize <= 0) {\n // current buffered data is filling entire quota\n return\n }\n\n const byteLength = streamingSegment.data.byteLength\n if (byteLength > appendSize) {\n const newOffset = this.appendOffset + appendSize\n const chunk = streamingSegment.data.slice(\n this.appendOffset,\n newOffset\n )\n await sourceBufferController.append(chunk)\n if (this.appendOffset === 0) {\n this.buffered.push(streamingSegment)\n }\n this.appendOffset = newOffset\n logVerbose(\n this,\n `appended chunk, this.appendOffset: ${this.appendOffset}`\n )\n } else {\n await sourceBufferController.append(streamingSegment.data)\n this.appendOffset = streamingSegment.data.byteLength\n this.buffered.push(streamingSegment)\n }\n if (!tail) this.refreshHead() // Update quality immediately if buffer was empty\n this.setHasData(true)\n }\n\n private abortCurrentSegment() {\n this.segmentAbort.abort()\n }\n\n /**\n * Checks if the playhead has progressed past the current head segment and shifts the linked list.\n * Updates the playback quality if changed.\n */\n private refreshHead() {\n const head = this.head\n const tail = this.tail\n const time = this.playbackController.currentTime\n if (head && time >= head.endTime && head !== tail) {\n // The playhead has passed the end of the head segment.\n this.buffered.shift()\n }\n this.playbackQuality = this.head?.quality ?? null\n }\n\n private getMaxAppendSize(contentType: ContentType): number {\n const maxAppendSize =\n this.options.maxAppendSize[contentType] ?? DEFAULT_MAX_APPEND_SIZE\n const sourceBufferQuota = sourceBufferQuotas.get(contentType)\n return sourceBufferQuota == null\n ? maxAppendSize\n : Math.min(sourceBufferQuota, maxAppendSize)\n }\n\n private _playbackQuality: MediaQualityMetadata | null = null\n\n get playbackQuality(): MediaQualityMetadata | null {\n return this._playbackQuality\n }\n\n /**\n * Returns the quality currently buffering.\n */\n get bufferingQuality(): MediaQualityMetadata | null {\n return this._bufferingQuality\n }\n\n private set bufferingQuality(value: MediaQualityMetadata | null) {\n const previous = this._bufferingQuality\n if (value?.qualityId === previous?.qualityId) return\n this._bufferingQuality = value\n logDebug(this, 'bufferingQualityChange', value)\n this.dispatch('bufferingQualityChange', {\n previous,\n current: value,\n })\n }\n\n /**\n * Sets the current playback quality and emits a playbackQualityChange event.\n * No-ops if quality id has not changed.\n */\n private set playbackQuality(value: MediaQualityMetadata | null) {\n const previous = this._playbackQuality\n if (value?.qualityId === previous?.qualityId) return\n this._playbackQuality = value\n logDebug(this, 'playbackQualityChange', value)\n this.dispatch('playbackQualityChange', {\n previous,\n current: value,\n })\n }\n\n /**\n * The last error emitted.\n * Buffering will halt if this controller is in an error state.\n * Deactivating this controller will reset the error state.\n */\n get error(): Error | null {\n return this._error\n }\n\n /**\n * Returns true if the media source's ready state is 'open'\n */\n private get mediaSourceOpen(): boolean {\n return this.mediaSourceController.readyState === 'open'\n }\n\n /**\n * Returns true if the media source's ready state is 'closed'\n */\n private get mediaSourceClosed(): boolean {\n return this.mediaSourceController.readyState === 'closed'\n }\n\n /**\n * Returns true if the last segment has been appended.\n */\n get bufferingEnded(): boolean {\n return this._bufferingEnded\n }\n\n get hasData(): boolean {\n return this._hasData\n }\n\n private setHasData(value: boolean): void {\n if (this._hasData === value) return\n const previous = this._hasData\n this._hasData = value\n this.dispatch('hasDataChange', { previous, current: value })\n }\n\n private readonly handleError = (error: Error) => {\n if ('name' in error && error.name === 'QuotaExceededError') {\n const contentType = this.bufferingQuality?.contentType\n if (contentType) {\n const newAppendSize =\n this.getMaxAppendSize(contentType) * QUOTA_REACHED_SCALE\n if (newAppendSize >= MIN_APPEND_SIZE) {\n sourceBufferQuotas.set(contentType, newAppendSize)\n logWarn(\n this,\n 'QuotaExceededError, new source buffer limit:',\n (newAppendSize / 1024 / 1024).toFixed(1) + ' MiB'\n )\n const sourceBufferController = this.sourceBufferController\n if (sourceBufferController) {\n this.clear()\n }\n return // If the quota size was successfully reduced, do not err and try again.\n }\n }\n }\n if (this.tryCodecFallback(error)) {\n // The failing codec was denylisted and playback will retry with a\n // different quality; do not enter an error state.\n return\n }\n if (!isSilentError(error)) {\n // Set this controller to an error state. If in an error state, buffering will\n // not continue.\n this._error = error\n this.dispatch('error', {\n target: this,\n error,\n })\n }\n }\n\n /**\n * Attempts to recover from a SourceBuffer decode/append failure caused by a\n * codec the browser reported as supported but cannot actually decode.\n *\n * Denylists the failing quality's codec so subsequent quality selection\n * avoids it, then clears and retries. Returns true when a fallback was\n * initiated (the caller should not enter an error state), false otherwise.\n *\n * Guards against loops: recovery only proceeds when the codec was newly\n * denylisted. A repeat failure for an already-denylisted codec (e.g. a\n * single-codec stream with no alternative) returns false and falls through\n * to the normal error path, so playback errors out rather than looping.\n */\n private tryCodecFallback(error: Error): boolean {\n if (!(error instanceof SourceBufferError)) return false\n const quality = this.bufferingQuality\n const mimeType = quality?.mimeType\n const contentType = quality?.contentType\n if (!mimeType || !contentType) return false\n // denylistCodecsFromMimeType returns false if all codecs were already\n // denylisted, which bounds recovery to one attempt per codec.\n if (!denylistCodecsFromMimeType(mimeType)) return false\n logWarn(\n this,\n 'SourceBuffer append failed; denylisting codec and requesting reload:',\n mimeType\n )\n // A decode failure poisons the MediaSource, so in-place recovery is not\n // possible. Signal a recoverable codec failure; the player reloads the\n // track, and the denylist steers selection to a codec that decodes.\n this.dispatch('codecUnsupported', { mimeType, contentType })\n return true\n }\n\n /**\n * Returns the amount of time buffered at the current media position.\n * @private\n */\n getBufferedTime(): number {\n if (!this.active) return 0\n const time = this.playbackController.currentTime\n const range = this.sourceBufferController!.buffered.getRangeAt(time)\n if (!range) return 0\n return range[1] - time\n }\n\n /**\n * Returns true if the playhead has become disconnected from the continuous buffer.\n */\n private needsBufferClear(): boolean {\n const buffered = this.sourceBufferController!.buffered\n if (buffered.empty) return false\n const time = this.playbackController.currentTime\n // The source buffer allows multiple ranges, but buffering produces a\n // single contiguous range in practice.\n const range = buffered.ranges[0]\n return time < range[0] - 0.01 || time > range[1] + 0.5\n }\n\n /**\n * Cancels any currently buffering fragments and clears the source buffer.\n */\n clear(): void {\n if (!this.active) return\n logDebug(this, 'clear')\n this.abortCurrentSegment()\n // Enqueue clearing the buffer and buffered list.\n this.queue\n .enqueue(this.finishAndClearBuffers)\n .catch(this.handleError)\n .finally(() => {\n this.resetBufferedState()\n this.pollBufferImmediate()\n })\n }\n\n private endBuffering(): void {\n logDebug(this, 'bufferingEnded')\n this._bufferingEnded = true\n this.bufferingQuality = null\n this.dispatch('bufferingEnded', {})\n }\n\n private resetBufferedState() {\n this.decoderId = null\n this.appendOffset = 0\n this.buffered.clear()\n this._bufferingEnded = false\n this.bufferingQuality = null\n this.playbackQuality = null\n this.setHasData(false)\n }\n\n /**\n * Finish any partial appends and clear the source buffer.\n */\n private finishAndClearBuffers = async () => {\n if (!this.active) return\n logVerbose(this, 'finishAndClearBuffers')\n await this.sourceBufferController!.clear()\n logVerbose(this, 'finishAndClearBuffers complete')\n }\n\n get disposed(): boolean {\n return this.disposer.disposed\n }\n\n dispose() {\n this.deactivate()\n super.dispose()\n this.disposer.dispose()\n }\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type {\n AnyRecord,\n Disposable,\n ReadonlyAbort,\n ReadonlyEventHost,\n ReadonlyRanges,\n} from '@amazon/vinyl-util'\nimport type { SegmentReference } from './SegmentReference'\nimport type { ChangeEvent } from '../event/ChangeEvent'\nimport type { MediaQualityMetadata } from './MediaQualityMetadata'\nimport type { LoadSpanMeasurement } from './LoadMetric'\n\n/**\n * Forward-snap tolerance, in seconds, applied when looking up a segment by time.\n *\n * If the requested time falls within this window before a segment's `startTime`,\n * that segment is returned rather than treating the gap as uncovered. This absorbs\n * small alignment differences between qualities, where one quality's segment may\n * begin a few milliseconds later than another's at the same logical boundary.\n *\n * Pass to `getSegmentAtTime` (and `MediaQualityData.getSegment`) as the `affordance`\n * argument. Callers resuming streaming after a seek should also bias the requested\n * time *behind* the playhead by at least this amount, so any subsequent appends\n * cover the playhead without leaving a gap. The `SegmentController` clamps negative\n * request times to `0`, so callers don't need to guard against the bias going below\n * the start of the timeline.\n */\nexport const SEGMENT_START_AFFORDANCE = 0.2\n\nexport interface SegmentControllerEventMap {\n /**\n * fetchedRanges have been updated.\n */\n readonly fetchedRangesChange: AnyRecord\n\n /**\n * Emitted when the timeline has changed.\n */\n readonly change: AnyRecord\n\n /**\n * Dispatched when the current streaming quality changes.\n * This is dispatched when a new quality is requested.\n */\n readonly streamingQualityChange: ChangeEvent<MediaQualityMetadata | null>\n\n /**\n * The first init or media segment fetch of this stream completed.\n */\n readonly loadSpanMeasured: LoadSpanMeasurement\n}\n\n/**\n * The SegmentController provides segments to buffer for the given time.\n * It is expected to prefetch segments based on the expectation of when the segments will be\n * needed next.\n */\nexport interface ReadonlySegmentController extends ReadonlyEventHost<SegmentControllerEventMap> {\n readonly error: Error | null\n\n /**\n * The time ranges currently fetched.\n */\n readonly fetchedRanges: ReadonlyRanges\n\n /**\n * The most recently requested quality metadata.\n */\n readonly streamingQuality: MediaQualityMetadata | null\n\n /**\n * Returns a Promise for a segment covering the given time, with quality chosen by\n * the configured `QualitySelector`. Resolves to `null` if no media exists at that\n * time. Negative `time` values are clamped to `0`.\n *\n * The lookup forward-snaps by `SEGMENT_START_AFFORDANCE`: if `time` falls within\n * that window before a segment's `startTime`, that segment is returned. This\n * absorbs sub-second segment-boundary differences across qualities so an ABR\n * switch doesn't replay or skip media at the boundary.\n *\n * Calling this also blocks the prefetch queue until the returned promise settles,\n * so the active request is prioritized over background prefetching.\n *\n * @param time The time, in seconds, the requested segment should span.\n * @param abort Aborts the returned promise (rejecting with `AbortError`) and\n * releases the prefetch-queue lock. The underlying network request may continue\n * so its result can still populate the cache.\n */\n getSegment(\n time: number,\n abort?: ReadonlyAbort\n ): Promise<SegmentReference<ArrayBuffer> | null>\n}\n\n/**\n * Configuration the track is expected to provide to the SegmentController.\n */\nexport interface PrefetchOptions {\n /**\n * The prefetching priority of the track. Higher numbers take precedence.\n */\n readonly trackPrefetchPriority: number\n\n /**\n * When the track is inactive, the starting time to prefetch from.\n */\n readonly startTime: number\n}\n\n/**\n * Provides segments for a given time.\n * Handles segment prefetching and caching.\n */\nexport interface SegmentController\n extends ReadonlySegmentController, Disposable {\n /**\n * Configures this segment provider.\n */\n configure(options: Partial<PrefetchOptions>): void\n\n /**\n * Clears the cached segments.\n * Currently pending segment promises will be rejected with an abort reason.\n */\n clear(): void\n\n /**\n * Indicates that this segment provider is providing segments for an active track and should be prioritized\n * accordingly.\n */\n activate(): void\n\n /**\n * Indicates that this segment provider is providing segments for an inactive track.\n */\n deactivate(): void\n\n /**\n * Resets failed segments to a pending state.\n */\n reset(): void\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { ErrorOrigin } from '@amazon/vinyl-util'\nimport { ReportableError } from '@amazon/vinyl-util'\n\n/**\n * An error emitted from the SourceBuffer.\n */\nexport class SourceBufferError extends ReportableError {\n get [Symbol.toStringTag](): string {\n return 'SourceBufferError'\n }\n\n constructor(\n message = `A SourceBuffer error has occurred.`,\n origin = ErrorOrigin.MEDIA\n ) {\n super(message, origin)\n Object.setPrototypeOf(this, SourceBufferError.prototype)\n }\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * Extracts the individual codec strings from a mimeType's `codecs=` parameter.\n * Returns an empty array when no codecs parameter is present.\n */\nexport function extractCodecs(mimeType: string): string[] {\n const match = /codecs\\s*=\\s*\"?([^\"]*)\"?/i.exec(mimeType)\n if (!match || !match[1]) return []\n return match[1]\n .split(',')\n .map((c) => c.trim())\n .filter((c) => c.length > 0)\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { extractCodecs } from '../../util/media/codecSupport'\n\n/**\n * A runtime denylist of media codecs that failed to decode after a SourceBuffer\n * append, despite the browser reporting them as supported.\n *\n * Some browsers report a codec as supported via `MediaSource.isTypeSupported`\n * yet fail to decode it (e.g. HEVC on Chromium without a platform decoder),\n * surfacing as an append/decode error only once media is fed to the\n * SourceBuffer. When that happens, the failing codec is recorded here so that\n * quality selection avoids it and playback can fall back to a codec that does\n * decode.\n *\n * This mirrors the runtime {@link getSourceBufferQuota} learning: it is a\n * process-wide singleton learned from real append failures, with a reset hook\n * for tests and re-detection. Entries are the individual RFC 6381 codec\n * strings (e.g. `hvc1.2.20000000.L123.B0`), stored lowercased.\n */\nconst denylistedCodecs = /* @__PURE__ */ new Set<string>()\n\n/**\n * Records every codec in the given mimeType as denylisted. Returns true if any\n * codec was newly added (i.e. was not already denylisted), false if all codecs\n * were already present. The return value lets callers bound retry loops: a\n * repeat failure for an already-denylisted codec should not trigger another\n * fallback attempt.\n */\nexport function denylistCodecsFromMimeType(mimeType: string): boolean {\n const codecs = extractCodecs(mimeType)\n let added = false\n for (const codec of codecs) {\n const lower = codec.toLowerCase()\n if (!denylistedCodecs.has(lower)) {\n denylistedCodecs.add(lower)\n added = true\n }\n }\n return added\n}\n\n/**\n * Returns true when any codec in the given mimeType has been denylisted.\n */\nexport function isMimeTypeDenylisted(mimeType: string): boolean {\n const codecs = extractCodecs(mimeType)\n return codecs.some((c) => denylistedCodecs.has(c.toLowerCase()))\n}\n\n/**\n * Returns the currently denylisted codec strings (lowercased). Primarily for\n * diagnostics and testing.\n */\nexport function getDenylistedCodecs(): readonly string[] {\n return [...denylistedCodecs]\n}\n\n/**\n * Clears the runtime codec denylist. Intended for tests and for re-detecting\n * support (e.g. after an environment change).\n */\nexport function clearCodecDenylist(): void {\n denylistedCodecs.clear()\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {\n type AnyRecord,\n closeTo,\n createDisposer,\n type Disposable,\n type Disposer,\n DomEventHost,\n ErrorLevel,\n ErrorOrigin,\n EventHostImpl,\n IllegalStateError,\n isSilentError,\n type Json,\n logDebug,\n type LogTarget,\n logWarn,\n type ReadonlyEventHost,\n type ReadonlySet,\n ReportableError,\n toJson,\n toLowerCase,\n} from '@amazon/vinyl-util'\nimport type { ObservableValue } from '@amazon/vinyl-observable'\nimport type { ContentTypesValue } from '../ContentTypesValue'\nimport type { BasicErrorEvent } from '../../event/BasicErrorEvent'\nimport type { ContentType } from '../MediaQualityMetadata'\nimport type { MediaTimeline } from '../MediaTimeline'\nimport { LIVE_DURATION } from '../../playback/PlaybackController'\nimport { nextSourceBufferIdle } from '../../util/media/sourceBuffer'\n\n/**\n * Chrome 52 has decoding errors when duration is set to the mediaPresentationDuration.\n * Adds a slight padding as a workaround.\n * @private\n */\nexport const DURATION_PADDING = 0.1\n\nexport interface SourceBufferRef extends Disposable {\n /**\n * The source buffer.\n */\n readonly value: SourceBuffer\n}\n\nexport interface MediaSourceControllerEventMap {\n /**\n * The media source has entered a 'closed' state.\n */\n readonly sourceClose: AnyRecord\n\n /**\n * The media source has entered an 'ended' state.\n */\n readonly sourceEnded: AnyRecord\n\n /**\n * The media source has entered an 'open' state.\n */\n readonly sourceOpen: AnyRecord\n\n /**\n * All source buffers have been created, the media source duration has been set, and data\n * may be appended.\n */\n readonly readyToAppend: AnyRecord\n\n /**\n * An error has occurred.\n */\n readonly error: BasicErrorEvent\n}\n\nexport interface ReadonlyMediaSourceController extends ReadonlyEventHost<MediaSourceControllerEventMap> {\n /**\n * Returns the parent media source ready state.\n */\n readonly readyState: ReadyState\n\n /**\n * True if all source buffers have been created and data may be appended.\n */\n readonly readyToAppend: boolean\n}\n\nexport interface MediaSourceController extends ReadonlyMediaSourceController {\n /**\n * Constructs a new SourceBuffer with the given content type and mime type.\n */\n createSourceBuffer(\n contentType: ContentType,\n mimeType: string\n ): SourceBufferRef\n\n /**\n * Signals the end of the stream.\n * @param error A string representing an error to throw when the end of the stream is reached.\n */\n endOfStream(error?: EndOfStreamError): void\n\n /**\n * Creates the internal media source.\n * Returns an Object URL to use as the source for this stream.\n *\n * Implementation note:\n * Only the first\n */\n activate(): string\n\n /**\n * Deactivates the controller, disposing underlying resources.\n */\n deactivate(): void\n}\n\nexport interface MediaSourceControllerImplDeps {\n /**\n * Creates a new media source.\n */\n readonly mediaSourceFactory: () => MediaSource\n\n /**\n * Provides the streams that must be created before appending.\n */\n readonly contentTypesValue: ContentTypesValue\n\n /**\n * The media timeline used to determine duration.\n */\n readonly mediaTimelineTransformed: ObservableValue<Promise<MediaTimeline>>\n}\n\nexport class MediaSourceControllerImpl\n extends EventHostImpl<MediaSourceControllerEventMap>\n implements MediaSourceController, LogTarget\n{\n get [Symbol.toStringTag](): string {\n return 'MediaSourceControllerImpl'\n }\n\n private readonly sourceBuffers = /* @__PURE__ */ new Set<SourceBuffer>()\n\n private mediaSource: MediaSource | null = null\n private objectUrl: string | null = null\n private activateDisposer: Disposer | null = null\n private contentTypes: ReadonlySet<ContentType> | null = null\n private durationSet = false\n\n /**\n * Token for the in-flight duration update; used to discard stale results when\n * the timeline changes or the source closes mid-fetch.\n */\n private durationToken = 0\n\n constructor(private readonly deps: MediaSourceControllerImplDeps) {\n super()\n }\n\n get active(): boolean {\n return this.activateDisposer != null\n }\n\n activate(): string {\n this.activateDisposer = createDisposer()\n const add = this.activateDisposer.add\n\n const mediaSource = this.deps.mediaSourceFactory()\n this.mediaSource = mediaSource\n\n const domEvents = add(\n new DomEventHost<MediaSourceEventMap>(mediaSource)\n )\n domEvents.on('sourceopen', () => {\n this.refreshDuration().catch(this.errorHandler)\n })\n domEvents.on('sourceclose', () => {\n this.durationSet = false\n ++this.durationToken\n })\n\n // Redispatch events from the media source:\n for (const key of [\n 'sourceClose',\n 'sourceOpen',\n 'sourceEnded',\n ] as const) {\n domEvents.on(toLowerCase(key), () => this.dispatch(key, {}))\n }\n add(\n this.deps.mediaTimelineTransformed.onData(() => {\n this.refreshDuration().catch(this.errorHandler)\n })\n )\n\n // React to content type changes (fires immediately with the current\n // value and again whenever the timeline reveals new content types).\n add(\n this.deps.contentTypesValue.onData((contentTypesPromise) => {\n // The pending content types are unknown until the new promise\n // resolves, so the controller is not ready to append until then.\n this.contentTypes = null\n contentTypesPromise\n .then((contentTypes) => {\n if (\n this.deps.contentTypesValue.value !==\n contentTypesPromise\n )\n return // Stale\n this.contentTypes = contentTypes\n this.checkReady()\n })\n .catch(this.errorHandler)\n })\n )\n this.objectUrl = URL.createObjectURL(mediaSource)\n return this.objectUrl\n }\n\n deactivate() {\n if (!this.active) return\n this.activateDisposer!.dispose()\n this.activateDisposer = null\n // Invalidate any in-flight refreshDuration so its continuation returns\n // at the token check rather than setting duration (and logging) after\n // deactivation.\n ++this.durationToken\n try {\n URL.revokeObjectURL(this.objectUrl!)\n } catch (error) {\n logWarn(this, 'error revoking object url', error)\n }\n }\n\n private get sourceBufferCount(): number {\n return this.sourceBuffers.size\n }\n\n private readonly errorHandler = (error: any) => {\n if (isSilentError(error)) return\n this.dispatch('error', {\n target: this,\n error,\n })\n }\n\n /**\n * Sets the duration on the media source from the current media timeline.\n * Live streams use LIVE_DURATION since not all browsers support +Infinity duration.\n *\n * MSE throws InvalidStateError if duration is set while any source buffer is updating,\n * so we wait for all tracked source buffers to be idle first.\n */\n private async refreshDuration(): Promise<void> {\n const mediaSource = this.mediaSource!\n const timelinePromise = this.deps.mediaTimelineTransformed.value\n const token = ++this.durationToken\n const timeline = await timelinePromise\n const duration = await timeline.getDuration()\n const value =\n duration === Infinity ? LIVE_DURATION : duration + DURATION_PADDING\n await Promise.all(Array.from(this.sourceBuffers, nextSourceBufferIdle))\n if (\n token !== this.durationToken ||\n mediaSource.readyState !== 'open' ||\n closeTo(mediaSource.duration, value, 0.1)\n )\n return\n logDebug(this, `setting duration: ${value}`)\n mediaSource.duration = value\n this.durationSet = true\n this.checkReady()\n }\n\n get readyState(): ReadyState {\n return this.mediaSource?.readyState ?? 'closed'\n }\n\n createSourceBuffer(\n contentType: ContentType,\n mimeType: string\n ): SourceBufferRef {\n if (!this.active) {\n throw new IllegalStateError(\n 'cannot create a source buffer when not active'\n )\n }\n const mediaSource = this.mediaSource!\n logDebug(\n this,\n 'create source buffer',\n contentType,\n mimeType,\n mediaSource.readyState,\n 'sourceBufferCount:',\n this.sourceBufferCount\n )\n let sourceBuffer: SourceBuffer\n try {\n sourceBuffer = mediaSource.addSourceBuffer(mimeType)\n } catch (error: any) {\n throw new MediaSourceError('error creating source buffer', error)\n }\n sourceBuffer.mode = 'sequence'\n this.sourceBuffers.add(sourceBuffer)\n this.checkReady()\n\n return {\n value: sourceBuffer,\n dispose: () => {\n logDebug(\n this,\n 'removing source buffer from media source',\n mediaSource.readyState\n )\n if (mediaSource.readyState !== 'closed') {\n mediaSource.removeSourceBuffer(sourceBuffer)\n }\n this.sourceBuffers.delete(sourceBuffer)\n },\n }\n }\n\n /**\n * Emits a 'readyToAppend' event if all source buffers have been created and the duration\n * has been applied to the media source.\n */\n private readonly checkReady = () => {\n if (this.readyToAppend) this.dispatch('readyToAppend', {})\n }\n\n endOfStream(error?: EndOfStreamError) {\n logDebug(this, 'endOfStream, error:', error)\n this.mediaSource?.endOfStream(error)\n }\n\n get readyToAppend(): boolean {\n return (\n this.durationSet &&\n this.contentTypes?.size === this.sourceBufferCount\n )\n }\n\n dispose() {\n super.dispose()\n this.deactivate()\n }\n}\n\nexport class MediaSourceError extends ReportableError {\n get [Symbol.toStringTag](): string {\n return 'MediaSourceError'\n }\n\n constructor(\n message: string,\n private readonly reason: Error\n ) {\n super(message, ErrorOrigin.INTERNAL, ErrorLevel.FATAL)\n Object.setPrototypeOf(this, MediaSourceError.prototype)\n }\n\n toJSON(): Json {\n return {\n ...super.toJSON(),\n reason: toJson(this.reason),\n }\n }\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { promise } from '@amazon/vinyl-util'\nimport type { Maybe } from '@amazon/vinyl-util'\nimport { SourceBufferError } from '../../streaming/buffering/error/SourceBufferError'\nimport { AbortError } from '@amazon/vinyl-util'\n\n/**\n * Returns a promise that resolves when the given source buffer is next idle.\n * If the source buffer errs, the promise will be rejected with a {@link SourceBufferError}.\n *\n * @param sourceBuffer\n */\nexport function nextSourceBufferIdle(\n sourceBuffer: Maybe<SourceBuffer>\n): Promise<void> {\n if (!sourceBuffer) return Promise.resolve()\n if (!sourceBuffer.updating) return Promise.resolve()\n return promise((resolve, reject) => {\n const removeListeners = () => {\n sourceBuffer.removeEventListener('error', onErred)\n sourceBuffer.removeEventListener('abort', onAborted)\n sourceBuffer.removeEventListener('update', onEnded)\n }\n const onEnded = () => {\n removeListeners()\n resolve()\n }\n const onErred = (_event: any) => {\n removeListeners()\n reject(new SourceBufferError())\n }\n const onAborted = () => {\n removeListeners()\n reject(new AbortError())\n }\n sourceBuffer.addEventListener('error', onErred)\n sourceBuffer.addEventListener('abort', onAborted)\n sourceBuffer.addEventListener('update', onEnded)\n })\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {\n createLogPrefix,\n createTaskQueue,\n createTimeRangesReader,\n type Disposable,\n emptyRanges,\n ErrorOrigin,\n IllegalStateError,\n logDebug,\n type LogTarget,\n nextEventAsPromise,\n type ReadonlyRanges,\n type Task,\n} from '@amazon/vinyl-util'\nimport { nextSourceBufferIdle } from '../../util/media/sourceBuffer'\nimport { SourceBufferError } from './error/SourceBufferError'\nimport type {\n MediaSourceController,\n SourceBufferRef,\n} from './MediaSourceController'\nimport type { ContentType } from '../MediaQualityMetadata'\n\n// Prevents unintentionally dropped keyframes\nexport const APPEND_WINDOW_START_OFFSET = 0.05\nexport const APPEND_WINDOW_END_OFFSET = 0.01\n\n// The number of seconds before aborting the wait for media source controller's readyToAppend event.\nexport const READY_TO_APPEND_TIMEOUT = 30\n\nexport type SourceBufferControllerFactory = () => SourceBufferController\n\nexport interface SourceBufferController extends Disposable {\n readonly buffered: ReadonlyRanges\n\n /**\n * Returns true if an operation is currently running.\n */\n isBusy(): boolean\n\n /**\n * Enqueues an operation.\n * Guaranteed to be invoked when the source buffer is not updating.\n */\n enqueue<T = void>(task: Task<T>): Promise<T>\n\n /**\n * Enqueues appending an initialization segment, reinitializing the decoder.\n */\n appendInit(data: ArrayBuffer, mimeType: string): Promise<void>\n\n /**\n * Enqueues appending a media segment.\n * An `appendInit` call must precede appending media segments.\n * A promise is returned that will resolve when the task is complete.\n */\n append(data: ArrayBuffer): Promise<void>\n\n /**\n * Sets the timestampOffset on the backing source buffer.\n */\n setTimestampOffset(timestampOffset: number): Promise<void>\n\n /**\n * Sets the append window on the backing source buffer.\n * Keyframes outside this range will be discarded.\n */\n setAppendWindow(\n appendWindowStart?: number,\n appendWindowEnd?: number\n ): Promise<void>\n\n /**\n * Removes media segments within a specific time range from the SourceBuffer.\n */\n remove(startTime: number, endTime: number): Promise<void>\n\n /**\n * Aborts any pending buffers and clears all buffered ranges.\n */\n clear(): Promise<void>\n}\n\nexport interface SourceBufferControllerImplDeps {\n /**\n * Produces the source buffer for appending.\n */\n readonly mediaSourceController: MediaSourceController\n}\n\n/**\n * The SourceBufferController manages a single source buffer. It provides queued commands for appending and clearing\n * data.\n */\nexport class SourceBufferControllerImpl\n implements LogTarget, SourceBufferController, Disposable\n{\n get [Symbol.toStringTag](): string {\n return `SourceBuffer_${this.contentType}`\n }\n\n private sourceBufferRef: SourceBufferRef | null = null\n\n private mimeType: string | null = null\n private queue = /* @__PURE__ */ createTaskQueue()\n\n // Assigned in the constructor body: a field initializer runs before the\n // contentType param-property, so it would capture `undefined`.\n readonly logPrefix: string\n private readonly mediaSourceController: MediaSourceController\n\n constructor(\n deps: SourceBufferControllerImplDeps,\n readonly contentType: ContentType\n ) {\n this.logPrefix = createLogPrefix(`SourceBuffer_${contentType}`)\n logDebug(this, 'constructed, contentType:', contentType)\n this.mediaSourceController = deps.mediaSourceController\n }\n\n private get sourceBuffer(): SourceBuffer | null {\n return this.sourceBufferRef && this.sourceBufferRef.value\n }\n\n private _buffered: ReadonlyRanges | null = null\n get buffered(): ReadonlyRanges {\n if (this._buffered == null) {\n if (!this.sourceBuffer) this._buffered = emptyRanges\n else\n this._buffered = createTimeRangesReader(\n this.sourceBuffer.buffered\n )\n }\n return this._buffered\n }\n\n /**\n * Clears the cached buffered ranges. They will be recreated next access.\n */\n private clearBufferedCache = () => {\n this._buffered = null\n }\n\n isBusy(): boolean {\n return this.queue.running > 0\n }\n\n enqueue<T = void>(task: Task<T>): Promise<T> {\n return this.queue.enqueue(task)\n }\n\n async appendInit(data: ArrayBuffer, mimeType: string): Promise<void> {\n return this.queue.enqueue(async (abort) => {\n if (this.mimeType !== mimeType) {\n if (this.sourceBuffer && 'changeType' in this.sourceBuffer) {\n // There is an existing source buffer and its mime type can be changed.\n logDebug(this, 'changeType', mimeType)\n this.sourceBuffer.changeType(mimeType)\n } else {\n // There is either no existing source buffer or a new buffer must be created\n // with the new mime type.\n this.sourceBufferRef?.dispose()\n const newSourceBufferRef =\n this.mediaSourceController.createSourceBuffer(\n this.contentType,\n mimeType\n )\n // Do not append to the source buffer until all streams have been created:\n if (!this.mediaSourceController.readyToAppend)\n await nextEventAsPromise(\n this.mediaSourceController,\n 'readyToAppend',\n { timeout: READY_TO_APPEND_TIMEOUT, abort }\n ).catch((error) => {\n // The readyToAppend was aborted or timed out, dispose the source buffer\n newSourceBufferRef.dispose()\n throw error\n })\n this.sourceBufferRef = newSourceBufferRef\n }\n this.mimeType = mimeType\n }\n const sourceBuffer = this.sourceBuffer!\n logDebug(this, `appending init ${data.byteLength} bytes`)\n sourceBuffer.appendBuffer(data)\n await this.nextIdle()\n logDebug(this, 'appended init')\n })\n }\n\n async append(data: ArrayBuffer): Promise<void> {\n return this.queue.enqueue(async () => {\n logDebug(this, `appending ${data.byteLength} bytes`)\n const sourceBuffer = this.sourceBuffer\n if (!sourceBuffer)\n throw new SourceBufferError(\n 'media segment provided before init segment',\n ErrorOrigin.INTERNAL\n )\n sourceBuffer.appendBuffer(data)\n await this.nextIdle()\n logDebug(this, 'appended', this.buffered)\n })\n }\n\n setTimestampOffset(timestampOffset: number): Promise<void> {\n return this.queue.enqueue(() => {\n const sourceBuffer = this.sourceBuffer\n if (!sourceBuffer)\n throw new IllegalStateError(\n 'source buffer must be initialized before setting timestamp offset'\n )\n logDebug(this, 'timestampOffset:', timestampOffset.toFixed(4))\n sourceBuffer.timestampOffset = timestampOffset\n })\n }\n\n setAppendWindow(\n appendWindowStart: number = 0,\n appendWindowEnd: number = Number.POSITIVE_INFINITY\n ): Promise<void> {\n return this.queue.enqueue(() => {\n const sourceBuffer = this.sourceBuffer\n if (!sourceBuffer)\n throw new IllegalStateError(\n 'source buffer must be initialized before setting append window'\n )\n const finalAppendWindowStart = Math.max(\n 0,\n appendWindowStart - APPEND_WINDOW_START_OFFSET\n )\n const finalAppendWindowEnd =\n appendWindowEnd + APPEND_WINDOW_END_OFFSET\n logDebug(\n this,\n 'appendWindow:',\n finalAppendWindowStart.toFixed(4),\n finalAppendWindowEnd.toFixed(4)\n )\n\n // start may not be greater than end, even temporarily.\n // Avoids the error: \"Failed to set the 'appendWindow___' property\"\n sourceBuffer.appendWindowStart = 0\n sourceBuffer.appendWindowEnd = finalAppendWindowEnd\n sourceBuffer.appendWindowStart = finalAppendWindowStart\n })\n }\n\n remove(startTime: number, endTime: number): Promise<void> {\n return this.queue.enqueue(async () => {\n if (endTime > startTime) {\n logDebug(this, `removing range: ${startTime}-${endTime}`)\n this.sourceBuffer?.remove(startTime, endTime)\n await this.nextIdle()\n logDebug(this, 'removed, new buffered:', this.buffered)\n }\n })\n }\n\n /**\n * Returns a promise that resolves when the source buffer is no longer updating.\n * @private\n */\n private nextIdle = (): Promise<void> =>\n nextSourceBufferIdle(this.sourceBuffer).finally(this.clearBufferedCache)\n\n async clear(): Promise<void> {\n await this.remove(0, Number.POSITIVE_INFINITY)\n }\n\n /**\n * Aborts any pending operations and disposes the backed SourceBuffer.\n */\n dispose() {\n logDebug(this, 'dispose')\n this.queue.abort()\n this.sourceBufferRef?.dispose()\n this.sourceBufferRef = null\n }\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {\n createDisposer,\n createLogPrefix,\n type Disposable,\n EventHostImpl,\n logDebug,\n type Maybe,\n type ReadonlyEventHost,\n type ReadonlyRanges,\n redispatchEvents,\n} from '@amazon/vinyl-util'\nimport type { StreamingEventMap } from './StreamingEventMap'\nimport type { SegmentController } from './SegmentController'\nimport type { BufferingController } from './buffering/BufferingController'\nimport type { ContentType, MediaQualityMetadata } from './MediaQualityMetadata'\nimport { createContainer, type Factories } from '@amazon/vinyl-di'\n\n/**\n * Creates a new ContentStream for the given content type.\n */\nexport type ContentStreamFactory = (contentType: ContentType) => ContentStream\n\nexport interface ContentStream\n extends ReadonlyEventHost<StreamingEventMap>, Disposable {\n /**\n * The content type for this stream.\n * E.g. 'audio' or 'video'\n */\n readonly contentType: ContentType\n\n /**\n * The prefetched time ranges.\n */\n readonly fetchedRanges: ReadonlyRanges\n\n /**\n * The quality currently being requested.\n */\n readonly streamingQuality: MediaQualityMetadata | null\n\n /**\n * The quality of the currently buffered media for this stream.\n */\n readonly bufferingQuality: MediaQualityMetadata | null\n\n /**\n * The quality for the currently buffered media at currentTime for this stream.\n */\n readonly playbackQuality: MediaQualityMetadata | null\n\n /**\n * The error, if in an error state.\n */\n readonly error: Error | null\n\n /**\n * True if the last segment has been appended.\n */\n readonly bufferingEnded: boolean\n\n /**\n * True while this stream's buffer holds any data.\n */\n readonly hasData: boolean\n\n /**\n * Starts prefetching with the given priority and prefetch start time.\n * @param options\n */\n preload(options: ContentStreamPreloadOptions): void\n\n clearPrefetch(): void\n\n /**\n * Resets the track to recover from error states.\n * Resets both the segment controller and buffering controller to clear failed segments and error conditions.\n */\n reset(): void\n\n /**\n * Activates the content stream, activating sub-controllers.\n */\n activate(options: Maybe<ContentStreamActivateOptions>): void\n\n /**\n * Deactivates the content stream, deactivating sub-controllers.\n */\n deactivate(): void\n}\n\nexport interface ContentStreamPreloadOptions {\n /**\n * Track priority for prefetching.\n * Higher values take precedence.\n */\n readonly prefetchPriority: number\n\n /**\n * The media presentation time (in seconds) to begin prefetching.\n */\n readonly startTime?: Maybe<number>\n}\n\nexport interface ContentStreamActivateOptions {\n /**\n * The media presentation time (in seconds) to seek to.\n */\n readonly startTime?: Maybe<number>\n}\n\nexport interface ContentStreamImplDeps {\n readonly bufferingController: BufferingController\n readonly segmentController: SegmentController\n}\n\nexport class ContentStreamImpl\n extends EventHostImpl<StreamingEventMap>\n implements ContentStream\n{\n get [Symbol.toStringTag](): string {\n return `ContentStream_${this.contentType}`\n }\n\n // Assigned in the constructor body: a field initializer runs before the\n // contentType param-property, so it would capture `undefined`.\n readonly logPrefix: string\n\n private disposer = /* @__PURE__ */ createDisposer()\n private readonly segmentController: SegmentController\n private readonly bufferingController: BufferingController\n\n constructor(\n dependencyFactories: Factories<ContentStreamImplDeps>,\n readonly contentType: ContentType\n ) {\n super()\n this.logPrefix = createLogPrefix(`ContentStream_${contentType}`)\n const { add } = this.disposer\n const deps = add(createContainer(dependencyFactories)).dependencies\n\n this.segmentController = deps.segmentController\n redispatchEvents(this, this.segmentController, [\n 'fetchedRangesChange',\n 'loadSpanMeasured',\n ])\n\n this.bufferingController = deps.bufferingController\n redispatchEvents(this, this.segmentController, [\n 'streamingQualityChange',\n ])\n redispatchEvents(this, this.bufferingController, [\n 'bufferingQualityChange',\n 'playbackQualityChange',\n 'bufferingEnded',\n 'hasDataChange',\n 'error',\n 'codecUnsupported',\n ])\n }\n\n preload(options: ContentStreamPreloadOptions) {\n this.segmentController.configure({\n startTime: options.startTime ?? 0,\n trackPrefetchPriority: options.prefetchPriority,\n })\n }\n\n get fetchedRanges(): ReadonlyRanges {\n return this.segmentController.fetchedRanges\n }\n\n get streamingQuality(): MediaQualityMetadata | null {\n return this.segmentController.streamingQuality ?? null\n }\n\n get bufferingQuality(): MediaQualityMetadata | null {\n return this.bufferingController.bufferingQuality ?? null\n }\n\n get playbackQuality(): MediaQualityMetadata | null {\n return this.bufferingController.playbackQuality ?? null\n }\n\n get hasData(): boolean {\n return this.bufferingController.hasData\n }\n\n get bufferingEnded(): boolean {\n return this.bufferingController.bufferingEnded\n }\n\n get error(): Error | null {\n return this.bufferingController.error ?? this.segmentController.error\n }\n\n /**\n * Clears all fetched fragments and source buffers. Streaming will resume.\n * This should be called if a change has been made where the user would expect an immediate change,\n * for example, changing streaming quality from SD to HD.\n */\n clearPrefetch() {\n logDebug(this, 'clearPrefetch')\n this.segmentController.clear()\n this.bufferingController.clear()\n }\n\n /**\n * Resets the track to recover from error states.\n * Resets both the segment controller and buffering controller to clear failed segments and error conditions.\n */\n reset(): void {\n this.segmentController.reset()\n this.bufferingController.reset()\n }\n\n activate(options: ContentStreamActivateOptions): void {\n logDebug(this, 'activate')\n this.segmentController.configure({\n startTime: options.startTime ?? 0,\n })\n this.segmentController.activate()\n this.bufferingController.activate()\n }\n\n deactivate(): void {\n this.segmentController.deactivate()\n this.bufferingController.deactivate()\n }\n\n dispose(): void {\n super.dispose()\n this.disposer.dispose()\n }\n}\n\n/**\n * The `Factory` to create a function which satisfies `ContentStreamFactory`.\n */\nexport function createContentStreamFactory(deps: {\n readonly createContentStreamFactories: (\n contentType: ContentType\n ) => Factories<ContentStreamImplDeps>\n}) {\n return ((contentType: ContentType) => {\n return new ContentStreamImpl(\n deps.createContentStreamFactories(contentType),\n contentType\n )\n }) satisfies ContentStreamFactory\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type {\n ContentType,\n RestrictableContentType,\n} from './MediaQualityMetadata'\nimport type { ContentTypesValue } from './ContentTypesValue'\nimport type { ObservableValue } from '@amazon/vinyl-observable'\nimport { combineData } from '@amazon/vinyl-observable'\nimport type { ReadonlySet } from '@amazon/vinyl-util'\n\nexport interface AllowedContentTypesValueDeps {\n /**\n * The unfiltered content types present in the manifest.\n */\n readonly baseContentTypesValue: ContentTypesValue\n\n /**\n * The player options. The `allowedContentTypes` allow list restricts which\n * media content types are streamed; `null` means no restriction.\n */\n readonly options: ObservableValue<{\n readonly allowedContentTypes: readonly RestrictableContentType[] | null\n }>\n}\n\n/**\n * Wraps a {@link ContentTypesValue} with the `allowedContentTypes` allow list\n * from the player options. When the allow list is set, only media content\n * types (`'audio'`, `'video'`) in the list are emitted; other media streams\n * are ignored. When it is `null`, the underlying content types pass through\n * unchanged. Text is never restricted by the allow list and always passes\n * through (captions are governed by caption selection).\n *\n * Because the result is derived from the `allowedContentTypes` option via\n * {@link combineData}, changing the option re-emits a newly filtered set, which\n * reloads the track using only the allowed content types.\n */\nexport function createAllowedContentTypesValue(\n deps: AllowedContentTypesValueDeps\n): ContentTypesValue {\n return combineData({\n contentTypes: deps.baseContentTypesValue,\n allowedContentTypes: deps.options.pick('allowedContentTypes'),\n }).map(async ({ contentTypes, allowedContentTypes }) => {\n return filterContentTypes(await contentTypes, allowedContentTypes)\n })\n}\n\n/**\n * Returns the subset of `contentTypes` permitted by the `allowedContentTypes`\n * allow list. A `null` allow list permits everything. Text always passes\n * through regardless of the allow list.\n */\nfunction filterContentTypes(\n contentTypes: ReadonlySet<ContentType>,\n allowedContentTypes: readonly RestrictableContentType[] | null\n): ReadonlySet<ContentType> {\n if (allowedContentTypes == null) return contentTypes\n const allowed = new Set<ContentType>(allowedContentTypes)\n const filtered = new Set<ContentType>()\n for (const contentType of contentTypes) {\n // Text is not subject to the allow list; keep it regardless.\n if (contentType === 'text' || allowed.has(contentType)) {\n filtered.add(contentType)\n }\n }\n return filtered\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { ObservableValue } from '@amazon/vinyl-observable'\nimport { combineData } from '@amazon/vinyl-observable'\nimport type { Capabilities } from '../client/Capabilities'\nimport type { DrmController } from '../drm/DrmController'\nimport type { MediaTimeline } from './MediaTimeline'\nimport {\n filterTimelineQualities,\n filterTimelineQualitiesAsync,\n} from './mediaTimelineFilter'\nimport { createLanguageFilter } from './mediaTimelineLanguageFilter'\nimport {\n createAudioDescriptionFilter,\n throwNoPlayableAudio,\n} from './mediaTimelineAccessibilityFilter'\nimport {\n canPlayMimeType,\n throwMimeTypesUnsupported,\n} from '../track/filters/resourceTypeFilter'\nimport {\n canPlayKeySystem,\n throwKeySystemsUnsupported,\n} from '../track/filters/keySystemFilter'\nimport {\n supportsAudioSamplingRate,\n throwSamplingRatesUnsupported,\n} from '../track/filters/sampleRateFilter'\nimport { throwLanguagesUnsupported } from '../track/filters/languageFilter'\nimport type { CodecOverrides } from '../util/media/codecOverrides'\nimport { resolveCodecOverride } from '../util/media/codecOverrides'\n\nexport interface DefaultMediaTimelineTransformerDeps {\n readonly capabilities: Capabilities\n readonly drmController: DrmController\n readonly mediaTimeline: ObservableValue<Promise<MediaTimeline>>\n readonly options: ObservableValue<{\n readonly preferredAudioLanguage: string | readonly string[] | null\n readonly preferDescriptiveAudio?: boolean\n readonly codecOverrides?: CodecOverrides\n }>\n}\n\n/**\n * The default media timeline transformer filters out unplayable qualities\n * and applies language preferences. Shared by Dash and HLS.\n */\nexport function createDefaultMediaTimelineTransformer(\n deps: DefaultMediaTimelineTransformerDeps\n): ObservableValue<Promise<MediaTimeline>> {\n /**\n * Applies explicit codec overrides on top of browser support detection.\n * An `'allow'`/`'deny'` override for a quality's codec supersedes\n * {@link canPlayMimeType}; otherwise the browser's support check is used.\n */\n function canPlayWithOverrides(\n quality: Parameters<typeof canPlayMimeType>[1],\n codecOverrides: CodecOverrides | undefined\n ): boolean {\n if (quality.mimeType) {\n const override = resolveCodecOverride(\n quality.mimeType,\n codecOverrides\n )\n if (override === 'allow') return true\n if (override === 'deny') return false\n }\n return canPlayMimeType(deps, quality)\n }\n\n async function transformTimeline(\n timeline: MediaTimeline\n ): Promise<MediaTimeline> {\n const codecOverrides = deps.options.value.codecOverrides\n let t = filterTimelineQualities(\n (quality) => canPlayWithOverrides(quality, codecOverrides),\n throwMimeTypesUnsupported,\n timeline\n )\n t = await filterTimelineQualitiesAsync(\n (quality) => canPlayKeySystem(deps, quality),\n throwKeySystemsUnsupported,\n t\n )\n t = filterTimelineQualities(\n (quality, index, array) =>\n supportsAudioSamplingRate(deps, quality, index, array),\n throwSamplingRatesUnsupported,\n t\n )\n // Resolve audio-description eligibility BEFORE the language filter.\n // Description renditions are an accessibility opt-in, not general audio,\n // so they must be gated out (unless opted in via preferDescriptiveAudio)\n // before language selection runs. Otherwise a description rendition\n // whose language tag happens to score higher than the main audio's\n // (e.g. a described 'en' beating a main 'en-US') could win language\n // selection and evict the main audio, stranding the listener on\n // described audio they never opted into. With this gate first, the\n // language filter only ever picks among eligible (main, or opted-in\n // description) renditions.\n t = filterTimelineQualities(\n createAudioDescriptionFilter(\n deps.options.value.preferDescriptiveAudio ?? false\n ),\n throwNoPlayableAudio,\n t\n )\n t = filterTimelineQualities(\n createLanguageFilter(\n deps.options.value.preferredAudioLanguage,\n 'audio'\n ),\n throwLanguagesUnsupported,\n t\n )\n return t\n }\n\n return combineData({\n timeline: deps.mediaTimeline,\n preferredAudioLanguage: deps.options.pick('preferredAudioLanguage'),\n preferDescriptiveAudio: deps.options.pick('preferDescriptiveAudio'),\n codecOverrides: deps.options.pick('codecOverrides'),\n }).map(async ({ timeline }) => {\n return transformTimeline(await timeline)\n })\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type {\n MediaPeriod,\n MediaQualityData,\n MediaTimeline,\n} from './MediaTimeline'\nimport type { MediaQualityMetadata } from './MediaQualityMetadata'\nimport type {\n FilterPredicate,\n FilterPredicateAsync,\n Maybe,\n} from '@amazon/vinyl-util'\nimport { map, memoize } from '@amazon/vinyl-util'\n\n/**\n * Filters qualities in a MediaTimeline using a synchronous predicate.\n * If filtering would remove all qualities from any period, throws via `throwError`.\n */\nexport function filterTimelineQualities(\n filter: Maybe<FilterPredicate<MediaQualityMetadata>>,\n throwError: () => never,\n timeline: MediaTimeline\n): MediaTimeline {\n if (!filter) return timeline\n const mapMetadataArray = memoize(\n (qualities: readonly MediaQualityData[]) =>\n map(qualities, (q) => q.metadata),\n (qualities) => qualities,\n 1\n )\n\n const periods = timeline.periods.map((period) => {\n const filtered = period.qualities.filter((q, index) =>\n filter(q.metadata, index, mapMetadataArray(period.qualities))\n )\n return { ...period, qualities: filtered }\n })\n\n if (periods.some((p) => p.qualities.length === 0)) {\n throwError()\n }\n\n return { ...timeline, periods }\n}\n\n/**\n * Filters qualities in a MediaTimeline using an asynchronous predicate.\n * If filtering would remove all qualities from any period, throws via `throwError`.\n */\nexport async function filterTimelineQualitiesAsync(\n filter: FilterPredicateAsync<MediaQualityMetadata>,\n throwError: () => never,\n timeline: MediaTimeline\n): Promise<MediaTimeline> {\n const mapMetadataArray = memoize(\n (qualities: readonly MediaQualityData[]) =>\n map(qualities, (q) => q.metadata),\n (qualities) => qualities,\n 1\n )\n\n const periods: MediaPeriod[] = []\n for (const period of timeline.periods) {\n const filtered: MediaQualityData[] = []\n const metadataArray = mapMetadataArray(period.qualities)\n for (let i = 0; i < period.qualities.length; i++) {\n if (await filter(period.qualities[i].metadata, i, metadataArray)) {\n filtered.push(period.qualities[i])\n }\n }\n periods.push({ ...period, qualities: filtered })\n }\n\n if (periods.some((p) => p.qualities.length === 0)) {\n throwError()\n }\n\n return { ...timeline, periods }\n}\n\n/**\n * Creates a language filter predicate for use with filterTimelineQualities.\n */\nexport { createLanguageFilter } from './mediaTimelineLanguageFilter'\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { MediaQualityMetadata } from './MediaQualityMetadata'\nimport type { FilterPredicate } from '@amazon/vinyl-util'\nimport { memoize } from '@amazon/vinyl-util'\nimport { languageRelatedness } from '../track/filters/languageFilter'\n\n/**\n * Resolves the preferred-language option to an ordered list of BCP 47 tags,\n * most-preferred first.\n *\n * - a string becomes a single-element list\n * - an array is used as-is (already ordered)\n * - `null` falls back to the platform's `navigator.languages` order \u2014 `null`\n * means \"use the platform preference\", not \"no preference\"\n * - an empty list (empty array, or `navigator.languages` unavailable) means no\n * preference: keep all languages\n */\nexport function resolvePreferredLanguages(\n preferred: string | readonly string[] | null\n): readonly string[] {\n if (typeof preferred === 'string') return [preferred]\n if (preferred) return preferred\n if (typeof navigator !== 'undefined') return [...navigator.languages]\n return []\n}\n\n/**\n * Creates a filter predicate that keeps the qualities best matching the\n * preferred language(s). The preference is an ordered list (see\n * {@link resolvePreferredLanguages}): earlier entries win, and relatedness\n * (exact > parent > sibling > child) breaks ties within a single preference.\n *\n * The best match is computed per period (per unique array reference), so\n * periods with different available languages are handled independently. When no\n * available language relates to any preference, all are kept (playback is never\n * stranded). Qualities not matching the content type, or without a language\n * tag, are always kept.\n *\n * @param preferredLanguage BCP 47 tag, ordered list of tags, or null (which\n * falls back to `navigator.languages`).\n * @param contentType Only filter qualities matching this content type (e.g. 'audio').\n */\nexport function createLanguageFilter(\n preferredLanguage: string | readonly string[] | null,\n contentType: string\n): FilterPredicate<MediaQualityMetadata> | null {\n const preferences = resolvePreferredLanguages(preferredLanguage)\n if (preferences.length === 0) return null\n\n // Ranks a language against the ordered preference list. Earlier preferences\n // dominate (weighted by list position); relatedness breaks ties within one.\n // 0 means the language is unrelated to every preference.\n const scoreLang = (lang: string): number => {\n let best = 0\n for (let i = 0; i < preferences.length; i++) {\n const rel = languageRelatedness(preferences[i], lang)\n if (rel > 0) {\n best = Math.max(best, (preferences.length - i) * 10 + rel)\n }\n }\n return best\n }\n\n // The best score among the period's languages, memoized per unique array.\n const bestScoreForPeriod = memoize(\n (array: ArrayLike<MediaQualityMetadata>) => {\n let best = 0\n for (const quality of Array.from(array)) {\n if (quality.contentType === contentType && quality.lang) {\n best = Math.max(best, scoreLang(quality.lang))\n }\n }\n return best\n },\n (array) => array,\n 1\n )\n\n return (quality, _index, array) => {\n if (quality.contentType !== contentType) return true\n if (!quality.lang) return true\n const best = bestScoreForPeriod(array)\n // Nothing matched any preference; keep all rather than strand playback.\n if (best === 0) return true\n return scoreLang(quality.lang) === best\n }\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { compareBy, max, MediaUnsupportedError } from '@amazon/vinyl-util'\n\nexport function throwLanguagesUnsupported(): never {\n throw new MediaUnsupportedError(\n 'No content matching preferred language',\n 'language'\n )\n}\n\n/**\n * Map from ISO 639-2 (3-letter) to ISO 639-1 (2-letter) codes.\n * Covers the most common languages encountered in streaming media.\n */\nconst iso3to2 = /* @__PURE__ */ new Map<string, string>([\n ['aar', 'aa'],\n ['abk', 'ab'],\n ['afr', 'af'],\n ['aka', 'ak'],\n ['amh', 'am'],\n ['ara', 'ar'],\n ['arg', 'an'],\n ['asm', 'as'],\n ['ava', 'av'],\n ['ave', 'ae'],\n ['aym', 'ay'],\n ['aze', 'az'],\n ['bak', 'ba'],\n ['bam', 'bm'],\n ['bel', 'be'],\n ['ben', 'bn'],\n ['bis', 'bi'],\n ['bod', 'bo'],\n ['bos', 'bs'],\n ['bre', 'br'],\n ['bul', 'bg'],\n ['cat', 'ca'],\n ['ces', 'cs'],\n ['cha', 'ch'],\n ['che', 'ce'],\n ['chu', 'cu'],\n ['chv', 'cv'],\n ['cor', 'kw'],\n ['cos', 'co'],\n ['cre', 'cr'],\n ['cym', 'cy'],\n ['dan', 'da'],\n ['deu', 'de'],\n ['div', 'dv'],\n ['dzo', 'dz'],\n ['ell', 'el'],\n ['eng', 'en'],\n ['epo', 'eo'],\n ['est', 'et'],\n ['eus', 'eu'],\n ['ewe', 'ee'],\n ['fao', 'fo'],\n ['fas', 'fa'],\n ['fij', 'fj'],\n ['fin', 'fi'],\n ['fra', 'fr'],\n ['fry', 'fy'],\n ['ful', 'ff'],\n ['gla', 'gd'],\n ['gle', 'ga'],\n ['glg', 'gl'],\n ['glv', 'gv'],\n ['grn', 'gn'],\n ['guj', 'gu'],\n ['hat', 'ht'],\n ['hau', 'ha'],\n ['heb', 'he'],\n ['her', 'hz'],\n ['hin', 'hi'],\n ['hmo', 'ho'],\n ['hrv', 'hr'],\n ['hun', 'hu'],\n ['hye', 'hy'],\n ['ibo', 'ig'],\n ['ido', 'io'],\n ['iii', 'ii'],\n ['iku', 'iu'],\n ['ile', 'ie'],\n ['ina', 'ia'],\n ['ind', 'id'],\n ['ipk', 'ik'],\n ['isl', 'is'],\n ['ita', 'it'],\n ['jav', 'jv'],\n ['jpn', 'ja'],\n ['kal', 'kl'],\n ['kan', 'kn'],\n ['kas', 'ks'],\n ['kat', 'ka'],\n ['kau', 'kr'],\n ['kaz', 'kk'],\n ['khm', 'km'],\n ['kik', 'ki'],\n ['kin', 'rw'],\n ['kir', 'ky'],\n ['kom', 'kv'],\n ['kon', 'kg'],\n ['kor', 'ko'],\n ['kua', 'kj'],\n ['kur', 'ku'],\n ['lao', 'lo'],\n ['lat', 'la'],\n ['lav', 'lv'],\n ['lim', 'li'],\n ['lin', 'ln'],\n ['lit', 'lt'],\n ['ltz', 'lb'],\n ['lub', 'lu'],\n ['lug', 'lg'],\n ['mah', 'mh'],\n ['mal', 'ml'],\n ['mar', 'mr'],\n ['mkd', 'mk'],\n ['mlg', 'mg'],\n ['mlt', 'mt'],\n ['mon', 'mn'],\n ['mri', 'mi'],\n ['msa', 'ms'],\n ['mya', 'my'],\n ['nau', 'na'],\n ['nav', 'nv'],\n ['nbl', 'nr'],\n ['nde', 'nd'],\n ['ndo', 'ng'],\n ['nep', 'ne'],\n ['nld', 'nl'],\n ['nno', 'nn'],\n ['nob', 'nb'],\n ['nor', 'no'],\n ['nya', 'ny'],\n ['oci', 'oc'],\n ['oji', 'oj'],\n ['ori', 'or'],\n ['orm', 'om'],\n ['oss', 'os'],\n ['pan', 'pa'],\n ['pli', 'pi'],\n ['pol', 'pl'],\n ['por', 'pt'],\n ['pus', 'ps'],\n ['que', 'qu'],\n ['roh', 'rm'],\n ['ron', 'ro'],\n ['run', 'rn'],\n ['rus', 'ru'],\n ['sag', 'sg'],\n ['san', 'sa'],\n ['sin', 'si'],\n ['slk', 'sk'],\n ['slv', 'sl'],\n ['sme', 'se'],\n ['smo', 'sm'],\n ['sna', 'sn'],\n ['snd', 'sd'],\n ['som', 'so'],\n ['sot', 'st'],\n ['spa', 'es'],\n ['sqi', 'sq'],\n ['srd', 'sc'],\n ['srp', 'sr'],\n ['ssw', 'ss'],\n ['sun', 'su'],\n ['swa', 'sw'],\n ['swe', 'sv'],\n ['tah', 'ty'],\n ['tam', 'ta'],\n ['tat', 'tt'],\n ['tel', 'te'],\n ['tgk', 'tg'],\n ['tgl', 'tl'],\n ['tha', 'th'],\n ['tir', 'ti'],\n ['ton', 'to'],\n ['tsn', 'tn'],\n ['tso', 'ts'],\n ['tuk', 'tk'],\n ['tur', 'tr'],\n ['twi', 'tw'],\n ['uig', 'ug'],\n ['ukr', 'uk'],\n ['urd', 'ur'],\n ['uzb', 'uz'],\n ['ven', 've'],\n ['vie', 'vi'],\n ['vol', 'vo'],\n ['wln', 'wa'],\n ['wol', 'wo'],\n ['xho', 'xh'],\n ['yid', 'yi'],\n ['yor', 'yo'],\n ['zha', 'za'],\n ['zho', 'zh'],\n ['zul', 'zu'],\n // Bibliographic codes (ISO 639-2/B) that differ from terminological codes\n ['alb', 'sq'],\n ['arm', 'hy'],\n ['baq', 'eu'],\n ['bur', 'my'],\n ['chi', 'zh'],\n ['cze', 'cs'],\n ['dut', 'nl'],\n ['fre', 'fr'],\n ['geo', 'ka'],\n ['ger', 'de'],\n ['gre', 'el'],\n ['ice', 'is'],\n ['mac', 'mk'],\n ['mao', 'mi'],\n ['may', 'ms'],\n ['per', 'fa'],\n ['rum', 'ro'],\n ['slo', 'sk'],\n ['tib', 'bo'],\n ['wel', 'cy'],\n])\n\n/**\n * Normalizes a BCP 47 / RFC 5646 language tag.\n *\n * - Converts ISO 639-2 (3-letter) codes to ISO 639-1 (2-letter)\n * - Forces language to lowercase, region to uppercase\n * - Discards script/dialect subtags beyond language-REGION\n *\n * Examples: `eng` \u2192 `en`, `en-us` \u2192 `en-US`, `fra-CA` \u2192 `fr-CA`\n */\nexport function normalizeLanguage(locale: string): string {\n const parts = locale.split('-')\n let language = (parts[0] || '').toLowerCase()\n language = iso3to2.get(language) || language\n const region = parts[1] ? parts[1].toUpperCase() : ''\n return region ? `${language}-${region}` : language\n}\n\n/**\n * Computes a relatedness score between two language codes.\n * Higher is better. 0 means unrelated.\n *\n * - 4: exact match after normalization (e.g. `en-US` vs `en-US`)\n * - 3: candidate is parent of target (e.g. `en` vs `en-US`)\n * - 2: candidate is sibling of target (e.g. `en-CA` vs `en-US`)\n * - 1: candidate is child of target (e.g. `en-US` vs `en`)\n * - 0: unrelated\n */\nexport function languageRelatedness(target: string, candidate: string): number {\n const t = normalizeLanguage(target)\n const c = normalizeLanguage(candidate)\n\n if (c === t) return 4\n\n const tParts = t.split('-')\n const cParts = c.split('-')\n\n if (tParts[0] !== cParts[0]) return 0\n\n // candidate is parent of target: candidate has no region, target does\n if (cParts.length === 1 && tParts.length === 2) return 3\n\n // candidate is sibling: both have regions (different, since exact match already checked)\n if (cParts.length === 2 && tParts.length === 2) return 2\n\n // candidate is child of target: target has no region, candidate does\n return 1 // tParts.length === 1 && cParts.length === 2\n}\n\n/**\n * Finds the best language match from a set of available languages.\n * Returns the best matching language, or undefined if the set is empty.\n * When no language is related, the first available language is returned.\n */\nexport function findBestLanguageMatch(\n target: string,\n available: ArrayLike<string>\n): string | undefined {\n return max(\n available,\n compareBy((lang) => languageRelatedness(target, lang))\n )\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { MediaQualityMetadata } from './MediaQualityMetadata'\nimport type { FilterPredicate } from '@amazon/vinyl-util'\nimport { MediaUnsupportedError, memoize } from '@amazon/vinyl-util'\n\n/**\n * Thrown if the audio-description filter ever emptied a period's audio. The\n * filter keeps at least one audio rendition per period by design, so this is a\n * defensive guard rather than an expected path.\n */\nexport function throwNoPlayableAudio(): never {\n throw new MediaUnsupportedError('No playable audio rendition', 'audio')\n}\n\n/**\n * Characteristics that mark an audio rendition as an audio description (a.k.a.\n * described video / DVS) \u2014 narration of on-screen action for viewers who cannot\n * see it. HLS signals this with the `public.accessibility.describes-video`\n * CHARACTERISTIC; DASH with a `description` Role. Such renditions must not be\n * chosen as the default audio; they are an accessibility opt-in.\n */\nexport const AUDIO_DESCRIPTION_CHARACTERISTICS: readonly string[] = [\n 'public.accessibility.describes-video',\n 'description',\n]\n\n/**\n * Whether an audio quality is an audio-description rendition.\n */\nexport function isAudioDescription(quality: MediaQualityMetadata): boolean {\n return quality.characteristics.some((c) =>\n AUDIO_DESCRIPTION_CHARACTERISTICS.includes(c)\n )\n}\n\n/**\n * Creates a filter that keeps audio-description renditions out of (or, when\n * opted in, restricts audio to) the audio selection.\n *\n * - `preferDescription: false` (default): drop audio-description renditions\n * from each period *when a non-description audio alternative exists*, so the\n * main audio is chosen by default instead of the description track. If a\n * period has only description audio, it is kept (playback is never stranded).\n * - `preferDescription: true`: keep only description renditions when the period\n * has any; otherwise keep all (again, never strand playback).\n *\n * Non-audio qualities are always kept.\n */\nexport function createAudioDescriptionFilter(\n preferDescription: boolean\n): FilterPredicate<MediaQualityMetadata> {\n // Per period (per unique array reference): does it have description audio,\n // and does it have non-description (\"main\") audio?\n const periodFlags = memoize(\n (array: ArrayLike<MediaQualityMetadata>) => {\n let hasDescription = false\n let hasMain = false\n for (const quality of Array.from(array)) {\n if (quality.contentType !== 'audio') continue\n if (isAudioDescription(quality)) hasDescription = true\n else hasMain = true\n }\n return { hasDescription, hasMain }\n },\n (array) => array,\n 1\n )\n\n return (quality, _index, array) => {\n if (quality.contentType !== 'audio') return true\n const { hasDescription, hasMain } = periodFlags(array)\n if (preferDescription) {\n // Nothing to prefer; keep all rather than strand playback.\n if (!hasDescription) return true\n return isAudioDescription(quality)\n }\n // No main alternative; keep all rather than strand playback.\n if (!hasMain) return true\n return !isAudioDescription(quality)\n }\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { Capabilities } from '../../client/Capabilities'\nimport type { MediaFormatMetadata } from '../../streaming/MediaQualityMetadata'\nimport { MediaUnsupportedError } from '@amazon/vinyl-util'\n\nexport function throwMimeTypesUnsupported(): never {\n throw new MediaUnsupportedError(\n 'No resource type supported (container/codec).',\n 'resource-type'\n )\n}\n\n/**\n * Returns true when the media's codec and container is supported.\n */\nexport function canPlayMimeType(\n deps: { readonly capabilities: Capabilities },\n metadata: MediaFormatMetadata\n): boolean {\n if (!metadata.mimeType) return false\n return deps.capabilities.canPlayTypeMse(metadata.mimeType)\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { MediaQualityMetadata } from '../../streaming/MediaQualityMetadata'\nimport { type DrmController } from '../../drm/DrmController'\nimport { MediaUnsupportedError } from '@amazon/vinyl-util'\n\nexport function throwKeySystemsUnsupported(): never {\n throw new MediaUnsupportedError('No key system supported.', 'key-system')\n}\n\n/**\n * Returns true when the media's key system is supported or the representation has no content protection.\n */\nexport async function canPlayKeySystem(\n deps: { readonly drmController: DrmController },\n metadata: MediaQualityMetadata\n): Promise<boolean> {\n if (!metadata.contentProtections.length) return true // Is not content protected.\n return (await deps.drmController.isSupported(metadata)).supported\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { MediaQualityMetadata } from '../../streaming/MediaQualityMetadata'\nimport {\n hasBrowser,\n Browser,\n last,\n MediaUnsupportedError,\n every,\n map,\n min,\n} from '@amazon/vinyl-util'\nimport type { Capabilities } from '../../client/Capabilities'\n\nexport function throwSamplingRatesUnsupported(): never {\n throw new MediaUnsupportedError('No supported sample rate', 'sampling-rate')\n}\n\n/**\n * Returns true when the media's sampling rate is supported.\n * If Firefox (which does not support >48kHz), filter out all sampling rates above the supported sampling rate.\n * All other browsers filter out all sampling rates above the supported sampling rate unless this will filter all\n * and then do not filter the lowest sampling rate.\n */\nexport function supportsAudioSamplingRate(\n deps: { readonly capabilities: Capabilities },\n metadata: MediaQualityMetadata,\n _index: number,\n array: ArrayLike<MediaQualityMetadata>\n): boolean {\n const isFirefox = hasBrowser(Browser.FIREFOX)\n const maxSampleRate = deps.capabilities.sampleRate\n const samplingRate = last(metadata.audioSamplingRate)\n\n if (!samplingRate || !maxSampleRate) return true // sampling rate not set\n\n if (isFirefox) {\n // Firefox: filter out all sampling rates above 48_000 Hz\n return samplingRate <= 48_000\n }\n\n // Other browsers: filter out all sampling rates above supported unless this will filter all\n if (samplingRate <= maxSampleRate) return true\n\n // Check if filtering all would remove everything\n const allAboveMax = every(array, (item) => {\n const itemSamplingRate = last(item.audioSamplingRate)\n return itemSamplingRate != null && itemSamplingRate > maxSampleRate\n })\n\n if (allAboveMax) {\n // Find the lowest sampling rate and only allow that one\n const samplingRates = map(array, (item) =>\n last(item.audioSamplingRate)\n ).filter((rate): rate is number => rate != null)\n const lowestSamplingRate = min(samplingRates)\n return samplingRate === lowestSamplingRate\n }\n\n return false\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { extractCodecs } from './codecSupport'\n\n/**\n * An explicit application-provided decision to allow or deny a codec,\n * bypassing the browser's support detection.\n *\n * - `'allow'` forces the codec to be treated as supported even if the browser\n * reports it unsupported (e.g. to opt in to a codec the app knows the\n * platform can decode via an external path).\n * - `'deny'` forces the codec to be treated as unsupported even if the browser\n * reports it supported (e.g. to work around a browser that falsely claims\n * support, or to exclude a codec by policy).\n */\nexport type CodecOverride = 'allow' | 'deny'\n\n/**\n * Explicit codec allow/deny overrides. Keys are RFC 6381 codec strings or\n * prefixes (matched case-insensitively against the start of each codec in a\n * mimeType's `codecs=` list, so `\"hvc1\"` matches `\"hvc1.2.20000000.L123.B0\"`).\n *\n * An override supersedes the browser's support detection entirely. When a\n * mimeType contains multiple codecs, a `'deny'` on any of them denies the\n * mimeType; an `'allow'` applies only when no codec is denied.\n */\nexport type CodecOverrides = Readonly<Record<string, CodecOverride>>\n\n/**\n * Resolves the effective override decision for a mimeType against a set of\n * {@link CodecOverrides}, or undefined when no override applies (in which case\n * the caller should fall back to normal support detection).\n *\n * A `'deny'` on any contained codec wins over an `'allow'` on another, so an\n * explicit deny is never silently overridden by an allow elsewhere in the\n * mimeType.\n */\nexport function resolveCodecOverride(\n mimeType: string,\n overrides: CodecOverrides | undefined\n): CodecOverride | undefined {\n if (!overrides) return undefined\n const entries = Object.entries(overrides)\n if (entries.length === 0) return undefined\n\n const codecs = extractCodecs(mimeType)\n if (codecs.length === 0) return undefined\n\n let sawAllow = false\n for (const codec of codecs) {\n const lower = codec.toLowerCase()\n for (const [key, decision] of entries) {\n if (!lower.startsWith(key.toLowerCase())) continue\n // A deny anywhere wins immediately; otherwise remember the allow.\n if (decision === 'deny') return 'deny'\n sawAllow = true\n }\n }\n return sawAllow ? 'allow' : undefined\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {\n array,\n object,\n type ObjectSchema,\n record,\n type RecordSchema,\n string,\n} from '@amazon/vinyl-validation'\nimport { first, type Maybe, type ReadonlyRecord } from '@amazon/vinyl-util'\nimport { type Uri } from '@amazon/vinyl-xml'\n\n/**\n * A map of scheme URIs to a descriptor list.\n */\nexport type DescriptorRecord = ReadonlyRecord<\n Uri,\n readonly Descriptor[] | undefined\n>\n\n/**\n * A generic descriptor providing extended information.\n */\nexport interface Descriptor {\n /**\n * An optional unique identifier for the descriptor.\n */\n readonly id?: Maybe<string>\n\n /**\n * An optional value associated with the descriptor, whose interpretation depends on the scheme.\n */\n readonly value?: Maybe<string>\n}\n\n/**\n * Gets The first matching descriptor value from a record with a matching URI and optional id.\n *\n * @param record The descriptor record.\n * @param uri The URI key.\n * @param id An optional id. If provided the descriptor must have a matching id.\n */\nexport function getDescriptorValue(\n record: DescriptorRecord,\n uri: Uri,\n id?: Maybe<string>\n): string | null {\n let arr = record[uri]\n if (!arr) return null\n if (id !== undefined) arr = arr.filter((descriptor) => descriptor.id === id)\n return first(arr)?.value ?? null\n}\n\nexport const descriptorValidator: ObjectSchema<Descriptor> = /* @__PURE__ */ object({\n id: /* @__PURE__ */ /* @__PURE__ */ /* @__PURE__ */ string().maybe().optional(),\n value: /* @__PURE__ */ /* @__PURE__ */ /* @__PURE__ */ string().maybe().optional(),\n})\n\nexport const descriptorRecordValidator: RecordSchema<DescriptorRecord> = /* @__PURE__ */ record<\n Uri,\n readonly Descriptor[] | undefined\n>(/* @__PURE__ */ string(), /* @__PURE__ */ /* @__PURE__ */ /* @__PURE__ */ array(descriptorValidator).readonly().orUndefined())\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { data, type MutableValue } from '@amazon/vinyl-observable'\nimport {\n createAbortSlot,\n createDisposer,\n type EventHandler,\n EventHostImpl,\n logDebug,\n type SignalOptions,\n type Unsubscribe,\n} from '@amazon/vinyl-util'\nimport type {\n ManifestController,\n ManifestControllerEventMap,\n ManifestProvider,\n} from './ManifestController'\n\nexport interface ManifestControllerImplDeps<T> {\n readonly manifestProvider: ManifestProvider<T>\n}\n\nexport class ManifestControllerImpl<T> implements ManifestController<\n Promise<T>\n> {\n get [Symbol.toStringTag](): string {\n return 'ManifestControllerImpl'\n }\n\n get logPrefix(): string {\n return 'ManifestControllerImpl'\n }\n\n private readonly _data: MutableValue<Promise<T>>\n private _error: Error | null = null\n private readonly abortSlot = /* @__PURE__ */ createAbortSlot()\n private readonly disposer = /* @__PURE__ */ createDisposer()\n private readonly events = /* @__PURE__ */ new EventHostImpl<ManifestControllerEventMap>()\n private manifestSpanArmed = true\n\n constructor(private readonly deps: ManifestControllerImplDeps<T>) {\n // Kick off the initial manifest request. requestManifest() attaches its\n // own rejection handler, so the stored promise never rejects unhandled.\n this._data = data(this.requestManifest())\n }\n\n on<K extends keyof ManifestControllerEventMap>(\n type: K,\n handler: EventHandler<ManifestControllerEventMap[K]>,\n options?: SignalOptions\n ): Unsubscribe {\n return this.events.on(type, handler, options)\n }\n\n hasAnyListeners(): boolean {\n return this.events.hasAnyListeners()\n }\n\n hasListeners(type: keyof ManifestControllerEventMap): boolean {\n return this.events.hasListeners(type)\n }\n\n readonly __eventMapType = this.events.__eventMapType\n\n /**\n * The most recent error from the manifest provider, or null.\n */\n get error(): Error | null {\n return this._error\n }\n\n refresh(): void {\n logDebug(this, 'refresh')\n this._data.value = this.requestManifest()\n }\n\n private requestManifest(): Promise<T> {\n this.abortSlot.abort()\n this._error = null\n const promise = this.deps.manifestProvider(this.abortSlot.value)\n this.measureLoadSpan(promise)\n promise.catch((error: Error) => {\n this._error = error\n })\n return promise\n }\n\n /**\n * Measures the initial manifest fetch as a load span, re-arming on failure\n * so a recovered load is still measured.\n */\n private measureLoadSpan(promise: Promise<T>): void {\n if (!this.manifestSpanArmed) return\n this.manifestSpanArmed = false\n const startTime = Date.now()\n promise.then(\n () =>\n this.events.dispatch('loadSpanMeasured', {\n kind: 'manifest',\n startTime,\n endTime: Date.now(),\n }),\n () => (this.manifestSpanArmed = true)\n )\n }\n\n reset(): void {\n logDebug(this, 'reset')\n if (this._error) {\n this.refresh()\n }\n }\n\n get value(): Promise<T> {\n return this._data.value\n }\n\n get changeId(): number {\n return this._data.changeId\n }\n\n getValue(): Promise<T> {\n return this._data.getValue()\n }\n\n onData(\n callback: (value: Promise<T>, previous?: Promise<T>) => void\n ): () => void {\n return this._data.onData(callback)\n }\n\n map<U>(fn: (value: Promise<T>) => U) {\n return this._data.map(fn)\n }\n\n pick<K extends keyof NonNullable<Promise<T>>>(key: K) {\n return this._data.pick(key)\n }\n\n get disposed(): boolean {\n return this.disposer.disposed\n }\n\n dispose(): void {\n this.abortSlot.abort()\n this.disposer.dispose()\n this.events.dispose()\n }\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {\n createShortUid,\n type Maybe,\n type MutableDeep,\n} from '@amazon/vinyl-util'\nimport type { ObjectSchema } from '@amazon/vinyl-validation'\nimport {\n array,\n enumOf,\n isOneOf,\n number,\n object,\n string,\n tuple,\n} from '@amazon/vinyl-validation'\nimport {\n type DescriptorRecord,\n descriptorRecordValidator,\n descriptorValidator,\n} from './DescriptorRecord'\n\nimport type { DrmInitDataType } from './DrmInitDataType'\nimport type { CencEncryptionScheme } from '../drm/CencEncryptionScheme'\nimport { DrmKeySystem } from '../drm/DrmKeySystem'\nimport type { FrameRate } from '@amazon/vinyl-mpd-parser'\n\nexport type ContentType = 'audio' | 'video' | 'text'\n\nexport const ALL_CONTENT_TYPES = [\n 'video',\n 'audio',\n 'text',\n] as const satisfies ContentType[]\n\n/**\n * The content types that can be restricted via an allow list (see\n * `VinylOptions.allowedContentTypes`). Text is intentionally excluded: text\n * tracks (subtitles / closed captions) are governed by caption selection, not\n * by the content-type allow list, so they always remain available.\n */\nexport type RestrictableContentType = Exclude<ContentType, 'text'>\n\nexport const RESTRICTABLE_CONTENT_TYPES = [\n 'video',\n 'audio',\n] as const satisfies RestrictableContentType[]\n\n/**\n * Contains media formatting and encryption metadata.\n */\nexport interface MediaFormatMetadata {\n /**\n * The content type of the representation, e.g. 'audio', 'video', 'text'\n * Must be non-null for segmented media.\n */\n readonly contentType: ContentType | null\n\n /**\n * The full MIME type of the media.\n *\n * Must be non-null for segmented media.\n */\n readonly mimeType: string | null\n\n /**\n * The initialization data format.\n */\n readonly initDataType: DrmInitDataType | null\n\n /**\n * The method of encryption, or null.\n */\n readonly encryptionScheme: CencEncryptionScheme | null\n\n /**\n * Protection schemes used in this media.\n */\n readonly contentProtections: readonly DrmProtection[]\n}\n\n/**\n * Protection information for a key system.\n * Media may have more than one protection system.\n */\nexport interface DrmProtection {\n /**\n * The key system used in the encryption.\n */\n readonly keySystem: DrmKeySystem\n\n /**\n * The initialization key, in base 64.\n */\n readonly pssh?: Maybe<string>\n\n /**\n * PlayReady object.\n */\n readonly pro?: Maybe<string>\n}\n\nexport const drmProtectionValidator: ObjectSchema<DrmProtection> =\n /* @__PURE__ */ descriptorValidator.extend({\n keySystem: /* @__PURE__ */ enumOf(DrmKeySystem),\n pro: /* @__PURE__ */ /* @__PURE__ */ /* @__PURE__ */ string().maybe().optional(),\n pssh: /* @__PURE__ */ /* @__PURE__ */ /* @__PURE__ */ string().maybe().optional(),\n })\n\nexport const mediaFormatMetadataValidator: ObjectSchema<MediaFormatMetadata> =\n /* @__PURE__ */ object({\n contentProtections: /* @__PURE__ */ /* @__PURE__ */ array(drmProtectionValidator).readonly(),\n contentType: /* @__PURE__ */ /* @__PURE__ */ isOneOf('audio', 'video', 'text').orNull(),\n initDataType: /* @__PURE__ */ /* @__PURE__ */ string().orNull(),\n encryptionScheme: /* @__PURE__ */ /* @__PURE__ */ string().orNull(),\n mimeType: /* @__PURE__ */ /* @__PURE__ */ string().orNull(),\n })\n\n/**\n * Metadata representing attributes of a media representation.\n */\nexport interface MediaQualityMetadata extends MediaFormatMetadata {\n /**\n * Provides a decoding identifier. If this value changes from the previously buffered\n * segment, the initialization segment must be buffered before appending the media segment.\n * Unique to the track.\n */\n readonly decoderId: string\n\n /**\n * The quality id identifies the quality representation.\n * Unique to the track.\n */\n readonly qualityId: string\n\n /**\n * Optional string specifying the codec(s) used for this representation. The format follows the RFC 6381 codec\n * string format.\n */\n readonly codecs: string | null\n\n /**\n * The average bandwidth in bits per second required for playing this representation.\n * For HLS, and non-segmented media this will be null.\n */\n readonly bandwidth: number | null\n\n /**\n * The peak bandwidth in bits per second required for playing this representation\n * with its cumulative A/V content streams.\n *\n * Guaranteed to be set for segmented media.\n */\n readonly bandwidthTotal: number | null\n\n /**\n * Audio sampling rate(s) in samples per second.\n * An array of either one or two decimal integer values. If there are two elements this represents a minimum and\n * maximum sampling rate of the audio media.\n */\n readonly audioSamplingRate: readonly number[] | null\n\n /**\n * Frame rate for video representations, specified either as a ratio of integers, e.g. [30000, 1001]\n */\n readonly frameRate: FrameRate | null\n\n /**\n * For video representations, the width of the video in pixels.\n */\n readonly width: number | null\n\n /**\n * For video representations, the height of the video in pixels.\n */\n readonly height: number | null\n\n /**\n * Information that may enhance playback or presentation.\n */\n readonly supplementalProperties: DescriptorRecord\n\n /**\n * Specifies the language of the content, using a code as defined by RFC 5646.\n */\n readonly lang: string | null\n\n /**\n * Media characteristics / accessibility roles describing this rendition,\n * e.g. `public.accessibility.describes-video` (HLS CHARACTERISTICS) or a\n * DASH Role / Accessibility scheme value such as `description`. Used to keep\n * accessibility renditions (e.g. audio description) from being auto-selected\n * by default. Empty when none are signaled.\n */\n readonly characteristics: readonly string[]\n\n /**\n * Identifies the group this quality belongs to (e.g. the adaptation set).\n */\n readonly groupId: string\n\n /**\n * The group IDs that this quality is permitted to switch to during playback.\n * Derived from the DASH `urn:mpeg:dash:adaptation-set-switching:2016` supplemental property.\n * Includes the quality's own groupId.\n * Null means no switching constraint (all groups are permitted).\n * An array restricts switching to only the listed group IDs.\n * Default behavior:\n * - DASH: restricted to own group unless adaptation-set-switching property is present.\n * - HLS: restricted to variants with the same base codec and language.\n */\n readonly switchingGroupIds: readonly string[] | null\n}\n\n/**\n * Creates a new, empty media format metadata object.\n */\nexport function createEmptyMediaFormatMetadata(): MutableDeep<MediaFormatMetadata> {\n return {\n contentType: null,\n mimeType: null,\n initDataType: null,\n encryptionScheme: null,\n contentProtections: [],\n }\n}\n\n/**\n * Creates a new empty media quality metadata object.\n */\nexport function createEmptyMediaQualityMetadata(): MutableDeep<MediaQualityMetadata> {\n return {\n ...createEmptyMediaFormatMetadata(),\n decoderId: createShortUid(),\n qualityId: createShortUid(),\n codecs: null,\n bandwidth: null,\n bandwidthTotal: null,\n supplementalProperties: {},\n audioSamplingRate: null,\n frameRate: null,\n height: null,\n width: null,\n lang: null,\n characteristics: [],\n groupId: createShortUid(),\n switchingGroupIds: null,\n }\n}\n\nexport const mediaQualityMetadataValidator: ObjectSchema<MediaQualityMetadata> =\n /* @__PURE__ */ mediaFormatMetadataValidator.extend({\n audioSamplingRate: /* @__PURE__ */ /* @__PURE__ */ /* @__PURE__ */ array(/* @__PURE__ */ number()).readonly().orNull(),\n bandwidth: /* @__PURE__ */ /* @__PURE__ */ number().orNull(),\n bandwidthTotal: /* @__PURE__ */ /* @__PURE__ */ number().orNull(),\n codecs: /* @__PURE__ */ /* @__PURE__ */ string().orNull(),\n decoderId: /* @__PURE__ */ string(),\n frameRate: /* @__PURE__ */ /* @__PURE__ */ /* @__PURE__ */ tuple(/* @__PURE__ */ number(), /* @__PURE__ */ number()).readonly().orNull(),\n height: /* @__PURE__ */ /* @__PURE__ */ number().orNull(),\n qualityId: /* @__PURE__ */ string(),\n supplementalProperties: descriptorRecordValidator,\n width: /* @__PURE__ */ /* @__PURE__ */ number().orNull(),\n lang: /* @__PURE__ */ /* @__PURE__ */ string().orNull(),\n characteristics: /* @__PURE__ */ /* @__PURE__ */ array(/* @__PURE__ */ string()).readonly(),\n groupId: /* @__PURE__ */ string(),\n switchingGroupIds: /* @__PURE__ */ /* @__PURE__ */ /* @__PURE__ */ array(/* @__PURE__ */ string()).readonly().orNull(),\n })\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { SegmentReference } from './SegmentReference'\nimport type { SegmentDataProvider } from './SegmentDataSlot'\nimport type { MediaQualityMetadata } from './MediaQualityMetadata'\nimport { sortedInsertionIndex } from '@amazon/vinyl-util'\nimport type { AdBreakList } from '../ad/AdBreakInfo'\n\n/**\n * Represents a single quality within a period, providing access to its metadata\n * and segment data.\n */\nexport interface MediaQualityData {\n readonly metadata: MediaQualityMetadata\n\n /**\n * Gets the segment reference at the given time, or null if the time is outside the range.\n * @param time The time, in seconds, relative to the presentation timeline.\n * @param affordance Forward-snap tolerance in seconds: if `time` falls just before a\n * segment's start (within `affordance`), that segment is returned. Defaults to `0`.\n */\n getSegment(\n time: number,\n affordance?: number\n ): Promise<SegmentReference<SegmentDataProvider> | null>\n}\n\n/**\n * Represents a period within the media timeline.\n */\nexport interface MediaPeriod {\n readonly startTime: number\n readonly endTime: number\n readonly qualities: readonly MediaQualityData[]\n}\n\n/**\n * Represents the full media timeline, composed of one or more periods.\n */\nexport interface MediaTimeline {\n readonly periods: readonly MediaPeriod[]\n\n /**\n * The minimum duration of the buffer that a client should maintain for uninterrupted playback.\n */\n readonly minBufferTime: number\n\n /**\n * Ad breaks discovered from the media presentation (e.g. HLS Interstitials,\n * DASH SCTE-35). Empty when the stream carries no ad signals.\n */\n getAdBreaks(): Promise<AdBreakList>\n\n /**\n * The total duration of the media, in seconds.\n * Returns `Infinity` for live streams.\n * Rejects when there are no segments to derive a duration from.\n */\n getDuration(): Promise<number>\n}\n\n/**\n * Gets the period spanning the given presentation time.\n */\nexport function getMediaPeriodAtTime(\n timeline: MediaTimeline,\n time: number\n): MediaPeriod | null {\n const index =\n sortedInsertionIndex(timeline.periods, time, (time, period) => {\n return time - period.startTime\n }) - 1\n if (index < 0) return null\n const period = timeline.periods[index]\n return time >= period.endTime ? null : period\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { Mutable, Unsubscribe } from '@amazon/vinyl-util'\nimport {\n Abort,\n clone,\n closeTo,\n createDisposer,\n createLogPrefix,\n EventHostImpl,\n getNetworkState,\n getOrSet,\n isSilentError,\n logDebug,\n logError,\n noop,\n type Range,\n rangeIntersects,\n RangesImpl,\n type ReadonlyAbort,\n type ReadonlyRanges,\n throttle,\n withAbort,\n} from '@amazon/vinyl-util'\nimport { isMimeTypeDenylisted } from './buffering/codecDenylist'\nimport type { ReadonlyPlaybackController } from '../playback/ReadonlyPlaybackController'\nimport {\n type PrefetchOptions,\n SEGMENT_START_AFFORDANCE,\n type SegmentController,\n type SegmentControllerEventMap,\n} from './SegmentController'\nimport {\n type SegmentDataProvider,\n SegmentDataSlot,\n SegmentStatus,\n} from './SegmentDataSlot'\nimport {\n defaultTrackPriority,\n enqueueSegmentPrefetch,\n immediatePrefetchPriority,\n type SegmentPrefetchPriority,\n} from './SegmentPrefetch'\nimport {\n getSegmentAtTime,\n getSegmentInsertionIndexAtTime,\n} from './util/segment'\nimport type { SegmentReference } from './SegmentReference'\nimport type { LoadSpanKind } from './LoadMetric'\nimport type { ContentType, MediaQualityMetadata } from './MediaQualityMetadata'\nimport type { ObservableValue } from '@amazon/vinyl-observable'\nimport type { MediaTimeline } from './MediaTimeline'\nimport { getMediaPeriodAtTime, type MediaPeriod } from './MediaTimeline'\nimport type { PrefetchState, QualitySelector } from './abr/QualitySelector'\n\n/**\n * The interval to check if additional segments should be prefetched.\n */\nexport const PREFETCH_POLL_THROTTLE = 1\n\nexport interface SegmentControllerImplDeps {\n readonly playbackController: ReadonlyPlaybackController\n\n readonly mediaTimelineTransformed: ObservableValue<Promise<MediaTimeline>>\n\n readonly qualitySelector: QualitySelector\n}\n\nexport interface SegmentControllerImplOptions {\n /**\n * The amount of time ahead of the playhead to prefetch when the track is active.\n * Default: 240\n */\n readonly prefetchActive: number\n\n /**\n * The amount of time to prefetch when the track is not active.\n * Default: 20\n */\n readonly prefetchInactive: number\n\n /**\n * The number of seconds behind the playhead to retain segments.\n * Default: 30\n */\n readonly retainTail: number\n}\n\nexport const defaultSegmentControllerBaseOptions: SegmentControllerImplOptions =\n {\n prefetchActive: 180,\n prefetchInactive: 20,\n retainTail: 30,\n }\n\n/**\n * Default SegmentController implementation.\n * Provides segments for a given time.\n * Handles segment prefetching and caching.\n *\n * Uses mediaTimelineTransformed to resolve segments directly from the MediaTimeline.\n */\nexport class SegmentControllerImpl\n extends EventHostImpl<SegmentControllerEventMap>\n implements SegmentController\n{\n get [Symbol.toStringTag](): string {\n return `Segment_${this.contentType}`\n }\n\n // Assigned in the constructor body: a field initializer runs before the\n // contentType param-property, so it would capture `undefined`.\n readonly logPrefix: string\n\n private _active = false\n get active(): boolean {\n return this._active\n }\n\n private readonly _fetchedRanges = /* @__PURE__ */ new RangesImpl()\n private _startTime = 0\n\n /**\n * A map of decoder id to init segment slots.\n * This allows representations with seamless bitstream switching to share initialization segments without\n * making unnecessary requests or decoder re-initializations.\n */\n private readonly cachedInitSegments = /* @__PURE__ */ new Map<string, SegmentDataSlot>()\n private readonly cachedSegments: SegmentReference<SegmentDataSlot>[] = []\n\n private readonly disposer = /* @__PURE__ */ createDisposer()\n readonly options: SegmentControllerImplOptions\n\n private prefetchingPriority: Mutable<SegmentPrefetchPriority> =\n /* @__PURE__ */ clone(defaultTrackPriority)\n\n /**\n * True if the last segment in the prefetch range has been cached.\n */\n private ended = false\n private prefetching = false\n private _error: Error | null = null\n\n // Load-span metrics latch on the first init/media fetch attempt (the flag\n // is cleared when the request is issued) and re-arm if that attempt fails,\n // so a recovered load is still measured.\n private initSpanArmed = true\n private firstSegmentSpanArmed = true\n\n private timeUpdateSub: Unsubscribe | null = null\n private seekingSub: Unsubscribe | null = null\n\n // When disposed, aborts in-flight operations.\n private readonly abort = /* @__PURE__ */ new Abort()\n\n /**\n * Cached last period lookup for fast repeated access.\n */\n private _cachedPeriod: MediaPeriod | null = null\n\n constructor(\n readonly deps: SegmentControllerImplDeps,\n readonly contentType: ContentType,\n options?: Partial<SegmentControllerImplOptions>\n ) {\n super()\n this.logPrefix = createLogPrefix(`Segment_${contentType}`)\n logDebug(this, 'constructed')\n const { add } = this.disposer\n this.options = {\n ...defaultSegmentControllerBaseOptions,\n ...options,\n }\n add(\n deps.mediaTimelineTransformed.onData(() => {\n // If the media timeline changes, re-check ended state.\n this.ended = false\n this._cachedPeriod = null\n this.pollPrefetch()\n this.dispatch('change', {})\n })\n )\n\n add(\n getNetworkState().on('online', () => {\n logDebug(this, 'online, resetting prefetch')\n this.reset()\n })\n )\n }\n\n get error(): Error | null {\n return this._error\n }\n\n /**\n * Gets the period at the given time, using a cache for the last returned period.\n */\n private async getPeriodAtTime(time: number): Promise<MediaPeriod | null> {\n if (\n this._cachedPeriod &&\n time >= this._cachedPeriod.startTime &&\n time < this._cachedPeriod.endTime\n ) {\n return this._cachedPeriod\n }\n const timeline = await this.deps.mediaTimelineTransformed.value\n const period = getMediaPeriodAtTime(timeline, time)\n if (period) this._cachedPeriod = period\n return period\n }\n\n /**\n * Configures this segment provider and initiates prefetching.\n * This may be called multiple times, for example when re-using a cached track a new track priority and start time\n * can be provided.\n */\n configure(options: Partial<PrefetchOptions>) {\n if (options.startTime != null) this._startTime = options.startTime\n if (options.trackPrefetchPriority != null)\n this.prefetchingPriority.trackPriority =\n options.trackPrefetchPriority\n this.ended = false\n this.pollPrefetch()\n }\n\n get startTime(): number {\n return this._startTime\n }\n\n get trackPrefetchPriority(): number {\n return this.prefetchingPriority.trackPriority\n }\n\n /**\n * Returns the range that should be prefetched.\n */\n private get prefetchRange(): Range {\n return this.active\n ? this.prefetchRangeActive\n : this.prefetchRangeInactive\n }\n\n /**\n * Returns the range that should be prefetched when inactive.\n * This range will not be removed during sweeps unless `clear` is called.\n */\n private get prefetchRangeInactive(): Range {\n const prefetchFrom = this.startTime\n const prefetchTo = prefetchFrom + this.options.prefetchInactive\n return [prefetchFrom, prefetchTo]\n }\n\n /**\n * Returns the range that should be prefetched while active.\n */\n private get prefetchRangeActive(): Range {\n const prefetchFrom = this.deps.playbackController.currentTime\n const prefetchTo = prefetchFrom + this.options.prefetchActive\n return [prefetchFrom, prefetchTo]\n }\n\n /**\n * Clears data segments no longer within the current prefetch range.\n * Init segments will not be changed.\n */\n private sweepCachedSegments() {\n // The inactive range (typically first couple segments of a track) will not be removed.\n const inactiveRange = this.prefetchRangeInactive\n\n // The active range prefetch expanded to include the retain tail will not be removed if the track is active.\n const activeRange = this.active\n ? ([\n this.prefetchRangeActive[0] - this.options.retainTail,\n this.prefetchRangeActive[1],\n ] as const)\n : null\n let n = this.cachedSegments.length\n for (let i = 0; i < n; i++) {\n const cachedSegment = this.cachedSegments[i]\n // Check if the cached segment is still within our retain window.\n const { startTime, endTime } = cachedSegment\n const cachedRange = [startTime, endTime] as const\n if (\n !rangeIntersects(inactiveRange, cachedRange) &&\n !(activeRange && rangeIntersects(activeRange, cachedRange))\n ) {\n // No longer need the segment. Does nothing if inactive.\n cachedSegment.data.clear()\n this.cachedSegments.splice(i, 1)\n logDebug(\n this,\n 'removing cached segment at: ',\n cachedSegment.startTime\n )\n i--\n n--\n }\n }\n }\n\n /**\n * Gets the next time to prefetch, or null if the prefetch range has been filled.\n */\n private getNextTimeToPrefetch(): number | null {\n const [prefetchFrom, prefetchTo] = this.prefetchRange\n // fetchedRanges are directly from the segments, safe to use when getting next segment.\n const currentRange = this.fetchedRanges.getRangeAt(prefetchFrom)\n const nextTime = currentRange == null ? prefetchFrom : currentRange[1]\n if (nextTime >= prefetchTo - Number.EPSILON) return null\n return nextTime\n }\n\n private pollPrefetch = /* @__PURE__ */ this.disposer.add(\n /* @__PURE__ */ throttle(\n () => {\n if (this.error) return\n this.sweepCachedSegments()\n if (this.ended || this.prefetching) return\n\n const nextTime = this.getNextTimeToPrefetch()\n if (nextTime == null) return // Prefetched the full range\n this.prefetching = true\n // Enqueue the prefetch.\n enqueueSegmentPrefetch(\n async () => {\n this.abort.throwIfAborted()\n // Quality selection is done at the time of getSegment(), which is called when\n // a slot is created. Defer slot creation until request is about to be made.\n logDebug(this, `Prefetching`, nextTime.toFixed(4))\n const slot = await this.getSlotAtTime(nextTime)\n this.abort.throwIfAborted()\n if (!slot) {\n logDebug(this, 'prefetch ended')\n this.ended = true\n return\n }\n await withAbort(\n Promise.all([\n this.requestInitData(slot),\n this.requestSegmentData(slot),\n ]),\n this.abort\n )\n },\n this.contentType,\n this.prefetchingPriority\n )\n .catch(this.prefetchErrorHandler)\n .finally(() => {\n this.prefetching = false\n if (!this.disposed) this.pollPrefetch()\n })\n },\n PREFETCH_POLL_THROTTLE,\n {\n leading: true,\n trailing: true,\n }\n )\n )\n\n private prefetchErrorHandler = (error: any) => {\n // Only log the error for prefetch failures, it will get reported if/when it is attempted\n // to be buffered.\n if (!this.disposed && !isSilentError(error)) {\n logError(this, 'Error prefetching segment', error)\n this._error = error\n }\n }\n\n /**\n * Requests init-segment data, measuring the first fetch as a load span.\n */\n private requestInitData(\n slot: SegmentReference<SegmentDataSlot>\n ): Promise<ArrayBuffer> {\n const request = slot.initData.request()\n if (this.initSpanArmed) {\n this.initSpanArmed = false\n this.measureLoadSpan('initSegment', request)\n }\n return request\n }\n\n /**\n * Requests media-segment data, measuring the first fetch as a load span.\n */\n private requestSegmentData(\n slot: SegmentReference<SegmentDataSlot>\n ): Promise<ArrayBuffer> {\n const request = slot.data.request()\n if (this.firstSegmentSpanArmed) {\n this.firstSegmentSpanArmed = false\n this.measureLoadSpan('firstSegment', request)\n }\n return request\n }\n\n private measureLoadSpan(\n kind: LoadSpanKind,\n request: Promise<ArrayBuffer>\n ): void {\n const startTime = Date.now()\n request.then(\n () =>\n this.dispatch('loadSpanMeasured', {\n kind,\n startTime,\n endTime: Date.now(),\n }),\n () => {\n if (kind === 'initSegment') this.initSpanArmed = true\n else this.firstSegmentSpanArmed = true\n }\n )\n }\n\n get fetchedRanges(): ReadonlyRanges {\n return this._fetchedRanges\n }\n\n /**\n * Gets the number of seconds currently prefetched.\n */\n get fetchedTime(): number {\n const time = this.active\n ? this.deps.playbackController.currentTime\n : this._startTime\n const currentRange = this.fetchedRanges.getRangeAt(time)\n if (!currentRange) return 0\n return currentRange[1] - time\n }\n\n private _streamingQuality: MediaQualityMetadata | null = null\n\n get streamingQuality(): MediaQualityMetadata | null {\n return this._streamingQuality\n }\n\n private set streamingQuality(value: MediaQualityMetadata | null) {\n const previous = this._streamingQuality\n if (value?.qualityId === previous?.qualityId) return\n this._streamingQuality = value\n logDebug(this, 'streamingQualityChange', value)\n this.dispatch('streamingQualityChange', {\n previous,\n current: value,\n })\n }\n\n getSegment(\n time: number,\n abort?: ReadonlyAbort\n ): Promise<SegmentReference<ArrayBuffer> | null> {\n logDebug(this, `requesting segment at time: ${time.toFixed(4)}`)\n const segmentReferencePromise = withAbort(\n this._getSegment(Math.max(0, time)),\n abort\n )\n\n // When a segment is actively needed, block the prefetch queue until the active segment promise settles:\n enqueueSegmentPrefetch(\n () => segmentReferencePromise,\n this.contentType,\n immediatePrefetchPriority\n ).catch(noop)\n return segmentReferencePromise\n }\n\n private async _getSegment(\n time: number\n ): Promise<SegmentReference<ArrayBuffer> | null> {\n const streamingSlot = await this.getSlotAtTime(time)\n if (!streamingSlot) return null\n logDebug(\n this,\n `init status: ${streamingSlot.initData.status}, data status: ${streamingSlot.data.status}`\n )\n // If prefetch failed, try again now that the segment is actively needed:\n this.resetSlot(streamingSlot)\n\n const initAndDataPromise = Promise.all([\n this.requestInitData(streamingSlot),\n this.requestSegmentData(streamingSlot),\n ])\n\n // If the requested time is close to the start of the next segment, immediately start prefetching the next\n // segment, and not resolving until both are cached.\n let minBufferPrefetch: Promise<void> = Promise.resolve()\n const minBufferTime = await this.getMinBufferTime()\n if (streamingSlot.endTime - time < minBufferTime) {\n minBufferPrefetch = this.prefetchImmediate(\n streamingSlot.endTime\n ).catch(noop) // Ignore error until it is the next segment needed\n }\n const [initData, data] = await initAndDataPromise\n await minBufferPrefetch\n return {\n ...streamingSlot,\n initData,\n data,\n }\n }\n\n /**\n * Gets the minimum buffer time from the timeline.\n * Falls back to a reasonable default.\n */\n private async getMinBufferTime(): Promise<number> {\n const timeline = await this.deps.mediaTimelineTransformed.value\n return timeline.minBufferTime\n }\n\n /**\n * Prefetches the segment at the given time. Does not use the background scheduler.\n *\n * @param time\n */\n private async prefetchImmediate(time: number): Promise<void> {\n const slot = await this.getSlotAtTime(time)\n if (!slot) return\n await Promise.all([\n this.requestInitData(slot),\n this.requestSegmentData(slot),\n ])\n }\n\n /**\n * Gets a streaming segment slot that spans the given time, or null if there is no media at that time.\n * Slots will be cached until they slide out of the retention range or `clear` is called.\n */\n private async getSlotAtTime(\n time: number\n ): Promise<SegmentReference<SegmentDataSlot> | null> {\n // Check if there is a cached slot.\n const cachedSegment = getSegmentAtTime(\n time,\n this.cachedSegments,\n SEGMENT_START_AFFORDANCE\n )\n if (cachedSegment) return cachedSegment\n\n const newSlot = await withAbort(\n this.createSlotForTime(time),\n this.abort\n )\n this.abort.throwIfAborted()\n\n if (!newSlot) return null\n newSlot.data.onStatusChange = () => {\n // When the data segment settles, update the fetched ranges.\n if (newSlot.data.status === SegmentStatus.RESOLVED)\n this._fetchedRanges.add(newSlot.startTime, newSlot.endTime)\n else if (newSlot.data.status === SegmentStatus.INACTIVE)\n this._fetchedRanges.remove(newSlot.startTime, newSlot.endTime)\n this.dispatch('fetchedRangesChange', {})\n }\n\n // Insert the slot, in order.\n const insertionIndex = getSegmentInsertionIndexAtTime(\n newSlot.startTime,\n this.cachedSegments\n )\n\n // Slot creation is asynchronous, to allow requesting index ranges. Check if a slot for this time was already\n // created.\n if (insertionIndex > 0) {\n const cachedSegment = this.cachedSegments[insertionIndex - 1]\n if (closeTo(newSlot.startTime, cachedSegment.startTime)) {\n return cachedSegment\n }\n }\n logDebug(\n this,\n `created slot at ${insertionIndex} for time ${newSlot.startTime.toFixed(4)}`\n )\n this.cachedSegments.splice(insertionIndex, 0, newSlot)\n return newSlot\n }\n\n /**\n * Gets a cached init segment slot for the given decoder id. If a slot is not cached, create one.\n */\n private getOrCreateInitSlot(\n decoderId: string,\n segmentDataProvider: SegmentDataProvider\n ): SegmentDataSlot {\n return getOrSet(this.cachedInitSegments, decoderId, () => {\n return new SegmentDataSlot(segmentDataProvider)\n })\n }\n\n /**\n * Creates a slot that spans the given time, or returns null if there is no media at that time.\n * Uses the mediaTimelineTransformed to resolve segments directly.\n */\n private async createSlotForTime(\n time: number\n ): Promise<SegmentReference<SegmentDataSlot> | null> {\n const period = await this.getPeriodAtTime(time)\n if (!period) return null\n\n // Filter qualities to this content type, excluding any whose codec has\n // been denylisted at runtime after a decode/append failure (the browser\n // claimed support it does not actually have). If every quality for this\n // content type is denylisted, fall back to the unfiltered set so\n // playback still attempts something rather than stalling silently.\n const contentTypeQualities = period.qualities.filter(\n (q) => q.metadata.contentType === this.contentType\n )\n const playableQualities = contentTypeQualities.filter(\n (q) =>\n !q.metadata.mimeType ||\n !isMimeTypeDenylisted(q.metadata.mimeType)\n )\n const filteredQualities =\n playableQualities.length > 0\n ? playableQualities\n : contentTypeQualities\n if (filteredQualities.length === 0) return null\n\n // Gets the preceding segment encoding metadata for quality selection.\n let previousQuality: MediaQualityMetadata | null = null\n const previousIndex =\n getSegmentInsertionIndexAtTime(time, this.cachedSegments) - 1\n if (previousIndex >= 0)\n previousQuality = this.cachedSegments[previousIndex].quality\n\n const prefetchState: PrefetchState = {\n fetchedTime: this.fetchedTime,\n previousQuality,\n active: this.active,\n }\n\n const metadataArray = filteredQualities.map((q) => q.metadata)\n const index = this.deps.qualitySelector.selectQuality(\n metadataArray,\n prefetchState\n )\n const selectedQuality = filteredQualities[index]\n\n const segment = await selectedQuality.getSegment(\n time,\n SEGMENT_START_AFFORDANCE\n )\n this.abort.throwIfAborted()\n this.streamingQuality = segment?.quality ?? null\n if (!segment) return null\n\n return {\n ...segment,\n quality: segment.quality,\n initData: this.getOrCreateInitSlot(\n segment.quality.decoderId,\n segment.initData\n ),\n data: new SegmentDataSlot(segment.data),\n }\n }\n\n /**\n * Indicates that this segment provider is providing segments for an active track and should be prioritized\n * accordingly.\n * Time ranges to be prefetched will change to the active prefetch window.\n */\n activate(): void {\n if (this._active) return\n logDebug(this, 'activate')\n this._active = true\n this.pollPrefetch()\n const playbackController = this.deps.playbackController\n this.timeUpdateSub = playbackController.on(\n 'timeUpdate',\n this.pollPrefetch\n )\n this.seekingSub = playbackController.on('seeking', () => {\n this.ended = false\n this._error = null\n this.pollPrefetch()\n })\n }\n\n /**\n * Deactivates the segment provider.\n * This clears cached segments not within the inactive prefetch range.\n * Time ranges to be prefetched will change to the inactive prefetch window.\n */\n deactivate(): void {\n if (!this._active) return\n logDebug(this, 'deactivate')\n this._active = false\n this.sweepCachedSegments()\n this.timeUpdateSub!()\n this.timeUpdateSub = null\n this.seekingSub!()\n this.seekingSub = null\n }\n\n clear(): void {\n logDebug(this, 'clear')\n this.cachedSegments.forEach((slot) => {\n slot.data.onStatusChange = null\n slot.data.clear()\n slot.initData.clear()\n })\n this.cachedSegments.length = 0\n this.cachedInitSegments.clear()\n this._fetchedRanges.clear()\n this.ended = false\n this._error = null\n this._cachedPeriod = null\n if (!this.disposed) this.pollPrefetch()\n this.dispatch('fetchedRangesChange', {})\n }\n\n reset(): void {\n logDebug(this, 'reset')\n this.cachedSegments.forEach((slot) => this.resetSlot(slot))\n this._error = null\n this.pollPrefetch()\n }\n\n /**\n * Resets the slot if it's in an error state.\n * @param slot\n */\n private resetSlot(slot: SegmentReference<SegmentDataSlot>) {\n if (slot.data.status === SegmentStatus.ERRED) {\n logDebug(this, 'resetting failed segment at time:', slot.startTime)\n this.ended = false\n slot.data.clear()\n }\n if (slot.initData.status === SegmentStatus.ERRED) {\n logDebug(this, 'resetting failed init segment')\n this.ended = false\n slot.initData.clear()\n }\n }\n\n get disposed(): boolean {\n return this.disposer.disposed\n }\n\n dispose(): void {\n logDebug(this, 'disposing')\n super.dispose()\n this.disposer.dispose()\n this.deactivate()\n this.clear()\n this.abort.abort()\n }\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { Disposable, Maybe } from '@amazon/vinyl-util'\nimport {\n createAbortSlot,\n isSilentError,\n type ReadonlyAbort,\n} from '@amazon/vinyl-util'\n\nexport enum SegmentStatus {\n /**\n * This segment has not been requested.\n */\n INACTIVE = 'inactive',\n\n /**\n * The segment has been requested but not yet completed.\n */\n PENDING = 'pending',\n\n /**\n * The segment has finished requesting.\n */\n RESOLVED = 'resolved',\n\n /**\n * The segment failed to load.\n */\n ERRED = 'erred',\n}\n\n/**\n * A function that returns a promise to segment data.\n */\nexport type SegmentDataProvider = (\n abort?: Maybe<ReadonlyAbort>\n) => Promise<ArrayBuffer>\n\n/**\n * A SegmentSlot is a holder for a segment buffer. It may be requested, cleared, and its status observed.\n */\nexport class SegmentDataSlot implements Disposable {\n /**\n * Called when the status has changed.\n */\n onStatusChange: (() => void) | null = null\n\n private _status: SegmentStatus = SegmentStatus.INACTIVE\n private readonly abortSlot = /* @__PURE__ */ createAbortSlot()\n\n private bufferPromise: Promise<ArrayBuffer> | null = null\n\n constructor(private readonly requestSegmentData: SegmentDataProvider) {}\n\n /**\n * This segment's request status.\n */\n get status(): SegmentStatus {\n return this._status\n }\n\n private set status(value: SegmentStatus) {\n this._status = value\n if (this.onStatusChange) this.onStatusChange()\n }\n\n /**\n * Aborts the request if the status is currently {@link SegmentStatus.PENDING}, and clears the cached buffer.\n * The status will go back to {@link SegmentStatus.INACTIVE} and the segment may be requested again in the future.\n */\n clear(): void {\n if (this.status === SegmentStatus.INACTIVE) return\n this.abortSlot.abort()\n this.bufferPromise = null\n this.status = SegmentStatus.INACTIVE\n }\n\n /**\n * Begins the segment request now if it has not already been requested.\n * The promise returned will settle after this slot's status has updated and onStatusChange callback invoked.\n */\n request(): Promise<ArrayBuffer> {\n if (!this.bufferPromise) {\n this.status = SegmentStatus.PENDING\n\n // Chains status handling to the promise returned by requestSegment.\n this.bufferPromise = this.requestSegmentData(this.abortSlot.value)\n .then((result) => {\n this.status = SegmentStatus.RESOLVED\n return result\n })\n .catch((error) => {\n if (isSilentError(error)) {\n // Allows this data slot to be requested again.\n this.bufferPromise = null\n this.status = SegmentStatus.INACTIVE\n } else {\n // A higher severity error, do not try again.\n this.status = SegmentStatus.ERRED\n }\n throw error\n })\n }\n return this.bufferPromise\n }\n\n /**\n * Clears this segment and removes its handler.\n */\n dispose(): void {\n this.clear()\n this.onStatusChange = null\n }\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { Task, TaskQueue } from '@amazon/vinyl-util'\nimport {\n type Comparator,\n compareBy,\n createTaskQueue,\n globalRef,\n} from '@amazon/vinyl-util'\nimport type { ContentType } from './MediaQualityMetadata'\n\n/**\n * Properties affecting segment prefetch priority.\n * Each track when prefetching will only add one segment to the prefetch queue at a time.\n */\nexport interface SegmentPrefetchPriority {\n /**\n * The track's prefetch priority.\n */\n readonly trackPriority: number\n\n /**\n * The starting time of the segment.\n */\n readonly segmentStartTime: number\n\n /**\n * The time position prefetching starts for this segment's track.\n */\n readonly prefetchStartTime: number\n}\n\nexport const defaultTrackPriority = {\n // Default priority is lowest, but not used. Use enqueueSegmentPrefetch to enqueue.\n trackPriority: 0,\n segmentStartTime: 9007199254740991, // Number.MAX_SAFE_INTEGER,\n prefetchStartTime: 0,\n} as const satisfies SegmentPrefetchPriority\n\n/**\n * Highest priority; used to block prefetching while an actively-needed operation is enqueued.\n */\nexport const immediatePrefetchPriority = {\n trackPriority: 9007199254740991, // Number.MAX_SAFE_INTEGER,\n segmentStartTime: 0,\n prefetchStartTime: 0,\n}\n\n/**\n * A comparator for segment prefetching.\n * Given tracks A, B, and C with track priorities 1, 2, and 3 respectively:\n * The expected prefetch order will be:\n *\n * A0\n * B0 // \"lean forward\" case\n * C0 // \"lean forward\" case\n * A1 ... An\n * B1 ... Bn\n * C1 ... Cn\n *\n * Note that background prefetching is in parallel to prefetching for the active track.\n */\nexport const segmentPriorityComparatorRef = /* @__PURE__ */ globalRef<\n Comparator<SegmentPrefetchPriority>\n>(() => {\n return compareBy(\n (e) => {\n // First segments always take priority over subsequent ones.\n return e.segmentStartTime <= e.prefetchStartTime ? 0 : 1\n },\n // Next, consider track priority.\n (e) => -e.trackPriority\n )\n})\n\n// Task queues for each content type\nexport const prefetchPriorityQueuesRef = /* @__PURE__ */ globalRef<\n Record<ContentType, TaskQueue<SegmentPrefetchPriority>>\n>(() => {\n return {\n video: createTaskQueue<SegmentPrefetchPriority>(\n segmentPriorityComparatorRef.value,\n defaultTrackPriority\n ),\n audio: createTaskQueue<SegmentPrefetchPriority>(\n segmentPriorityComparatorRef.value,\n defaultTrackPriority\n ),\n text: createTaskQueue<SegmentPrefetchPriority>(\n segmentPriorityComparatorRef.value,\n defaultTrackPriority\n ),\n }\n})\n\n/**\n * Enqueues a task to request a streaming segment for a specific content type.\n * This should only be used for low priority background requests. Active tracks should request without\n * prioritization for the immediately needed segment.\n * Tracks are expected to prefetch one segment at a time, in order.\n *\n * @param requestTask\n * @param contentType\n * @param priority\n */\nexport function enqueueSegmentPrefetch(\n requestTask: Task<any>,\n contentType: ContentType,\n priority: SegmentPrefetchPriority\n): Promise<void> {\n return prefetchPriorityQueuesRef.value[contentType].enqueue(\n requestTask,\n priority\n )\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { sortedInsertionIndex } from '@amazon/vinyl-util'\nimport type { MediaSegmentMetadata } from '../SegmentReference'\n\n/**\n * Returns the segment whose range covers `time` (`startTime <= time < endTime`), or\n * \u2014 when `affordance > 0` \u2014 the next segment if `time` falls within `affordance`\n * seconds before its `startTime`. Returns `null` if neither applies.\n *\n * Note: with `affordance > 0`, when `time` lies in the last `affordance` seconds of a\n * segment that does cover it, the *next* segment is returned instead. This is\n * deliberate \u2014 callers use `affordance` to absorb sub-second boundary differences\n * across qualities \u2014 but it means the result is not strictly the segment containing\n * `time`. Callers needing exact containment should pass `affordance = 0`.\n *\n * @param time Lookup time, in seconds.\n * @param segments Segments sorted by `startTime` ascending.\n * @param affordance Forward-snap tolerance in seconds: if `time` falls just before a\n * segment's `startTime` (within `affordance`), that segment is returned. The original\n * `time` is still compared against `endTime`, so coverage never extends past it.\n */\nexport function getSegmentAtTime<T extends MediaSegmentMetadata>(\n time: number,\n segments: readonly T[],\n affordance = 0\n): T | null {\n const index =\n getSegmentInsertionIndexAtTime(time + affordance, segments) - 1\n if (index < 0) return null\n const segment = segments[index]\n return time >= segment.endTime ? null : segment\n}\n\n/**\n * Returns the count of segments whose `startTime <= time` \u2014 i.e. the index at which a\n * segment with that `startTime` would be inserted to keep the array sorted ascending.\n *\n * @param time Lookup time, in seconds.\n * @param segments Segments sorted by `startTime` ascending.\n */\nexport function getSegmentInsertionIndexAtTime(\n time: number,\n segments: readonly MediaSegmentMetadata[]\n): number {\n return sortedInsertionIndex(\n segments,\n time,\n (time, element) => time - element.startTime\n )\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { ChangeEvent } from '../event/ChangeEvent'\nimport type { ContentType, MediaQualityMetadata } from './MediaQualityMetadata'\nimport type { BasicErrorEvent } from '../event/BasicErrorEvent'\nimport type { AnyRecord } from '@amazon/vinyl-util'\nimport type { SeekRange } from '../track/SeekRange'\nimport type { LoadSpanMeasurement } from './LoadMetric'\n\n/**\n * Events a track dispatches related to streaming quality and status.\n */\nexport interface StreamingEventMap {\n /**\n * The actively streamed content types have changed.\n */\n readonly contentTypesChange: ChangeEvent<ReadonlySet<ContentType>>\n\n /**\n * fetchedRanges have been updated.\n */\n readonly fetchedRangesChange: AnyRecord\n\n /**\n * Dispatched when the currently streaming quality changes.\n * This is dispatched when a new streaming quality has been requested.\n */\n readonly streamingQualityChange: ChangeEvent<MediaQualityMetadata | null>\n\n /**\n * Dispatched when the currently buffering quality changes.\n * This is dispatched before the segment is appended.\n */\n readonly bufferingQualityChange: ChangeEvent<MediaQualityMetadata | null>\n\n /**\n * The currently playing quality has changed.\n */\n readonly playbackQualityChange: ChangeEvent<MediaQualityMetadata | null>\n\n /**\n * The last segment has finished appending.\n */\n readonly bufferingEnded: AnyRecord\n\n /**\n * The buffer went from empty to holding data, or back to empty.\n */\n readonly hasDataChange: ChangeEvent<boolean>\n\n /**\n * Dispatched when a streaming error occurs.\n */\n readonly error: BasicErrorEvent\n\n /**\n * Emitted when the error state has been reset.\n */\n readonly reset: AnyRecord\n\n /**\n * The available qualities for the current period have changed.\n */\n readonly qualitiesChange: ChangeEvent<readonly MediaQualityMetadata[]>\n\n /**\n * The available unfiltered qualities for the current period have changed.\n */\n readonly qualitiesUnfilteredChange: ChangeEvent<\n readonly MediaQualityMetadata[]\n >\n\n /**\n * A codec the browser reported as supported failed to decode on append and\n * has been denylisted at runtime. The current media should be reloaded so\n * quality selection can fall back to a codec that decodes. Recoverable:\n * this is dispatched instead of an `error`, and the player reloads the\n * track in response.\n */\n readonly codecUnsupported: CodecUnsupportedEvent\n\n /**\n * The seekable range on the media timeline has changed.\n */\n readonly seekRangeChange: ChangeEvent<SeekRange | null>\n\n /**\n * A stage of the track load completed. Rather than redispatch this raw\n * measurement, the player attributes it to the current track and\n * republishes it as the `loadSpan` event.\n */\n readonly loadSpanMeasured: LoadSpanMeasurement\n}\n\n/**\n * Payload for {@link StreamingEventMap.codecUnsupported}.\n */\nexport interface CodecUnsupportedEvent {\n /**\n * The mimeType (including the failing codec) that was denylisted.\n */\n readonly mimeType: string\n\n /**\n * The content type of the stream whose append failed.\n */\n readonly contentType: ContentType\n}\n\n/**\n * All streaming-related events a track may emit.\n * These will be bubbled by the player.\n */\nexport const ALL_STREAMING_EVENTS = [\n 'contentTypesChange',\n 'fetchedRangesChange',\n 'streamingQualityChange',\n 'bufferingQualityChange',\n 'playbackQualityChange',\n 'bufferingEnded',\n 'hasDataChange',\n 'error',\n 'reset',\n 'qualitiesChange',\n 'qualitiesUnfilteredChange',\n 'codecUnsupported',\n 'seekRangeChange',\n 'loadSpanMeasured',\n] as const satisfies readonly (keyof StreamingEventMap)[]\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { DashManifest } from '@amazon/vinyl-mpd-parser'\nimport { resolveUrl } from '@amazon/vinyl-util'\nimport type { TextTrackInfo } from './TextTrack'\n\n/**\n * Discovers sidecar text tracks from a DASH manifest.\n *\n * Considers an `<AdaptationSet>` to carry text when one of:\n * - `contentType=\"text\"`\n * - `mimeType` starts with `text/` (e.g. `text/vtt`)\n * - `mimeType` is `application/mp4` *and* the codec/role indicates text\n *\n * Within a text adaptation set, each `<Representation>` becomes one\n * {@link TextTrackInfo}. The `BaseURL` chain (MPD \u2192 Period \u2192 AdaptationSet \u2192\n * Representation) is resolved against the supplied `baseUrl`.\n *\n * Only sidecar (single-file) WebVTT renditions are surfaced. Segmented text\n * tracks (`stpp`/`wvtt` codecs) are ignored - they would require streaming\n * through MSE which the sidecar pipeline does not support.\n *\n * @param manifest The parsed DASH manifest.\n * @param baseUrl The URL of the manifest, used as the root for `BaseURL`\n * resolution.\n */\nexport function discoverDashTextTracks(\n manifest: DashManifest,\n baseUrl: string\n): readonly TextTrackInfo[] {\n const out: TextTrackInfo[] = []\n\n const periods = manifest.MPD.Period\n const mpdBase = chainBase(baseUrl, manifest.MPD.BaseURL)\n\n for (let p = 0; p < periods.length; p++) {\n const period = periods[p]\n const periodBase = chainBase(mpdBase, period.BaseURL)\n const adaptationSets = period.AdaptationSet ?? []\n for (const adaptationSet of adaptationSets) {\n if (!isTextAdaptationSet(adaptationSet)) continue\n const asBase = chainBase(periodBase, adaptationSet.BaseURL)\n const representations = adaptationSet.Representation ?? []\n for (const representation of representations) {\n const repBase = chainBase(asBase, representation.BaseURL)\n const uri = pickRepresentationUri(repBase, representation.id)\n const mimeType =\n representation.mimeType ?? adaptationSet.mimeType ?? null\n // Only surface sidecar formats. Segmented text (stpp/wvtt) is\n // intentionally skipped.\n if (!isSidecarTextMime(mimeType)) continue\n const language = adaptationSet.lang ?? null\n const roleValues = (adaptationSet.Role ?? [])\n .filter((d) => d.schemeIdUri === 'urn:mpeg:dash:role:2011')\n .map((d) => d.value)\n .filter((v): v is string => v != null)\n // Accessibility descriptors (e.g. SDH / hard-of-hearing) also\n // describe the track's role; surface them as characteristics.\n const accessibility = (adaptationSet.Accessibility ?? [])\n .map((d) => d.value)\n .filter((v): v is string => v != null)\n const characteristics = [...roleValues, ...accessibility]\n const isCaption = roleValues.includes('caption')\n const isDefault = roleValues.includes('main')\n // DASH signals forced text via the `forced_subtitle` /\n // `forced-subtitle` role value.\n const forced =\n roleValues.includes('forced_subtitle') ||\n roleValues.includes('forced-subtitle')\n out.push({\n id: `dash-text-${p}-${representation.id}`,\n kind: isCaption ? 'captions' : 'subtitles',\n language,\n label: language ?? representation.id,\n default: isDefault,\n forced,\n characteristics,\n uri,\n mimeType,\n })\n }\n }\n }\n\n return out\n}\n\nfunction isTextAdaptationSet(adaptationSet: {\n readonly contentType?: string\n readonly mimeType?: string\n}): boolean {\n if (adaptationSet.contentType === 'text') return true\n const mt = adaptationSet.mimeType\n if (mt && mt.startsWith('text/')) return true\n return false\n}\n\nfunction isSidecarTextMime(mimeType: string | null): boolean {\n // Permissive when manifest omits the MIME type, otherwise require a\n // text/* MIME type. Segmented codec-only types like application/mp4\n // (used with stpp/wvtt codecs) are excluded.\n if (mimeType == null) return true\n return mimeType.startsWith('text/')\n}\n\nfunction chainBase(\n parent: string,\n bases: readonly { readonly _content: string }[] | undefined\n): string {\n if (!bases || bases.length === 0) return parent\n return resolveUrl(bases[0]._content, parent)\n}\n\nfunction pickRepresentationUri(base: string, id: string): string {\n // For a sidecar text representation, the BaseURL is expected to point at\n // the file. When the chain ends in a directory (trailing `/`), append a\n // conventional `<id>.vtt` filename so the loader can fetch the resource.\n if (base.endsWith('/')) {\n return resolveUrl(`${id}.vtt`, base)\n }\n return base\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { HlsMainPlaylist } from '@amazon/vinyl-hls-parser'\nimport { resolveUrl } from '@amazon/vinyl-util'\nimport type { TextTrackInfo } from './TextTrack'\n\n/**\n * Discovers sidecar text tracks from an HLS multivariant playlist.\n *\n * Per RFC 8216 \u00A74.3.4.2, subtitle renditions are signaled with\n * `EXT-X-MEDIA:TYPE=SUBTITLES` and (when usable as sidecar) carry a `URI`\n * attribute pointing at a media playlist or, in the simplified single-file\n * case, a `.vtt` file directly.\n *\n * Closed captions (`TYPE=CLOSED-CAPTIONS`) are intentionally excluded - they\n * are delivered in-band with the video stream and are surfaced by the browser\n * automatically, not through a sidecar fetch.\n *\n * @param mainPlaylist The parsed HLS main playlist.\n * @param baseUrl The URL of the main playlist, used to resolve relative URIs.\n */\nexport function discoverHlsTextTracks(\n mainPlaylist: HlsMainPlaylist,\n baseUrl: string\n): readonly TextTrackInfo[] {\n const out: TextTrackInfo[] = []\n let index = 0\n const parentDefines =\n mainPlaylist.defines && Object.keys(mainPlaylist.defines).length > 0\n ? mainPlaylist.defines\n : undefined\n for (const rendition of mainPlaylist.alternativeRenditions) {\n if (rendition.type !== 'SUBTITLES') continue\n if (!rendition.uri) continue\n const resolved = resolveUrl(rendition.uri, baseUrl)\n out.push({\n id: `hls-text-${index++}-${rendition.groupId}-${rendition.name}`,\n kind: 'subtitles',\n language: rendition.language ?? null,\n label: rendition.name,\n default: rendition.default === true,\n forced: rendition.forced === true,\n characteristics: rendition.characteristics ?? [],\n uri: resolved,\n // HLS subtitle renditions don't carry a MIME type; WebVTT is the\n // overwhelmingly dominant format for sidecar HLS subtitles.\n mimeType: 'text/vtt',\n ...(parentDefines && { variables: parentDefines }),\n })\n }\n return out\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { ErrorOrigin, ValidationError } from '@amazon/vinyl-util'\n\n/**\n * A single WebVTT cue.\n *\n * @see https://www.w3.org/TR/webvtt1/\n */\nexport interface WebVttCue {\n /**\n * Optional cue identifier, the line that appears before the timing line.\n */\n readonly id: string | null\n\n /**\n * Cue start time in seconds.\n */\n readonly startTime: number\n\n /**\n * Cue end time in seconds.\n */\n readonly endTime: number\n\n /**\n * The cue text payload, with line breaks preserved as `\\n`.\n */\n readonly text: string\n}\n\n/**\n * The result of parsing a WebVTT document.\n */\nexport interface WebVttDocument {\n /**\n * Parsed cues in document order.\n */\n readonly cues: readonly WebVttCue[]\n}\n\nconst WEBVTT_HEADER = 'WEBVTT'\n\n// Trailing cue settings are tolerated but ignored. They are separated from the\n// end timestamp by whitespace, so the tail is matched as an optional group that\n// begins with a whitespace character. Using `(?:\\s.*)?$` rather than `\\s*(.*)$`\n// avoids the ambiguous overlap between `\\s*` and `.*` (both match spaces), which\n// would allow polynomial backtracking on space-heavy input.\nconst TIME_RE =\n /^\\s*(?:(\\d+):)?([0-5]?\\d):([0-5]?\\d)\\.(\\d{3})\\s*-->\\s*(?:(\\d+):)?([0-5]?\\d):([0-5]?\\d)\\.(\\d{3})(?:\\s.*)?$/\n\n/**\n * Parses a WebVTT document into a list of cues.\n *\n * Implements a forgiving subset of the WebVTT 1.0 specification: header\n * detection, comment blocks (lines starting with `NOTE`), styling/region\n * blocks (skipped), cue identifiers, and HH:MM:SS.mmm or MM:SS.mmm timestamps.\n * Cue settings on the timing line are tolerated and ignored.\n *\n * @param input The raw WebVTT document text. Both LF and CRLF line endings\n * are supported, and a leading BOM is stripped if present.\n * @throws ValidationError if the input is missing the WEBVTT header.\n */\nexport function parseWebVtt(input: string): WebVttDocument {\n if (typeof input !== 'string') {\n throw new ValidationError(\n 'WebVTT input must be a string',\n ErrorOrigin.MEDIA\n )\n }\n let text = input\n // Strip BOM\n if (text.charCodeAt(0) === 0xfeff) text = text.slice(1)\n // Normalize line endings\n const lines = text.split(/\\r\\n|\\r|\\n/)\n\n if (lines.length === 0 || !isWebVttHeader(lines[0])) {\n throw new ValidationError(\n 'WebVTT must begin with a WEBVTT header',\n ErrorOrigin.MEDIA\n )\n }\n\n const cues: WebVttCue[] = []\n // Per the WebVTT spec, everything from the `WEBVTT` signature up to (and\n // including) the first blank line is the file header \u2014 any metadata\n // header lines (e.g. HLS's `X-TIMESTAMP-MAP=...`) belong in that block\n // and MUST NOT be interpreted as cue content.\n let i = 1\n while (i < lines.length && lines[i] !== '') i++\n\n while (i < lines.length) {\n // Skip empty lines between blocks.\n if (lines[i] === '') {\n i++\n continue\n }\n // NOTE comment block: skip until blank line.\n if (lines[i] === 'NOTE' || lines[i].startsWith('NOTE ')) {\n i++\n while (i < lines.length && lines[i] !== '') i++\n continue\n }\n // STYLE / REGION blocks - skip until blank line.\n if (lines[i] === 'STYLE' || lines[i] === 'REGION') {\n i++\n while (i < lines.length && lines[i] !== '') i++\n continue\n }\n\n // Cue: optional identifier, then a timing line, then payload.\n let id: string | null = null\n let timingLine: string\n const firstLine = lines[i]\n if (TIME_RE.test(firstLine)) {\n timingLine = firstLine\n i++\n } else {\n id = firstLine\n i++\n if (i >= lines.length) break\n timingLine = lines[i]\n i++\n }\n\n const match = TIME_RE.exec(timingLine)\n if (!match) {\n // Skip malformed cue: drain to next blank line.\n while (i < lines.length && lines[i] !== '') i++\n continue\n }\n\n const startTime = toSeconds(match[1], match[2], match[3], match[4])\n const endTime = toSeconds(match[5], match[6], match[7], match[8])\n\n const payloadLines: string[] = []\n while (i < lines.length && lines[i] !== '') {\n payloadLines.push(lines[i])\n i++\n }\n\n cues.push({\n id,\n startTime,\n endTime,\n text: payloadLines.join('\\n'),\n })\n }\n\n return { cues }\n}\n\nfunction isWebVttHeader(line: string): boolean {\n if (!line.startsWith(WEBVTT_HEADER)) return false\n if (line.length === WEBVTT_HEADER.length) return true\n const next = line.charCodeAt(WEBVTT_HEADER.length)\n // Header may be followed by space, tab, or any text after a separator.\n return next === 0x20 || next === 0x09\n}\n\nfunction toSeconds(\n hours: string | undefined,\n minutes: string,\n seconds: string,\n millis: string\n): number {\n const h = hours ? Number(hours) : 0\n const m = Number(minutes)\n const s = Number(seconds)\n const ms = Number(millis)\n return h * 3600 + m * 60 + s + ms / 1000\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { languageRelatedness } from '../track/filters/languageFilter'\nimport type { TextTrackInfo } from './TextTrack'\n\n/**\n * Resolves the preferred-text-language option to an ordered list of BCP 47\n * tags, most-preferred first. Unlike the audio equivalent, `null` resolves to\n * an empty list (no preference) rather than falling back to\n * `navigator.languages` \u2014 captions default to off.\n */\nfunction resolvePreferredTextLanguages(\n preferred: string | readonly string[] | null\n): readonly string[] {\n if (typeof preferred === 'string') return [preferred]\n if (preferred) return preferred\n return []\n}\n\n/**\n * Chooses the text track that best matches the preferred language(s), or null\n * when none relate (or there is no preference / no tracks).\n *\n * Language dominates: a track is ranked first by which preference it relates to\n * (earlier entries win) and how closely (see {@link languageRelatedness}).\n * Within a single language, a full track is preferred over a forced-only track\n * (a user asking for a caption language wants the full captions, not just the\n * forced foreign-dialogue cues), and a manifest-default track breaks any\n * remaining tie.\n */\nexport function pickPreferredTextTrack(\n tracks: readonly TextTrackInfo[],\n preferred: string | readonly string[] | null\n): TextTrackInfo | null {\n const prefs = resolvePreferredTextLanguages(preferred)\n if (tracks.length === 0 || prefs.length === 0) return null\n\n let best: TextTrackInfo | null = null\n let bestScore = 0\n for (const track of tracks) {\n const score = scoreTextTrack(track, prefs)\n if (score > bestScore) {\n bestScore = score\n best = track\n }\n }\n return best\n}\n\n/**\n * Scores a track against the ordered preference list. 0 means unrelated to\n * every preference (never selected). Preference position and language\n * relatedness are weighted so they dominate the full/forced/default tiebreaks.\n */\nfunction scoreTextTrack(\n track: TextTrackInfo,\n prefs: readonly string[]\n): number {\n if (track.language == null) return 0\n let best = 0\n for (let i = 0; i < prefs.length; i++) {\n const rel = languageRelatedness(prefs[i], track.language)\n if (rel > 0) {\n best = Math.max(best, (prefs.length - i) * 100 + rel * 10)\n }\n }\n if (best === 0) return 0\n // Tiebreaks within the same language: prefer full over forced, then default.\n if (!track.forced) best += 2\n if (track.default) best += 1\n return best\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {\n Abort,\n equalDeep,\n EventHostImpl,\n type Maybe,\n type RequestInitOptions,\n type Unsubscribe,\n} from '@amazon/vinyl-util'\nimport type {\n TextTrackController,\n TextTrackEventMap,\n TextTrackInfo,\n} from './TextTrack'\nimport { loadWebVttCues } from './SidecarTextTrackLoader'\nimport type { WebVttCue } from './parseWebVtt'\nimport type { ObservableValue } from '@amazon/vinyl-observable'\nimport { pickPreferredTextTrack } from './pickPreferredTextTrack'\nimport { applyVttCueStyle, isVttCue, type VttCueStyle } from './VttCueStyle'\n\nexport interface SidecarTextTrackControllerDeps {\n /**\n * The HTML media element on which to attach the in-band TextTrack\n * representation. Cues for the active text track are added to a TextTrack\n * created via `media.addTextTrack`. Setting this to null disables DOM\n * integration; cues are still loaded and surfaced via events.\n */\n readonly media: HTMLMediaElement | null\n\n /**\n * Optional request init options forwarded with each VTT fetch (e.g. CORS).\n */\n readonly requestInit?: Maybe<RequestInitOptions>\n\n /**\n * Preferred caption language(s), most-preferred first. A non-null\n * preference auto-selects the best-matching track, re-applied as the track\n * list changes. Changing the preference to null clears the selection\n * (captions off). An initial null (or an absent observable) is \"no\n * preference\": forced tracks still auto-select until the app makes an\n * explicit choice \u2014 it does not force captions off.\n */\n readonly preferredTextLanguage?: ObservableValue<\n string | readonly string[] | null\n >\n\n /**\n * Layout style applied to each rendered VTTCue (see\n * {@link VttCueStyle}). Read per cue as it is appended, so a change affects\n * subsequently-rendered cues. Absent means no styling (browser defaults).\n */\n readonly cueStyle?: ObservableValue<VttCueStyle | null>\n}\n\n/**\n * Manages a sidecar WebVTT-based text track lifecycle:\n *\n * - holds a discovered list of {@link TextTrackInfo}\n * - on activation, fetches the chosen track's WebVTT and pushes cues to a\n * `TextTrack` created on the `HTMLMediaElement`\n * - clears any previously activated cues when switching tracks\n *\n * The controller is intentionally agnostic of HLS/DASH discovery details. Its\n * input is whatever list of {@link TextTrackInfo} entries the manifest layer\n * decides to surface.\n */\nexport class SidecarTextTrackController\n extends EventHostImpl<TextTrackEventMap>\n implements TextTrackController\n{\n get [Symbol.toStringTag](): string {\n return 'SidecarTextTrackController'\n }\n\n private _tracks: readonly TextTrackInfo[] = []\n private _active: TextTrackInfo | null = null\n private _domTrack: TextTrack | null = null\n private loadAbort: Abort | null = null\n // True once the app has made an explicit selection (including null). Until\n // then, forced tracks auto-select on discovery.\n private _userSelected = false\n private readonly preferredLanguageSub: Unsubscribe | null\n\n constructor(private readonly deps: SidecarTextTrackControllerDeps) {\n super()\n this.preferredLanguageSub =\n deps.preferredTextLanguage?.onData((value, previous) => {\n if (previous !== undefined) this.applyPreferredLanguage(value)\n }) ?? null\n }\n\n get textTracks(): readonly TextTrackInfo[] {\n return this._tracks\n }\n\n get activeTextTrack(): TextTrackInfo | null {\n return this._active\n }\n\n /**\n * Replaces the discovered text track list. Emits `textTracksChange`. If\n * the previously active track is no longer present, clears the active\n * selection and emits `activeTextTrackChange`.\n */\n setTextTracks(tracks: readonly TextTrackInfo[]): void {\n if (equalDeep(this._tracks, tracks)) return\n const previous = this._tracks\n this._tracks = tracks\n this.dispatch('textTracksChange', { previous, current: tracks })\n\n if (this._active && !tracks.some((t) => t.id === this._active!.id)) {\n // Clear a now-absent selection, but keep _userSelected intact.\n this.selectById(null)\n }\n\n // A preferred language re-selects the best match as the list changes;\n // otherwise auto-show forced captions until the app makes an explicit\n // choice.\n const preferred = this.deps.preferredTextLanguage?.value\n if (preferred != null) {\n this.applyPreferredLanguage(preferred)\n } else if (!this._userSelected && !this._active) {\n const forced = this.pickForcedTrack(tracks)\n if (forced) this.selectById(forced.id)\n }\n }\n\n setActiveTextTrack(id: string | null): void {\n // An explicit app choice; stop auto-selecting forced tracks.\n this._userSelected = true\n this.selectById(id)\n }\n\n /**\n * Selects the track best matching the preferred language(s), or clears the\n * selection when the preference is null or nothing matches.\n */\n private applyPreferredLanguage(\n preferred: string | readonly string[] | null\n ): void {\n const target = pickPreferredTextTrack(this._tracks, preferred)\n this.setActiveTextTrack(target?.id ?? null)\n }\n\n /**\n * Applies a selection by id (null clears it) without marking it as an\n * explicit user choice. Shared by setActiveTextTrack and forced auto-select.\n */\n private selectById(id: string | null): void {\n const next = id == null ? null : this._tracks.find((t) => t.id === id)\n if (id != null && !next) return // unknown id is a no-op\n const target = next ?? null\n if (target?.id === this._active?.id) return\n const previous = this._active\n this.clearDomTrack()\n this.loadAbort?.abort()\n this.loadAbort = null\n this._active = target\n this.dispatch('activeTextTrackChange', {\n previous,\n current: target,\n })\n if (target) this.startLoad(target)\n }\n\n /**\n * The forced track to auto-select, or null. Prefers the default track's\n * language, else the first forced track.\n */\n private pickForcedTrack(\n tracks: readonly TextTrackInfo[]\n ): TextTrackInfo | null {\n const forced = tracks.filter((t) => t.forced)\n if (forced.length === 0) return null\n const defaultLang = tracks.find((t) => t.default)?.language\n if (defaultLang != null) {\n const match = forced.find((t) => t.language === defaultLang)\n if (match) return match\n }\n return forced[0]\n }\n\n suspend(): void {\n this.loadAbort?.abort()\n this.loadAbort = null\n this.clearDomTrack()\n }\n\n resume(): void {\n // Rebuild only when an active selection exists and it isn't already\n // rendering (clearDomTrack/suspend nulls _domTrack; setActiveTextTrack\n // sets it).\n if (!this._active || this._domTrack) return\n this.startLoad(this._active)\n }\n\n /**\n * Cancels any in-flight load, clears the DOM TextTrack, and resets state.\n * Called by the host when the underlying media is unloaded.\n */\n dispose(): void {\n super.dispose()\n this.preferredLanguageSub?.()\n this.loadAbort?.abort()\n this.loadAbort = null\n this.clearDomTrack()\n this._tracks = []\n this._active = null\n }\n\n private startLoad(track: TextTrackInfo): void {\n const media = this.deps.media\n // Without a media element there's nowhere to render cues and no\n // playhead to drive segment selection, so skip fetching entirely.\n // The active-selection state still surfaces via events.\n if (!media) return\n const abort = new Abort()\n this.loadAbort = abort\n // Create the DOM TextTrack up front so cues render incrementally as\n // segments arrive rather than after the whole playlist loads.\n const dom = this.ensureDomTrack(media, track)\n const CueCtor = getVttCueConstructor()\n // Adjacent HLS caption segments commonly repeat the boundary cue in\n // both segments (packagers do this so a client that only fetches one\n // segment still renders the overlapping cue). Track seen keys per\n // active load so we don't push the same cue twice.\n const seen = new Set<string>()\n loadWebVttCues(track.uri, {\n abort,\n requestInit: this.deps.requestInit,\n variables: track.variables,\n getCurrentTime: () => media.currentTime,\n onCues: (cues) => {\n if (abort.aborted()) return\n if (CueCtor) this.appendCues(dom, CueCtor, cues, seen)\n },\n }).catch((error) => {\n if (abort.aborted()) return\n this.dispatch('textTrackError', {\n track,\n error:\n error instanceof Error ? error : new Error(String(error)),\n })\n })\n }\n\n private ensureDomTrack(\n media: HTMLMediaElement,\n track: TextTrackInfo\n ): TextTrack {\n const dom = media.addTextTrack(\n track.kind,\n track.label,\n track.language ?? undefined\n )\n dom.mode = 'showing'\n this._domTrack = dom\n return dom\n }\n\n private appendCues(\n dom: TextTrack,\n CueCtor: VttCueCtor,\n cues: readonly WebVttCue[],\n seen: Set<string>\n ): void {\n for (const cue of cues) {\n const key = `${cue.startTime}|${cue.endTime}|${cue.text}`\n if (seen.has(key)) continue\n seen.add(key)\n const domCue = new CueCtor(cue.startTime, cue.endTime, cue.text)\n if (cue.id != null) domCue.id = cue.id\n // Apply the configured cue layout style (e.g. the default `size: 90`\n // inset so long lines don't clip in fullscreen, which `::cue` CSS\n // cannot fix). Only VTTCues carry these properties.\n const cueStyle = this.deps.cueStyle?.value\n if (cueStyle && isVttCue(domCue)) {\n applyVttCueStyle(domCue, cueStyle)\n }\n dom.addCue(domCue)\n }\n }\n\n private clearDomTrack(): void {\n const dom = this._domTrack\n if (!dom) return\n dom.mode = 'disabled'\n // Best-effort: remove any cues we added so a future activation starts\n // from a clean slate. Some platforms recreate the underlying TextTrack\n // when the source changes; this is defensive.\n if (dom.cues) {\n const all = Array.from(\n dom.cues as unknown as Iterable<TextTrackCue>\n )\n for (const cue of all) dom.removeCue(cue)\n }\n this._domTrack = null\n }\n}\n\ninterface VttCueCtor {\n new (\n start: number,\n end: number,\n text: string\n ): TextTrackCue & {\n id: string\n }\n}\n\nfunction getVttCueConstructor(): VttCueCtor | null {\n const g = globalThis as unknown as {\n VTTCue?: VttCueCtor\n TextTrackCue?: VttCueCtor\n }\n return g.VTTCue ?? g.TextTrackCue ?? null\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type {\n Maybe,\n ReadonlyAbort,\n RequestInitOptions,\n} from '@amazon/vinyl-util'\nimport { requestWithRetry, resolveUrl, sleep } from '@amazon/vinyl-util'\nimport { parseMediaPlaylist } from '@amazon/vinyl-hls-parser'\nimport { parseWebVtt, type WebVttCue } from './parseWebVtt'\n\n/**\n * Seconds ahead of the playhead to keep cues buffered. Mirrors the media\n * pipeline's default HLS `minBufferTime` so captions stay in step with the\n * audio/video buffer.\n */\nexport const DEFAULT_TEXT_LOOK_AHEAD = 10\n\n/**\n * Seconds behind the playhead to keep cues buffered. Small window so that a\n * short rewind (e.g. accidental skip-back) doesn't force a refetch.\n */\nexport const DEFAULT_TEXT_LOOK_BEHIND = 2\n\n/**\n * Polling interval, in seconds, when no segment is currently in the buffer\n * window. Short enough to feel responsive after a seek without spinning.\n */\nconst IDLE_POLL_SECONDS = 0.25\n\nexport interface LoadWebVttCuesOptions {\n readonly abort?: Maybe<ReadonlyAbort>\n readonly requestInit?: Maybe<RequestInitOptions>\n\n /**\n * HLS EXT-X-DEFINE variables to make available for `IMPORT` and for\n * substitution of segment URIs when loading from an HLS media playlist.\n */\n readonly variables?: Maybe<Readonly<Record<string, string>>>\n\n /**\n * Invoked with each batch of cues as soon as they are parsed. Called once\n * per HLS segment, or once for a direct `.vtt` document.\n */\n readonly onCues: (cues: readonly WebVttCue[]) => void\n\n /**\n * Returns the current playback time (seconds on the presentation\n * timeline). Used to fetch caption segments in a window around the\n * playhead rather than draining the entire playlist up front.\n */\n readonly getCurrentTime: () => number\n\n /**\n * Seconds ahead of the playhead to keep buffered. Default 10s.\n */\n readonly lookAhead?: Maybe<number>\n\n /**\n * Seconds behind the playhead to keep buffered. Default 2s.\n */\n readonly lookBehind?: Maybe<number>\n}\n\n/**\n * Loads WebVTT cues from a URI, streaming them by playhead position.\n *\n * Two URI shapes are accepted:\n * - Direct `.vtt` document: fetched once and delivered via `onCues`.\n * - HLS media playlist (`.m3u8`): the playlist is parsed, then segments\n * whose time range overlaps the buffer window around `getCurrentTime()`\n * are fetched (closest to the playhead first), one at a time. Each\n * segment's cues are delivered via `onCues` as it is parsed.\n *\n * Cue start/end times are expected to already be on the presentation\n * timeline (Shaka packager's default WebVTT output), so segments are joined\n * without offset.\n *\n * The returned promise resolves once every segment has been fetched, or the\n * abort signal fires. Fetch failures reject the promise.\n */\nexport async function loadWebVttCues(\n uri: string,\n options: LoadWebVttCuesOptions\n): Promise<void> {\n const { abort, requestInit, variables, onCues, getCurrentTime } = options\n const lookAhead = options.lookAhead ?? DEFAULT_TEXT_LOOK_AHEAD\n const lookBehind = options.lookBehind ?? DEFAULT_TEXT_LOOK_BEHIND\n const init = requestInit ?? undefined\n\n if (looksLikeMediaPlaylist(uri)) {\n return streamMediaPlaylist({\n uri,\n init,\n abort,\n variables: variables ?? undefined,\n onCues,\n getCurrentTime,\n lookAhead,\n lookBehind,\n })\n }\n const response = await requestWithRetry(uri, init, { abort })\n const contentType = (\n response.headers.get('content-type') ?? ''\n ).toLowerCase()\n const body = await response.text()\n if (contentType.includes('mpegurl') || body.startsWith('#EXTM3U')) {\n return streamMediaPlaylistText({\n text: body,\n baseUrl: response.url || uri,\n init,\n abort,\n variables: variables ?? undefined,\n onCues,\n getCurrentTime,\n lookAhead,\n lookBehind,\n })\n }\n const cues = parseWebVtt(body).cues\n if (cues.length > 0) onCues(cues)\n}\n\nfunction looksLikeMediaPlaylist(uri: string): boolean {\n const path = uri.split(/[?#]/)[0]\n return path.toLowerCase().endsWith('.m3u8')\n}\n\ninterface StreamCtx {\n readonly uri?: string\n readonly text?: string\n readonly baseUrl?: string\n readonly init: RequestInitOptions | undefined\n readonly abort: Maybe<ReadonlyAbort>\n readonly variables: Readonly<Record<string, string>> | undefined\n readonly onCues: (cues: readonly WebVttCue[]) => void\n readonly getCurrentTime: () => number\n readonly lookAhead: number\n readonly lookBehind: number\n}\n\nasync function streamMediaPlaylist(ctx: StreamCtx): Promise<void> {\n const response = await requestWithRetry(ctx.uri!, ctx.init, {\n abort: ctx.abort,\n })\n const text = await response.text()\n return streamMediaPlaylistText({\n ...ctx,\n text,\n baseUrl: response.url || ctx.uri!,\n })\n}\n\nasync function streamMediaPlaylistText(ctx: StreamCtx): Promise<void> {\n const playlist = parseMediaPlaylist(ctx.text!, ctx.variables)\n const segments = playlist.segments\n // Precompute each segment's [start, end] on the presentation timeline.\n const ranges: { start: number; end: number }[] = []\n let cursor = 0\n for (const seg of segments) {\n ranges.push({ start: cursor, end: cursor + seg.duration })\n cursor += seg.duration\n }\n const pending = new Set<number>(segments.map((_, i) => i))\n\n while (pending.size > 0 && !ctx.abort?.aborted()) {\n const idx = pickInWindow(pending, ranges, ctx)\n if (idx < 0) {\n await sleep(IDLE_POLL_SECONDS, ctx.abort).catch(() => {})\n continue\n }\n pending.delete(idx)\n const segUri = resolveUrl(segments[idx].uri, ctx.baseUrl!)\n const res = await requestWithRetry(segUri, ctx.init, {\n abort: ctx.abort,\n })\n const body = await res.text()\n const cues = parseWebVtt(body).cues\n if (cues.length > 0) ctx.onCues(cues)\n }\n}\n\n/**\n * Selects the pending segment closest to the playhead whose time range\n * overlaps [now - lookBehind, now + lookAhead]. Returns -1 when no pending\n * segment intersects the window \u2014 the caller should sleep and re-check.\n */\nfunction pickInWindow(\n pending: ReadonlySet<number>,\n ranges: readonly { start: number; end: number }[],\n ctx: StreamCtx\n): number {\n const now = ctx.getCurrentTime()\n const windowStart = now - ctx.lookBehind\n const windowEnd = now + ctx.lookAhead\n let best = -1\n let bestDist = Number.POSITIVE_INFINITY\n for (const idx of pending) {\n const r = ranges[idx]\n if (r.end < windowStart || r.start > windowEnd) continue\n const mid = (r.start + r.end) / 2\n const dist = Math.abs(mid - now)\n if (dist < bestDist) {\n bestDist = dist\n best = idx\n }\n }\n return best\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { ObjectSchema } from '@amazon/vinyl-validation'\nimport { boolean, isOneOf, number, object } from '@amazon/vinyl-validation'\n\n/**\n * Layout style applied to each rendered WebVTT cue, mirroring the settable\n * positioning properties of the DOM `VTTCue`. Only the properties that are set\n * are applied; the rest keep the browser defaults.\n *\n * These are the WebVTT cue-box layout controls (not text color/font, which are\n * only reachable via the non-configurable `::cue` pseudo-element). See\n * {@link https://developer.mozilla.org/docs/Web/API/VTTCue}.\n */\nexport interface VttCueStyle {\n /** Text alignment within the cue box. */\n readonly align?: AlignSetting\n /** Line (vertical) position, as a line number/percentage or `'auto'`. */\n readonly line?: number | AutoKeyword\n /** How `line` is anchored. */\n readonly lineAlign?: LineAlignSetting\n /** Inline position of the cue box, as a percentage or `'auto'`. */\n readonly position?: number | AutoKeyword\n /** How `position` is anchored. */\n readonly positionAlign?: PositionAlignSetting\n /** Size of the cue box as a percentage of the video dimension. */\n readonly size?: number\n /** Whether `line` is a line number (true) or a percentage (false). */\n readonly snapToLines?: boolean\n /** Writing direction. */\n readonly vertical?: DirectionSetting\n}\n\n/**\n * Type guard for a DOM cue that is a `VTTCue` (and so carries the WebVTT layout\n * properties). On platforms without `VTTCue`, cues are plain `TextTrackCue`s\n * that cannot be styled.\n */\nexport function isVttCue(cue: TextTrackCue): cue is VTTCue {\n return typeof VTTCue !== 'undefined' && cue instanceof VTTCue\n}\n\n/**\n * Applies the configured layout style to a `VTTCue`, setting only the\n * properties present in `style`.\n */\nexport function applyVttCueStyle(cue: VTTCue, style: VttCueStyle): void {\n if (style.align !== undefined) cue.align = style.align\n if (style.line !== undefined) cue.line = style.line\n if (style.lineAlign !== undefined) cue.lineAlign = style.lineAlign\n if (style.position !== undefined) cue.position = style.position\n if (style.positionAlign !== undefined)\n cue.positionAlign = style.positionAlign\n if (style.size !== undefined) cue.size = style.size\n if (style.snapToLines !== undefined) cue.snapToLines = style.snapToLines\n if (style.vertical !== undefined) cue.vertical = style.vertical\n}\n\nexport const vttCueStyleValidator: ObjectSchema<VttCueStyle> = /* @__PURE__ */ object({\n align: /* @__PURE__ */ /* @__PURE__ */ isOneOf('start', 'center', 'end', 'left', 'right').optional(),\n line: /* @__PURE__ */ /* @__PURE__ */ /* @__PURE__ */ number().or(/* @__PURE__ */ isOneOf('auto')).optional(),\n lineAlign: /* @__PURE__ */ /* @__PURE__ */ isOneOf('start', 'center', 'end').optional(),\n position: /* @__PURE__ */ /* @__PURE__ */ /* @__PURE__ */ number().or(/* @__PURE__ */ isOneOf('auto')).optional(),\n positionAlign: /* @__PURE__ */ /* @__PURE__ */ isOneOf(\n 'line-left',\n 'center',\n 'line-right',\n 'auto'\n ).optional(),\n size: /* @__PURE__ */ /* @__PURE__ */ number().optional(),\n snapToLines: /* @__PURE__ */ /* @__PURE__ */ boolean().optional(),\n vertical: /* @__PURE__ */ /* @__PURE__ */ isOneOf('', 'rl', 'lr').optional(),\n})\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { ChangeEvent } from '../event/ChangeEvent'\nimport type { ReadonlyEventHost } from '@amazon/vinyl-util'\n\n/**\n * Categorizes the role of a text track. Mirrors HTMLMediaElement.TextTrackKind.\n */\nexport type TextTrackKind =\n | 'subtitles'\n | 'captions'\n | 'descriptions'\n | 'chapters'\n | 'metadata'\n\n/**\n * Identifies and describes an available text track.\n * One TextTrackInfo is produced per discovered subtitle rendition.\n */\nexport interface TextTrackInfo {\n /**\n * A stable, unique identifier within the current media presentation.\n */\n readonly id: string\n\n /**\n * The text track kind. Defaults to 'subtitles' when not otherwise specified.\n */\n readonly kind: TextTrackKind\n\n /**\n * The BCP 47 language tag for the cues in this track, or null if unknown.\n */\n readonly language: string | null\n\n /**\n * A human-readable label for the track.\n */\n readonly label: string\n\n /**\n * Set when the source manifest signals this track as the default selection.\n */\n readonly default: boolean\n\n /**\n * Whether this is a forced track: it carries essential text (e.g.\n * translations of foreign-language dialogue) meant to be shown even when\n * the user has not enabled subtitles. Two tracks may share a language and\n * differ only by this flag, so selection must distinguish them.\n */\n readonly forced: boolean\n\n /**\n * Media characteristics / accessibility roles describing the track, e.g.\n * `public.accessibility.transcribes-spoken-dialog` (HLS CHARACTERISTICS) or\n * a DASH role/accessibility scheme value. Empty when none are signaled.\n */\n readonly characteristics: readonly string[]\n\n /**\n * The full URL of the underlying text resource (typically a WebVTT file).\n */\n readonly uri: string\n\n /**\n * The MIME type signaled by the source manifest, when known.\n */\n readonly mimeType: string | null\n\n /**\n * HLS EXT-X-DEFINE variables inherited from the parent multivariant\n * playlist. Sidecar text-track media playlists commonly `IMPORT` these\n * names and reference them in segment URIs. Present only for HLS-sourced\n * tracks whose parent playlist declared any variables.\n */\n readonly variables?: Readonly<Record<string, string>>\n}\n\n/**\n * Events dispatched by a {@link TextTrackController}.\n */\nexport interface TextTrackEventMap {\n /**\n * Emitted when the available text tracks change.\n */\n readonly textTracksChange: ChangeEvent<readonly TextTrackInfo[]>\n\n /**\n * Emitted when the active text track changes.\n */\n readonly activeTextTrackChange: ChangeEvent<TextTrackInfo | null>\n\n /**\n * Emitted when an error occurs while loading or activating a text track.\n */\n readonly textTrackError: TextTrackErrorEvent\n}\n\nexport interface TextTrackErrorEvent {\n readonly track: TextTrackInfo\n readonly error: Error\n}\n\nexport const ALL_TEXT_TRACK_EVENTS = [\n 'textTracksChange',\n 'activeTextTrackChange',\n 'textTrackError',\n] as const satisfies readonly (keyof TextTrackEventMap)[]\n\n/**\n * Read-only view of available text tracks and the active selection.\n */\nexport interface ReadonlyTextTrackController extends ReadonlyEventHost<TextTrackEventMap> {\n /**\n * The list of currently discovered text tracks.\n */\n readonly textTracks: readonly TextTrackInfo[]\n\n /**\n * The currently active text track, or null if none is active.\n */\n readonly activeTextTrack: TextTrackInfo | null\n}\n\n/**\n * Provides access to the text tracks of the current media and allows\n * selecting one for playback.\n *\n * Selection is persisted across track changes only when applications choose\n * to call {@link setActiveTextTrack} again on the new track. This matches\n * how audio tracks are typically driven.\n */\nexport interface TextTrackController extends ReadonlyTextTrackController {\n /**\n * Selects the text track with the given id, or clears the active text\n * track when called with null. No-op if the id does not match a known\n * text track.\n */\n setActiveTextTrack(id: string | null): void\n\n /**\n * Suspends cue rendering without changing the active selection: cancels any\n * in-flight load and tears down the DOM text track (so its cues stop\n * showing). Called when the owning media track is deactivated \u2014 e.g. while\n * an ad plays over the suspended content. {@link resume} rebuilds it.\n */\n suspend(): void\n\n /**\n * Rebuilds the DOM text track for the active selection after a\n * {@link suspend}, reloading its cues. No-op when nothing is active or when\n * already rendering. Called when the owning media track is reactivated.\n */\n resume(): void\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {\n type AnyRecord,\n type Clearable,\n createDisposer,\n type Disposable,\n EventHostImpl,\n getNetworkState,\n logDebug,\n onAny,\n type ReadonlyEventHost,\n RequestError,\n type Unsubscribe,\n} from '@amazon/vinyl-util'\nimport type { PlaybackController } from '../playback/PlaybackController'\nimport type { ChangeEvent } from '../event/ChangeEvent'\n\nexport interface AutoResetControllerEventMap {\n /**\n * Notifies that playback errors should be reset and retried.\n */\n readonly reset: AnyRecord\n\n /**\n * Dispatched when {@link AutoResetController.resetPending} changes.\n */\n readonly resetPendingChange: ChangeEvent<boolean>\n}\n\n/**\n * Notifies when playback should be reset and retried after a transient,\n * potentially-recoverable error.\n *\n * Once an eligible error is set, the controller watches for opportunities\n * to emit a `reset` event:\n * - Immediately when the network transitions back to online\n * - After a timeout interval, if online and retries are not exhausted\n * - Immediately on user playback actions (play, pause, seeking, playing)\n *\n * Each error triggers a single retry timeout. If another error occurs\n * after a reset, {@link AutoResetController.setError} should be called again\n * to schedule the next retry attempt.\n */\nexport interface AutoResetController\n extends ReadonlyEventHost<AutoResetControllerEventMap>, Clearable {\n /**\n * Sets the current playback error and, if eligible, begins watching for\n * retry opportunities.\n *\n * An error is eligible when it is a {@link RequestError} that did not\n * receive an HTTP response (i.e. `response == null`), indicating a\n * transient network failure such as connection loss or DNS failure.\n * All other errors \u2014 including HTTP failures with a response (4xx/5xx),\n * and non-RequestError errors \u2014 are ignored, since those are unlikely\n * to recover on their own.\n *\n * Subsequent calls while an error is already set are ignored until the\n * error is cleared via a reset emission or {@link Clearable.clear}.\n *\n * After a reset, if another eligible error occurs, this method should\n * be called again to schedule the next retry attempt.\n *\n * @param error The error to monitor for retry opportunities\n */\n setError(error: Error): void\n\n /**\n * True while an eligible error is being watched and a `reset` event\n * may still be emitted. Becomes false once the error is cleared, a\n * reset is emitted, or all retries are exhausted.\n *\n * Listen to `resetPendingChange` events for changes.\n */\n readonly resetPending: boolean\n}\n\nexport interface AutoResetControllerImplDeps {\n readonly playbackController: PlaybackController\n}\n\nexport interface AutoResetControllerImplOptions {\n /**\n * If false, disables auto reset behavior.\n * default: true\n */\n readonly enabled: boolean\n\n /**\n * The total number of times to reset when there has not been successful\n * playback.\n *\n * E.g. a retryInterval of 30 and maxRetries of 30 will retry for 15 minutes before stopping.\n *\n * default: 30\n */\n readonly maxRetries: number\n\n /**\n * The number of seconds between retries.\n *\n * When an error is set, a single timeout is scheduled for this interval.\n * If the retry limit hasn't been reached and the device is online, a reset\n * event is emitted. For subsequent errors after reset, setError() must be\n * called again to schedule the next retry timeout.\n */\n readonly retryInterval: number\n}\n\nexport const defaultResetControllerOptions = {\n enabled: true,\n maxRetries: 30,\n retryInterval: 30,\n} as const satisfies AutoResetControllerImplOptions\n\nexport class AutoResetControllerImpl\n extends EventHostImpl<AutoResetControllerEventMap>\n implements AutoResetController, Disposable\n{\n get [Symbol.toStringTag](): string {\n return 'AutoResetControllerImpl'\n }\n\n private readonly options: AutoResetControllerImplOptions\n private _error: Error | null = null\n private watchSub: Unsubscribe | null = null\n private currentRetry = 0\n private disposer = /* @__PURE__ */ createDisposer()\n\n constructor(\n readonly deps: AutoResetControllerImplDeps,\n options?: Partial<AutoResetControllerImplOptions>\n ) {\n super()\n logDebug(this, 'constructor')\n this.options = {\n ...defaultResetControllerOptions,\n ...options,\n }\n\n this.disposer.add(\n onAny(\n deps.playbackController,\n ['play', 'pause', 'seeking', 'playing'],\n (_event) => {\n // On certain user-initiated playback events, reset the currentRetry count and emit a reset event\n // if in an error state.\n this.currentRetry = 0\n this.reset()\n }\n )\n )\n }\n\n setError(error: Error): void {\n if (!this.options.enabled || this._error) return\n if (error instanceof RequestError && error.response == null) {\n this._error = error\n this.setResetPending(true)\n }\n }\n\n get resetPending(): boolean {\n return this.watchSub != null\n }\n\n private setResetPending(value: boolean): void {\n if (this.resetPending === value) {\n logDebug(this, 'setResetPending', value, 'no-op')\n return\n }\n logDebug(this, 'setResetPending', value)\n this.watchSub?.()\n this.watchSub = null\n if (value) {\n const networkState = getNetworkState()\n const { add, dispose: watchSub } = createDisposer()\n this.watchSub = watchSub\n add(\n networkState.on('online', () => {\n logDebug(this, 'online, emitting reset')\n this.reset()\n })\n )\n\n const intervalId = setTimeout(() => {\n if (this.currentRetry++ < this.options.maxRetries) {\n if (networkState.onLine) {\n logDebug(this, 'interval, emitting reset')\n this.reset()\n }\n } else {\n logDebug(this, 'max retries exhausted, pausing playback')\n this.setResetPending(false)\n }\n }, this.options.retryInterval * 1000)\n add(() => clearTimeout(intervalId))\n }\n this.dispatch('resetPendingChange', {\n previous: !value,\n current: value,\n })\n }\n\n private reset(): void {\n if (!this._error) return\n this.clear()\n this.dispatch('reset', {})\n }\n\n clear() {\n if (!this._error) return\n this._error = null\n this.setResetPending(false)\n }\n\n get disposed(): boolean {\n return this.disposer.disposed\n }\n\n dispose(): void {\n this.disposer.dispose()\n this.clear()\n }\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type {\n Maybe,\n Mutable,\n MutableRequestParams,\n ReadonlyAbort,\n RequestInitOptions,\n RequestInterceptor,\n Timestamp,\n} from '@amazon/vinyl-util'\nimport {\n getHostname,\n last,\n networkMetricsController,\n normalizeHeadersInit,\n requestWithRetry,\n} from '@amazon/vinyl-util'\nimport { type ByteRange, stringifyByteRange } from '@amazon/vinyl-mpd-parser'\nimport type { SegmentDataProvider } from '../streaming/SegmentDataSlot'\n\nexport interface CreateSegmentDataProviderDeps {\n readonly requestInterceptor: RequestInterceptor\n readonly segmentRequestInit: Maybe<RequestInitOptions>\n}\n\nexport interface CreateSegmentDataProviderOptions {\n readonly url: string\n readonly mediaRange?: Maybe<ByteRange>\n readonly serviceId?: Maybe<string>\n /**\n * If true, reports downlink transfer speeds to network metrics.\n */\n readonly reportDownlinkMetrics: boolean\n}\n\nexport function createSegmentDataProvider(\n deps: CreateSegmentDataProviderDeps,\n options: CreateSegmentDataProviderOptions\n): SegmentDataProvider {\n return async (abort?: Maybe<ReadonlyAbort>) => {\n const init: Mutable<RequestInitOptions> = {\n ...deps.segmentRequestInit,\n }\n if (options.mediaRange) {\n init.headers = {\n ...normalizeHeadersInit(init.headers),\n Range: `bytes=${stringifyByteRange(options.mediaRange)}`,\n }\n }\n\n const params: MutableRequestParams = {\n input: options.url,\n init,\n }\n deps.requestInterceptor(params)\n\n const serviceId = options.serviceId ?? getHostname(options.url)\n const requestStart = Date.now()\n const response = await requestWithRetry(params.input, params.init, {\n serviceId,\n abort,\n })\n const responseEnd = Date.now()\n\n const arrayBuffer = await response.arrayBuffer()\n const contentEnd = Date.now()\n\n let responseStart: Timestamp | null = null\n if ('getEntriesByName' in performance) {\n const lastRequest: any = last(\n performance.getEntriesByName(params.input)\n )\n if (lastRequest) {\n // Resource timing information was available, use it to get a more accurate response start time. A\n // value of 0 means timing information was denied, likely due to a cross-origin request without\n // Timing-Allow-Origin response headers.\n if (lastRequest.responseStart) {\n responseStart =\n performance.timeOrigin + lastRequest.responseStart\n }\n }\n }\n\n if (options.reportDownlinkMetrics) {\n networkMetricsController.value.addDownlinkTransferEntry({\n bytes: arrayBuffer.byteLength,\n serviceId,\n requestStart,\n responseStart,\n responseEnd,\n contentEnd,\n })\n }\n return arrayBuffer\n }\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {\n ErrorOrigin,\n type Maybe,\n ownKeys,\n type ReadonlyRecord,\n} from '@amazon/vinyl-util'\nimport {\n any,\n isOneOf,\n number,\n object,\n type ObjectSchema,\n string,\n type ValueSchema,\n} from '@amazon/vinyl-validation'\n\nimport type { Track, TrackTypeId, TrackUri } from './Track'\nimport { type DrmOptions, drmOptionsValidator } from '../drm/DrmOptions'\n\nexport interface TrackLoadOptions {\n /**\n * The track type, used to map to a track factory.\n */\n readonly type: TrackTypeId\n\n /**\n * The track identifier.\n */\n readonly uri: TrackUri\n\n /**\n * The track configuration.\n */\n readonly config?: Maybe<TrackConfigOptions>\n}\n\n/**\n * General configuration for tracks set in track load options.\n */\nexport interface TrackConfigOptions {\n /**\n * The time to seek to when the track has been activated.\n * For MSE tracks this will affect pre-fetching.\n */\n readonly startTime?: Maybe<number>\n\n /**\n * Extra application data to associate with the track.\n */\n readonly extra?: any\n\n /**\n * DRM Configuration overrides for this track.\n */\n readonly drm?: Partial<DrmOptions>\n}\n\nexport const trackConfigOptionsValidator: ObjectSchema<TrackConfigOptions> =\n /* @__PURE__ */ object({\n extra: /* @__PURE__ */ /* @__PURE__ */ any().optional(),\n startTime: /* @__PURE__ */ /* @__PURE__ */ /* @__PURE__ */ number().maybe().optional(),\n drm: /* @__PURE__ */ /* @__PURE__ */ drmOptionsValidator.partial().optional(),\n })\n\nexport const trackLoadOptionsValidator: ObjectSchema<TrackLoadOptions> = /* @__PURE__ */ object(\n {\n type: /* @__PURE__ */ string(),\n uri: /* @__PURE__ */ /* @__PURE__ */ string().notEmpty(),\n config: /* @__PURE__ */ /* @__PURE__ */ trackConfigOptionsValidator.maybe().optional(),\n }\n)\n\n/**\n * Produces a new Track for the given configuration options.\n */\nexport interface TrackFactory<TrackLoadOptionsType extends TrackLoadOptions> {\n /**\n * Throws a validation error if the track options are invalid.\n */\n validate(options: TrackLoadOptionsType): void\n\n /**\n * Constructs a new track from the provided load options.\n */\n createTrack(options: TrackLoadOptionsType): Track\n}\n\nexport type InferLoadOptionsFromFactory<T extends TrackFactory<any>> =\n T extends TrackFactory<infer LoadOptions> ? LoadOptions : never\n\nexport type CombinedTrackFactoryOptions<\n T extends ReadonlyRecord<TrackTypeId, TrackFactory<TrackLoadOptions>>,\n> = InferLoadOptionsFromFactory<T[keyof T]>\n\nexport type TrackFactoryRecord = ReadonlyRecord<\n TrackTypeId,\n TrackFactory<TrackLoadOptions>\n>\n\n/**\n * Validates that the keys of the track factory record match the track type\n * for the track factory.\n */\nexport type ValidTrackFactoryRecord<T extends TrackFactoryRecord> = {\n readonly [K in keyof T]: K extends InferLoadOptionsFromFactory<T[K]>['type']\n ? T[K]\n : never\n}\n\n/**\n * Given a map of TrackTypeId => TrackFactory, returns a track factory\n * that supports any of the provided track types.\n * The factory will be mapped by the track load options `type` property.\n *\n * @param factories\n */\nexport function createTrackFactory<T extends TrackFactoryRecord>(\n factories: ValidTrackFactoryRecord<T>\n): TrackFactory<CombinedTrackFactoryOptions<T>> {\n // Validates that the track type attempting to be created exists in the factory map.\n const typeValidator: ValueSchema<keyof T> = isOneOf(...ownKeys(factories))\n return {\n validate(options): void {\n typeValidator.assert(options.type, ErrorOrigin.API)\n factories[options.type].validate(options)\n },\n\n createTrack(options): Track {\n return factories[options.type].createTrack(options)\n },\n }\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { PlaybackSource } from '../../playback/PlaybackSource'\nimport type { Track, TrackTypeId, TrackUri } from '../Track'\nimport { type TrackBaseDeps } from '../TrackBase'\nimport {\n type TrackFactory,\n type TrackLoadOptions,\n trackLoadOptionsValidator,\n} from '../TrackFactory'\nimport { ErrorOrigin, type Maybe } from '@amazon/vinyl-util'\nimport { func, isOneOf, type ObjectSchema } from '@amazon/vinyl-validation'\nimport {\n SourceTrackBase,\n type SourceTrackConfigOptions,\n sourceTrackBaseOptionsValidator,\n} from './SourceTrackBase'\n\n/**\n * Dependencies for a SourceObjectTrack.\n */\nexport interface SourceObjectTrackDeps extends TrackBaseDeps {\n readonly playbackSource: PlaybackSource\n}\n\nexport interface SourceObjectTrackLoadOptions extends TrackLoadOptions {\n readonly type: 'srcObject'\n\n /**\n * A function to produce a MediaStream, or Promise<MediaStream>.\n */\n readonly srcObjectProvider: (\n uri: TrackUri\n ) => Promise<MediaStream> | MediaStream\n\n /**\n * Configuration options for the SourceObjectTrack.\n * Will be provided on preload and activate.\n */\n readonly config?: Maybe<SourceTrackConfigOptions>\n}\n\nconst loadOptionsValidator: ObjectSchema<SourceObjectTrackLoadOptions> =\n /* @__PURE__ */ trackLoadOptionsValidator.extend({\n srcObjectProvider: /* @__PURE__ */ func(),\n type: /* @__PURE__ */ isOneOf('srcObject'),\n config: /* @__PURE__ */ /* @__PURE__ */ sourceTrackBaseOptionsValidator.maybe().optional(),\n })\n\nexport function createSourceObjectTrackFactory(\n deps: SourceObjectTrackDeps\n): TrackFactory<SourceObjectTrackLoadOptions> {\n return {\n validate(options: SourceObjectTrackLoadOptions): void {\n loadOptionsValidator.assert(options, ErrorOrigin.API)\n },\n\n createTrack(options: SourceObjectTrackLoadOptions): Track {\n return new SourceObjectTrack(\n options.uri,\n options.type,\n Promise.resolve(options.srcObjectProvider(options.uri)),\n deps\n )\n },\n }\n}\n\n// TODO: Accept a provider function instead of a Promise for srcObject to support reset.\nexport class SourceObjectTrack extends SourceTrackBase<MediaStream> {\n get [Symbol.toStringTag](): string {\n return 'SourceObjectTrack'\n }\n\n constructor(\n uri: TrackUri,\n type: TrackTypeId,\n srcObject: Promise<MediaStream>,\n protected readonly deps: SourceObjectTrackDeps\n ) {\n super(uri, type, srcObject, deps)\n }\n\n protected setSrc(src: MediaStream) {\n this.deps.playbackSource.srcObject = src\n }\n\n protected clearSrc(): void {\n this.deps.playbackSource.srcObject = null\n this.deps.playbackSource.load()\n }\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {\n createAbortSlot,\n createDisposer,\n emptyRanges,\n equalDeep,\n EventHostImpl,\n isSilentError,\n logDebug,\n type Maybe,\n noop,\n type ReadonlyRanges,\n type ReadonlySet,\n} from '@amazon/vinyl-util'\nimport type { PlaybackController } from '../playback/PlaybackController'\nimport type {\n Track,\n TrackEventMap,\n TrackPreloadOptions,\n TrackTypeId,\n TrackUri,\n} from './Track'\nimport type { SeekRange } from './SeekRange'\nimport { type DrmController } from '../drm/DrmController'\nimport type {\n ContentType,\n MediaQualityMetadata,\n} from '../streaming/MediaQualityMetadata'\nimport type { TextTrackController } from '../text/TextTrack'\nimport type { TrackAds } from '../ad/AdBreakInfo'\nimport type { TrackConfigOptions } from './TrackFactory'\n\n/**\n * Dependencies for TrackBase.\n */\nexport interface TrackBaseDeps {\n /**\n * When the track is activated, playback will seek to the track's start time.\n */\n readonly playbackController: PlaybackController\n\n /**\n * DrmController manages track encryption.\n */\n readonly drmController: DrmController\n}\n\n/**\n * A base class for all tracks.\n */\nexport abstract class TrackBase<\n EventMap extends TrackEventMap = TrackEventMap,\n ConfigType extends TrackConfigOptions = TrackConfigOptions,\n>\n extends EventHostImpl<EventMap>\n implements Track<ConfigType>\n{\n get [Symbol.toStringTag](): string {\n return 'TrackBase'\n }\n\n /**\n * The current load options, if this is an active track.\n */\n protected loadOptions: Maybe<ConfigType> = null\n\n protected readonly errorHandler = (error: any): void => {\n if (this._error) return // Already in an error state\n if (!isSilentError(error)) {\n this._error = error\n this.dispatch('error', {\n target: this,\n error,\n })\n }\n }\n protected readonly disposer = /* @__PURE__ */ createDisposer()\n protected drmSessionAbort = /* @__PURE__ */ createAbortSlot()\n\n get fetchedRanges(): ReadonlyRanges {\n return emptyRanges\n }\n\n /**\n * Default text track controller is null. Tracks that surface text tracks\n * (e.g. {@link MseTrack}) override this getter.\n */\n get textTrackController(): TextTrackController | null {\n return null\n }\n\n /**\n * The presentation seek range of the media.\n * Most often {start=0, end=duration} but may be different depending on the\n * media timeline.\n */\n get seekRange(): SeekRange | null {\n return this._seekRange\n }\n\n abstract get contentTypes(): ReadonlySet<ContentType>\n\n abstract get qualities(): readonly MediaQualityMetadata[] | null\n abstract get qualitiesUnfiltered(): readonly MediaQualityMetadata[] | null\n\n abstract getStreamingQuality(\n contentType: ContentType\n ): MediaQualityMetadata | null\n abstract getBufferingQuality(\n contentType: ContentType\n ): MediaQualityMetadata | null\n abstract getPlaybackQuality(\n contentType: ContentType\n ): MediaQualityMetadata | null\n\n /**\n * Sets on handleError, cleared on 'reset'.\n */\n protected _error: Error | null = null\n private _active = false\n private _seekRange: SeekRange | null = null\n\n protected constructor(\n /**\n * The identifier of this track, used as the key in the track cache.\n */\n readonly uri: TrackUri,\n\n /**\n * The track type.\n */\n readonly type: TrackTypeId,\n\n protected readonly deps: TrackBaseDeps\n ) {\n super()\n }\n\n toString(): string {\n return `[${this[Symbol.toStringTag]}#${this.uri}]`\n }\n\n get error(): Error | null {\n return this._error\n }\n\n preload(\n _trackOptions: TrackPreloadOptions,\n _loadOptions: Maybe<ConfigType>\n ): void {}\n\n get extra(): any {\n return this.loadOptions?.extra ?? null\n }\n\n get active(): boolean {\n return this._active\n }\n\n get disposed(): boolean {\n return this.disposer.disposed\n }\n\n activate(loadOptions: Maybe<ConfigType>): void {\n if (this._active) return\n this.loadOptions = loadOptions\n this.reset() // Reset error state on activate\n this._active = true\n logDebug(this, 'activate', this.uri)\n this.deps.playbackController\n .seekTo(loadOptions?.startTime ?? 0)\n .catch(noop)\n this.deps.drmController.configure(loadOptions?.drm)\n this.onActivated(loadOptions)\n }\n\n /**\n * The track has been activated.\n * Operations on shared resources such as the playback controller may only be done while the\n * track is currently active. For example if there is a loading operation before the\n * playback source is set, isActive must be checked before the property is changed.\n */\n abstract onActivated(loadOptions: Maybe<ConfigType>): void\n\n deactivate(): void {\n if (!this._active) return\n this._active = false\n this.loadOptions = null\n logDebug(this, 'deactivate', this.uri)\n this.deps.playbackController.pause()\n this.onDeactivated()\n this.closeDrmSessions()\n }\n\n abstract onDeactivated(): void\n\n abstract clearPrefetch(): void\n\n protected closeDrmSessions() {\n this.drmSessionAbort.abort()\n }\n\n /**\n * Resolves to this track's ads.\n * Implementations may override to provide ad breaks.\n */\n getAds(): Promise<TrackAds> {\n return Promise.resolve({\n adBreaks: [],\n trackUri: this.uri,\n })\n }\n\n protected setSeekRange(value: SeekRange): void {\n const prev = this._seekRange\n if (equalDeep(prev, value)) return\n const previous = this._seekRange\n this._seekRange = value\n logDebug(this, `seekRangeChange start=${value.start}, end=${value.end}`)\n this.dispatch('seekRangeChange', {\n previous,\n current: value,\n })\n }\n\n /**\n * Resets the track to recover from error states.\n * Base implementation does nothing.\n *\n * Overrides should dispatch 'reset' after resetting error state.\n */\n reset(hard = false): void {\n if (!hard && !this._error) {\n logDebug(this, 'reset no-op')\n return\n }\n if (hard) {\n // On a hard reset, deactivate/activate the track,\n // restore playback seek and playing state.\n if (this._active) {\n const loadOptions = this.loadOptions\n const { playbackController } = this.deps\n const wasPaused =\n playbackController.paused || playbackController.ended\n const time = playbackController.currentTime\n this.onDeactivated()\n // Clear the prefetch on a hard reset, in the case of codecs unsupported, the prefetch would\n // otherwise contain unsupported segments.\n this.clearPrefetch()\n this.onActivated(loadOptions)\n playbackController.seekTo(time).catch(noop)\n if (!wasPaused) playbackController.play().catch(noop)\n } else {\n this.clearPrefetch()\n }\n }\n logDebug(this, 'reset, hard:', hard)\n this._error = null\n this.dispatch('reset', {})\n }\n\n dispose() {\n if (this.active) this.deactivate()\n else this.closeDrmSessions() // closes sessions created from prefetch.\n this.disposer.dispose()\n super.dispose()\n }\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { TrackEventMap } from '../Track'\nimport type { Unsubscribe } from '@amazon/vinyl-util'\nimport { EventHostImpl, type ReadonlySet } from '@amazon/vinyl-util'\nimport { PlaybackReadyState } from '../../playback/ReadonlyPlaybackController'\nimport type { PlaybackController } from '../../playback/PlaybackController'\nimport type { ChangeEvent } from '../../event/ChangeEvent'\nimport type {\n ContentType,\n MediaQualityMetadata,\n} from '../../streaming/MediaQualityMetadata'\n\n/**\n * FixedPlaybackQuality has a singular quality for selection.\n *\n * streamingQuality will always be the fixed quality.\n *\n * bufferingQuality will be the fixed quality when active, otherwise null.\n *\n * playbackQuality will be the fixed quality when active and data is buffered, otherwise null.\n */\nexport class FixedPlaybackQuality extends EventHostImpl<\n Pick<\n TrackEventMap,\n | 'streamingQualityChange'\n | 'bufferingQualityChange'\n | 'playbackQualityChange'\n >\n> {\n private _fixedQuality!: MediaQualityMetadata\n private _contentTypes = /* @__PURE__ */ new Set<ContentType>()\n\n private _isActive = false\n get active(): boolean {\n return this._isActive\n }\n\n constructor(\n fixedQuality: MediaQualityMetadata,\n private readonly deps: {\n readonly playbackController: PlaybackController\n }\n ) {\n super()\n this.fixedQuality = fixedQuality\n }\n\n get contentTypes(): ReadonlySet<ContentType> {\n return this._contentTypes\n }\n\n get fixedQuality(): MediaQualityMetadata {\n return this._fixedQuality\n }\n\n set fixedQuality(value: MediaQualityMetadata) {\n const previous = this._fixedQuality\n this._fixedQuality = value\n this._contentTypes = new Set()\n if (value.contentType) this._contentTypes.add(value.contentType)\n this.dispatch('streamingQualityChange', {\n previous,\n current: this._fixedQuality,\n })\n if (this.active) {\n this.bufferingQuality = value\n if (\n this.deps.playbackController.readyState >=\n PlaybackReadyState.HAVE_CURRENT_DATA\n ) {\n this.playbackQuality = value\n }\n }\n }\n\n getStreamingQuality(contentType: ContentType): MediaQualityMetadata | null {\n if (contentType !== this._fixedQuality.contentType) return null\n return this._fixedQuality\n }\n\n private _bufferingQuality: MediaQualityMetadata | null = null\n getBufferingQuality(contentType: ContentType): MediaQualityMetadata | null {\n if (contentType !== this._bufferingQuality?.contentType) return null\n return this._bufferingQuality\n }\n\n private set bufferingQuality(value: MediaQualityMetadata | null) {\n const previous = this._bufferingQuality\n if (previous === value) return\n this._bufferingQuality = value\n this.dispatch('bufferingQualityChange', {\n previous,\n current: this._bufferingQuality,\n })\n }\n\n private _playbackQuality: MediaQualityMetadata | null = null\n getPlaybackQuality(contentType: ContentType): MediaQualityMetadata | null {\n if (contentType !== this._playbackQuality?.contentType) return null\n return this._playbackQuality\n }\n\n private set playbackQuality(value: MediaQualityMetadata | null) {\n const previous = this._playbackQuality\n if (previous === value) return\n this._playbackQuality = value\n this.dispatch('playbackQualityChange', {\n previous,\n current: this._playbackQuality,\n })\n }\n\n private readyStateChangeSub: Unsubscribe | null = null\n activate() {\n if (this._isActive) return\n this._isActive = true\n this.bufferingQuality = this._fixedQuality\n const pC = this.deps.playbackController\n this.readyStateChangeSub = pC.on(\n 'readyStateChange',\n this.onReadyStateChange\n )\n if (pC.readyState >= PlaybackReadyState.HAVE_CURRENT_DATA) {\n this.playbackQuality = this._fixedQuality\n }\n }\n\n deactivate() {\n if (!this._isActive) return\n this._isActive = false\n this.readyStateChangeSub!()\n this.readyStateChangeSub = null\n this.bufferingQuality = null\n this.playbackQuality = null\n }\n\n private onReadyStateChange = (event: ChangeEvent<PlaybackReadyState>) => {\n const hasData = event.current >= PlaybackReadyState.HAVE_CURRENT_DATA\n this.playbackQuality = hasData ? this._fixedQuality : null\n }\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { TrackBase, type TrackBaseDeps } from '../TrackBase'\nimport type {\n TrackEventMap,\n TrackPreloadOptions,\n TrackTypeId,\n TrackUri,\n} from '../Track'\nimport { FixedPlaybackQuality } from './FixedPlaybackQuality'\nimport {\n createDisposer,\n logDebug,\n type Maybe,\n type ReadonlySet,\n redispatchEvents,\n type Unsubscribe,\n} from '@amazon/vinyl-util'\nimport {\n type ContentType,\n createEmptyMediaQualityMetadata,\n type MediaQualityMetadata,\n mediaQualityMetadataValidator,\n} from '../../streaming/MediaQualityMetadata'\nimport type { ObjectSchema } from '@amazon/vinyl-validation'\nimport {\n type TrackConfigOptions,\n trackConfigOptionsValidator,\n} from '../TrackFactory'\n\nexport interface SourceTrackConfigOptions extends TrackConfigOptions {\n /**\n * Quality metadata.\n * May be used to configure DRM (for native HLS), codec, or other track metadata.\n */\n readonly qualityMetadata?: Maybe<Partial<MediaQualityMetadata>>\n}\n\nexport const sourceTrackBaseOptionsValidator: ObjectSchema<SourceTrackConfigOptions> =\n /* @__PURE__ */ trackConfigOptionsValidator.extend({\n qualityMetadata: /* @__PURE__ */ /* @__PURE__ */ /* @__PURE__ */ mediaQualityMetadataValidator\n .partial()\n .maybe()\n .optional(),\n })\n\nconst emptyMediaQualityMetadata: MediaQualityMetadata =\n /* @__PURE__ */ createEmptyMediaQualityMetadata()\n\nexport abstract class SourceTrackBase<\n SrcType,\n EventMap extends TrackEventMap = TrackEventMap,\n TrackConfigOptions extends SourceTrackConfigOptions =\n SourceTrackConfigOptions,\n> extends TrackBase<EventMap, TrackConfigOptions> {\n private readonly fixedPlaybackQuality: FixedPlaybackQuality\n private _resolvedSrc: SrcType | null = null\n private activeSub: Unsubscribe | null = null\n\n protected constructor(\n uri: TrackUri,\n type: TrackTypeId,\n public readonly src: Promise<SrcType>,\n protected readonly deps: TrackBaseDeps\n ) {\n super(uri, type, deps)\n const add = this.disposer.add\n this.src\n .then((src) => {\n this._resolvedSrc = src\n if (this.active) this.setSrc(src)\n })\n .catch(this.errorHandler)\n this.fixedPlaybackQuality = add(\n new FixedPlaybackQuality(emptyMediaQualityMetadata, deps)\n )\n this.fixedPlaybackQuality.on('bufferingQualityChange', (event) => {\n this.deps.drmController.setBufferingDrmInfo(event.current, {\n trackUri: this.uri,\n abort: this.drmSessionAbort.value,\n })\n })\n redispatchEvents(this, this.fixedPlaybackQuality, [\n 'streamingQualityChange',\n 'bufferingQualityChange',\n 'playbackQualityChange',\n ])\n }\n\n preload(\n trackOptions: TrackPreloadOptions,\n loadOptions: Maybe<TrackConfigOptions>\n ) {\n super.preload(trackOptions, loadOptions)\n this.fixedPlaybackQuality.fixedQuality = {\n ...emptyMediaQualityMetadata,\n ...loadOptions?.qualityMetadata,\n }\n }\n\n get contentTypes(): ReadonlySet<ContentType> {\n return this.fixedPlaybackQuality.contentTypes\n }\n\n get qualities(): readonly MediaQualityMetadata[] | null {\n return null\n }\n\n get qualitiesUnfiltered(): readonly MediaQualityMetadata[] | null {\n return null\n }\n\n getStreamingQuality(contentType: ContentType): MediaQualityMetadata | null {\n return this.fixedPlaybackQuality.getStreamingQuality(contentType)\n }\n\n getBufferingQuality(contentType: ContentType): MediaQualityMetadata | null {\n return this.fixedPlaybackQuality.getBufferingQuality(contentType)\n }\n\n getPlaybackQuality(contentType: ContentType): MediaQualityMetadata | null {\n return this.fixedPlaybackQuality.getPlaybackQuality(contentType)\n }\n\n onActivated(): void {\n const { add, dispose } = createDisposer()\n this.activeSub = dispose\n add(\n this.deps.playbackController.on('durationChange', (event) => {\n this.setSeekRange({\n start: 0,\n end: event.current,\n })\n })\n )\n this.fixedPlaybackQuality.activate()\n this.deps.drmController.initializeForPlayback(\n this.fixedPlaybackQuality.fixedQuality,\n { trackUri: this.uri, abort: this.drmSessionAbort.value }\n )\n if (this._resolvedSrc != null) this.setSrc(this._resolvedSrc)\n add(() => {\n if (this._resolvedSrc != null) this.clearSrc()\n this.fixedPlaybackQuality.deactivate()\n })\n }\n\n protected abstract setSrc(src: SrcType): void\n protected abstract clearSrc(): void\n\n onDeactivated(): void {\n this.activeSub?.()\n this.activeSub = null\n }\n\n clearPrefetch() {\n // Source tracks do not prefetch\n logDebug(this, 'clearPrefetch no-op')\n }\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { Track, TrackTypeId, TrackUri } from '../Track'\nimport { type TrackBaseDeps } from '../TrackBase'\nimport {\n type TrackFactory,\n type TrackLoadOptions,\n trackLoadOptionsValidator,\n} from '../TrackFactory'\nimport { ErrorOrigin, type Maybe } from '@amazon/vinyl-util'\nimport { func, isOneOf, type ObjectSchema } from '@amazon/vinyl-validation'\nimport {\n SourceTrackBase,\n sourceTrackBaseOptionsValidator,\n type SourceTrackConfigOptions,\n} from './SourceTrackBase'\nimport type { PlaybackSource } from '../../playback/PlaybackSource'\n\n/**\n * Dependencies for a SourceTrack.\n */\nexport interface SourceTrackDeps extends TrackBaseDeps {\n readonly playbackSource: PlaybackSource\n}\n\nexport interface SourceTrackLoadOptions extends TrackLoadOptions {\n readonly type: 'src'\n\n /**\n * If set, will be called to provide the track src.\n * Otherwise, the uri will be used.\n */\n readonly srcProvider?: Maybe<(uri: TrackUri) => Promise<string> | string>\n\n /**\n * Configuration options for the SourceTrack.\n * Will be provided on preload and activate.\n */\n readonly config?: Maybe<SourceTrackConfigOptions>\n}\n\nconst loadOptionsValidator: ObjectSchema<SourceTrackLoadOptions> =\n /* @__PURE__ */ trackLoadOptionsValidator.extend({\n config: /* @__PURE__ */ /* @__PURE__ */ sourceTrackBaseOptionsValidator.maybe().optional(),\n srcProvider: /* @__PURE__ */ /* @__PURE__ */ /* @__PURE__ */ func().maybe().optional(),\n type: /* @__PURE__ */ isOneOf('src'),\n })\n\nexport function createSourceTrackFactory(\n deps: SourceTrackDeps\n): TrackFactory<SourceTrackLoadOptions> {\n return {\n validate(options: SourceTrackLoadOptions) {\n loadOptionsValidator.assert(options, ErrorOrigin.API)\n },\n\n createTrack(options: SourceTrackLoadOptions): Track {\n return new SourceTrack(\n options.uri,\n options.type,\n options.srcProvider\n ? Promise.resolve(options.srcProvider(options.uri))\n : Promise.resolve(options.uri),\n deps\n )\n },\n }\n}\n\n// TODO: Accept a provider function instead of a Promise for src to support reset.\nexport class SourceTrack extends SourceTrackBase<string> {\n get [Symbol.toStringTag](): string {\n return 'SourceTrack'\n }\n\n constructor(\n uri: TrackUri,\n type: TrackTypeId,\n src: Promise<string>,\n protected readonly deps: SourceTrackDeps\n ) {\n super(uri, type, src, deps)\n }\n\n protected setSrc(src: string) {\n this.deps.playbackSource.src = src\n }\n\n protected clearSrc() {\n this.deps.playbackSource.src = null\n this.deps.playbackSource.load()\n }\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {\n type DashManifestData,\n type DashManifestProvider,\n} from './DashManifestProvider'\nimport {\n type TrackConfigOptions,\n type TrackFactory,\n type TrackLoadOptions,\n trackLoadOptionsValidator,\n} from '../TrackFactory'\nimport type { ObservableValue } from '@amazon/vinyl-observable'\nimport {\n ErrorOrigin,\n type Maybe,\n type RequestInitOptions,\n} from '@amazon/vinyl-util'\nimport {\n func,\n isOneOf,\n object,\n type ObjectSchema,\n} from '@amazon/vinyl-validation'\nimport type { Track } from '../Track'\nimport { type Factories } from '@amazon/vinyl-di'\nimport type { DashMediaQualityMetadataResolver } from './DashMediaQualityMetadataResolver'\nimport { MseTrack, type MseTrackDeps } from '../mse/MseTrack'\nimport type { MediaTimeline } from '../../streaming/MediaTimeline'\nimport type { DashManifestController } from './DashManifestController'\n\nexport interface DashTrackLoadOptions extends TrackLoadOptions {\n readonly type: 'dash'\n\n /**\n * If set, will be used to resolve the dash manifest.\n * Otherwise, the uri will be assumed to represent a URL to an MPD.\n * The manifest provider is not expected to cache results.\n */\n readonly manifestProvider?: Maybe<DashManifestProvider>\n\n /**\n * If a manifest provider is not set, the uri will be used to fetch a manifest.\n * This can be set to provide Request initialization options such as headers or request method.\n */\n readonly requestInit?: Maybe<RequestInitOptions>\n\n /**\n * Request initialization options for segment requests, such as headers.\n * Range headers set by the player for byte-range requests will not be overridden.\n */\n readonly segmentRequestInit?: Maybe<RequestInitOptions>\n\n /**\n * Configuration options for the DashTrack.\n * Will be set before the track is activated.\n */\n readonly config?: Maybe<TrackConfigOptions>\n}\n\nconst loadOptionsValidator: ObjectSchema<DashTrackLoadOptions> =\n /* @__PURE__ */ trackLoadOptionsValidator.extend({\n manifestProvider: /* @__PURE__ */ /* @__PURE__ */ /* @__PURE__ */ func().maybe().optional(),\n requestInit: /* @__PURE__ */ /* @__PURE__ */ /* @__PURE__ */ /* @__PURE__ */ object({}).cast<RequestInitOptions>().maybe().optional(),\n segmentRequestInit: /* @__PURE__ */ /* @__PURE__ */ /* @__PURE__ */ /* @__PURE__ */ object({})\n .cast<RequestInitOptions>()\n .maybe()\n .optional(),\n type: /* @__PURE__ */ isOneOf('dash'),\n })\n\nexport type DashTrackFactoryDeps = {\n readonly createDashFactories: (\n loadOptions: DashTrackLoadOptions\n ) => Factories<DashTrackDeps>\n}\n\nexport function createDashTrackFactory(\n deps: DashTrackFactoryDeps\n): TrackFactory<DashTrackLoadOptions> {\n return {\n validate(options: DashTrackLoadOptions) {\n loadOptionsValidator.assert(options, ErrorOrigin.API)\n },\n\n createTrack(loadOptions: DashTrackLoadOptions): Track {\n return new MseTrack(\n loadOptions.uri,\n loadOptions.type,\n deps.createDashFactories(loadOptions)\n )\n },\n }\n}\n\nexport interface DashTrackDeps extends MseTrackDeps {\n readonly manifestController: DashManifestController\n readonly mediaQualityMetadataResolver: DashMediaQualityMetadataResolver\n readonly manifestTransformed: ObservableValue<Promise<DashManifestData>>\n readonly mediaTimeline: ObservableValue<Promise<MediaTimeline>>\n readonly mediaTimelineTransformed: ObservableValue<Promise<MediaTimeline>>\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { TrackBase, type TrackBaseDeps } from '../TrackBase'\nimport {\n Abort,\n equalDeep,\n first,\n type Fun,\n IntersectionRanges,\n logDebug,\n type Maybe,\n noop,\n type ReadonlyRanges,\n type ReadonlySet,\n redispatchEvents,\n type Unsubscribe,\n} from '@amazon/vinyl-util'\nimport type { TrackPreloadOptions, TrackTypeId, TrackUri } from '../Track'\nimport type {\n ContentType,\n MediaQualityMetadata,\n} from '../../streaming/MediaQualityMetadata'\nimport { createContainer, type Factories } from '@amazon/vinyl-di'\nimport type {\n ContentStream,\n ContentStreamPreloadOptions,\n} from '../../streaming/ContentStream'\nimport type { MediaSourceController } from '../../streaming/buffering/MediaSourceController'\nimport type { PlaybackSource } from '../../playback/PlaybackSource'\nimport type { ContentTypesValue } from '../../streaming/ContentTypesValue'\nimport type { ManifestController } from '../../streaming/ManifestController'\nimport type { ObservableValue } from '@amazon/vinyl-observable'\nimport {\n getMediaPeriodAtTime,\n type MediaPeriod,\n type MediaTimeline,\n} from '../../streaming/MediaTimeline'\nimport type { TextTrackController } from '../../text/TextTrack'\nimport type { TrackConfigOptions } from '../TrackFactory'\nimport type { LoadSpanMeasurement } from '../../streaming/LoadMetric'\nimport type { TrackAds } from '../../ad/AdBreakInfo'\nimport type { VinylOptions } from '../../vinyl/VinylOptions'\n\n/**\n * How long to wait after all streams have data before checking whether a seek\n * is still stuck, in seconds.\n */\nexport const SEEKING_STALL_TIME_CHECK = 0.1\n\n/**\n * How far to nudge the playhead, in seconds, to recover a stuck seek.\n */\nexport const PLAYHEAD_NUDGE = 0.05\n\nexport type MseTrackDeps = TrackBaseDeps & {\n readonly contentTypesValue: ContentTypesValue\n readonly contentStreamFactory: (contentType: ContentType) => ContentStream\n readonly manifestController: ManifestController<unknown>\n readonly mediaSourceController: MediaSourceController\n readonly playbackSource: PlaybackSource\n readonly mediaTimeline: ObservableValue<Promise<MediaTimeline>>\n readonly mediaTimelineTransformed: ObservableValue<Promise<MediaTimeline>>\n /**\n * Optional sidecar text track controller for this track. When provided,\n * the controller is exposed via {@link MseTrack.textTrackController} and\n * disposed when the track itself is disposed.\n */\n readonly textTrackController?: TextTrackController | null\n\n /**\n * Player options that re-select this track's audio/streams. A change (not\n * the initial value) is applied to this track immediately so it takes\n * effect without waiting for the buffered media to drain.\n */\n readonly preferredAudioLanguage: ObservableValue<\n VinylOptions['preferredAudioLanguage']\n >\n readonly allowedContentTypes: ObservableValue<\n VinylOptions['allowedContentTypes']\n >\n readonly preferDescriptiveAudio: ObservableValue<\n VinylOptions['preferDescriptiveAudio']\n >\n readonly abr: ObservableValue<VinylOptions['abr']>\n}\n\ntype FunctionKeys<T> = {\n [P in keyof T]: T[P] extends Fun ? P : never\n}[keyof T]\n\n/**\n * An MseTrack uses media source extensions for streaming.\n */\nexport class MseTrack extends TrackBase {\n get [Symbol.toStringTag](): string {\n return 'MseTrack'\n }\n\n declare protected readonly deps: MseTrackDeps\n\n override get textTrackController(): TextTrackController | null {\n // Reading a dep on a disposed track throws DisposedError (its DI\n // container's lazies are disposed); a stale reference has no controller.\n if (this.disposed) return null\n return this.deps.textTrackController ?? null\n }\n\n private readonly streams: ContentStream[] = []\n private stallNudgeTimer: ReturnType<typeof setTimeout> | null = null\n private readonly disposeAbort = /* @__PURE__ */ new Abort()\n private lastPreloadOptions: ContentStreamPreloadOptions | null = null\n private readonly allFetchedRanges: ReadonlyRanges[] = []\n private readonly _fetchedRanges = /* @__PURE__ */ new IntersectionRanges(\n this.allFetchedRanges,\n { useCache: true }\n )\n private _contentTypes: ReadonlySet<ContentType> = /* @__PURE__ */ new Set()\n\n private _qualities: readonly MediaQualityMetadata[] | null = null\n private _qualitiesUnfiltered: readonly MediaQualityMetadata[] | null = null\n private timeUpdateSub: Unsubscribe | null = null\n private _cachedPeriod: MediaPeriod | null = null\n\n constructor(\n uri: TrackUri,\n type: TrackTypeId,\n dependencyFactories: Factories<MseTrackDeps>\n ) {\n const depsContainer = createContainer(dependencyFactories)\n const deps = depsContainer.dependencies\n super(uri, type, deps)\n logDebug(this, 'constructed')\n const { add } = this.disposer\n add(depsContainer)\n this.deps = deps\n\n add(\n deps.contentTypesValue.onData((contentTypesPromise) => {\n contentTypesPromise\n .then((value) => this.setContentTypes(value))\n .catch(this.errorHandler)\n })\n )\n\n // DRM\n this.on('streamingQualityChange', (event) => {\n if (this.active) {\n this.deps.drmController.initializeForPlayback(event.current, {\n trackUri: this.uri,\n abort: this.disposeAbort,\n })\n }\n })\n\n this.on('bufferingQualityChange', (event) => {\n // Keep the DRM info while a stream's buffering transiently clears\n // (a seek or reaching the end): with multiple encrypted streams, an\n // `encrypted` event from another stream still (re)appending its init\n // segment needs it. The info is cleared on deactivation instead.\n if (event.current == null) return\n this.deps.drmController.setBufferingDrmInfo(event.current, {\n trackUri: this.uri,\n abort: this.disposeAbort,\n })\n })\n\n // Listen for timeline changes to update qualities seek ranges and ads.\n add(\n deps.mediaTimelineTransformed.onData(() => {\n this._cachedPeriod = null\n this.updateQualities()\n this.updateSeekRanges()\n this.dispatch('adsChange', {})\n })\n )\n add(\n deps.mediaTimeline.onData(() => {\n this._cachedPeriod = null\n this.updateQualitiesUnfiltered()\n })\n )\n\n // Surface the manifest fetch span alongside the streams' segment spans,\n // attributing it to this track at the source.\n add(\n deps.manifestController.on('loadSpanMeasured', (measurement) =>\n this.dispatchLoadSpan(measurement)\n )\n )\n\n // Audio/stream selection options: a change (never the initial value)\n // re-filters the timeline, so rebuild this track's streams in place.\n add(\n deps.preferredAudioLanguage.onData((_value, previous) => {\n if (previous !== undefined) this.reloadStreams()\n })\n )\n add(\n deps.allowedContentTypes.onData((_value, previous) => {\n if (previous !== undefined) this.reloadStreams()\n })\n )\n add(\n deps.preferDescriptiveAudio.onData((_value, previous) => {\n if (previous !== undefined) this.reloadStreams()\n })\n )\n // A resolution-restriction change re-selects a quality from the same\n // streams, so clearing the buffer is enough \u2014 no rebuild is needed.\n add(\n deps.abr.onData((value, previous) => {\n if (previous === undefined) return\n if (\n value.maxHeight !== previous.maxHeight ||\n value.maxWidth !== previous.maxWidth\n ) {\n this.clearPrefetch()\n }\n })\n )\n }\n\n /**\n * Clears this track's buffers and rebuilds its streams so a changed\n * audio/language/content-type selection applies immediately.\n * {@link reset} with `hard` safely no-ops the rebuild for an inactive\n * (cached) track.\n */\n private reloadStreams(): void {\n this.clearPrefetch()\n this.reset(/* hard */ true)\n }\n\n /**\n * Re-dispatches a sub-controller's load span stamped with this track's uri,\n * so the span attributes to the track that owns it at the source.\n */\n private dispatchLoadSpan(measurement: LoadSpanMeasurement): void {\n this.dispatch('loadSpanMeasured', {\n ...measurement,\n trackUri: this.uri,\n })\n }\n\n /**\n * Updates the cached qualities list from the transformed timeline for the current period.\n */\n private updateQualities(): void {\n this.withTimeline(this.deps.mediaTimelineTransformed, (timeline) => {\n const time = this.deps.playbackController.currentTime\n const period = getMediaPeriodAtTime(timeline, time)\n this._cachedPeriod = period\n const newQualities = period\n ? period.qualities.map((q) => q.metadata)\n : null\n if (!equalDeep(newQualities, this._qualities)) {\n const previous = this._qualities\n this._qualities = newQualities\n if (newQualities) {\n this.dispatch('qualitiesChange', {\n previous: previous ?? [],\n current: newQualities,\n })\n }\n }\n })\n }\n\n async getAds(): Promise<TrackAds> {\n const timeline = await this.deps.mediaTimeline.value\n return {\n trackUri: this.uri,\n adBreaks: await timeline.getAdBreaks(),\n }\n }\n\n /**\n * Updates the cached unfiltered qualities list from the raw timeline for the current period.\n */\n private updateQualitiesUnfiltered(): void {\n this.withTimeline(this.deps.mediaTimeline, (timeline) => {\n const time = this.deps.playbackController.currentTime\n const period = getMediaPeriodAtTime(timeline, time)\n const newQualities = period\n ? period.qualities.map((q) => q.metadata)\n : null\n if (!equalDeep(newQualities, this._qualitiesUnfiltered)) {\n const previous = this._qualitiesUnfiltered\n this._qualitiesUnfiltered = newQualities\n if (newQualities) {\n this.dispatch('qualitiesUnfilteredChange', {\n previous: previous ?? [],\n current: newQualities,\n })\n }\n }\n })\n }\n\n private updateSeekRanges(): void {\n this.withTimeline(\n this.deps.mediaTimelineTransformed,\n (timeline, interrupted) => {\n timeline\n .getDuration()\n .then((duration) => {\n if (interrupted()) return\n const start = first(timeline.periods)?.startTime ?? 0\n this.setSeekRange({\n start,\n end: start + duration,\n })\n })\n .catch(this.errorHandler)\n }\n )\n }\n\n /**\n * Invokes a callback when the given timeline promise resolves and was not\n * interrupted by that timeline changing or the track being disposed.\n *\n * Pass `mediaTimelineTransformed` for the playable (filtered) view or\n * `mediaTimeline` for the raw, unfiltered view.\n */\n private withTimeline(\n timelineSource: ObservableValue<Promise<MediaTimeline>>,\n callback: (timeline: MediaTimeline, interrupted: () => boolean) => void\n ) {\n const timelinePromise = timelineSource.value\n const interrupted = () =>\n this.disposed || timelinePromise !== timelineSource.value\n timelinePromise\n .then((timeline) => {\n if (!interrupted()) callback(timeline, interrupted)\n })\n .catch(this.errorHandler)\n }\n\n /**\n * Creates and adds a content stream for the given content type.\n *\n * @param contentType\n */\n protected createStream(contentType: ContentType): void {\n const stream = this.deps.contentStreamFactory(contentType)\n redispatchEvents(this, stream, [\n 'fetchedRangesChange',\n 'streamingQualityChange',\n 'bufferingQualityChange',\n 'playbackQualityChange',\n 'codecUnsupported',\n ])\n // Stamp the segment spans with this track's uri at the source rather\n // than blindly redispatching the unattributed measurement.\n stream.on('loadSpanMeasured', (measurement) =>\n this.dispatchLoadSpan(measurement)\n )\n stream.on('bufferingEnded', () => {\n if (this.bufferingEnded) {\n this.deps.mediaSourceController.endOfStream()\n this.dispatch('bufferingEnded', {})\n }\n })\n stream.on('hasDataChange', () => this.checkStalledSeek())\n stream.on('fetchedRangesChange', () => {\n this._fetchedRanges.invalidate()\n })\n stream.on('error', (event) => {\n if (!this._error) {\n // Set error state and bubble event\n this._error = event.error\n this.dispatch('error', event)\n }\n })\n\n // The fetched ranges of the track is the intersection of all content stream fetched ranges.\n this.allFetchedRanges.push(stream.fetchedRanges)\n this._fetchedRanges.invalidate()\n\n this.streams.push(stream)\n if (this.lastPreloadOptions) {\n stream.preload(this.lastPreloadOptions)\n }\n if (this.loadOptions) {\n stream.activate(this.loadOptions)\n }\n }\n\n preload(\n trackOptions: TrackPreloadOptions,\n loadOptions: Maybe<TrackConfigOptions>\n ) {\n const options: ContentStreamPreloadOptions = {\n startTime: loadOptions?.startTime,\n prefetchPriority: trackOptions.prefetchPriority,\n }\n this.lastPreloadOptions = options\n this.callOnStreams('preload', options)\n }\n\n get contentTypes(): ReadonlySet<ContentType> {\n return this._contentTypes\n }\n\n get qualities(): readonly MediaQualityMetadata[] | null {\n return this._qualities\n }\n\n get qualitiesUnfiltered(): readonly MediaQualityMetadata[] | null {\n return this._qualitiesUnfiltered\n }\n\n get fetchedRanges(): ReadonlyRanges {\n return this._fetchedRanges\n }\n\n /**\n * Clears all fetched fragments and source buffers. Streaming will resume.\n * This should be called if a change has been made where the user would expect an immediate change,\n * for example, changing streaming quality from SD to HD.\n */\n clearPrefetch() {\n logDebug(this, 'clearPrefetch')\n this.callOnStreams('clearPrefetch')\n }\n\n /**\n * Resets the track to recover from error states.\n * Resets both the segment controller and buffering controller to clear failed segments and error conditions.\n */\n reset(hard = false): void {\n if (!hard && !this.error) {\n logDebug(this, 'reset no-op')\n return\n }\n super.reset(hard)\n this.deps.manifestController.reset()\n this.callOnStreams('reset')\n }\n\n onActivated(loadOptions: Maybe<TrackConfigOptions>): void {\n // A disposed track's deps throw DisposedError on access; never touch them.\n if (this.disposed) return\n // Rebuild the DOM text track. The element's added TextTracks are\n // dropped when the source is reset on deactivation (e.g. suspended for\n // an ad), so the active selection must be re-rendered on reactivation.\n this.deps.textTrackController?.resume()\n // AirPlay not supported using managed media sources\n this.deps.playbackSource.disableRemotePlayback = true\n\n this.streams.forEach((stream) => {\n this.deps.drmController.initializeForPlayback(\n stream.streamingQuality,\n { trackUri: this.uri, abort: this.disposeAbort }\n )\n })\n this.deps.playbackSource.src =\n this.deps.mediaSourceController.activate()\n this.callOnStreams('activate', loadOptions)\n\n // Listen for timeUpdate to detect period changes.\n this.timeUpdateSub = this.deps.playbackController.on(\n 'timeUpdate',\n () => {\n const time = this.deps.playbackController.currentTime\n const cached = this._cachedPeriod\n if (\n cached &&\n time >= cached.startTime &&\n time < cached.endTime\n ) {\n // The period hasn't changed\n return\n }\n this.updateQualities()\n this.updateQualitiesUnfiltered()\n }\n )\n }\n\n onDeactivated(): void {\n // A disposed track's deps throw DisposedError on access; never touch them.\n if (this.disposed) return\n this.timeUpdateSub?.()\n this.timeUpdateSub = null\n this.callOnStreams('deactivate')\n // Streams' transient buffering clears no longer clear the DRM info, so\n // clear it here now that the track is no longer buffering.\n this.deps.drmController.setBufferingDrmInfo(null, {\n trackUri: this.uri,\n abort: this.disposeAbort,\n })\n // Tear down the DOM text track so its cues stop showing while this\n // track is suspended (e.g. an ad playing over it). The selection is\n // retained and re-rendered on reactivation via resume().\n this.deps.textTrackController?.suspend()\n\n this.deps.playbackSource.src = null\n this.deps.playbackSource.load()\n this.deps.mediaSourceController.deactivate()\n }\n\n getStreamingQuality(contentType: ContentType): MediaQualityMetadata | null {\n return this.getStream(contentType)?.streamingQuality ?? null\n }\n\n getBufferingQuality(contentType: ContentType): MediaQualityMetadata | null {\n return this.getStream(contentType)?.bufferingQuality ?? null\n }\n\n getPlaybackQuality(contentType: ContentType): MediaQualityMetadata | null {\n return this.getStream(contentType)?.playbackQuality ?? null\n }\n\n /**\n * Calls the specified method on all streams with the provided arguments.\n */\n private callOnStreams<K extends FunctionKeys<ContentStream>>(\n functionName: K,\n ...args: Parameters<ContentStream[K]>\n ) {\n this.streams.forEach((stream) => {\n ;(stream[functionName] as Fun)(...args)\n })\n }\n\n private getStream(contentType: ContentType): ContentStream | undefined {\n return this.streams.find((s) => s.contentType === contentType)\n }\n\n private clearStreams() {\n this.callOnStreams('dispose')\n this.streams.length = 0\n this.allFetchedRanges.length = 0\n this._fetchedRanges.invalidate()\n }\n\n get bufferingEnded(): boolean {\n return this.streams.every((stream) => stream.bufferingEnded)\n }\n\n /**\n * A seek only completes once every stream has data at the target, but on\n * some platforms the element can stay stuck `seeking` even after that. Once\n * all streams hold data, if we're still seeking a moment later, nudge the\n * playhead to prod the element into completing the seek.\n */\n private checkStalledSeek(): void {\n const { playbackController } = this.deps\n if (this.stallNudgeTimer !== null || !playbackController.seeking) return\n if (!this.streams.length || !this.streams.every((s) => s.hasData)) {\n return\n }\n this.stallNudgeTimer = setTimeout(() => {\n this.stallNudgeTimer = null\n if (this.disposed || !playbackController.seeking) return\n if (!this.streams.every((s) => s.hasData)) return\n const from = playbackController.currentTime\n const to = from + PLAYHEAD_NUDGE\n // An internal recovery seek, not a user seek \u2014 logged so the two\n // are distinguishable in playback traces.\n logDebug(\n this,\n 'nudging playhead to recover a stalled seek',\n from,\n '->',\n to\n )\n playbackController.seekTo(to, 0).catch(noop)\n }, SEEKING_STALL_TIME_CHECK * 1000)\n }\n\n private setContentTypes(contentTypes: ReadonlySet<ContentType>) {\n if (this.disposed) return\n const previous = this.contentTypes\n if (equalDeep(previous, contentTypes)) return // no-op\n logDebug(this, 'content types:', contentTypes)\n if (previous.size) {\n // Content types were previously set, hard reset this track\n // so the media source is recreated\n this.reset(/* hard */ true)\n }\n this.clearStreams()\n for (const contentType of contentTypes) {\n this.createStream(contentType)\n }\n // Sets the content types and dispatches a change event:\n this._contentTypes = contentTypes\n this.dispatch('contentTypesChange', {\n previous,\n current: contentTypes,\n })\n }\n\n dispose(): void {\n logDebug(this, 'dispose')\n if (this.stallNudgeTimer !== null) clearTimeout(this.stallNudgeTimer)\n this.clearStreams()\n super.dispose()\n }\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { Maybe, RequestInitOptions } from '@amazon/vinyl-util'\nimport { ErrorOrigin } from '@amazon/vinyl-util'\nimport {\n type TrackConfigOptions,\n type TrackFactory,\n type TrackLoadOptions,\n trackLoadOptionsValidator,\n} from '../TrackFactory'\nimport type { Track } from '../Track'\nimport type { HlsManifestController } from './HlsManifestController'\nimport type { HlsManifestData } from './HlsManifestData'\nimport type { HlsMediaQualityMetadataResolver } from './HlsMediaQualityMetadataResolver'\nimport type { MseTrackDeps } from '../mse/MseTrack'\nimport { MseTrack } from '../mse/MseTrack'\nimport {\n func,\n isOneOf,\n object,\n type ObjectSchema,\n} from '@amazon/vinyl-validation'\nimport type { Factories } from '@amazon/vinyl-di'\nimport type { ObservableValue } from '@amazon/vinyl-observable'\nimport type { MediaTimeline } from '../../streaming/MediaTimeline'\nimport type { ManifestProvider } from '../../streaming/ManifestController'\n\nexport interface HlsTrackLoadOptions extends TrackLoadOptions {\n readonly type: 'hls'\n readonly manifestProvider?: Maybe<ManifestProvider<HlsManifestData>>\n readonly requestInit?: Maybe<RequestInitOptions>\n readonly segmentRequestInit?: Maybe<RequestInitOptions>\n readonly config?: Maybe<TrackConfigOptions>\n}\n\nconst loadOptionsValidator: ObjectSchema<HlsTrackLoadOptions> =\n /* @__PURE__ */ trackLoadOptionsValidator.extend({\n manifestProvider: /* @__PURE__ */ /* @__PURE__ */ /* @__PURE__ */ func().maybe().optional(),\n requestInit: /* @__PURE__ */ /* @__PURE__ */ /* @__PURE__ */ /* @__PURE__ */ object({}).cast<RequestInitOptions>().maybe().optional(),\n segmentRequestInit: /* @__PURE__ */ /* @__PURE__ */ /* @__PURE__ */ /* @__PURE__ */ object({})\n .cast<RequestInitOptions>()\n .maybe()\n .optional(),\n type: /* @__PURE__ */ isOneOf('hls'),\n })\n\nexport interface HlsTrackDeps extends MseTrackDeps {\n readonly manifestController: HlsManifestController\n readonly manifestTransformed: ObservableValue<Promise<HlsManifestData>>\n readonly mediaQualityMetadataResolver: HlsMediaQualityMetadataResolver\n readonly mediaTimeline: ObservableValue<Promise<MediaTimeline>>\n readonly mediaTimelineTransformed: ObservableValue<Promise<MediaTimeline>>\n}\n\nexport type HlsTrackFactoryDeps = {\n readonly createHlsFactories: (\n loadOptions: HlsTrackLoadOptions\n ) => Factories<HlsTrackDeps>\n}\n\nexport function createHlsTrackFactory(\n deps: HlsTrackFactoryDeps\n): TrackFactory<HlsTrackLoadOptions> {\n return {\n validate(options: HlsTrackLoadOptions) {\n loadOptionsValidator.assert(options, ErrorOrigin.API)\n },\n\n createTrack(loadOptions: HlsTrackLoadOptions): Track {\n return new MseTrack(\n loadOptions.uri,\n loadOptions.type,\n deps.createHlsFactories(loadOptions)\n )\n },\n }\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {\n createSourceObjectTrackFactory,\n type SourceObjectTrackDeps,\n type SourceObjectTrackLoadOptions,\n} from './source/SourceObjectTrack'\nimport {\n createSourceTrackFactory,\n type SourceTrackDeps,\n type SourceTrackLoadOptions,\n} from './source/SourceTrack'\nimport type { TrackTypeId } from './Track'\nimport type { TrackFactory } from './TrackFactory'\nimport type { ReadonlyRecord } from '@amazon/vinyl-util'\nimport {\n createDashTrackFactory,\n type DashTrackFactoryDeps,\n type DashTrackLoadOptions,\n} from './dash/DashTrack'\nimport {\n createHlsTrackFactory,\n type HlsTrackFactoryDeps,\n type HlsTrackLoadOptions,\n} from './hls/HlsTrack'\n\nexport interface VinylTrackFactoryDeps\n extends\n SourceTrackDeps,\n SourceObjectTrackDeps,\n DashTrackFactoryDeps,\n HlsTrackFactoryDeps {}\n\nexport type VinylTrackLoadOptions =\n | SourceObjectTrackLoadOptions\n | SourceTrackLoadOptions\n | DashTrackLoadOptions\n | HlsTrackLoadOptions\n\n/**\n * Provides a map of track type id to their respective loaders.\n * @param deps\n */\nexport function createVinylTrackFactories(deps: VinylTrackFactoryDeps) {\n return {\n src: createSourceTrackFactory(deps),\n srcObject: createSourceObjectTrackFactory(deps),\n dash: createDashTrackFactory(deps),\n hls: createHlsTrackFactory(deps),\n } as const satisfies ReadonlyRecord<\n TrackTypeId,\n TrackFactory<VinylTrackLoadOptions>\n >\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { last, merge, sortedInsertionIndex } from '@amazon/vinyl-util'\n\nimport {\n type AdaptationSetType,\n type DashManifest,\n type MPDtype,\n type PeriodType,\n type RepresentationType,\n type SegmentBaseType,\n type SegmentListType,\n type SegmentTemplateType,\n} from '@amazon/vinyl-mpd-parser'\nimport { getRepresentationMimeInfo } from './mimeType'\n\n// TODO: For dynamic MPDs, availability time offsets should be summed.\n\n/**\n * Calculates the inherited SegmentList for the given representation. Or returns undefined if no SegmentList is\n * present in the hierarchy.\n */\nexport function getSegmentList(\n representation: RepresentationType\n): SegmentListType | undefined {\n return mergeIfAnyDefined(\n representation.parent.parent.SegmentList,\n representation.parent.SegmentList,\n representation.SegmentList\n )\n}\n\n/**\n * Calculates the inherited SegmentTemplate for the given representation. Or returns undefined if no SegmentTemplate is\n * present in the hierarchy.\n */\nexport function getSegmentTemplate(\n representation: RepresentationType\n): SegmentTemplateType | undefined {\n return mergeIfAnyDefined(\n representation.parent.parent.SegmentTemplate,\n representation.parent.SegmentTemplate,\n representation.SegmentTemplate\n )\n}\n\n/**\n * Calculates the inherited SegmentBase for the given representation. Or returns undefined if no SegmentBase is\n * present in the hierarchy.\n */\nexport function getSegmentBase(\n representation: RepresentationType\n): SegmentBaseType | undefined {\n return mergeIfAnyDefined(\n representation.parent.parent.SegmentBase,\n representation.parent.SegmentBase,\n representation.SegmentBase\n )\n}\n\n/**\n * Returns the representation's ancestry: [MPD, Period, AdaptationSet, Representation]\n */\nexport function getRepresentationAncestry(\n representation: RepresentationType\n): readonly [MPDtype, PeriodType, AdaptationSetType, RepresentationType] {\n const adaptationSet = representation.parent\n const period = adaptationSet.parent\n const mpd = period.parent\n return [mpd, period, adaptationSet, representation]\n}\n\n/**\n * Merges the properties of all sources into a new object.\n * Used to calculate inherited properties.\n * If all sources are undefined, returns undefined.\n */\nfunction mergeIfAnyDefined<T>(...sources: T[]): T | undefined {\n if (!sources.some((source) => source)) return undefined\n return merge(...sources)\n}\n\nexport type PeriodRange = readonly [number, number | null]\n\n/**\n * Calculates the period start and end time.\n */\nexport function calculatePeriodTimeRange(period: PeriodType): PeriodRange {\n return [calculatePeriodStart(period), calculatePeriodEnd(period)]\n}\n\n/**\n * Calculates the start time of the given period.\n *\n * In a static presentation, the first period SHALL start at the zero point of the MPD timeline (with a\n * Period@start value of 0 seconds).\n */\nexport function calculatePeriodStart(period: PeriodType): number {\n return period.start ?? 0\n}\n\n/**\n * In a static presentation, the last period SHALL have a Period@duration.\n *\n * In a dynamic presentation, the first period SHALL start at or after the zero point of the MPD timeline (with a\n * Period@start value of 0 seconds or greater).\n *\n * In a dynamic presentation, the last period MAY have a Period@duration, in which case it has a fixed duration. If\n * without Period@duration, the last period in a dynamic presentation has an unlimited duration (that may later be\n * shortened by an MPD update).\n */\nexport function calculatePeriodEnd(period: PeriodType): number | null {\n if (period.start != null && period.duration != null)\n return period.start + period.duration\n\n const mpd = period.parent\n const periodIndex = mpd.Period.indexOf(period)\n if (periodIndex < mpd.Period.length - 1)\n return calculatePeriodStart(mpd.Period[periodIndex + 1])\n else return mpd.mediaPresentationDuration ?? null\n}\n\n/**\n * Converts a sample time to an MPD-relative time.\n *\n * The samples within a representation exist on a linear sample timeline defined by the encoder. This function maps\n * those sample times onto the MPD timeline.\n *\n * https://dashif-documents.azurewebsites.net/Guidelines-TimingModel/master/Guidelines-TimingModel.html\n *\n * @param sampleTime The sample start time, in timescale units, relative to the media.\n * @param periodStart The presentation start time of the period, relative to the MPD timeline.\n * @param presentationTimeOffset Specifies a presentation time offset in the media timeline relative to the start\n * of the Period, in timescale units, used to adjust the timing of media presentation.\n * @param timescale The timescale, in units per second.\n */\nexport function sampleToMpdTime(\n sampleTime: number,\n periodStart: number,\n presentationTimeOffset: number,\n timescale: number\n): number {\n return periodStart + (sampleTime - presentationTimeOffset) / timescale\n}\n\n/**\n * Gets the period spanning the given presentation time.\n */\nexport function getPeriodAtTime(\n manifest: DashManifest,\n time: number\n): PeriodType | null {\n const index =\n sortedInsertionIndex(manifest.MPD.Period, time, (time, period) => {\n return time - calculatePeriodStart(period)\n }) - 1\n if (index < 0) return null\n const period = manifest.MPD.Period[index]\n const periodEnd = calculatePeriodEnd(period)\n return periodEnd != null && time >= periodEnd ? null : period\n}\n\n/**\n * Flattens representations across all adaptation sets for the given Period.\n */\nexport function flattenRepresentations(\n period: PeriodType\n): RepresentationType[] {\n const out: RepresentationType[] = []\n period.AdaptationSet?.forEach((adaptationSet) => {\n adaptationSet.Representation?.forEach((representation) => {\n out.push(representation)\n })\n })\n return out\n}\n\n/**\n * Flattens the representations across all adaptation sets for the given Period\n * that the MSE media pipeline can play, i.e. `audio` and `video`.\n *\n * Text adaptation sets (e.g. `contentType=\"text\"` WebVTT sidecar subtitles) are\n * excluded: they are surfaced through the sidecar text-track pipeline\n * (`discoverDashTextTracks`), not buffered through MSE, so including them here\n * would create an unplayable text SourceBuffer and stall playback.\n */\nexport function flattenMediaRepresentations(\n period: PeriodType\n): RepresentationType[] {\n return flattenRepresentations(period).filter((representation) => {\n const { contentType } = getRepresentationMimeInfo(representation)\n return contentType === 'audio' || contentType === 'video'\n })\n}\n\n/**\n * Calculates the manifest duration, either from the mediaPresentationDuration or the last period end time.\n * Returns `Infinity` for live (dynamic) presentations.\n * Throws if duration cannot be determined.\n */\nexport function calculateDuration(manifest: DashManifest): number {\n if (manifest.MPD.type === 'dynamic') return Infinity\n const mpdDuration = manifest.MPD.mediaPresentationDuration\n if (mpdDuration != null) return mpdDuration\n const lastPeriod = last(manifest.MPD.Period)\n if (!lastPeriod) {\n throw new Error('Unable to determine manifest duration: no periods')\n }\n const end = calculatePeriodEnd(lastPeriod)\n if (end == null) {\n throw new Error('Unable to determine manifest duration')\n }\n return end\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { ContentType } from '../../streaming/MediaQualityMetadata'\n\n/**\n * RFC 6381 codec prefixes for video content.\n */\nconst VIDEO_CODEC_PREFIXES = [\n 'avc1',\n 'avc3',\n 'hvc1',\n 'hev1',\n 'vp09',\n 'av01',\n 'dvh1',\n 'dvhe',\n] as const\n\n/**\n * RFC 6381 codec prefixes for audio content.\n */\nconst AUDIO_CODEC_PREFIXES = ['mp4a', 'ac-3', 'ec-3', 'opus', 'flac'] as const\n\n/**\n * RFC 6381 codec prefixes for text/subtitle content.\n */\nconst TEXT_CODEC_PREFIXES = ['stpp', 'wvtt'] as const\n\n/**\n * Returns the ContentType for a single RFC 6381 codec string, or null if\n * unrecognized.\n */\nexport function codecToContentType(codec: string): ContentType | null {\n const lower = codec.trim().toLowerCase()\n for (const p of VIDEO_CODEC_PREFIXES) {\n if (lower.startsWith(p)) return 'video'\n }\n for (const p of AUDIO_CODEC_PREFIXES) {\n if (lower.startsWith(p)) return 'audio'\n }\n for (const p of TEXT_CODEC_PREFIXES) {\n if (lower.startsWith(p)) return 'text'\n }\n return null\n}\n\n/**\n * Splits a comma-separated CODECS attribute value and returns the set of\n * ContentType values present.\n */\nexport function codecsToContentTypes(codecs: string): Set<ContentType> {\n const types = new Set<ContentType>()\n for (const codec of codecs.split(',')) {\n const type = codecToContentType(codec)\n if (type) types.add(type)\n }\n return types\n}\n\n/**\n * Returns the full MIME type string for a content type, optionally with codecs.\n */\nexport function contentTypeToMimeType(\n contentType: ContentType,\n codecs: string | null\n): string {\n const base = contentType === 'video' ? 'video/mp4' : 'audio/mp4'\n return codecs ? `${base}; codecs=\"${codecs}\"` : base\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { RepresentationType } from '@amazon/vinyl-mpd-parser'\nimport type { ContentType } from '../../../streaming/MediaQualityMetadata'\nimport { codecToContentType } from '../../mse/codec'\n\nexport interface RepresentationMimeInfo {\n readonly mimeType: string | null\n readonly contentType: ContentType | null\n}\n\n/**\n * Returns the full mime type with codecs and the inferred content type from the\n * provided representation.\n */\nexport function getRepresentationMimeInfo(\n representation: RepresentationType\n): RepresentationMimeInfo {\n const adaptationSet = representation.parent\n let mimeType = representation.mimeType ?? adaptationSet.mimeType\n const codecs = representation.codecs ?? adaptationSet.codecs\n if (!mimeType) {\n const contentType =\n (adaptationSet.contentType as ContentType | undefined) ??\n (codecs ? codecToContentType(codecs.split(',')[0]) : null)\n switch (contentType) {\n case 'audio':\n mimeType = 'audio/mp4'\n break\n case 'video':\n mimeType = 'video/mp4'\n break\n default:\n return { mimeType: null, contentType: null }\n }\n const fullMimeType = codecs\n ? `${mimeType}; codecs=\"${codecs}\"`\n : mimeType\n return { mimeType: fullMimeType, contentType }\n }\n const fullMimeType = codecs ? `${mimeType}; codecs=\"${codecs}\"` : mimeType\n let contentType: ContentType | null =\n (adaptationSet.contentType as ContentType | undefined) ?? null\n if (!contentType) {\n if (mimeType.startsWith('audio/')) contentType = 'audio'\n else if (mimeType.startsWith('video/')) contentType = 'video'\n else if (\n mimeType.startsWith('text/') ||\n mimeType === 'application/json' ||\n mimeType === 'application/xml'\n )\n contentType = 'text'\n }\n return { mimeType: fullMimeType, contentType }\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { Maybe, MaybePromise } from '@amazon/vinyl-util'\nimport {\n ErrorOrigin,\n getSidxSampleTimes,\n parseSidxBox,\n ValidationError,\n} from '@amazon/vinyl-util'\nimport type {\n ByteRange,\n MultipleSegmentBaseType,\n RepresentationType,\n SegmentBaseType,\n SegmentListType,\n SegmentTemplateType,\n SegmentTimelineType,\n} from '@amazon/vinyl-mpd-parser'\nimport {\n calculatePeriodTimeRange,\n getSegmentBase,\n getSegmentList,\n getSegmentTemplate,\n type PeriodRange,\n sampleToMpdTime,\n} from '../util/mpd'\nimport {\n type DashUriResolveDeps,\n resolveDashUri,\n segmentTemplateUrl,\n} from '../util/uriResolution'\nimport {\n createSegmentDataProvider,\n type CreateSegmentDataProviderDeps,\n} from '../../createSegmentDataProvider'\nimport { getSegmentAtTime } from '../../../streaming/util/segment'\nimport type {\n MediaSegmentReference,\n SegmentReference,\n} from '../../../streaming/SegmentReference'\nimport type { SegmentDataProvider } from '../../../streaming/SegmentDataSlot'\nimport type { MediaQualityMetadata } from '../../../streaming/MediaQualityMetadata'\nimport type { DashMediaQualityMetadataResolver } from '../DashMediaQualityMetadataResolver'\n\nexport interface DashSegmentProviderDeps\n extends DashUriResolveDeps, CreateSegmentDataProviderDeps {\n /**\n * Produces abstract metadata from a dash representation.\n */\n readonly mediaQualityMetadataResolver: DashMediaQualityMetadataResolver\n}\n\nexport interface DashRepresentationSegmentProvider {\n /**\n * Gets a segment reference within this representation for the given time, in seconds, relative to the period.\n *\n * @param time\n * @param affordance Forward-snap tolerance in seconds: if `time` falls just before a\n * segment's start (within `affordance`), that segment is returned. Defaults to `0`.\n */\n getSegment(\n time: number,\n affordance?: number\n ): Promise<SegmentReference<SegmentDataProvider> | null>\n}\n\ninterface GetTimelineOptions {\n readonly baseUrl: string\n readonly representation: RepresentationType\n readonly periodTimeRange: PeriodRange\n}\n\n/**\n * Metadata and a data provider for a segment.\n */\ntype DataSegmentRef = MediaSegmentReference<SegmentDataProvider>\n\n/**\n * Creates a representation timeline for the given representation.\n */\nexport function createDashRepresentationSegmentProvider(\n deps: DashSegmentProviderDeps,\n baseUrl: string,\n representation: RepresentationType\n): DashRepresentationSegmentProvider {\n const quality: MediaQualityMetadata =\n deps.mediaQualityMetadataResolver(representation)\n const options: GetTimelineOptions = {\n baseUrl,\n periodTimeRange: calculatePeriodTimeRange(representation.parent.parent),\n representation,\n }\n\n // 5.3.9.1 General\n // The elements SegmentBase, SegmentTemplate and SegmentList may be present in the\n // Representation element itself. In addition, to express default values, they may be present in the\n // Period and AdaptationSet element. At each level at most one of the three, SegmentBase,\n // SegmentTemplate and SegmentList, shall be present. Further, if SegmentTemplate or SegmentList is present on\n // one level of the hierarchy, then the other one shall not be present on any lower hierarchy level.\n\n const segmentTemplate = getSegmentTemplate(representation)\n const segmentList = getSegmentList(representation)\n const segmentBase = getSegmentBase(representation)\n\n let segmentsPromise: MaybePromise<\n readonly MediaSegmentReference<SegmentDataProvider>[]\n > | null = null\n\n let initUri: Maybe<string>\n let initRange: Maybe<ByteRange>\n\n if (segmentTemplate?.initialization) {\n initUri = segmentTemplateUrl(segmentTemplate.initialization, {\n representation,\n })\n }\n\n const commonSegmentBase = segmentTemplate ?? segmentList ?? segmentBase\n if (!commonSegmentBase) {\n throw new ValidationError(\n 'Manifest must have one of SegmentList, SegmentTemplate, or SegmentBase',\n ErrorOrigin.MEDIA\n )\n }\n\n if (commonSegmentBase.Initialization) {\n initUri = commonSegmentBase.Initialization.sourceURL\n initRange = commonSegmentBase.Initialization.range\n }\n\n if (!initUri && !initRange)\n throw new ValidationError(\n 'Missing initialization range',\n ErrorOrigin.MEDIA\n )\n\n const { url: initUrl, serviceLocation: initServiceLocation } =\n resolveDashUri(deps, { baseUrl, representation, uri: initUri })\n const initData = createSegmentDataProvider(deps, {\n url: initUrl,\n mediaRange: initRange,\n serviceId: initServiceLocation,\n reportDownlinkMetrics: false,\n })\n\n let getSegmentReferences: () => MaybePromise<\n readonly MediaSegmentReference<SegmentDataProvider>[]\n >\n\n // If an index range is present, use that to calculate segment data.\n // The index location may be defined in several locations:\n // SegmentBase.indexRange, SegmentBase.RepresentationIndex, or SegmentTemplate.index\n // One of segmentList, segmentTemplate, or segmentBase is guaranteed to be set.\n if (segmentList) {\n getSegmentReferences = () =>\n createSegmentsFromSegmentList(deps, {\n ...options,\n segmentList,\n })\n } else if (segmentTemplate) {\n getSegmentReferences = () =>\n createSegmentsFromSegmentTemplate(deps, {\n ...options,\n segmentTemplate,\n })\n } else if (segmentBase) {\n getSegmentReferences = () =>\n createSegmentsFromSegmentBase(deps, {\n ...options,\n segmentBase,\n })\n }\n\n return {\n async getSegment(\n time: number,\n affordance = 0\n ): Promise<SegmentReference<SegmentDataProvider> | null> {\n if (!segmentsPromise) segmentsPromise = getSegmentReferences()\n const segments = await Promise.resolve(segmentsPromise).catch(\n (error) => {\n // When the segments list fails (for example the sidx range request fails),\n // retry on the next request.\n segmentsPromise = null\n throw error\n }\n )\n const segment = getSegmentAtTime(time, segments, affordance)\n if (!segment) return null\n return {\n quality,\n ...segment,\n initData,\n }\n },\n }\n}\n\n/**\n * Creates a segment list when the representation has a SegmentList.\n */\nfunction createSegmentsFromSegmentList(\n deps: DashSegmentProviderDeps,\n options: GetTimelineOptions & {\n readonly segmentList: SegmentListType\n }\n): readonly DataSegmentRef[] {\n const { baseUrl, periodTimeRange, representation, segmentList } = options\n const segmentUrls = segmentList.SegmentURL\n if (segmentUrls) {\n // Fabricate a segment timeline from the segment duration.\n const timescale = getTimescale(segmentList)\n const sampleTimes = calculateSegmentSampleTimes({\n multipleSegmentBase: segmentList,\n periodTimeRange,\n numSegments: segmentUrls.length,\n })\n const presentationTimeOffset = segmentList.presentationTimeOffset ?? 0\n\n return createTimeline(\n {\n sampleTimes,\n presentationTimeOffset,\n periodTimeRange,\n timescale,\n },\n (i) => {\n const segmentUrl = segmentUrls[i]\n const { url, serviceLocation } = resolveDashUri(deps, {\n baseUrl,\n uri: segmentUrl.media,\n representation,\n })\n return createSegmentDataProvider(deps, {\n url,\n mediaRange: segmentUrl.mediaRange,\n serviceId: serviceLocation,\n reportDownlinkMetrics: true,\n })\n }\n )\n } else {\n if (segmentList.href) {\n throw new ValidationError(\n 'SegmentList.href currently unsupported',\n ErrorOrigin.MEDIA\n )\n } else {\n throw new ValidationError(\n 'could not determine segments from SegmentList',\n ErrorOrigin.MEDIA\n )\n }\n }\n}\n\n/**\n * SegmentTemplate contains URIs with template tokens, as defined in 5.3.9.4.4.\n *\n * @see segmentTemplateUrl\n */\nfunction createSegmentsFromSegmentTemplate(\n deps: DashSegmentProviderDeps,\n options: GetTimelineOptions & {\n readonly segmentTemplate: SegmentTemplateType\n }\n): readonly DataSegmentRef[] {\n const { baseUrl, periodTimeRange, representation, segmentTemplate } =\n options\n if (!segmentTemplate.media) {\n throw new ValidationError(\n 'SegmentTemplate.media required',\n ErrorOrigin.MEDIA\n )\n }\n const media = segmentTemplate.media\n const presentationTimeOffset = segmentTemplate.presentationTimeOffset ?? 0\n\n const sampleTimes = calculateSegmentSampleTimes({\n multipleSegmentBase: segmentTemplate,\n periodTimeRange,\n })\n\n const timescale = getTimescale(segmentTemplate)\n let segmentNumber = segmentTemplate.startNumber ?? 1\n return createTimeline(\n {\n timescale,\n presentationTimeOffset,\n periodTimeRange,\n sampleTimes,\n },\n (_, sampleTime) => {\n const uri = segmentTemplateUrl(media, {\n representation,\n sampleTime,\n segmentNumber: segmentNumber++,\n })\n const { url, serviceLocation } = resolveDashUri(deps, {\n baseUrl,\n uri,\n representation,\n })\n return createSegmentDataProvider(deps, {\n url,\n serviceId: serviceLocation,\n reportDownlinkMetrics: true,\n })\n }\n )\n}\n\n/**\n * When SegmentBase is provided, get the timeline from the index range.\n */\nasync function createSegmentsFromSegmentBase(\n deps: DashSegmentProviderDeps,\n options: GetTimelineOptions & {\n readonly segmentBase: SegmentBaseType\n }\n): Promise<readonly DataSegmentRef[]> {\n const { baseUrl, periodTimeRange, representation, segmentBase } = options\n if (segmentBase.indexRange) {\n // Load the sidx box from the mp4.\n const indexRange = segmentBase.indexRange\n const { url: indexUrl, serviceLocation: indexServiceLocation } =\n resolveDashUri(deps, { baseUrl, representation })\n const sidx = parseSidxBox(\n await createSegmentDataProvider(deps, {\n url: indexUrl,\n mediaRange: indexRange,\n serviceId: indexServiceLocation,\n reportDownlinkMetrics: false,\n })()\n )\n\n const sampleTimes = getSidxSampleTimes(sidx)\n let rangeStart = Number(sidx.firstOffset) + indexRange[1]! + 1\n return createTimeline(\n {\n sampleTimes,\n periodTimeRange,\n presentationTimeOffset: segmentBase.presentationTimeOffset ?? 0,\n timescale: sidx.timescale,\n },\n (i) => {\n const segmentReference = sidx.references[i]\n const size = segmentReference.referencedSize\n const provider = createSegmentDataProvider(deps, {\n url: indexUrl,\n mediaRange: [rangeStart, rangeStart + size - 1],\n serviceId: indexServiceLocation,\n reportDownlinkMetrics: true,\n })\n rangeStart += size\n return provider\n }\n )\n } else {\n throw new ValidationError('Manifest missing segments')\n }\n}\n\n/**\n * Returns an array of start times, in timescale units for the segments in the given multiple segment base.\n * The last time in the list will be the end time, in timescale units.\n */\nfunction calculateSegmentSampleTimes(options: {\n readonly multipleSegmentBase: MultipleSegmentBaseType\n readonly periodTimeRange: PeriodRange\n readonly numSegments?: Maybe<number>\n}): readonly number[] {\n const { multipleSegmentBase, periodTimeRange } = options\n const timescale = getTimescale(multipleSegmentBase)\n\n let startTimes: readonly number[]\n if (multipleSegmentBase.SegmentTimeline) {\n startTimes = calculateSampleTimesFromSegmentTimeline(\n multipleSegmentBase.SegmentTimeline\n )\n } else {\n // Fabricate a segment timeline from the segment duration.\n const sampleDuration = getSampleDuration(multipleSegmentBase) // The unscaled duration\n startTimes = calculateFixedSegmentSampleTimes({\n timescale,\n periodTimeRange,\n sampleDuration,\n numSegments: options.numSegments,\n })\n }\n return startTimes\n}\n\n/**\n * Given a SegmentTimeline element, calculates the sample start times of each segment, in timescale units.\n * The last time in the list will be the end time, in timescale units.\n */\nfunction calculateSampleTimesFromSegmentTimeline(\n segmentTimeline: SegmentTimelineType\n): readonly number[] {\n const out: number[] = new Array((segmentTimeline.S?.length ?? 0) + 1)\n let startTime = 0\n let c = 0\n\n segmentTimeline.S?.forEach((s) => {\n // If the start time 't' is defined, use it, otherwise use the calculated current time\n startTime = s.t != null ? s.t : startTime\n\n // Calculate segment details for the number of repeats\n for (let i = 0; i <= s.r; i++) {\n out[c++] = startTime\n startTime += s.d\n }\n })\n out[c++] = startTime\n return out\n}\n\n/**\n * Creates media segment sample start times, in timescale units, with a given duration.\n * The last time in the list will be the duration, in timescale units.\n *\n * @param options\n */\nfunction calculateFixedSegmentSampleTimes(options: {\n readonly sampleDuration: number\n readonly timescale: number\n readonly periodTimeRange: PeriodRange\n readonly numSegments?: Maybe<number>\n}): readonly number[] {\n const { sampleDuration, timescale } = options\n const [periodStart, periodEnd] = options.periodTimeRange\n if (periodEnd == null)\n throw new ValidationError(\n 'MPD.mediaPresentationDuration or Period.duration required',\n ErrorOrigin.MEDIA\n )\n const numSegments =\n options.numSegments ??\n Math.ceil((periodEnd - periodStart) / (sampleDuration / timescale))\n const out: number[] = new Array(numSegments + 1)\n let startTime = 0\n for (let i = 0; i < numSegments; i++) {\n out[i] = startTime\n startTime += sampleDuration\n }\n out[numSegments] = periodEnd * timescale\n return out\n}\n\n/**\n * Creates a timeline of DataSegmentRef objects from a sample timeline list and a data provider factory.\n *\n * @param sampleTimes The list of sample times, in timescale units, to convert into MPD presentation times.\n * @param periodTimeRange The time range of the period, in seconds.\n * @param presentationTimeOffset The presentation time offset, in samples per second.\n * @param timescale The timescale units, in samples per second.\n * @param dataProviderFactory Creates the data provider for the segment at the given index and sample start time.\n */\nfunction createTimeline(\n {\n sampleTimes,\n periodTimeRange,\n presentationTimeOffset,\n timescale,\n }: {\n sampleTimes: readonly number[]\n periodTimeRange: PeriodRange\n presentationTimeOffset: number\n timescale: number\n },\n dataProviderFactory: (i: number, sampleTime: number) => SegmentDataProvider\n): readonly DataSegmentRef[] {\n const [periodStart, periodEnd] = periodTimeRange\n const mpdTimes = sampleTimes.map((sampleTime) => {\n return sampleToMpdTime(\n sampleTime,\n periodStart,\n presentationTimeOffset,\n timescale\n )\n })\n const n = mpdTimes.length - 1\n const out = new Array<DataSegmentRef>(n)\n for (let i = 0; i < n; i++) {\n const startTime = mpdTimes[i]\n const endTime = mpdTimes[i + 1]\n out[i] = {\n data: dataProviderFactory(i, sampleTimes[i]),\n timestampOffset: startTime,\n startTime: Math.max(periodStart, startTime),\n endTime: periodEnd == null ? endTime : Math.min(periodEnd, endTime),\n }\n }\n return out\n}\n\n/**\n * Validates that timescale is set, returning it.\n *\n * @param multipleSegmentBase\n */\nfunction getTimescale(multipleSegmentBase: MultipleSegmentBaseType): number {\n if (!multipleSegmentBase.timescale)\n throw new ValidationError('invalid timescale', ErrorOrigin.MEDIA)\n return multipleSegmentBase.timescale\n}\n\n/**\n * Validates that duration is set, returning it.\n *\n * @param multipleSegmentBase\n */\nfunction getSampleDuration(\n multipleSegmentBase: MultipleSegmentBaseType\n): number {\n if (!multipleSegmentBase.duration)\n throw new ValidationError('invalid duration', ErrorOrigin.MEDIA)\n return multipleSegmentBase.duration\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { BaseURLType, RepresentationType } from '@amazon/vinyl-mpd-parser'\nimport { getRepresentationAncestry } from './mpd'\nimport type { Uri } from '@amazon/vinyl-xml'\nimport type { Maybe } from '@amazon/vinyl-util'\nimport {\n ErrorOrigin,\n IllegalArgumentError,\n resolveUrl,\n substituteIdentifiers,\n ValidationError,\n} from '@amazon/vinyl-util'\n\n/**\n * Selects a base URL alternate.\n */\nexport interface BaseUrlSelector {\n /**\n * Given a list of Dash base URLs, chooses which one will be used.\n *\n * @param baseUrls A list of Dash base URL objects for a single scope.\n * Guaranteed to not be empty.\n */\n selectBaseUrl(baseUrls: readonly BaseURLType[]): BaseURLType\n}\n\nexport const pickFirstBaseUrlSelector: BaseUrlSelector = {\n selectBaseUrl(baseUrls: readonly BaseURLType[]): BaseURLType {\n return baseUrls[0]\n },\n}\n\nexport interface DashUriResolveDeps {\n /**\n * Selects the BaseURL from provided alternates.\n */\n readonly baseUrlSelector: BaseUrlSelector\n}\n\nexport interface ResolvedDashUri {\n /**\n * The absolute URL.\n */\n readonly url: string\n\n /**\n * The service location.\n * @see BaseURL.serviceLocation\n */\n readonly serviceLocation: string | null\n}\n\nexport interface DashUriResolveOptions {\n /**\n * The URI to resolve.\n */\n readonly uri?: Maybe<Uri>\n\n /**\n * The representation to use as the scope for BaseURL resolution.\n */\n readonly representation: RepresentationType\n\n /**\n * The resource location of the manifest.\n */\n readonly baseUrl: string\n}\n\n/**\n * Resolves the base URL. Walks down the ancestry, concatenating BaseURL paths according to\n * MPEG-DASH ISO/IEC 23009-1 standard, section 5.6.4.\n *\n * The BaseURL elements are used to define the base URL against which relative URLs specified in the manifest are\n * resolved. This can occur at multiple levels within the manifest (e.g., at the Period, Adaptation Set, or\n * Representation level).\n * Relative URLs are resolved according to standard URL resolution rules, as defined by RFC 3986. This involves\n * resolving the relative URL against the effective base URL, which could be the URL of the manifest itself or\n * a <BaseURL> specified at a higher level in the manifest hierarchy.\n *\n * Manifest URL as Base: If no <BaseURL> is specified, the URL from which the DASH manifest (MPD file) was\n * retrieved acts as the base URL for resolving any relative URLs.\n *\n * https://standards.iso.org/ittf/PubliclyAvailableStandards/index.html\n *\n * Note: URL resolution is not a simple concatenation, the `URL` class is used to resolve relative URLs per RFC\n * 3986:2005.\n *\n * @return Returns a resolved BaseURL object with calculated values according to inheritance rules.\n */\nexport function resolveDashUri(\n deps: DashUriResolveDeps,\n options: DashUriResolveOptions\n): ResolvedDashUri {\n const { representation, baseUrl, uri } = options\n const baseUrlSelector = deps.baseUrlSelector\n\n const scopeChain = getRepresentationAncestry(representation)\n\n let resolved = baseUrl\n let serviceLocation: string | null = null\n scopeChain.forEach((scope) => {\n if (scope.BaseURL && scope.BaseURL.length) {\n const selectedBaseUrl = baseUrlSelector.selectBaseUrl(scope.BaseURL)\n resolved = resolveUrl(selectedBaseUrl._content, resolved)\n if (selectedBaseUrl.serviceLocation)\n serviceLocation = selectedBaseUrl.serviceLocation\n }\n })\n if (uri != null) {\n resolved = resolveUrl(uri, resolved)\n } else if (resolved === baseUrl) {\n throw new ValidationError(\n 'media missing URI or BaseURL',\n ErrorOrigin.MEDIA\n )\n }\n return { url: resolved, serviceLocation }\n}\n\nexport interface SegmentTemplateUriOptions {\n /**\n * The sequence number of the segment. Will replace `$Number$` in url templates.\n */\n readonly segmentNumber?: Maybe<number>\n\n /**\n * The sample time of the segment. Will replace `$Time$` in url templates.\n */\n readonly sampleTime?: Maybe<number>\n\n /**\n * The representation, will use the id and bandwidth for replacement tokens.\n */\n readonly representation: RepresentationType\n}\n\n/**\n * Supported segment template tokens\n *\n * Does not currently support SubNumber.\n */\ninterface SegmentTemplateTokens {\n /**\n * This placeholder is replaced by the ID of the representation.\n */\n readonly RepresentationID: string\n\n /**\n * This placeholder is replaced by the sequence number of the segment.\n */\n readonly Number: number\n\n /**\n * This placeholder is replaced by the calculated sample time of the segment.\n */\n readonly Time: number\n\n /**\n * Replaced by the bandwidth attribute of the representation.\n */\n readonly Bandwidth: number\n}\n\n/**\n * Creates a segment url using segment template tokens, as defined in 5.3.9.4.4.\n */\nexport function segmentTemplateUrl(\n uri: Uri,\n options: SegmentTemplateUriOptions\n): Uri {\n try {\n return substituteIdentifiers(uri, {\n Bandwidth: options.representation.bandwidth,\n Number: options.segmentNumber ?? 0,\n RepresentationID: options.representation.id,\n Time: options.sampleTime ?? 0,\n } as const satisfies SegmentTemplateTokens)\n } catch (error) {\n if (error instanceof IllegalArgumentError) {\n // An IllegalArgumentError here indicates that a template URL provided was unsupported.\n throw new ValidationError(error.message, ErrorOrigin.MEDIA)\n } else {\n throw error\n }\n }\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { DashManifestData } from './DashManifestProvider'\nimport type {\n MediaPeriod,\n MediaQualityData,\n MediaTimeline,\n} from '../../streaming/MediaTimeline'\nimport type { RepresentationType } from '@amazon/vinyl-mpd-parser'\nimport {\n calculateDuration,\n calculatePeriodEnd,\n calculatePeriodStart,\n flattenMediaRepresentations,\n} from './util/mpd'\nimport {\n createDashRepresentationSegmentProvider,\n type DashSegmentProviderDeps,\n} from './timeline/DashRepresentationSegmentProvider'\n\nexport type BuildDashMediaTimelineDeps = DashSegmentProviderDeps\n\n/**\n * Builds a MediaTimeline from a Dash manifest.\n */\nexport function buildDashMediaTimeline(\n deps: BuildDashMediaTimelineDeps,\n data: DashManifestData\n): MediaTimeline {\n const { manifest, baseUrl } = data\n const periods: MediaPeriod[] = manifest.MPD.Period.map((period) => {\n const startTime = calculatePeriodStart(period)\n const endTime = calculatePeriodEnd(period) ?? Infinity\n const representations = flattenMediaRepresentations(period)\n const qualities: MediaQualityData[] = representations.map(\n (representation: RepresentationType): MediaQualityData => {\n const metadata =\n deps.mediaQualityMetadataResolver(representation)\n const segmentProvider = createDashRepresentationSegmentProvider(\n deps,\n baseUrl,\n representation\n )\n return {\n metadata,\n getSegment: (time: number, affordance?: number) =>\n segmentProvider.getSegment(time, affordance),\n }\n }\n )\n return { startTime, endTime, qualities }\n })\n const duration = calculateDuration(manifest)\n return {\n periods,\n minBufferTime: manifest.MPD.minBufferTime,\n getAdBreaks: () => Promise.resolve([]), // Dash ads are not yet supported\n getDuration: () => Promise.resolve(duration),\n }\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { MediaSourceController } from '../../streaming/buffering/MediaSourceController'\nimport type { PlaybackController } from '../../playback/PlaybackController'\nimport type { QualitySelector } from '../../streaming/abr/QualitySelector'\nimport type { ObservableValue } from '@amazon/vinyl-observable'\nimport { type ContentStreamImplDeps } from '../../streaming/ContentStream'\nimport type { ContentType } from '../../streaming/MediaQualityMetadata'\nimport {\n SourceBufferControllerImpl,\n type SourceBufferControllerImplDeps,\n} from '../../streaming/buffering/SourceBufferController'\nimport {\n BufferingControllerImpl,\n type BufferingControllerImplDeps,\n} from '../../streaming/buffering/BufferingController'\nimport {\n SegmentControllerImpl,\n type SegmentControllerImplDeps,\n} from '../../streaming/SegmentControllerImpl'\nimport { type Maybe, memoize } from '@amazon/vinyl-util'\nimport {\n externalDependencies,\n type Factories,\n validateFactories,\n} from '@amazon/vinyl-di'\nimport type { ContentStreamingOptions } from '../../streaming/ContentStreamingOptions'\nimport type { MediaTimeline } from '../../streaming/MediaTimeline'\n\n/**\n * Dependencies needed for a new content stream provided by the dash track.\n */\nexport interface DashContentStreamTrackDeps {\n readonly mediaSourceController: MediaSourceController\n readonly playbackController: PlaybackController\n readonly mediaTimelineTransformed: ObservableValue<Promise<MediaTimeline>>\n readonly qualitySelector: QualitySelector\n}\n\n/**\n * Returns a function to produce the Factories needed for a new ContentStreamImpl.\n */\nexport function createDashContentStreamFactories(\n options: Maybe<ContentStreamingOptions>\n) {\n return (deps: DashContentStreamTrackDeps) =>\n memoize(\n (contentType: ContentType) => {\n return validateFactories({\n ...externalDependencies(deps),\n sourceBufferControllerFactory:\n (deps: SourceBufferControllerImplDeps) => () =>\n new SourceBufferControllerImpl(deps, contentType),\n bufferingController: (deps: BufferingControllerImplDeps) =>\n new BufferingControllerImpl(\n deps,\n contentType,\n options?.buffering\n ),\n segmentController: (deps: SegmentControllerImplDeps) =>\n new SegmentControllerImpl(\n deps,\n contentType,\n options?.segmentController\n ),\n } as const) satisfies Factories<ContentStreamImplDeps>\n },\n (contentType) => contentType\n )\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { DashManifestData } from './DashManifestProvider'\nimport type { DashMediaQualityMetadataResolver } from './DashMediaQualityMetadataResolver'\nimport { flattenMediaRepresentations } from './util/mpd'\nimport type { ContentType } from '../../streaming/MediaQualityMetadata'\nimport type { ContentTypesValue } from '../../streaming/ContentTypesValue'\nimport type { ObservableValue } from '@amazon/vinyl-observable'\nimport type { DashManifest } from '@amazon/vinyl-mpd-parser'\n\nexport interface DashContentTypesValueDeps {\n readonly manifestTransformed: ObservableValue<Promise<DashManifestData>>\n readonly mediaQualityMetadataResolver: DashMediaQualityMetadataResolver\n}\n\n/**\n * Creates an ObservableValue for the types of streams that are available in the\n * filtered dash manifest.\n */\nexport function createDashContentTypesValue(\n deps: DashContentTypesValueDeps\n): ContentTypesValue {\n return deps.manifestTransformed.map(async (manifestAndPath) => {\n return getContentTypes(deps, (await manifestAndPath).manifest)\n })\n}\n\n/**\n * Determines the types of streams that are available in the filtered dash\n * manifest.\n *\n * Given a Dash manifest, this will resolve to the set of content types present.\n */\nfunction getContentTypes(\n deps: DashContentTypesValueDeps,\n manifest: DashManifest\n): Set<ContentType> {\n const contentTypes = new Set<ContentType>()\n for (const period of manifest.MPD.Period) {\n if (!period.AdaptationSet) continue\n const mediaMetadata = flattenMediaRepresentations(period).map(\n deps.mediaQualityMetadataResolver\n )\n for (const { contentType } of mediaMetadata) {\n if (contentType) contentTypes.add(contentType)\n }\n }\n return contentTypes\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { ObservableValue } from '@amazon/vinyl-observable'\nimport type { DashManifestData } from './DashManifestProvider'\nimport type {\n AdaptationSetType,\n DashManifest,\n RepresentationType,\n} from '@amazon/vinyl-mpd-parser'\nimport { type Comparator, compareBy } from '@amazon/vinyl-util'\nimport {\n sortDashAdaptationSets,\n sortDashRepresentations,\n} from './manifestTransformUtils'\n\nexport interface DashManifestTransformerDeps {\n readonly manifestController: ObservableValue<Promise<DashManifestData>>\n}\n\n/**\n * The default dash manifest transformer sorts adaptation sets and representations.\n * Quality filtering is handled by the media timeline transformer.\n */\nexport function createDefaultDashManifestTransformer(\n deps: DashManifestTransformerDeps\n): ObservableValue<Promise<DashManifestData>> {\n return deps.manifestController.map(async (manifestAndPath) => {\n const { manifest, baseUrl } = await manifestAndPath\n let m: DashManifest = sortDashAdaptationSets(\n createDefaultAdaptationSetComparator(),\n manifest\n )\n m = sortDashRepresentations(createDefaultRepresentationComparator(), m)\n return { baseUrl, manifest: m }\n })\n}\n\n/**\n * The default adaptation set comparator orders by descending selectionPriority.\n */\nexport function createDefaultAdaptationSetComparator(): Comparator<AdaptationSetType> {\n return compareBy((adaptationSet) => -adaptationSet.selectionPriority)\n}\n\n/**\n * The default representation comparator orders by ascending quality ranking and descending bandwidth.\n */\nexport function createDefaultRepresentationComparator(): Comparator<RepresentationType> {\n return compareBy(\n (representation) => representation.qualityRanking,\n (representation) => -representation.bandwidth\n )\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type {\n AdaptationSetType,\n DashManifest,\n RepresentationType,\n} from '@amazon/vinyl-mpd-parser'\nimport type { DashManifestData } from './DashManifestProvider'\nimport type { ObservableValue } from '@amazon/vinyl-observable'\nimport {\n clone,\n type Comparator,\n type FilterPredicate,\n type MaybePromise,\n} from '@amazon/vinyl-util'\n\n/**\n * Returns true if the given Dash manifest has unfiltered representations in every Period.\n */\nexport function manifestIsPlayable(manifest: DashManifest): boolean {\n return manifest.MPD.Period.every((period) =>\n period.AdaptationSet?.some(\n (adaptationSet) => adaptationSet.Representation?.length\n )\n )\n}\n\n/**\n * Filters dash representations using a synchronous predicate.\n */\nexport function filterDashRepresentations(\n filter: FilterPredicate<RepresentationType>,\n throwError: () => never,\n manifest: DashManifest\n): DashManifest {\n const result = clone(manifest)\n\n for (const period of result.MPD.Period) {\n if (period.AdaptationSet) {\n for (const adaptationSet of period.AdaptationSet) {\n if (adaptationSet.Representation) {\n adaptationSet.Representation =\n adaptationSet.Representation.filter(filter)\n }\n }\n }\n }\n\n if (!manifestIsPlayable(result)) {\n throwError()\n }\n\n return result\n}\n\n/**\n * Filters dash adaptation sets using a synchronous predicate.\n */\nexport function filterDashAdaptationSets(\n filter: FilterPredicate<AdaptationSetType>,\n throwError: () => never,\n manifest: DashManifest\n): DashManifest {\n const result = clone(manifest)\n\n for (const period of result.MPD.Period) {\n if (period.AdaptationSet) {\n period.AdaptationSet = period.AdaptationSet.filter(filter)\n }\n }\n\n if (!manifestIsPlayable(result)) {\n throwError()\n }\n\n return result\n}\n\n/**\n * Sorts dash adaptation sets using a comparator.\n */\nexport function sortDashAdaptationSets(\n comparator: Comparator<AdaptationSetType>,\n manifest: DashManifest\n): DashManifest {\n const result = clone(manifest)\n\n for (const period of result.MPD.Period) {\n period.AdaptationSet?.sort(comparator)\n }\n\n return result\n}\n\n/**\n * Sorts dash representations using a comparator.\n */\nexport function sortDashRepresentations(\n comparator: Comparator<RepresentationType>,\n manifest: DashManifest\n): DashManifest {\n const result = clone(manifest)\n\n for (const period of result.MPD.Period) {\n if (period.AdaptationSet) {\n for (const adaptationSet of period.AdaptationSet) {\n if (adaptationSet.Representation) {\n adaptationSet.Representation.sort(comparator)\n }\n }\n }\n }\n\n return result\n}\n\n/**\n * Maps a manifest transformation function over a DashManifestData observable.\n * Handles the boilerplate of extracting manifest/baseUrl and reconstructing the result.\n */\nexport function mapManifestTransform(\n manifestController: ObservableValue<Promise<DashManifestData>>,\n transformManifest: (manifest: DashManifest) => MaybePromise<DashManifest>\n): ObservableValue<Promise<DashManifestData>> {\n return manifestController.map(async (manifestAndPath) => {\n const { manifest, baseUrl } = await manifestAndPath\n return {\n baseUrl,\n manifest: await transformManifest(manifest),\n }\n })\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {\n ErrorOrigin,\n type ExtractValues,\n getOrSet,\n getOrSetProp,\n memoize,\n type MutableDeep,\n sortedInsertionIndex,\n ValidationError,\n} from '@amazon/vinyl-util'\nimport {\n type AdaptationSetType,\n type ContentProtection,\n ContentProtectionScheme,\n type DescriptorType,\n type PeriodType,\n type RepresentationBaseType,\n type RepresentationType,\n} from '@amazon/vinyl-mpd-parser'\nimport type {\n ContentType,\n DrmProtection,\n MediaQualityMetadata,\n} from '../../streaming/MediaQualityMetadata'\nimport { type DrmKeySystemResolver } from '../../drm/DrmKeySystemResolver'\nimport { getRepresentationMimeInfo } from './util/mimeType'\nimport type { DescriptorRecord } from '../../streaming/DescriptorRecord'\nimport type { DrmInitDataType } from '../../streaming/DrmInitDataType'\nimport {\n type CencEncryptionScheme,\n parseCencEncryptionScheme,\n} from '../../drm/CencEncryptionScheme'\n\n/**\n * DASH supplemental property scheme URI for adaptation set switching.\n * @see https://dashif.org/docs/DASH-IF-IOP-v4.3.pdf Section 3.8\n */\nexport const ADAPTATION_SET_SWITCHING_SCHEME =\n 'urn:mpeg:dash:adaptation-set-switching:2016'\n\n/**\n * Creates abstract MediaQualityMetadata from a Dash Representation.\n */\nexport type DashMediaQualityMetadataResolver = (\n representation: RepresentationType\n) => MediaQualityMetadata\n\n/**\n * Returns a dash metadata resolver that calculates media encoding metadata from the representation.\n * The most recently used representations will return cached results.\n */\nexport function createDefaultDashMediaQualityMetadataResolver(\n deps: DashMediaQualityMetadataResolverDeps\n): DashMediaQualityMetadataResolver {\n return memoize(\n (representation) =>\n createMediaQualityMetadataFromDashRepresentation(\n representation,\n deps\n ),\n (representation) => representation,\n 30\n )\n}\n\nexport interface DashMediaQualityMetadataResolverDeps {\n readonly drmKeySystemResolver: DrmKeySystemResolver\n}\n\nexport function createMediaQualityMetadataFromDashRepresentation(\n representation: RepresentationType,\n deps: DashMediaQualityMetadataResolverDeps\n): MediaQualityMetadata {\n const { contentType, mimeType } = getRepresentationMimeInfo(representation)\n if (!contentType || !mimeType)\n throw new ValidationError(\n 'mimeType cannot be inferred',\n ErrorOrigin.MEDIA\n )\n const adaptationSet = representation.parent\n const period = adaptationSet.parent\n const mpd = period.parent\n\n const periodId = period.id ?? `$${mpd.Period.indexOf(period)}`\n const adaptationSetId =\n adaptationSet.id ?? `$${period.AdaptationSet!.indexOf(adaptationSet)}`\n const qualityId = `${periodId}_${adaptationSetId}_${representation.id}`\n // Representations within the same adaptation set where bitstreamSwitching is true can be changed without\n // reinitializing the decoder.\n let decoderId = `${periodId}_${adaptationSetId}`\n const bitstreamSwitching =\n adaptationSet.bitstreamSwitching ?? period.bitstreamSwitching\n if (!bitstreamSwitching) decoderId += `_${representation.id}`\n\n // Resolve the adaptation set switching group. Adaptation sets that declare\n // urn:mpeg:dash:adaptation-set-switching:2016 with each other's IDs form a switching group,\n // meaning their representations are permitted to switch between each other.\n const groupId = `${periodId}_${adaptationSetId}`\n const switchingGroupIds = resolveAdaptationSetSwitchingGroupIds(\n adaptationSet,\n periodId,\n adaptationSetId\n )\n\n // Pick a representation base property which may be inherited from the adaptation set.\n function pick<K extends keyof RepresentationBaseType>(\n key: K\n ): NonNullable<RepresentationBaseType[K]> | null {\n return representation[key] ?? adaptationSet[key] ?? null\n }\n\n // Combines the descriptors for the given key into a map of scheme URI to Descriptor lists.\n type DescriptorProps = keyof ExtractValues<\n Required<RepresentationBaseType>,\n readonly DescriptorType[]\n >\n function mergeDescriptors(key: DescriptorProps): DescriptorRecord {\n const arr1 = adaptationSet[key] ?? []\n const arr2 = representation[key] ?? []\n return mapDescriptors([...arr1, ...arr2])\n }\n\n // Role / Accessibility descriptor values describe the rendition's purpose\n // (e.g. `description` for audio description). Surfaced as characteristics so\n // accessibility renditions aren't auto-selected by default. Mirrors the\n // derivation in discoverDashTextTracks.\n const roleValues = (adaptationSet.Role ?? [])\n .filter((d) => d.schemeIdUri === 'urn:mpeg:dash:role:2011')\n .map((d) => d.value)\n .filter((v): v is string => v != null)\n const accessibilityValues = (adaptationSet.Accessibility ?? [])\n .map((d) => d.value)\n .filter((v): v is string => v != null)\n const characteristics = [...roleValues, ...accessibilityValues]\n\n const contentProtections = [\n ...(adaptationSet.ContentProtection ?? []),\n ...(representation.ContentProtection ?? []),\n ]\n\n // Get the encryption scheme from the parsed CENC ContentProtection value.\n let initDataType: DrmInitDataType | null = null\n let encryptionScheme: CencEncryptionScheme | null = null\n for (let i = contentProtections.length - 1; i >= 0; i--) {\n const cP = contentProtections[i]\n if (cP.schemeIdUri === ContentProtectionScheme.CENC) {\n initDataType = 'cenc'\n encryptionScheme =\n parseCencEncryptionScheme(cP.value)?.scheme ?? null\n break\n }\n }\n\n return {\n qualityId,\n decoderId,\n groupId,\n switchingGroupIds,\n mimeType,\n contentType,\n codecs: pick('codecs'),\n bandwidth: representation.bandwidth,\n bandwidthTotal: estimatePeakBandwidth(representation, contentType),\n audioSamplingRate: pick('audioSamplingRate'),\n frameRate: pick('frameRate'),\n width: pick('width'),\n height: pick('height'),\n lang: adaptationSet.lang ?? null,\n characteristics,\n contentProtections: contentProtections.flatMap((cP) =>\n contentProtectionToMetadata(cP, deps)\n ),\n encryptionScheme,\n initDataType,\n supplementalProperties: mergeDescriptors('SupplementalProperty'),\n }\n}\n\n/**\n * Estimates the total bandwidth a representation would use when paired with\n * proportionally matched qualities from sibling content types.\n *\n * For each sibling content type, the representation's relative position within its own\n * content type's sorted bandwidth list is mapped to the corresponding position in the\n * sibling's list. This produces realistic pairings \u2014 e.g. with video [v1,v2,v3,v4] and\n * audio [a1,a2], v1 pairs with a1, v2 with a1, v3 with a2, v4 with a2.\n */\nexport function estimatePeakBandwidth(\n representation: RepresentationType,\n contentType: ContentType\n): number {\n const sortedByType = getPeriodSortedBandwidths(representation.parent.parent)\n const own = sortedByType.get(contentType)\n if (!own || own.length === 0) return representation.bandwidth\n // Find the closest match in the descending-sorted array. indexOf would return -1\n // when the representation's bandwidth was collapsed by the 10% dedup threshold.\n const ownIndex = Math.max(\n 0,\n sortedInsertionIndex(own, representation.bandwidth, (a, b) => b - a) - 1\n )\n const position = own.length <= 1 ? 0 : ownIndex / (own.length - 1)\n let total = representation.bandwidth\n for (const [ct, bandwidths] of sortedByType) {\n if (ct === contentType) continue\n const peerIndex = Math.min(\n Math.round(position * (bandwidths.length - 1)),\n bandwidths.length - 1\n )\n total += bandwidths[peerIndex]\n }\n return total\n}\n\n/**\n * Returns sorted (descending) bandwidth arrays per content type for a period.\n * Bandwidths within 10% of an existing entry are collapsed to reduce noise\n * from near-duplicate quality tiers.\n * Cached by period reference.\n */\nexport const getPeriodSortedBandwidths = /* @__PURE__ */ memoize(\n (period: PeriodType): ReadonlyMap<ContentType, readonly number[]> => {\n const byType = new Map<ContentType, number[]>()\n for (const as of period.AdaptationSet ?? []) {\n for (const rep of as.Representation ?? []) {\n const contentType = getRepresentationMimeInfo(rep).contentType\n if (!contentType) continue\n const arr = getOrSet(byType, contentType, () => [])\n if (\n !arr.some(\n (existing) =>\n Math.abs(existing - rep.bandwidth) / existing < 0.1\n )\n ) {\n const index = sortedInsertionIndex(\n arr,\n rep.bandwidth,\n (a, b) => b - a\n )\n arr.splice(index, 0, rep.bandwidth)\n }\n }\n }\n return byType\n },\n (period) => period,\n 5\n)\n\n/**\n * Converts a Dash ContentProtection element to a list of DrmProtection metadata.\n */\nexport function contentProtectionToMetadata(\n contentProtection: ContentProtection,\n deps: DashMediaQualityMetadataResolverDeps\n): readonly DrmProtection[] {\n const keySystems = deps.drmKeySystemResolver(contentProtection.schemeIdUri)\n return keySystems.map((keySystem) => {\n return {\n keySystem,\n pssh: contentProtection.pssh?._content ?? null,\n pro: contentProtection.pro?._content ?? null,\n }\n })\n}\n\n/**\n * Creates a DescriptorRecord from the Dash list of DescriptorType objects.\n * @param descriptors\n */\nfunction mapDescriptors(\n descriptors: readonly DescriptorType[]\n): DescriptorRecord {\n const out: MutableDeep<DescriptorRecord> = {}\n for (const descriptor of descriptors) {\n const arr = getOrSetProp(out, descriptor.schemeIdUri, () => [])!\n arr.push({\n id: descriptor.id ?? null,\n value: descriptor.value ?? null,\n })\n }\n return out\n}\n\n/**\n * Resolves the group IDs that the given adaptation set is permitted to switch to.\n *\n * Per DASH spec, adaptation sets declare `urn:mpeg:dash:adaptation-set-switching:2016` with a\n * comma-separated list of other adaptation set IDs they can switch to.\n *\n * Always includes the adaptation set's own groupId. If no switching property is present,\n * returns only the adaptation set's own groupId.\n */\nfunction resolveAdaptationSetSwitchingGroupIds(\n adaptationSet: AdaptationSetType,\n periodId: string,\n adaptationSetId: string | number\n): readonly string[] | null {\n const selfGroupId = `${periodId}_${adaptationSetId}`\n const switchingProp = adaptationSet.SupplementalProperty?.find(\n (p) => p.schemeIdUri === ADAPTATION_SET_SWITCHING_SCHEME\n )\n if (!switchingProp) return [selfGroupId]\n\n const value = switchingProp.value?.trim()\n if (!value) return [selfGroupId]\n\n const targetIds = value.split(',').map((s) => s.trim())\n return [selfGroupId, ...targetIds.map((id) => `${periodId}_${id}`)]\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { DashTrackDeps, DashTrackLoadOptions } from './DashTrack'\nimport { type Maybe, type RequestInterceptor } from '@amazon/vinyl-util'\nimport { pickFirstBaseUrlSelector } from './util/uriResolution'\nimport { createDefaultDashManifestTransformer } from './createDefaultDashManifestTransformer'\nimport { createMediaSource } from '../../util/media/mediaSource'\nimport {\n createDefaultDashMediaQualityMetadataResolver,\n type DashMediaQualityMetadataResolverDeps,\n} from './DashMediaQualityMetadataResolver'\nimport {\n MediaSourceControllerImpl,\n type MediaSourceControllerImplDeps,\n} from '../../streaming/buffering/MediaSourceController'\nimport type { PlaybackController } from '../../playback/PlaybackController'\nimport { createDashContentStreamFactories } from './createDashContentStreamFactories'\nimport type { DrmKeySystemResolver } from '../../drm/DrmKeySystemResolver'\nimport type { DrmController } from '../../drm/DrmController'\nimport type { Capabilities } from '../../client/Capabilities'\nimport { QualitySelectorImpl } from '../../streaming/abr/QualitySelectorImpl'\nimport type { PlaybackSource } from '../../playback/PlaybackSource'\nimport {\n externalDependencies,\n type Factories,\n validateFactories,\n} from '@amazon/vinyl-di'\nimport { createDashManifestProvider } from './createDashManifestProvider'\nimport { createContentStreamFactory } from '../../streaming/ContentStream'\nimport type { ContentStreamingOptions } from '../../streaming/ContentStreamingOptions'\nimport { createDashContentTypesValue } from './createDashContentTypesValue'\nimport { createAllowedContentTypesValue } from '../../streaming/createAllowedContentTypesValue'\nimport type { ObservableValue } from '@amazon/vinyl-observable'\nimport type { VinylOptions } from '../../vinyl/VinylOptions'\nimport {\n buildDashMediaTimeline,\n type BuildDashMediaTimelineDeps,\n} from './buildDashMediaTimeline'\nimport { createDefaultMediaTimelineTransformer } from '../../streaming/createDefaultMediaTimelineTransformer'\nimport type { DashManifestData } from './DashManifestProvider'\nimport { SidecarTextTrackController } from '../../text/SidecarTextTrackController'\nimport { discoverDashTextTracks } from '../../text/discoverDashTextTracks'\nimport type { AdController } from '../../ad/AdController'\nimport {\n ManifestControllerImpl,\n type ManifestControllerImplDeps,\n} from '../../streaming/ManifestControllerImpl'\n\n/**\n * Player-level dependencies needed for the Dash-specific factories.\n */\nexport interface DashFactoryDeps {\n readonly options: ObservableValue<\n Pick<\n VinylOptions,\n | 'abr'\n | 'preferredAudioLanguage'\n | 'allowedContentTypes'\n | 'preferDescriptiveAudio'\n | 'preferredTextLanguage'\n | 'textCueStyle'\n >\n >\n readonly playbackController: PlaybackController\n readonly playbackSource: PlaybackSource\n readonly drmKeySystemResolver: DrmKeySystemResolver\n readonly requestInterceptor: RequestInterceptor\n readonly drmController: DrmController\n readonly capabilities: Capabilities\n /**\n * The HTML media element. Required to attach sidecar text tracks via\n * `media.addTextTrack`.\n */\n readonly media: HTMLMediaElement\n\n /**\n * The player-level ad controller. MseTrack sets discovered ad breaks on it\n * when the media timeline resolves.\n */\n readonly adController: AdController\n}\n\nexport type DashInitOptions = {\n readonly streaming?: Maybe<ContentStreamingOptions>\n}\n\n/**\n * Returns a function that provides default dependency factories required for\n * a new DashTrack.\n */\nexport function createDashFactories(options: Maybe<DashInitOptions>) {\n return (\n // Player-level dependencies\n deps: DashFactoryDeps\n ) => {\n return (loadOptions: DashTrackLoadOptions) =>\n validateFactories({\n // Spreads all player-level deps so disposing this track's\n // container never disposes the shared player-level controllers.\n ...externalDependencies(deps),\n\n baseContentTypesValue: createDashContentTypesValue,\n contentTypesValue: createAllowedContentTypesValue,\n baseUrlSelector: () => pickFirstBaseUrlSelector,\n segmentRequestInit: () => loadOptions.segmentRequestInit,\n manifestProvider: createDashManifestProvider(loadOptions),\n manifestController: (\n deps: ManifestControllerImplDeps<DashManifestData>\n ) => new ManifestControllerImpl(deps),\n mediaSourceFactory: () => createMediaSource,\n mediaQualityMetadataResolver: (\n deps: DashMediaQualityMetadataResolverDeps\n ) => createDefaultDashMediaQualityMetadataResolver(deps),\n mediaSourceController: (deps: MediaSourceControllerImplDeps) =>\n new MediaSourceControllerImpl(deps),\n\n createContentStreamFactories: createDashContentStreamFactories(\n options?.streaming\n ),\n contentStreamFactory: createContentStreamFactory,\n\n qualitySelector: (deps: {\n options: ObservableValue<Pick<VinylOptions, 'abr'>>\n }) =>\n new QualitySelectorImpl({\n options: deps.options.pick('abr'),\n }),\n preferredAudioLanguage: (deps: {\n options: ObservableValue<\n Pick<VinylOptions, 'preferredAudioLanguage'>\n >\n }) => deps.options.pick('preferredAudioLanguage'),\n allowedContentTypes: (deps: {\n options: ObservableValue<\n Pick<VinylOptions, 'allowedContentTypes'>\n >\n }) => deps.options.pick('allowedContentTypes'),\n preferDescriptiveAudio: (deps: {\n options: ObservableValue<\n Pick<VinylOptions, 'preferDescriptiveAudio'>\n >\n }) => deps.options.pick('preferDescriptiveAudio'),\n abr: (deps: {\n options: ObservableValue<Pick<VinylOptions, 'abr'>>\n }) => deps.options.pick('abr'),\n manifestTransformed: createDefaultDashManifestTransformer,\n mediaTimeline: (\n deps: BuildDashMediaTimelineDeps & {\n readonly manifestTransformed: ObservableValue<\n Promise<DashManifestData>\n >\n }\n ) =>\n deps.manifestTransformed.map(async (manifestPromise) => {\n const data = await manifestPromise\n return buildDashMediaTimeline(deps, data)\n }),\n mediaTimelineTransformed: createDefaultMediaTimelineTransformer,\n textTrackController: (deps: {\n readonly media: HTMLMediaElement\n readonly manifestTransformed: ObservableValue<\n Promise<DashManifestData>\n >\n readonly options: ObservableValue<\n Pick<\n VinylOptions,\n 'preferredTextLanguage' | 'textCueStyle'\n >\n >\n }) => {\n const controller = new SidecarTextTrackController({\n media: deps.media,\n requestInit: loadOptions.requestInit ?? undefined,\n preferredTextLanguage: deps.options.pick(\n 'preferredTextLanguage'\n ),\n cueStyle: deps.options.pick('textCueStyle'),\n })\n deps.manifestTransformed.onData((manifestPromise) => {\n manifestPromise\n .then((data) => {\n controller.setTextTracks(\n discoverDashTextTracks(\n data.manifest,\n data.baseUrl\n )\n )\n })\n .catch(() => {\n // Manifest errors are surfaced through the\n // manifest controller. Don't double-report.\n })\n })\n return controller\n },\n } as const) satisfies Factories<DashTrackDeps>\n }\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { Maybe } from '@amazon/vinyl-util'\nimport type { RequestInitOptions } from '@amazon/vinyl-util'\nimport type {\n MutableRequestParams,\n RequestInterceptor,\n} from '@amazon/vinyl-util'\nimport { noop } from '@amazon/vinyl-util'\nimport { clone, getLocation, resolveUrl } from '@amazon/vinyl-util'\nimport { requestWithRetry } from '@amazon/vinyl-util'\nimport { parseDashManifest } from '@amazon/vinyl-mpd-parser'\nimport type { DashManifestProvider } from './DashManifestProvider'\n\n/**\n * Creates a DashManifestProvider which performs a request to retrieve a dash manifest.\n * Can be a relative path.\n *\n * Usage example:\n *\n * ```createRequesterDashManifestProvider('https://example.com/manifest.mpd')```\n * @param input The resource location of the dash manifest.\n * @param init Optional request options such as headers.\n * @param requestInterceptor An optional transformer to mutate request parameters before the request is made.\n */\nexport function urlDashManifestProvider(\n input: string,\n init?: Maybe<RequestInitOptions>,\n requestInterceptor: RequestInterceptor = noop\n): DashManifestProvider {\n return async (abort) => {\n const params: MutableRequestParams = {\n input: resolveUrl(input, getLocation().href),\n init: clone(init) ?? {},\n }\n requestInterceptor(params)\n const response = await requestWithRetry(params.input, params.init, {\n abort,\n })\n const xml = await response.text()\n const manifest = parseDashManifest(xml)\n const baseInput = response.url || params.input\n return {\n manifest,\n baseUrl: resolveUrl('./', baseInput),\n }\n }\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { DashTrackLoadOptions } from './DashTrack'\nimport { urlDashManifestProvider } from './urlDashManifestProvider'\nimport type { RequestInterceptor } from '@amazon/vinyl-util'\n\n/**\n * Creates a DashManifestProvider which uses the manifestProvider set on the loadOptions, or a urlDashManifestProvider\n * if unset, which will use the loadOptions.uri as the manifest location.\n *\n * @param loadOptions\n */\nexport function createDashManifestProvider(loadOptions: DashTrackLoadOptions) {\n return (deps: { readonly requestInterceptor: RequestInterceptor }) => {\n return loadOptions.manifestProvider\n ? loadOptions.manifestProvider\n : urlDashManifestProvider(\n loadOptions.uri,\n loadOptions.requestInit,\n deps.requestInterceptor\n )\n }\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { ReadonlyPlaybackController } from '../../playback/ReadonlyPlaybackController'\nimport {\n SegmentControllerImpl,\n type SegmentControllerImplOptions,\n} from '../../streaming/SegmentControllerImpl'\nimport type { ContentType } from '../../streaming/MediaQualityMetadata'\nimport type { ObservableValue } from '@amazon/vinyl-observable'\nimport type { MediaTimeline } from '../../streaming/MediaTimeline'\nimport type { QualitySelector } from '../../streaming/abr/QualitySelector'\n\nexport interface SegmentControllerFactoryDeps {\n readonly playbackController: ReadonlyPlaybackController\n}\n\nexport function createSegmentControllerFactory(\n playerDeps: SegmentControllerFactoryDeps,\n contentType: ContentType,\n options?: Partial<SegmentControllerImplOptions>\n) {\n return (trackDeps: {\n readonly mediaTimelineTransformed: ObservableValue<\n Promise<MediaTimeline>\n >\n readonly qualitySelector: QualitySelector\n }) => {\n return new SegmentControllerImpl(\n {\n ...playerDeps,\n ...trackDeps,\n },\n contentType,\n options\n )\n }\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { ByteRange } from '@amazon/vinyl-mpd-parser'\nimport type { HlsByteRange } from '@amazon/vinyl-hls-parser'\n\n/** Converts an HLS byte range (`{offset, length}`) to a `ByteRange` (`[start, end]`). */\nexport function hlsByteRangeToMediaRange(byteRange: HlsByteRange): ByteRange {\n return [byteRange.offset, byteRange.offset + byteRange.length - 1]\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { HlsSegment } from '@amazon/vinyl-hls-parser'\nimport type { MediaSegmentReference } from '../../../streaming/SegmentReference'\nimport type { SegmentDataProvider } from '../../../streaming/SegmentDataSlot'\nimport {\n createSegmentDataProvider,\n type CreateSegmentDataProviderDeps,\n} from '../../createSegmentDataProvider'\nimport { hlsByteRangeToMediaRange } from './hlsByteRangeToMediaRange'\nimport { resolveUrl } from '@amazon/vinyl-util'\n\n/**\n * Builds a timeline of MediaSegmentReferences from an HLS media playlist's\n * segment list. Cumulative durations are used to compute start/end times.\n */\nexport function buildSegmentTimeline(\n deps: CreateSegmentDataProviderDeps,\n baseUrl: string,\n segments: readonly HlsSegment[]\n): readonly MediaSegmentReference<SegmentDataProvider>[] {\n const out: MediaSegmentReference<SegmentDataProvider>[] = new Array(\n segments.length\n )\n let time = 0\n for (let i = 0; i < segments.length; i++) {\n const seg = segments[i]\n const startTime = time\n const endTime = time + seg.duration\n const url = resolveUrl(seg.uri, baseUrl)\n out[i] = {\n timestampOffset: startTime,\n startTime,\n endTime,\n data: createSegmentDataProvider(deps, {\n url,\n mediaRange: seg.byteRange\n ? hlsByteRangeToMediaRange(seg.byteRange)\n : undefined,\n reportDownlinkMetrics: true,\n }),\n }\n time = endTime\n }\n return out\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { HlsManifestData } from './HlsManifestData'\nimport type { HlsMediaQualityMetadataResolver } from './HlsMediaQualityMetadataResolver'\nimport type {\n ContentType,\n MediaQualityMetadata,\n} from '../../streaming/MediaQualityMetadata'\nimport type {\n MediaPeriod,\n MediaQualityData,\n MediaTimeline,\n} from '../../streaming/MediaTimeline'\nimport type { SegmentReference } from '../../streaming/SegmentReference'\nimport type { SegmentDataProvider } from '../../streaming/SegmentDataSlot'\nimport { buildSegmentTimeline } from './util/hlsSegmentTime'\nimport { getSegmentAtTime } from '../../streaming/util/segment'\nimport { resolveUrl } from '@amazon/vinyl-util'\nimport { codecToContentType, contentTypeToMimeType } from '../mse/codec'\nimport {\n createSegmentDataProvider,\n type CreateSegmentDataProviderDeps,\n} from '../createSegmentDataProvider'\nimport { hlsByteRangeToMediaRange } from './util/hlsByteRangeToMediaRange'\nimport { createTransmuxer } from '@amazon/vinyl-transmux'\nimport type { AdBreakList } from '../../ad/AdBreakInfo'\nimport { discoverHlsInterstitials } from '../../ad/discoverHlsInterstitials'\n\nexport interface BuildHlsMediaTimelineDeps extends CreateSegmentDataProviderDeps {\n readonly mediaQualityMetadataResolver: HlsMediaQualityMetadataResolver\n}\n\n/**\n * Builds a MediaTimeline from an HLS manifest.\n * HLS has a single implicit period spanning the full duration.\n *\n * Audio is modeled per source: a variant that carries muxed audio (no separate\n * AUDIO rendition group) contributes an audio quality on its own playlist, while\n * a variant with a demuxed audio group contributes video only \u2014 one audio\n * quality is created per AUDIO rendition in the group, each carrying that\n * rendition's language and playlist. Modeling every language as its own audio\n * quality is what lets the timeline's language filter select among them.\n */\nexport function buildHlsMediaTimeline(\n deps: BuildHlsMediaTimelineDeps,\n data: HlsManifestData\n): MediaTimeline {\n const { mainPlaylist, baseUrl } = data\n const renditions = mainPlaylist.alternativeRenditions\n const audioRenditions = renditions.filter((r) => r.type === 'AUDIO')\n\n // HLS duration requires fetching a media playlist, so compute it lazily.\n const DEFAULT_MIN_BUFFER_TIME = 10\n\n const qualities: MediaQualityData[] = []\n\n for (const variant of mainPlaylist.variants) {\n const baseMetadata = deps.mediaQualityMetadataResolver(\n variant,\n renditions\n )\n const codecs = variant.codecs?.split(',') ?? []\n const contentTypes = new Set(\n codecs\n .map((c) => codecToContentType(c))\n .filter((t): t is ContentType => t != null)\n )\n // If no codecs, default to audio (e.g. TS streams).\n if (contentTypes.size === 0) contentTypes.add('audio')\n\n const hasDemuxedAudio =\n variant.audioGroup != null &&\n audioRenditions.some(\n (r) => r.groupId === variant.audioGroup && r.uri != null\n )\n\n // One quality per content type this variant delivers itself.\n for (const contentType of contentTypes) {\n // Demuxed audio is delivered by its rendition group (built below as\n // one quality per language), not by the video variant's playlist.\n if (contentType === 'audio' && hasDemuxedAudio) continue\n const codec =\n codecs.find((c) => codecToContentType(c) === contentType) ??\n null\n qualities.push(\n createHlsQualityData(deps, data, baseUrl, variant.uri, {\n ...baseMetadata,\n contentType,\n mimeType: contentTypeToMimeType(contentType, codec),\n codecs: codec,\n })\n )\n }\n }\n\n // One audio quality per demuxed audio rendition (per language), so the\n // media-timeline language filter can select among them.\n const seenAudio = new Set<string>()\n for (const rendition of audioRenditions) {\n const uri = rendition.uri\n if (uri == null || seenAudio.has(uri)) continue\n seenAudio.add(uri)\n // Prefer the variant whose own playlist IS this rendition: its CODECS\n // then describes this exact audio, the only reliable per-rendition codec\n // for a mixed-codec group (one group referenced by variants of differing\n // codecs). Fall back to any variant referencing the group for the common\n // demuxed case where the variant playlist is video and every group\n // variant shares one audio codec.\n const variant =\n mainPlaylist.variants.find((v) => v.uri === uri) ??\n mainPlaylist.variants.find(\n (v) => v.audioGroup === rendition.groupId\n )\n // A rendition neither self-described by a variant nor referenced by one\n // has no codec to play with.\n if (!variant) continue\n const audioCodec =\n variant.codecs\n ?.split(',')\n .find((c) => codecToContentType(c) === 'audio') ?? null\n const baseMetadata = deps.mediaQualityMetadataResolver(\n variant,\n renditions\n )\n // Disambiguate renditions that share a group and language (e.g. a main\n // and an audio-description track) by their unique NAME, so their\n // qualityIds don't collide.\n const qualitySuffix = rendition.language\n ? `${rendition.language}-${rendition.name}`\n : rendition.name\n qualities.push(\n createHlsQualityData(deps, data, baseUrl, uri, {\n ...baseMetadata,\n qualityId: `audio-${rendition.groupId}-${qualitySuffix}`,\n decoderId: uri,\n contentType: 'audio',\n codecs: audioCodec,\n mimeType: contentTypeToMimeType('audio', audioCodec),\n width: null,\n height: null,\n frameRate: null,\n lang: rendition.language ?? null,\n characteristics: rendition.characteristics ?? [],\n })\n )\n }\n\n const period: MediaPeriod = {\n startTime: 0,\n endTime: Infinity,\n qualities,\n }\n\n let cachedDuration: number | null = null\n\n return {\n periods: [period],\n minBufferTime: DEFAULT_MIN_BUFFER_TIME,\n getAdBreaks: () => discoverAdsFromManifest(data),\n async getDuration() {\n if (cachedDuration != null) return cachedDuration\n if (mainPlaylist.variants.length === 0) {\n throw new Error('Unable to determine HLS duration: no variants')\n }\n const playlist = await data.getMediaPlaylist(\n mainPlaylist.variants[0].uri\n )\n // Live playlists (no EXT-X-ENDLIST) have unbounded duration.\n if (!playlist.ended) return Infinity\n if (playlist.segments.length === 0) {\n throw new Error(\n 'Unable to determine HLS duration: no segments in media playlist'\n )\n }\n let total = 0\n for (const seg of playlist.segments) total += seg.duration\n cachedDuration = total\n return cachedDuration\n },\n }\n}\n\n/**\n * Builds the {@link MediaQualityData} for one HLS quality: its metadata plus a\n * getSegment that fetches from `playlistUri` (the variant playlist for video/\n * muxed qualities, or a rendition playlist for demuxed audio) and either serves\n * fMP4 directly (using its EXT-X-MAP init segment) or transmuxes MPEG-TS/ADTS.\n */\nfunction createHlsQualityData(\n deps: BuildHlsMediaTimelineDeps,\n data: HlsManifestData,\n baseUrl: string,\n playlistUri: string,\n metadata: MediaQualityMetadata\n): MediaQualityData {\n const transmuxer = createTransmuxer()\n return {\n metadata,\n async getSegment(\n time: number,\n affordance = 0\n ): Promise<SegmentReference<SegmentDataProvider> | null> {\n const playlist = await data.getMediaPlaylist(playlistUri)\n const playlistBaseUrl = resolveUrl(playlistUri, baseUrl)\n const segments = buildSegmentTimeline(\n deps,\n playlistBaseUrl,\n playlist.segments\n )\n const segment = getSegmentAtTime(time, segments, affordance)\n if (!segment) return null\n\n // fMP4: use #EXT-X-MAP init segment directly.\n const hlsMap = playlist.segments[0]?.map\n if (hlsMap) {\n return {\n quality: metadata,\n ...segment,\n initData: createSegmentDataProvider(deps, {\n url: resolveUrl(hlsMap.uri, playlistBaseUrl),\n mediaRange: hlsMap.byteRange\n ? hlsByteRangeToMediaRange(hlsMap.byteRange)\n : undefined,\n reportDownlinkMetrics: false,\n }),\n }\n }\n\n // MPEG-TS/ADTS: transmux to fMP4.\n const transmuxedQuality: MediaQualityMetadata = {\n ...metadata,\n mimeType: contentTypeToMimeType(\n metadata.contentType!,\n metadata.codecs\n ),\n }\n const rawDataProvider = segment.data\n return {\n quality: transmuxedQuality,\n ...segment,\n data: async (abort) => {\n const raw = await rawDataProvider(abort)\n return transmuxer.transmux(raw).mediaSegment\n },\n initData: async (abort) => {\n const raw = await rawDataProvider(abort)\n return transmuxer.transmux(raw).initSegment\n },\n }\n },\n } satisfies MediaQualityData\n}\n\nasync function discoverAdsFromManifest(\n data: HlsManifestData\n): Promise<AdBreakList> {\n if (data.mainPlaylist.variants.length === 0) return []\n // Use the first variant for the date range timeline\n // https://gist.github.com/bkataru/1fb67181ddf0edfc60c04f6f02518e74?utm_source=chatgpt.com#file-hls-specification-txt-L3449\n const variant = data.mainPlaylist.variants[0]\n const media = await data.getMediaPlaylist(variant.uri)\n const contentDuration = media.ended\n ? media.segments.reduce((sum, s) => sum + s.duration, 0)\n : null\n const playlistBaseUrl = resolveUrl(variant.uri, data.baseUrl)\n return discoverHlsInterstitials(media, playlistBaseUrl, contentDuration)\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { ObservableValue } from '@amazon/vinyl-observable'\nimport type { HlsManifestData } from './HlsManifestData'\n\nexport interface HlsManifestTransformerDeps {\n readonly manifestController: ObservableValue<Promise<HlsManifestData>>\n}\n\n/**\n * The default HLS manifest transformer sorts variants by bandwidth descending (highest quality first).\n * Quality and language filtering is handled by the media timeline transformer.\n */\nexport function createDefaultHlsManifestTransformer(\n deps: HlsManifestTransformerDeps\n): ObservableValue<Promise<HlsManifestData>> {\n return deps.manifestController.map(async (v) => {\n const data = await v\n const sorted = [...data.mainPlaylist.variants].sort(\n (a, b) => b.bandwidth - a.bandwidth\n )\n return {\n ...data,\n mainPlaylist: {\n ...data.mainPlaylist,\n variants: sorted,\n },\n }\n })\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { MediaSourceController } from '../../streaming/buffering/MediaSourceController'\nimport type { PlaybackController } from '../../playback/PlaybackController'\nimport type { QualitySelector } from '../../streaming/abr/QualitySelector'\nimport type { ObservableValue } from '@amazon/vinyl-observable'\nimport { type ContentStreamImplDeps } from '../../streaming/ContentStream'\nimport type { ContentType } from '../../streaming/MediaQualityMetadata'\nimport {\n SourceBufferControllerImpl,\n type SourceBufferControllerImplDeps,\n} from '../../streaming/buffering/SourceBufferController'\nimport {\n BufferingControllerImpl,\n type BufferingControllerImplDeps,\n} from '../../streaming/buffering/BufferingController'\nimport {\n SegmentControllerImpl,\n type SegmentControllerImplDeps,\n} from '../../streaming/SegmentControllerImpl'\nimport { type Maybe, memoize } from '@amazon/vinyl-util'\nimport {\n externalDependencies,\n type Factories,\n validateFactories,\n} from '@amazon/vinyl-di'\nimport type { ContentStreamingOptions } from '../../streaming/ContentStreamingOptions'\nimport type { MediaTimeline } from '../../streaming/MediaTimeline'\n\nexport interface HlsContentStreamTrackDeps {\n readonly mediaSourceController: MediaSourceController\n readonly playbackController: PlaybackController\n readonly mediaTimelineTransformed: ObservableValue<Promise<MediaTimeline>>\n readonly qualitySelector: QualitySelector\n}\n\nexport function createHlsContentStreamFactories(\n options: Maybe<ContentStreamingOptions>\n) {\n return (deps: HlsContentStreamTrackDeps) =>\n memoize(\n (contentType: ContentType) => {\n return validateFactories({\n ...externalDependencies(deps),\n sourceBufferControllerFactory:\n (deps: SourceBufferControllerImplDeps) => () =>\n new SourceBufferControllerImpl(deps, contentType),\n bufferingController: (deps: BufferingControllerImplDeps) =>\n new BufferingControllerImpl(\n deps,\n contentType,\n options?.buffering\n ),\n segmentController: (deps: SegmentControllerImplDeps) =>\n new SegmentControllerImpl(\n deps,\n contentType,\n options?.segmentController\n ),\n } as const) satisfies Factories<ContentStreamImplDeps>\n },\n (contentType) => contentType\n )\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { ContentType } from '../../streaming/MediaQualityMetadata'\nimport type { ContentTypesValue } from '../../streaming/ContentTypesValue'\nimport type { ObservableValue } from '@amazon/vinyl-observable'\nimport type { HlsManifestData } from './HlsManifestData'\nimport type { HlsMainPlaylist } from '@amazon/vinyl-hls-parser'\nimport { codecsToContentTypes } from '../mse/codec'\n\nexport interface HlsContentTypesValueDeps {\n readonly manifestTransformed: ObservableValue<Promise<HlsManifestData>>\n}\n\n/**\n * Creates an ObservableValue for the content types present in the HLS manifest.\n *\n * Per RFC 8216 \u00A74.3.4.2, content types are determined from:\n * 1. The CODECS attribute on EXT-X-STREAM-INF (variant streams)\n * 2. The TYPE attribute on EXT-X-MEDIA (alternative renditions)\n */\nexport function createHlsContentTypesValue(\n deps: HlsContentTypesValueDeps\n): ContentTypesValue {\n return deps.manifestTransformed.map(async (manifestData) => {\n return getContentTypes((await manifestData).mainPlaylist)\n })\n}\n\nfunction getContentTypes(mainPlaylist: HlsMainPlaylist): Set<ContentType> {\n const contentTypes = new Set<ContentType>()\n\n // Derive content types from variant CODECS attributes.\n // Only audio and video are relevant for MSE; text (subtitles/CC) is not\n // appended via SourceBuffer in HLS.\n for (const variant of mainPlaylist.variants) {\n if (variant.codecs) {\n for (const type of codecsToContentTypes(variant.codecs)) {\n if (type === 'audio' || type === 'video') {\n contentTypes.add(type)\n }\n }\n }\n }\n\n // Add audio/video from separate renditions not already covered by variant codecs.\n for (const rendition of mainPlaylist.alternativeRenditions) {\n if (rendition.type === 'AUDIO') contentTypes.add('audio')\n if (rendition.type === 'VIDEO') contentTypes.add('video')\n }\n\n return contentTypes\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type {\n AlternativeRendition,\n VariantStream,\n} from '@amazon/vinyl-hls-parser'\nimport type { MediaQualityMetadata } from '../../streaming/MediaQualityMetadata'\nimport { codecToContentType, contentTypeToMimeType } from '../mse/codec'\n\nexport type HlsMediaQualityMetadataResolver = (\n variant: VariantStream,\n renditions: readonly AlternativeRendition[]\n) => MediaQualityMetadata\n\nexport function createDefaultHlsMediaQualityMetadataResolver(): HlsMediaQualityMetadataResolver {\n return (variant, _renditions) => {\n const codecs = variant.codecs || null\n // Use the first codec to determine the primary content type.\n const contentType = codecs\n ? codecToContentType(codecs.split(',')[0])\n : null\n\n // Use the variant URI as the decoderId so each quality forces a decoder\n // re-initialization on switch.\n return {\n qualityId: `${variant.bandwidth}-${codecs ?? ''}`,\n decoderId: variant.uri,\n groupId: '0',\n switchingGroupIds: null,\n mimeType: contentType\n ? contentTypeToMimeType(contentType, codecs)\n : null,\n contentType,\n codecs,\n bandwidth: null,\n bandwidthTotal: variant.bandwidth,\n audioSamplingRate: null,\n width: variant.width ?? null,\n height: variant.height ?? null,\n frameRate: variant.frameRate\n ? ([variant.frameRate, 1] as const)\n : null,\n // A variant's own language is unknown/irrelevant: demuxed audio\n // carries its language on its rendition (buildHlsMediaTimeline\n // creates one audio quality per rendition), and video is\n // language-agnostic. Muxed variants have a single implicit language.\n lang: null,\n // Audio-rendition characteristics are applied per rendition in\n // buildHlsMediaTimeline; the variant itself carries none.\n characteristics: [],\n contentProtections: [],\n encryptionScheme: null,\n initDataType: null,\n supplementalProperties: {},\n }\n }\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { HlsTrackDeps, HlsTrackLoadOptions } from './HlsTrack'\nimport type { Maybe, RequestInterceptor } from '@amazon/vinyl-util'\nimport type { AdController } from '../../ad/AdController'\nimport { createMediaSource } from '../../util/media/mediaSource'\nimport { createDefaultHlsMediaQualityMetadataResolver } from './HlsMediaQualityMetadataResolver'\nimport {\n MediaSourceControllerImpl,\n type MediaSourceControllerImplDeps,\n} from '../../streaming/buffering/MediaSourceController'\nimport {\n externalDependencies,\n type Factories,\n validateFactories,\n} from '@amazon/vinyl-di'\nimport type { ContentStreamingOptions } from '../../streaming/ContentStreamingOptions'\nimport { createHlsContentTypesValue } from './createHlsContentTypesValue'\nimport { createAllowedContentTypesValue } from '../../streaming/createAllowedContentTypesValue'\nimport { createHlsContentStreamFactories } from './createHlsContentStreamFactories'\nimport { createContentStreamFactory } from '../../streaming/ContentStream'\nimport type { ObservableValue } from '@amazon/vinyl-observable'\nimport type { PlaybackController } from '../../playback/PlaybackController'\nimport type { DrmKeySystemResolver } from '../../drm/DrmKeySystemResolver'\nimport type { DrmController } from '../../drm/DrmController'\nimport type { Capabilities } from '../../client/Capabilities'\nimport type { PlaybackSource } from '../../playback/PlaybackSource'\nimport { QualitySelectorImpl } from '../../streaming/abr/QualitySelectorImpl'\nimport type { VinylOptions } from '../../vinyl/VinylOptions'\nimport { createDefaultHlsManifestTransformer } from './createDefaultHlsManifestTransformer'\nimport {\n buildHlsMediaTimeline,\n type BuildHlsMediaTimelineDeps,\n} from './buildHlsMediaTimeline'\nimport { createDefaultMediaTimelineTransformer } from '../../streaming/createDefaultMediaTimelineTransformer'\nimport type { HlsManifestData } from './HlsManifestData'\nimport { SidecarTextTrackController } from '../../text/SidecarTextTrackController'\nimport { discoverHlsTextTracks } from '../../text/discoverHlsTextTracks'\nimport {\n ManifestControllerImpl,\n type ManifestControllerImplDeps,\n} from '../../streaming/ManifestControllerImpl'\nimport { createHlsManifestProvider } from './createHlsManifestProvider'\n\nexport interface HlsFactoryDeps {\n readonly options: ObservableValue<\n Pick<\n VinylOptions,\n | 'abr'\n | 'preferredAudioLanguage'\n | 'allowedContentTypes'\n | 'preferDescriptiveAudio'\n | 'preferredTextLanguage'\n | 'textCueStyle'\n >\n >\n readonly playbackController: PlaybackController\n readonly playbackSource: PlaybackSource\n readonly drmKeySystemResolver: DrmKeySystemResolver\n readonly requestInterceptor: RequestInterceptor\n readonly drmController: DrmController\n readonly capabilities: Capabilities\n /**\n * The HTML media element. Required to attach sidecar text tracks via\n * `media.addTextTrack`.\n */\n readonly media: HTMLMediaElement\n\n /**\n * The player-level ad controller. MseTrack sets discovered ad breaks on it\n * when the media timeline resolves.\n */\n readonly adController: AdController\n}\n\nexport type HlsInitOptions = {\n readonly streaming?: Maybe<ContentStreamingOptions>\n}\n\nexport function createHlsFactories(options: Maybe<HlsInitOptions>) {\n return (deps: HlsFactoryDeps) => {\n return (loadOptions: HlsTrackLoadOptions) => {\n return validateFactories({\n // Spreads all player-level deps (including adController) as\n // external, non-owned dependencies so disposing this track's\n // container never disposes the shared player-level controllers.\n ...externalDependencies(deps),\n\n baseContentTypesValue: createHlsContentTypesValue,\n contentTypesValue: createAllowedContentTypesValue,\n\n manifestProvider: () => createHlsManifestProvider(loadOptions),\n manifestController: (\n deps: ManifestControllerImplDeps<HlsManifestData>\n ) => new ManifestControllerImpl(deps),\n\n manifestTransformed: createDefaultHlsManifestTransformer,\n\n mediaQualityMetadataResolver: () =>\n createDefaultHlsMediaQualityMetadataResolver(),\n\n mediaSourceFactory: () => createMediaSource,\n\n mediaSourceController: (deps: MediaSourceControllerImplDeps) =>\n new MediaSourceControllerImpl(deps),\n\n segmentRequestInit: () => loadOptions.segmentRequestInit,\n\n createContentStreamFactories: createHlsContentStreamFactories(\n options?.streaming\n ),\n contentStreamFactory: createContentStreamFactory,\n\n qualitySelector: (deps: {\n options: ObservableValue<Pick<VinylOptions, 'abr'>>\n }) =>\n new QualitySelectorImpl({\n options: deps.options.pick('abr'),\n }),\n\n preferredAudioLanguage: (deps: {\n options: ObservableValue<\n Pick<VinylOptions, 'preferredAudioLanguage'>\n >\n }) => deps.options.pick('preferredAudioLanguage'),\n allowedContentTypes: (deps: {\n options: ObservableValue<\n Pick<VinylOptions, 'allowedContentTypes'>\n >\n }) => deps.options.pick('allowedContentTypes'),\n preferDescriptiveAudio: (deps: {\n options: ObservableValue<\n Pick<VinylOptions, 'preferDescriptiveAudio'>\n >\n }) => deps.options.pick('preferDescriptiveAudio'),\n abr: (deps: {\n options: ObservableValue<Pick<VinylOptions, 'abr'>>\n }) => deps.options.pick('abr'),\n\n mediaTimeline: (\n deps: BuildHlsMediaTimelineDeps & {\n readonly manifestTransformed: ObservableValue<\n Promise<HlsManifestData>\n >\n }\n ) =>\n deps.manifestTransformed.map(async (manifestPromise) => {\n const data = await manifestPromise\n return buildHlsMediaTimeline(deps, data)\n }),\n mediaTimelineTransformed: createDefaultMediaTimelineTransformer,\n textTrackController: (deps: {\n readonly media: HTMLMediaElement\n readonly manifestTransformed: ObservableValue<\n Promise<HlsManifestData>\n >\n readonly options: ObservableValue<\n Pick<\n VinylOptions,\n 'preferredTextLanguage' | 'textCueStyle'\n >\n >\n }) => {\n const controller = new SidecarTextTrackController({\n media: deps.media,\n requestInit: loadOptions.requestInit ?? undefined,\n preferredTextLanguage: deps.options.pick(\n 'preferredTextLanguage'\n ),\n cueStyle: deps.options.pick('textCueStyle'),\n })\n deps.manifestTransformed.onData((manifestPromise) => {\n manifestPromise\n .then((data) => {\n controller.setTextTracks(\n discoverHlsTextTracks(\n data.mainPlaylist,\n data.baseUrl\n )\n )\n })\n .catch(() => {\n // Manifest errors are surfaced through the\n // manifest controller. Don't double-report.\n })\n })\n return controller\n },\n } as const) satisfies Factories<HlsTrackDeps>\n }\n }\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type {\n HlsMainPlaylist,\n HlsMediaPlaylist,\n} from '@amazon/vinyl-hls-parser'\nimport { parseMainPlaylist, parseMediaPlaylist } from '@amazon/vinyl-hls-parser'\nimport type {\n Maybe,\n ReadonlyAbort,\n RequestInitOptions,\n} from '@amazon/vinyl-util'\nimport { memoize, requestWithRetry, resolveUrl } from '@amazon/vinyl-util'\nimport type { HlsManifestData } from './HlsManifestData'\nimport type { HlsManifestProvider } from './createHlsManifestProvider'\n\nexport function createUrlHlsManifestProvider(\n url: string,\n requestInit?: RequestInitOptions\n): HlsManifestProvider {\n return async (abort?: ReadonlyAbort): Promise<HlsManifestData> => {\n const mainResponse = await requestWithRetry(url, requestInit, {\n abort,\n })\n const mainText = await mainResponse.text()\n\n // Use the response URL (after redirects) as the base for resolving\n // relative URIs and for resolving #EXT-X-DEFINE:QUERYPARAM tokens.\n const baseUrl = mainResponse.url || url\n const mainPlaylist = parseMainPlaylist(\n mainText,\n parseQueryParams(baseUrl)\n )\n\n const getMediaPlaylist = memoize(\n (uri: string) =>\n fetchMediaPlaylist({\n uri,\n baseUrl,\n defines: mainPlaylist.defines,\n requestInit,\n abort,\n }),\n (uri) => uri\n )\n\n return {\n mainPlaylist,\n baseUrl,\n getMediaPlaylist,\n }\n }\n}\n\nexport interface FetchMediaPlaylistOptions {\n /** The variant URI to resolve against the base URL. */\n readonly uri: string\n /** The base URL for resolving relative URIs. */\n readonly baseUrl: string\n /** Variable definitions from the main playlist. */\n readonly defines: HlsMainPlaylist['defines']\n /** Optional request configuration. */\n readonly requestInit?: Maybe<RequestInitOptions>\n /** Optional abort signal. */\n readonly abort?: Maybe<ReadonlyAbort>\n}\n\n/**\n * Fetches and parses an HLS media playlist from a variant URI.\n */\nexport async function fetchMediaPlaylist(\n options: FetchMediaPlaylistOptions\n): Promise<HlsMediaPlaylist> {\n const { uri, baseUrl, defines, requestInit, abort } = options\n const variantUrl = resolveUrl(uri, baseUrl)\n const response = await requestWithRetry(variantUrl, requestInit, { abort })\n const text = await response.text()\n // The resolved URL (after redirects) carries the query parameters that\n // #EXT-X-DEFINE:QUERYPARAM entries resolve against (e.g. MediaTailor ad\n // manifests). Fall back to the requested URL if the response omits it.\n const queryParams = parseQueryParams(response.url || variantUrl)\n return parseMediaPlaylist(text, defines, queryParams)\n}\n\n/**\n * Extracts a URL's query parameters into a plain record for\n * `#EXT-X-DEFINE:QUERYPARAM` resolution. Returns undefined when the URL has no\n * query string so the parser can skip substitution entirely.\n */\nfunction parseQueryParams(url: string): Record<string, string> | undefined {\n const queryStart = url.indexOf('?')\n if (queryStart === -1) return undefined\n const params: Record<string, string> = {}\n const search = new URLSearchParams(url.substring(queryStart + 1))\n for (const [key, value] of search) params[key] = value\n return params\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { HlsTrackLoadOptions } from './HlsTrack'\nimport { createUrlHlsManifestProvider } from './createUrlHlsManifestProvider'\nimport type { ManifestProvider } from '../../streaming/ManifestController'\nimport type { HlsManifestData } from './HlsManifestData'\n\nexport function createHlsManifestProvider(\n loadOptions: HlsTrackLoadOptions\n): HlsManifestProvider {\n return (\n loadOptions.manifestProvider ||\n createUrlHlsManifestProvider(\n loadOptions.uri,\n loadOptions.requestInit || undefined\n )\n )\n}\n\nexport type HlsManifestProvider = ManifestProvider<HlsManifestData>\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {\n type AnyRecord,\n countElements,\n createDisposer,\n type Disposable,\n EventHostImpl,\n first,\n getOrSet,\n IllegalStateError,\n logDebug,\n logError,\n logInfo,\n logVerbose,\n logWarn,\n LruCache,\n type Maybe,\n noop,\n type ReadonlyEventHost,\n resolveValueProvider,\n type Unsubscribe,\n} from '@amazon/vinyl-util'\nimport type { PlaybackController } from '../playback/PlaybackController'\nimport type { ReadonlyTrack, Track, TrackUri } from './Track'\nimport type {\n TrackConfigOptions,\n TrackFactory,\n TrackLoadOptions,\n} from './TrackFactory'\nimport type { ChangeEvent } from '../event/ChangeEvent'\nimport type { AdController } from '../ad/AdController'\nimport type { AdBreakInfo, AdInfo } from '../ad/AdBreakInfo'\n\nexport interface TrackControllerEventMap<\n TrackLoadOptionsType extends TrackLoadOptions,\n> {\n /**\n * A track became active. For content this may be deferred behind a preroll;\n * for an ad it fires as the ad activates. {@link queueChange} precedes it.\n */\n readonly trackActivated: TrackLifecycleEvent\n\n /**\n * A previously-active track was torn down (superseded or unloaded).\n */\n readonly trackDeactivated: TrackLifecycleEvent\n\n /**\n * Dispatched when the queue has changed.\n *\n * Will be emitted before {@link trackActivated}.\n */\n readonly queueChange: ChangeEvent<readonly TrackLoadOptionsType[]>\n\n /**\n * Emitted when the current track \u2014 including any postroll ads \u2014 has finished\n * playing. Fires once per track: as the queue advances it precedes the\n * resulting {@link trackActivated}, and for the final track it precedes\n * `queueEnded`. Distinct from the media element's `ended` (which also fires\n * for each ad) and from an individual ad's `adEnded`, so applications can act\n * on true track completion (e.g. logging a play) without confusing it with\n * an ad ending or the content ending before its postroll plays.\n */\n readonly trackEnded: TrackEndedEvent\n\n /**\n * Emitted when the last track of the playback queue (and any of its\n * postroll ads) have ended.\n */\n readonly queueEnded: AnyRecord\n}\n\nexport const ALL_TRACK_CONTROLLER_EVENTS = [\n 'trackActivated',\n 'trackDeactivated',\n 'queueChange',\n 'trackEnded',\n 'queueEnded',\n] as const satisfies readonly (keyof TrackControllerEventMap<any>)[]\n\n/** Payload for {@link trackActivated} / {@link trackDeactivated}. */\nexport interface TrackLifecycleEvent {\n readonly track: ReadonlyTrack\n}\n\n/**\n * Payload for the {@link TrackControllerEventMap.trackEnded} event: the load\n * options of the track that finished playing (including any postroll ads).\n */\nexport interface TrackEndedEvent {\n readonly track: TrackLoadOptions\n}\n\n/**\n * A readonly interface to the track controller.\n */\nexport interface ReadonlyTrackController<\n TrackLoadOptionsType extends TrackLoadOptions,\n> extends ReadonlyEventHost<TrackControllerEventMap<TrackLoadOptionsType>> {\n /**\n * The active track, or null when the selected track has not yet activated\n * (e.g. behind a preroll) or nothing is loaded.\n */\n readonly activeTrack: ReadonlyTrack | null\n\n /**\n * Returns the current queue of TrackLoadOptions.\n * Observe 'queueChange' for changes to this queue.\n */\n readonly queue: readonly TrackLoadOptionsType[]\n\n /**\n * Returns true if there is at least one track in the queue.\n */\n hasNext(): boolean\n\n /**\n * Returns true if the track with the given URI is cached.\n */\n isTrackCached(uri: TrackUri): boolean\n\n /**\n * Returns the cached track for the given URI, or null if the track is not cached.\n */\n getCachedTrack(uri: TrackUri): ReadonlyTrack | null\n\n /**\n * Returns an iterator of currently cached tracks.\n */\n getCachedTracks(): IterableIterator<ReadonlyTrack>\n}\n\n/**\n * Responsible for queuing track load configurations.\n * This is the authority for which is the current track.\n */\nexport interface TrackController<\n TrackLoadOptionsType extends TrackLoadOptions,\n> extends ReadonlyTrackController<TrackLoadOptionsType> {\n /**\n * Preloads the given list of tracks.\n * The tracks provided will not be enqueued.\n * The track controller's cache size will automatically increase to accommodate the request.\n *\n * Prefetch priority note:\n * Tracks have a prefetch priority, later calls to preload will have a higher precedence than previous calls.\n * Previous tracks given to `preload` will drop off when they are evicted from the cache. This is dependent on\n * cache size.\n *\n * @param loadOptionsList\n */\n preload(...loadOptionsList: readonly TrackLoadOptionsType[]): void\n\n /**\n * Sets the current queue to the provided track list.\n * When the track ends, the next will be played.\n *\n * `load` does not begin playback. Call `play()` after a load to start playback.\n * Browser autoplay policies may require the first call to `play()` to be in response to a user interaction\n * such as a click, touch, keypress, or voice event.\n *\n * Note that if the current track is the first track provided in the list, that track will be restarted.\n * To set the queue without unloading the current track, use {@link clearQueue} followed by {@link enqueue}.\n *\n * @param loadOptionsList A list of load configuration objects to set as a playback queue.\n */\n load(...loadOptionsList: readonly TrackLoadOptionsType[]): void\n\n /**\n * Unloads the active track and clears the queue.\n * This is the same as calling {@link load} with zero parameters.\n */\n unload(): void\n\n /**\n * Appends the given tracks to the current queue.\n *\n * @param loadOptionsList The track load configurations to append.\n */\n enqueue(...loadOptionsList: readonly TrackLoadOptionsType[]): void\n\n /**\n * Activates the next track in the queue.\n * If the media is not paused the next track will begin playing automatically.\n *\n * @see ReadonlyTrackController.hasNext\n */\n next(): void\n\n /**\n * Clears all fetched fragments and source buffers.\n * Playback will be interrupted, and streaming will resume again when data has been fetched and buffered.\n * This should be called if a change has been made where the user would expect an immediate change,\n * for example, changing streaming quality from SD to HD.\n *\n * Does not unload manifests.\n */\n clearPrefetch(): void\n\n /**\n * Clears the track cache, unloads the current track, and clears the queue.\n */\n clearTrackCache(): void\n\n /**\n * Clears the current queue.\n * Does not stop the current track or affect the prefetched cache.\n */\n clearQueue(): void\n\n /**\n * Resets the current track's error state.\n *\n * @param hard If true, the track will reset the playback state and\n * recreate media sources.\n */\n reset(hard?: boolean): void\n}\n\nexport interface TrackControllerImplDeps<\n TrackLoadOptionsType extends TrackLoadOptions,\n> {\n readonly trackFactory: TrackFactory<TrackLoadOptionsType>\n\n readonly playbackController: PlaybackController\n\n readonly adController: AdController\n\n readonly adTrackLoadOptionsProvider: AdTrackLoadOptionsProvider<TrackLoadOptionsType>\n}\n\nexport type AdTrackLoadOptionsProvider<\n TrackLoadOptionsType extends TrackLoadOptions,\n> = (adInfo: AdInfo) => Promise<TrackLoadOptionsType>\n\nexport interface TrackControllerImplOptions {\n /**\n * When tracks are queued, the number of tracks to prefetch ahead of the current track.\n * Default: 2\n */\n readonly trackPrefetchCount: number\n\n /**\n * The number of tracks that may be preloaded at one time (not counting queue prefetch).\n * This extends the track cache capacity and allows a certain number of tracks no longer in the queue to remain\n * cached.\n *\n * Default: 2\n */\n readonly preloadCapacity: number\n}\n\nconst defaultTrackControllerImplOptions = {\n trackPrefetchCount: 2,\n preloadCapacity: 2,\n} as const satisfies TrackControllerImplOptions\n\n/**\n * Track priority will be assigned based on calls to `preload`.\n * Segment background prefetching is shared if there are multiple players instances (in the rare case there would be\n * multiple players). Having a global incrementing trackPriority prevents one player from starving another.\n */\nexport const trackPriority = {\n value: 0,\n}\n\nexport class TrackControllerImpl<TrackLoadOptionsType extends TrackLoadOptions>\n extends EventHostImpl<TrackControllerEventMap<TrackLoadOptionsType>>\n implements TrackController<TrackLoadOptionsType>, Disposable\n{\n get [Symbol.toStringTag](): string {\n return 'TrackControllerImpl'\n }\n\n // When tracks are preloaded, the cache capacity may expand automatically to accommodate.\n private _autoPreloadCapacity = 0\n // The primary content track cache. Bounded by preloadCapacity + prefetch.\n private readonly trackCache = /* @__PURE__ */ new LruCache<string, Track>(0)\n // A monotonically increasing id for a queue change, to allow for queue changes during events.\n private queueIdx = 0\n private _queue: readonly TrackLoadOptionsType[] = []\n // The current content track data in the queue. This will never represent an ad.\n private _current: TrackLoadOptionsType | null = null\n // The current Track, may be a content track or an ad track.\n private _currentTrack: Track | null = null\n // The parent content track. Used as a reference to the track that initiated an ad break.\n private adParent: Track | null = null\n\n // Current-track subscriptions (e.g. `error` \u2192 adController.failAd),\n // re-bound per setCurrentTrack. Promote to a disposer if more are added.\n private currentTrackSub: Unsubscribe | null = null\n\n // Ad tracks keyed by parent content URI, kept out of the content cache.\n // Pegged to the parent: disposed when the parent is evicted (see onEvict).\n private readonly adTracksByParent = /* @__PURE__ */ new Map<\n TrackUri,\n Map<TrackUri, Track>\n >()\n\n private readonly disposer = /* @__PURE__ */ createDisposer()\n private _options: TrackControllerImplOptions =\n defaultTrackControllerImplOptions\n\n constructor(\n private readonly deps: TrackControllerImplDeps<TrackLoadOptionsType>,\n initialOptions?: Partial<TrackControllerImplOptions>\n ) {\n super()\n const { add } = this.disposer\n const { playbackController } = deps\n\n this.trackCache.onEvicting = (track) => {\n // Do not evict tracks within the prefetch range.\n return (\n this.getPrefetched().find((value) => value.uri === track.uri) ==\n null\n )\n }\n\n this.trackCache.onEvict = (track) => {\n logDebug(this, `Disposing track: ${track.uri}`)\n // Ad tracks are pegged to their parent \u2014 disposing them here keeps\n // them from outliving the content track they belong to.\n this.disposeAdTracksFor(track.uri)\n track.dispose()\n return true\n }\n\n add(playbackController.on('ended', this.onEnded))\n\n this.initializeAdHandling()\n this.configure(initialOptions)\n }\n\n private initializeAdHandling() {\n const { add } = this.disposer\n const { adController, adTrackLoadOptionsProvider, playbackController } =\n this.deps\n add(\n adController.on('adPreload', (event) => {\n // The playhead is approaching a midroll/postroll break; warm its\n // ad tracks for the current content track so they are ready on\n // entry. Prerolls are already warmed by preloadPrerollAds.\n const adParent = this.adParent\n if (adParent) this.preloadBreakAds(adParent, event.adBreak)\n })\n )\n add(\n adController.on('adEntered', (event) => {\n const adParent = this.adParent\n if (!adParent) {\n logDebug(this, 'ad entered, no parent track')\n return\n }\n const interrupted = () =>\n this.adParent !== adParent ||\n adController.currentAd !== event.ad\n if (event.ad.uri) {\n // Infer the track load options from the ad.\n adTrackLoadOptionsProvider(event.ad)\n .then((adTrack) => {\n if (!interrupted()) {\n // set adTrack\n this.setCurrentTrack(\n this.getOrCreateAdTrack(\n adParent.uri,\n adTrack\n ),\n {\n isAd: true,\n checkPreroll: false,\n config: {},\n }\n )\n playbackController.play().catch(noop)\n }\n })\n .catch((error) => {\n if (!interrupted()) adController.failAd(error)\n })\n }\n })\n )\n\n add(\n adController.on('adBreakCompleted', (event) => {\n logDebug(this, 'adBreakCompleted')\n const adParent = this.adParent\n if (!adParent) {\n logDebug(this, 'ad break completed, no parent track')\n return\n }\n if (adController.currentAdBreak) {\n logDebug(this, 'more adbreaks')\n return\n }\n if (adParent.active) {\n logDebug(this, 'no ads began')\n return\n }\n const adParentLoad = this._current!\n const placement = event.adBreak.placement\n const isPreroll = placement === 'preroll'\n const isPostroll = placement === 'postroll'\n\n // A completed postroll marks the end of the whole track\n // (content + postroll); preroll/midroll only resume content.\n if (isPostroll) {\n logDebug(this, 'trackEnded after postroll')\n this.dispatch('trackEnded', { track: adParentLoad })\n }\n if (isPostroll && this.hasNext()) {\n this.next()\n } else {\n // Overrides the config startTime to resume from the correct position.\n const startTime = isPreroll\n ? adParentLoad.config?.startTime\n : event.resumePosition\n // Resume the main track.\n this.setCurrentTrack(adParent, {\n config: {\n ...adParentLoad.config,\n startTime,\n },\n isAd: false,\n checkPreroll: false,\n })\n if (isPostroll) {\n logInfo(this, 'queueEnded after postroll ad(s)')\n this.dispatch('queueEnded', {})\n } else {\n playbackController.play().catch(noop)\n }\n }\n })\n )\n }\n\n /**\n * The current track has ended naturally. On the next tick advance the queue or emit queue ended.\n */\n private onEnded = () => {\n const { adController } = this.deps\n\n // `ended` fires for ad tracks too (they share the media element); an\n // ad's end is the AdController's concern, the queue or content may be resumed on 'adBreakCompleted'\n if (this.currentTrackIsAdTrack) return\n const track = this._current\n if (!track) {\n logWarn(this, 'an ended event was received with no current track')\n return\n }\n const interrupted = this.getQueueInterrupted()\n adController\n .enterPostroll()\n .then((postroll) => {\n if (postroll) {\n // There is a pending postroll, do not advance the queue,\n // a new adEntered event will fire.\n logDebug(this, 'postroll entered')\n } else {\n // The content ended with no postroll: the track is done.\n logDebug(this, 'trackEnded')\n this.dispatch('trackEnded', { track })\n // Adds a microtask delay to allow applications an opportunity to respond to 'ended' and 'trackEnded'\n // events before the queue is advanced.\n queueMicrotask(() => {\n if (interrupted()) return\n if (this.hasNext()) {\n this.next()\n } else {\n logInfo(this, 'queueEnded')\n this.dispatch('queueEnded', {})\n }\n })\n }\n })\n .catch((error) => {\n logError(this, 'enterPostroll failed', error)\n })\n }\n\n /**\n * Returns the currently set configuration.\n */\n get options(): TrackControllerImplOptions {\n return this._options\n }\n\n /**\n * Configures this track queue from the provided partial options.\n *\n * @param options\n */\n configure(options: Maybe<Partial<TrackControllerImplOptions>>) {\n logDebug(this, 'configure', options)\n this._options = {\n ...this._options,\n ...options,\n }\n this.checkCacheCapacity()\n }\n\n /**\n * Checks if the cache capacity needs to be changed.\n */\n private checkCacheCapacity() {\n const capacity =\n this.preloadCapacity + this._options.trackPrefetchCount + 1\n if (capacity !== this.trackCache.capacity) {\n logDebug(this, 'track cache capacity changed:', capacity)\n this.trackCache.capacity = capacity\n }\n }\n\n get queue(): readonly TrackLoadOptionsType[] {\n return this._queue\n }\n\n /**\n * Returns the subset of the queue that should be prefetched.\n * @private\n */\n private getPrefetched(): readonly TrackLoadOptionsType[] {\n const tracks: TrackLoadOptionsType[] = []\n if (this._current) tracks.push(this._current)\n tracks.push(...this._queue.slice(0, this.options.trackPrefetchCount))\n return tracks\n }\n\n isTrackCached(uri: TrackUri): boolean {\n return this.trackCache.has(uri)\n }\n\n getCachedTrack(uri: TrackUri): ReadonlyTrack | null {\n return this.trackCache.get(uri) ?? null\n }\n\n getCachedTracks(): IterableIterator<ReadonlyTrack> {\n return this.trackCache.values()\n }\n\n /**\n * Returns the current preload capacity.\n * This automatically increases when preload is called with more tracks than the current capacity.\n */\n get preloadCapacity(): number {\n return Math.max(\n this._autoPreloadCapacity,\n this._options.preloadCapacity\n )\n }\n\n private validateLoadOptions = (loadOptions: TrackLoadOptionsType) =>\n this.deps.trackFactory.validate(loadOptions)\n\n preload(...loadOptionsList: readonly TrackLoadOptionsType[]): void {\n logDebug(this, `preload ${loadOptionsList.length} items`)\n loadOptionsList.forEach(this.validateLoadOptions)\n this._preload(loadOptionsList)\n }\n\n private _preload(loadOptionsList: readonly TrackLoadOptionsType[]): void {\n const prefetched = this.getPrefetched()\n // Calculate the required preload capacity as the number of tracks requested that are not within the\n // prefetch window. If this value is greater than the current preloadCapacity, increase the cache size.\n const requiredPreloadCapacity = countElements(\n loadOptionsList,\n (loadOptions) => {\n return (\n prefetched.find((element) => {\n return element.uri === loadOptions.uri\n }) == null\n )\n }\n )\n if (this._autoPreloadCapacity < requiredPreloadCapacity) {\n this._autoPreloadCapacity = requiredPreloadCapacity\n this.checkCacheCapacity()\n }\n // Tracks requested to preload will have a priority where the first track in the list (next track) has\n // the highest precedence. (Higher priority values take precedence)\n trackPriority.value += loadOptionsList.length\n let priority = trackPriority.value\n for (const loadOptions of loadOptionsList) {\n const track = this.getOrCreateTrack(loadOptions)\n const prefetchPriority = priority--\n logVerbose(\n this,\n `preloading track ${track.uri} with priority ${prefetchPriority}`\n )\n track.preload(\n {\n prefetchPriority,\n },\n loadOptions.config ?? {}\n )\n this.preloadPrerollAds(track, prefetchPriority)\n }\n }\n\n private preloadPrerollAds(\n parentTrack: ReadonlyTrack,\n parentTrackPriority: number\n ): void {\n parentTrack\n .getAds()\n .then(async (trackAds) => {\n for (const [index, adBreak] of trackAds.adBreaks.entries()) {\n if (adBreak.placement !== 'preroll') continue\n const ads = await resolveValueProvider(adBreak.ads)\n for (const ad of ads) {\n await this.preloadAd({\n parentTrack,\n // A prefetch priority fractionally higher than the\n // parent track (so a preroll is warmed before its\n // content), later breaks slightly higher than earlier.\n prefetchPriority:\n parentTrackPriority + (index + 1) / 1000,\n ad,\n })\n }\n }\n })\n .catch((error) => {\n // Preloading prerolls is best-effort: an ad-discovery, ad-list,\n // or ad-options failure must not surface as an unhandled\n // rejection (it just means the preroll isn't warmed up).\n logVerbose(\n this,\n `preroll ad preload failed for ${parentTrack.uri}`,\n error\n )\n })\n }\n\n /**\n * Warms the ad tracks for an approaching midroll/postroll break (driven by\n * the ad controller's `adPreload`). Best-effort: an ad-list or ad-options\n * failure is logged, not thrown. The break is imminent, so its ad tracks\n * get a prefetch priority above the current content prefetch window.\n */\n private preloadBreakAds(\n parentTrack: ReadonlyTrack,\n adBreak: AdBreakInfo\n ): void {\n trackPriority.value += 1\n const prefetchPriority = trackPriority.value\n resolveValueProvider(adBreak.ads)\n .then(async (ads) => {\n for (const ad of ads) {\n await this.preloadAd({ parentTrack, prefetchPriority, ad })\n }\n })\n .catch((error) => {\n logVerbose(\n this,\n `ad preload failed for break ${adBreak.id}`,\n error\n )\n })\n }\n\n /** Preloads an ad for a parent track. Aborts if the parent track is disposed before the ad load options resolve. **/\n private async preloadAd({\n parentTrack,\n prefetchPriority,\n ad,\n }: {\n readonly parentTrack: ReadonlyTrack\n readonly prefetchPriority: number\n readonly ad: AdInfo\n }) {\n const { adTrackLoadOptionsProvider } = this.deps\n const loadOptions = await adTrackLoadOptionsProvider(ad)\n if (parentTrack.disposed) return\n logVerbose(\n this,\n `preloading ad id=${ad.id} uri=${ad.uri} priority=${prefetchPriority}`\n )\n const adTrack = this.getOrCreateAdTrack(parentTrack.uri, loadOptions)\n adTrack.preload(\n {\n prefetchPriority,\n },\n loadOptions.config ?? {}\n )\n }\n\n load(...loadOptionsList: readonly TrackLoadOptionsType[]): void {\n logDebug(this, `load ${loadOptionsList.length} items`)\n loadOptionsList.forEach(this.validateLoadOptions)\n this.setQueue(loadOptionsList[0], loadOptionsList.slice(1))\n }\n\n unload() {\n this.load()\n }\n\n enqueue(...loadOptionsList: readonly TrackLoadOptionsType[]): void {\n logDebug(this, `enqueue ${loadOptionsList.length} items`)\n loadOptionsList.forEach(this.validateLoadOptions)\n this.setQueue(this._current, this._queue.concat(loadOptionsList))\n if (this._currentTrack == null && this.hasNext()) this.next()\n }\n\n hasNext(): boolean {\n return this._queue.length > 0\n }\n\n next(): void {\n const playbackController = this.deps.playbackController\n const shouldPlay =\n playbackController.ended || !playbackController.paused\n const next = first(this._queue)\n logDebug(this, 'next, nextTrack:', next)\n this.setQueue(next, this._queue.slice(1), { shouldPlay })\n }\n\n clearTrackCache() {\n logDebug(this, 'clearTrackCache')\n this.trackCache.forEach((track) => {\n this.disposeAdTracksFor(track.uri)\n track.dispose()\n })\n this.trackCache.clear()\n this._autoPreloadCapacity = 0\n this.checkCacheCapacity()\n this.setQueue(null, [])\n }\n\n clearPrefetch(): void {\n for (const cachedTrack of this.trackCache.values()) {\n cachedTrack.clearPrefetch()\n }\n }\n\n clearQueue(): void {\n // Clears the upcoming queue without unloading the current track.\n this.setQueue(this._current, [])\n }\n\n /**\n * If the given track id is the current track or in the cache, returns that track.\n * Otherwise, constructs a new track, adds it to the cache, and returns it.\n *\n * @param loadOptions\n * @private\n */\n private getOrCreateTrack(loadOptions: TrackLoadOptionsType): Track {\n return getOrSet(this.trackCache, loadOptions.uri, () =>\n this.deps.trackFactory.createTrack(loadOptions)\n )\n }\n\n /**\n * Gets the cached ad track, or creates a new one and sets it in the\n * parent track mapping.\n * When the parent track is disposed, this ad track will be as well.\n *\n * @param parentUri The URI of the parent track.\n * @param loadOptions\n * @private\n */\n private getOrCreateAdTrack(\n parentUri: TrackUri,\n loadOptions: TrackLoadOptionsType\n ): Track {\n const parentTracks = getOrSet(\n this.adTracksByParent,\n parentUri,\n () => new Map()\n )\n return getOrSet(parentTracks, loadOptions.uri, () =>\n this.deps.trackFactory.createTrack(loadOptions)\n )\n }\n\n /**\n * Sets the current track and following queue.\n *\n * If the given track is already current, it will be de-activated and re-activated and the\n * trackDeactivated/trackActivated events will still be emitted. The same track may be in the\n * queue multiple times.\n */\n private setQueue(\n current: Maybe<TrackLoadOptionsType>,\n queue: readonly TrackLoadOptionsType[],\n options?: {\n /**\n * If true, starts playback after the track has changed.\n */\n readonly shouldPlay?: boolean\n }\n ): void {\n const { playbackController } = this.deps\n ++this.queueIdx\n const interrupted = this.getQueueInterrupted()\n const previousQueue = this._queue\n const previous = this._current\n\n if (previous !== current) {\n // Update the pointers before materializing the track, so eviction\n // protects the incoming track and its window, not the outgoing one.\n this._current = current ?? null\n this._queue = queue\n\n this.setCurrentTrack(\n current ? this.getOrCreateTrack(current) : null,\n {\n isAd: false,\n checkPreroll: true,\n config: current?.config,\n }\n )\n if (options?.shouldPlay) {\n // playback controller defers play until the new track is loaded\n playbackController.play().catch(noop)\n }\n } else {\n // Current track unchanged but the queue may have (e.g. enqueue).\n // Keep it in sync so hasNext()/next() work.\n this._queue = queue\n }\n this._preload(this.getPrefetched())\n logDebug(\n this,\n `track change, previous: ${previous?.uri} current: ${current?.uri}`\n )\n if (previousQueue !== queue) {\n this.dispatch('queueChange', {\n previous: previousQueue,\n current: queue,\n })\n }\n if (interrupted()) {\n throw new IllegalStateError(\n `cannot change the queue on a 'queueChange' or 'trackDeactivated' event`\n )\n }\n }\n\n private get currentTrackIsAdTrack(): boolean {\n return this._currentTrack !== this.adParent\n }\n\n /**\n * Sets the active track.\n * This may either be a content track created from `setQueue` or an ad track created from `adEntered`.\n *\n * @param newTrack\n * @param options\n * @private\n */\n private setCurrentTrack(\n newTrack: Track | null,\n options: {\n config?: Maybe<TrackConfigOptions>\n isAd: boolean\n checkPreroll: boolean\n }\n ): void {\n const { adController } = this.deps\n const previousTrack = this._currentTrack\n const previousWasActive = previousTrack?.active ?? false\n this._currentTrack = newTrack\n const interrupted = () => this._currentTrack !== newTrack\n previousTrack?.deactivate()\n if (previousTrack && previousWasActive) {\n this.dispatch('trackDeactivated', { track: previousTrack })\n }\n\n // Forward the active track's errors to the ad controller. When an ad\n // track errors (fails to load or errors mid-playback), this fails the\n // ad so the break advances rather than stalling on the broken ad; on a\n // content track failAd is a no-op (the error still surfaces as a player\n // error). Re-subscribed per track and torn down on the next change.\n this.currentTrackSub?.()\n this.currentTrackSub =\n newTrack?.on('error', (event) =>\n adController.failAd(event.error)\n ) ?? null\n\n if (!options.isAd) {\n this.adParent = newTrack\n adController.setAdsProvider(newTrack)\n }\n if (newTrack) {\n const activate = () => {\n if (interrupted()) return\n newTrack.activate(options.config ?? {})\n this.dispatch('trackActivated', { track: newTrack })\n }\n if (options.isAd || !options.checkPreroll) {\n activate() // Ads cannot have prerolls.\n } else {\n adController\n .enterPreroll()\n .then((preroll) => {\n if (preroll) return // preroll entered\n activate()\n })\n .catch((error) => {\n logError(this, 'enterPreroll failed', error)\n activate()\n })\n }\n }\n }\n\n /**\n * Disposes all preloaded ad tracks belonging to the given parent content\n * URI and drops the parent's entry from the ad map.\n */\n private disposeAdTracksFor(parentUri: TrackUri): void {\n const adTracks = this.adTracksByParent.get(parentUri)\n if (!adTracks) return\n this.adTracksByParent.delete(parentUri)\n for (const track of adTracks.values()) track.dispose()\n }\n\n /**\n * Returns a callback that returns true if the queue has changed or the controller disposed.\n */\n private getQueueInterrupted(): () => boolean {\n const idx = this.queueIdx\n return () => this.disposed || this.queueIdx !== idx\n }\n\n get activeTrack(): ReadonlyTrack | null {\n return this._currentTrack?.active ? this._currentTrack : null\n }\n\n reset(hard = false) {\n this._currentTrack?.reset(hard)\n }\n\n get disposed(): boolean {\n return this.disposer.disposed\n }\n\n dispose() {\n logDebug(this, 'dispose')\n super.dispose()\n this.clearTrackCache()\n this.disposer.dispose()\n }\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { CapabilitiesImplDeps } from '../client/CapabilitiesImpl'\nimport { CapabilitiesImpl } from '../client/CapabilitiesImpl'\nimport type { Merge, PartialDeep, PatchedRef } from '@amazon/vinyl-util'\nimport { mergeDeep, noop } from '@amazon/vinyl-util'\nimport { patchMediaElement } from '../patch/media/patchMediaElement'\nimport type {\n PlaybackControllerImplDeps,\n PlaybackControllerImplOptions,\n} from '../playback/PlaybackControllerImpl'\nimport { PlaybackControllerImpl } from '../playback/PlaybackControllerImpl'\nimport type { PlaybackSourceImplDeps } from '../playback/PlaybackSourceImpl'\nimport { PlaybackSourceImpl } from '../playback/PlaybackSourceImpl'\nimport {\n createVinylTrackFactories,\n type VinylTrackFactoryDeps,\n} from '../track/createVinylTrackFactories'\nimport type {\n TrackControllerImplDeps,\n TrackControllerImplOptions,\n} from '../track/TrackController'\nimport { TrackControllerImpl } from '../track/TrackController'\nimport { createTrackFactory } from '../track/TrackFactory'\nimport type { VinylDeps } from './VinylDeps'\nimport type { VinylPatchOptions } from './VinylPatchOptions'\nimport { defaultPatchOptions } from './VinylPatchOptions'\nimport { type QualitySelectorImplOptions } from '../streaming/abr/QualitySelectorImpl'\nimport {\n AdControllerImpl,\n type AdControllerImplDeps,\n type AdControllerImplOptions,\n} from '../ad/AdControllerImpl'\nimport { createDashFactories } from '../track/dash/createDashFactories'\nimport { createHlsFactories } from '../track/hls/createHlsFactories'\nimport { type DrmOptions } from '../drm/DrmOptions'\nimport { commonEmeFactory } from '../drm/commonEme/CommonEmeFactory'\nimport {\n DrmControllerImpl,\n type DrmControllerImplDeps,\n} from '../drm/DrmControllerImpl'\nimport { defaultDrmKeySystemResolver } from '../drm/DrmKeySystemResolver'\nimport { LoudnessNormalizationControllerImpl } from '../playback/loudness/LoudnessNormalizationControllerImpl'\nimport {\n AutoResetControllerImpl,\n type AutoResetControllerImplDeps,\n type AutoResetControllerImplOptions,\n} from '../track/AutoResetController'\nimport type { Dependencies, Factories } from '@amazon/vinyl-di'\nimport { validateFactories } from '@amazon/vinyl-di'\nimport type { ContentStreamingOptions } from '../streaming/ContentStreamingOptions'\nimport {\n defaultVinylOptions,\n type VinylOptions,\n vinylOptionsValidator,\n} from './VinylOptions'\nimport { playerConfigFactory } from './playerConfigFactory'\nimport type { ObservableValue } from '@amazon/vinyl-observable'\nimport { defaultAdLoadOptionsResolver } from '../ad/defaultAdLoadOptionsResolver'\n\n/**\n * Configuration used by the default dependency factories for Vinyl.\n *\n * These options are used during player construction, changes after construction will have no\n * effect.\n */\nexport interface VinylDependencyOptions {\n /**\n * The media element.\n */\n readonly media: HTMLMediaElement\n\n /**\n * Flags for patches that should be applied browser-specifically.\n * These will be defaulted based on the user-agent.\n */\n readonly patches?: PartialDeep<VinylPatchOptions>\n\n /**\n * Configuration for the track controller.\n */\n readonly trackController?: Partial<TrackControllerImplOptions>\n\n /**\n * Configuration for the playback controller.\n */\n readonly playbackController?: Partial<PlaybackControllerImplOptions>\n\n /**\n * Configuration for segmented streaming tracks (hls / dash).\n */\n readonly streaming?: PartialDeep<ContentStreamingOptions>\n\n /**\n * Configuration for all drm-related components.\n */\n readonly drm?: Partial<DrmOptions>\n\n /**\n * Configuration for adaptive bitrate switching.\n */\n readonly abr?: PartialDeep<QualitySelectorImplOptions>\n\n /**\n * Configuration for auto-reset behavior.\n */\n readonly autoReset?: Partial<AutoResetControllerImplOptions>\n\n /**\n * Configuration for the ad controller.\n */\n readonly adController?: Partial<AdControllerImplOptions>\n}\n\n/**\n * Creates the dependency factories for a standard player.\n *\n * @param options\n */\nexport function createVinylFactories(options: VinylDependencyOptions) {\n const patches = mergeDeep([\n defaultPatchOptions.value,\n options.patches ?? {},\n ])\n return validateFactories({\n options: playerConfigFactory<VinylOptions>(\n defaultVinylOptions,\n vinylOptionsValidator\n ),\n patchedMedia: (): PatchedRef<HTMLMediaElement> => {\n // Patches the media element if necessary.\n return patchMediaElement(options.media, patches.media)\n },\n media: (deps: {\n readonly patchedMedia: {\n readonly patched: HTMLMediaElement\n }\n }): HTMLMediaElement => deps.patchedMedia.patched,\n playbackController: (deps: PlaybackControllerImplDeps) =>\n new PlaybackControllerImpl(deps, options.playbackController),\n playbackSource: (deps: PlaybackSourceImplDeps) =>\n new PlaybackSourceImpl(deps),\n loudnessNormalizationController: (deps: {\n options: ObservableValue<\n Pick<VinylOptions, 'loudnessNormalization'>\n >\n }) =>\n new LoudnessNormalizationControllerImpl({\n options: deps.options.pick('loudnessNormalization'),\n }),\n capabilities: (deps: CapabilitiesImplDeps) =>\n new CapabilitiesImpl(deps),\n requestInterceptor: () => noop,\n trackFactory: (deps: VinylTrackFactoryDeps) =>\n createTrackFactory(createVinylTrackFactories(deps)),\n adTrackLoadOptionsProvider: () => defaultAdLoadOptionsResolver,\n trackController: (deps: TrackControllerImplDeps<any>) =>\n new TrackControllerImpl<any>(deps, options.trackController),\n drmKeySystemResolver: () => defaultDrmKeySystemResolver,\n drmController: (deps: DrmControllerImplDeps) =>\n new DrmControllerImpl(deps, options.drm),\n commonEme: commonEmeFactory,\n autoResetController: (deps: AutoResetControllerImplDeps) =>\n new AutoResetControllerImpl(deps, options.autoReset),\n adController: (deps: AdControllerImplDeps) =>\n new AdControllerImpl(deps, options.adController),\n createDashFactories: createDashFactories(options),\n createHlsFactories: createHlsFactories(options),\n } as const) satisfies Factories<VinylDeps>\n}\n\n/**\n * The dependency map type of the default player dependency factories.\n */\nexport type DefaultVinylFactories = ReturnType<typeof createVinylFactories>\n\n/**\n * Provides the dependency type for a dependency with merged overrides.\n */\nexport type InferVinylOverrideDependencyType<\n Overrides,\n K extends keyof DefaultVinylFactories,\n> = Dependencies<\n Overrides extends Factories\n ? Merge<DefaultVinylFactories, Overrides>\n : DefaultVinylFactories\n>[K]\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { MediaElementPatchOptions } from '../patch/media/MediaElementPatchOptions'\nimport { defaultMediaElementPatchOptions } from '../patch/media/MediaElementPatchOptions'\nimport { lazy } from '@amazon/vinyl-util'\n\n/**\n * Flags for applying patches.\n * Default flags will be applied based on user agent, but may be overridden during player creation.\n */\nexport interface VinylPatchOptions {\n readonly media: MediaElementPatchOptions\n}\n\nexport const defaultPatchOptions = /* @__PURE__ */ lazy<VinylPatchOptions>(() => {\n return {\n media: defaultMediaElementPatchOptions.value,\n } as const satisfies VinylPatchOptions\n})\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {\n defaultQualitySelectorImplOptions,\n type QualitySelectorImplOptions,\n qualitySelectorImplOptionsValidator,\n} from '../streaming/abr/QualitySelectorImpl'\nimport type { ObjectSchema } from '@amazon/vinyl-validation'\nimport {\n array,\n boolean,\n isOneOf,\n object,\n record,\n string,\n} from '@amazon/vinyl-validation'\nimport type { CodecOverrides } from '../util/media/codecOverrides'\nimport {\n RESTRICTABLE_CONTENT_TYPES,\n type RestrictableContentType,\n} from '../streaming/MediaQualityMetadata'\nimport {\n defaultLoudnessNormalizationControllerImplOptions,\n type LoudnessNormalizationControllerImplOptions,\n loudnessNormalizationControllerImplOptionsValidator,\n} from '../playback/loudness/LoudnessNormalizationControllerImplOptions'\nimport { type VttCueStyle, vttCueStyleValidator } from '../text/VttCueStyle'\n\nexport interface VinylOptions {\n /**\n * Configuration for the default adaptive bitrate selector.\n */\n readonly abr: QualitySelectorImplOptions\n\n readonly loudnessNormalization: LoudnessNormalizationControllerImplOptions\n\n /**\n * Preferred language(s) for audio content, as RFC 5646 codes (e.g. `'en'`,\n * `'ja'`, `'fr-CA'`). May be a single tag or an ordered list of tags \u2014\n * earlier entries are preferred, with the best relatedness match kept for\n * each period (audio without a language tag is always kept). `null` (the\n * default) is NOT \"no preference\": it orders by the platform's\n * `navigator.languages`. To keep every language, this option is not the\n * mechanism \u2014 omit language content or pass a tag matching all.\n */\n readonly preferredAudioLanguage: string | readonly string[] | null\n\n /**\n * Preferred language(s) for text tracks (subtitles / closed captions), as\n * RFC 5646 codes (e.g. `'en'`, `'ja'`, `'fr-CA'`). May be a single tag or\n * an ordered list of tags \u2014 earlier entries are preferred, with the best\n * relatedness match chosen among the discovered text tracks. When set, the\n * matching text track is selected automatically and the choice carries\n * across track changes (e.g. across an ad break), mirroring how\n * {@link preferredAudioLanguage} drives audio selection.\n *\n * Unlike audio, `null` (the default) means *no caption preference*: it does\n * NOT fall back to `navigator.languages` and does NOT force captions on \u2014\n * forced narrative subtitles still auto-display as usual. Setting it to a\n * language turns captions on in that language; setting it back to `null`\n * after a prior selection turns captions off.\n */\n readonly preferredTextLanguage: string | readonly string[] | null\n\n /**\n * Opt in to audio-description (a.k.a. described-video / DVS) audio: audio\n * renditions carrying an accessibility \"describes video\" characteristic that\n * narrate on-screen action. `false` (the default) keeps them out of the\n * automatic default-audio selection \u2014 they are chosen only when this is set.\n * When `true`, a description rendition is preferred where one exists for the\n * selected language. Changing this reselects audio immediately.\n */\n readonly preferDescriptiveAudio: boolean\n\n /**\n * Explicit codec allow/deny overrides that bypass browser support\n * detection. Keys are RFC 6381 codec strings or prefixes (e.g. `\"hvc1\"`),\n * values are `'allow'` or `'deny'`. An `'allow'` forces a codec to be\n * treated as supported; a `'deny'` forces it to be treated as unsupported.\n * Empty by default (support is determined solely by the browser and the\n * known-false-report list).\n */\n readonly codecOverrides: CodecOverrides\n\n /**\n * Allow list restricting which media content types (`'audio'`, `'video'`)\n * are streamed. When set, only streams whose content type is in the list\n * are created; all other media streams are ignored. For example,\n * `['audio']` streams audio but never video. Changing this reloads the\n * track using only the allowed content types. Null (the default) means no\n * restriction (all available media content types are streamed).\n *\n * Text tracks (subtitles / closed captions) are not affected by this allow\n * list; they are governed by caption selection and always remain\n * available.\n */\n readonly allowedContentTypes: readonly RestrictableContentType[] | null\n\n /**\n * Layout style applied to rendered WebVTT cues (the settable `VTTCue`\n * positioning properties: size, line, position, align, etc.). Applied to\n * each cue as it is added, on platforms that support `VTTCue`.\n *\n * Defaults to `{ size: 90 }`, insetting the cue box from the full video\n * width so long lines don't clip at the screen edges in fullscreen (which\n * `::cue` CSS cannot fix). Set to `null` to keep the browser defaults.\n */\n readonly textCueStyle: VttCueStyle | null\n}\n\nexport const defaultVinylOptions: VinylOptions = {\n abr: defaultQualitySelectorImplOptions,\n loudnessNormalization: defaultLoudnessNormalizationControllerImplOptions,\n preferredAudioLanguage: null,\n preferredTextLanguage: null,\n preferDescriptiveAudio: false,\n codecOverrides: {},\n allowedContentTypes: null,\n textCueStyle: { size: 90 },\n}\n\nexport const vinylOptionsValidator: ObjectSchema<VinylOptions> = /* @__PURE__ */ object({\n abr: qualitySelectorImplOptionsValidator,\n loudnessNormalization: loudnessNormalizationControllerImplOptionsValidator,\n preferredAudioLanguage: /* @__PURE__ */ /* @__PURE__ */ /* @__PURE__ */ string().or(/* @__PURE__ */ /* @__PURE__ */ array(/* @__PURE__ */ string()).readonly()).orNull(),\n preferredTextLanguage: /* @__PURE__ */ /* @__PURE__ */ /* @__PURE__ */ string().or(/* @__PURE__ */ /* @__PURE__ */ array(/* @__PURE__ */ string()).readonly()).orNull(),\n preferDescriptiveAudio: /* @__PURE__ */ boolean(),\n codecOverrides: /* @__PURE__ */ record(/* @__PURE__ */ string(), /* @__PURE__ */ isOneOf('allow', 'deny')),\n allowedContentTypes: /* @__PURE__ */ /* @__PURE__ */ /* @__PURE__ */ /* @__PURE__ */ array(/* @__PURE__ */ isOneOf(...RESTRICTABLE_CONTENT_TYPES))\n .cast<readonly RestrictableContentType[]>()\n .describe(\n 'Allow list of media content types (audio, video) to stream; other media streams are ignored. Text tracks are unaffected.'\n )\n .orNull(),\n textCueStyle: /* @__PURE__ */ vttCueStyleValidator.orNull(),\n})\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { data, type MutableValue } from '@amazon/vinyl-observable'\nimport type { AddDisposable, AnyRecord } from '@amazon/vinyl-util'\nimport type { Validator } from '@amazon/vinyl-validation'\n\nexport function playerConfigFactory<T>(\n defaults: T,\n validator: Validator<T>\n): (_deps: AnyRecord, add: AddDisposable) => MutableValue<T> {\n return (_deps, add) => {\n const config = data<T>(defaults)\n add(\n config.onData((data) => {\n // Throws if data does not pass validation\n validator.assert(data)\n })\n )\n return config\n }\n}\n", "/*\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { Client } from '../client/Client'\nimport {\n type AnyRecord,\n createDisposer,\n type Disposable,\n emptyRanges,\n equalDeep,\n EventHostImpl,\n logDebug,\n logInfo,\n logWarn,\n type ReadonlyRanges,\n type ReadonlySet,\n redispatchEvents,\n type Unsubscribe,\n} from '@amazon/vinyl-util'\nimport {\n createContainer,\n type Factories,\n type ValidFactoryOverrides,\n} from '@amazon/vinyl-di'\nimport { playerRegistryRef } from '../global/PlayerRegistry'\nimport type { PlaybackController } from '../playback/PlaybackController'\nimport {\n ALL_PLAYBACK_STATE_EVENTS,\n type PlaybackControllerEventMap,\n type PlaybackNetworkState,\n type PlaybackReadyState,\n} from '../playback/ReadonlyPlaybackController'\nimport type { VinylTrackLoadOptions } from '../track/createVinylTrackFactories'\nimport { type ReadonlyTrack, type TrackUri } from '../track/Track'\nimport type { SeekRange } from '../track/SeekRange'\nimport {\n ALL_TRACK_CONTROLLER_EVENTS,\n type TrackController,\n type TrackControllerEventMap,\n} from '../track/TrackController'\nimport type {\n InferLoadOptionsFromFactory,\n TrackLoadOptions,\n} from '../track/TrackFactory'\nimport type {\n DefaultVinylFactories,\n InferVinylOverrideDependencyType,\n VinylDependencyOptions,\n} from './createVinylFactories'\nimport { createVinylFactories } from './createVinylFactories'\nimport type { VinylDeps } from './VinylDeps'\nimport type { Capabilities } from '../client/Capabilities'\nimport { initializeVinylGlobal } from '../global/initializeVinylGlobal'\nimport {\n ALL_CONTENT_TYPES,\n type ContentType,\n type MediaQualityMetadata,\n} from '../streaming/MediaQualityMetadata'\nimport type { ReadonlyPlaybackStreamingState } from './ReadonlyPlaybackStreamingState'\nimport type { DrmController } from '../drm/DrmController'\nimport {\n ALL_STREAMING_EVENTS,\n type StreamingEventMap,\n} from '../streaming/StreamingEventMap'\nimport type { LoadMetricEventMap } from '../streaming/LoadMetric'\nimport type { InferObservableValueType } from '@amazon/vinyl-observable'\nimport type { VinylOptions } from './VinylOptions'\nimport type { AutoResetController } from '../track/AutoResetController'\nimport type { ChangeEvent } from '../event/ChangeEvent'\nimport {\n ALL_TEXT_TRACK_EVENTS,\n type TextTrackController,\n type TextTrackEventMap,\n type TextTrackInfo,\n} from '../text/TextTrack'\nimport { type AdEventMap, ALL_AD_EVENTS } from '../ad/AdController'\nimport type { AdBreakInfo, AdInfo, TrackAds } from '../ad/AdBreakInfo'\n\n/**\n * Events the Vinyl Player emits.\n */\nexport interface VinylPlayerEventMap<\n TrackLoadOptionsType extends TrackLoadOptions = VinylTrackLoadOptions,\n>\n extends\n PlaybackControllerEventMap,\n TrackControllerEventMap<TrackLoadOptionsType>,\n StreamingEventMap,\n TextTrackEventMap,\n AdEventMap,\n LoadMetricEventMap {\n /**\n * Dispatched when {@link VinylPlayer.resetPending} changes.\n *\n * `current` is true when the player has hit a transient, potentially\n * recoverable error (e.g. a network outage) and an automatic reset\n * attempt is scheduled. `current` is false once the pending reset is\n * emitted, the error is cleared, or all retries are exhausted.\n *\n * If `resetPending` becomes false while {@link VinylPlayer.error} is\n * still non-null, all automatic reset attempts have been exhausted\n * and playback will not recover without user action.\n */\n readonly resetPendingChange: ChangeEvent<boolean>\n}\n\n/**\n * A Vinyl Media Player.\n *\n * Unless custom dependencies need to be provided, use {@link createVinylPlayer} to construct\n * a new player implementation.\n */\nexport class VinylPlayer<\n TrackLoadOptionsType extends TrackLoadOptions = VinylTrackLoadOptions,\n OptionsType = VinylOptions,\n>\n extends EventHostImpl<VinylPlayerEventMap<TrackLoadOptionsType>>\n implements\n PlaybackController,\n TrackController<TrackLoadOptionsType>,\n ReadonlyPlaybackStreamingState,\n Disposable\n{\n get [Symbol.toStringTag](): string {\n return 'VinylPlayer'\n }\n\n protected readonly deps: VinylDeps<TrackLoadOptionsType, OptionsType>\n\n private get drmController(): DrmController {\n return this.deps.drmController\n }\n\n private get playbackController(): PlaybackController {\n return this.deps.playbackController\n }\n\n private get trackController(): TrackController<TrackLoadOptionsType> {\n return this.deps.trackController\n }\n\n private get autoResetController(): AutoResetController {\n return this.deps.autoResetController\n }\n\n /**\n * Provides information about the client, such as device and browser capabilities.\n */\n readonly client: Client\n\n private _error: Error | null = null\n\n protected readonly disposer = /* @__PURE__ */ createDisposer()\n\n /**\n * Constructs a new VinylPlayer with the given dependency factories.\n * This constructor is protected, use {@link createVinylPlayer} to construct a new player.\n *\n * @param factories\n * @see createVinylPlayer\n */\n protected constructor(\n factories: Factories<VinylDeps<TrackLoadOptionsType, OptionsType>>\n ) {\n initializeVinylGlobal()\n super()\n const add = this.disposer.add\n this.deps = add(createContainer(factories)).dependencies\n\n this.client = {\n capabilities: this.deps.capabilities,\n }\n playerRegistryRef.value.addPlayer(this)\n this.redispatchSubControllerEvents()\n this.redispatchCurrentTrackEvents()\n this.initializeAutoResetHandling()\n }\n\n protected redispatchSubControllerEvents(): void {\n const add = this.disposer.add\n add(\n redispatchEvents(\n this,\n this.playbackController,\n ALL_PLAYBACK_STATE_EVENTS.filter(notResetEvent)\n )\n )\n add(\n redispatchEvents(\n this,\n this.trackController,\n ALL_TRACK_CONTROLLER_EVENTS\n )\n )\n add(redispatchEvents(this, this.drmController, ['error']))\n // The shared DRM controller serves multiple tracks (active + preloaded),\n // so it stamps each license span with the initiating track at the source\n // (via its key session). Republish using that carried uri; drop spans\n // whose track is unknown rather than misattribute them to whatever track\n // happens to be current when the exchange resolves.\n add(\n this.drmController.on('loadSpanMeasured', (measurement) => {\n const trackUri = measurement.trackUri\n if (trackUri != null) {\n this.dispatch('loadSpan', { ...measurement, trackUri })\n }\n })\n )\n add(redispatchEvents(this, this.deps.adController, ALL_AD_EVENTS))\n\n this.on('error', (event) => {\n this._error = event.error\n })\n\n // A codec decode/append failure poisons the media pipeline; the track\n // must be rebuilt (not merely reset) to recover. The failing codec has\n // already been denylisted, so the reload selects a codec that decodes.\n add(\n this.on('codecUnsupported', (event) => {\n // While an ad is playing, the ad track owns the media pipeline;\n // do not rebuild the content track out from under it.\n if (this.deps.adController.currentAdBreak) return\n logWarn(\n this,\n 'codec unsupported, reloading track:',\n event.mimeType\n )\n this.trackController.reset(/* hard */ true)\n })\n )\n }\n\n /**\n * Certain track events are redispatched on the player for the current track.\n */\n protected redispatchCurrentTrackEvents() {\n let sub: Unsubscribe | null = null\n let textSub: Unsubscribe | null = null\n let metricSub: Unsubscribe | null = null\n // Track currently redispatched, driven by trackActivated/Deactivated.\n let activeTrack: ReadonlyTrack | null = null\n const add = this.disposer.add\n\n // Re-wires redispatch previous\u2192current and emits the state changes\n // (text, seek range, qualities).\n const transition = (current: ReadonlyTrack | null) => {\n const previous = activeTrack\n if (previous === current) return\n activeTrack = current\n\n // Clear the previous track's caption selection (it may stay cached),\n // before tearing down subs so activeTextTrackChange flows through.\n // Skip during an ad break: the content will resume, and its caption\n // selection must survive for resume() (deactivation only suspends\n // it). Tracks expose ReadonlyTrack; the controller is a full one.\n const prevTextController =\n previous?.textTrackController as TextTrackController | null\n if (!this.deps.adController.currentAdBreak) {\n prevTextController?.setActiveTextTrack(null)\n }\n sub?.()\n sub = null\n textSub?.()\n textSub = null\n metricSub?.()\n metricSub = null\n if (current) {\n sub = redispatchEvents(\n this,\n current,\n ALL_STREAMING_EVENTS.filter(notResetEvent).filter(\n notLoadSpanMeasuredEvent\n )\n )\n metricSub = current.on('loadSpanMeasured', (measurement) =>\n this.dispatch('loadSpan', {\n ...measurement,\n // The track stamps its own uri at the source; fall\n // back to the current track for any span that has\n // not been attributed upstream.\n trackUri: measurement.trackUri ?? current.uri,\n })\n )\n if (current.textTrackController) {\n textSub = redispatchEvents(\n this,\n current.textTrackController,\n ALL_TEXT_TRACK_EVENTS\n )\n }\n }\n this.emitTextTrackChangeEventsFor(previous, current)\n this.dispatch('fetchedRangesChange', {})\n this.dispatch('seekRangeChange', {\n previous: previous?.seekRange ?? null,\n current: current?.seekRange ?? null,\n })\n\n // Emit a quality change event for every stream that has changed\n // for streaming, buffering, and playback\n for (const contentType of ALL_CONTENT_TYPES) {\n for (const [eventType, getterName] of qualityEventsAndGetters) {\n const previousQuality =\n previous?.[getterName](contentType) ?? null\n const currentQuality =\n current?.[getterName](contentType) ?? null\n if (previousQuality !== currentQuality) {\n this.dispatch(eventType, {\n previous: previousQuality,\n current: currentQuality,\n })\n }\n }\n }\n\n // Emit qualities change events on track switch\n const prevQualities = previous?.qualities ?? null\n const curQualities = current?.qualities ?? null\n if (prevQualities !== curQualities && curQualities) {\n this.dispatch('qualitiesChange', {\n previous: prevQualities ?? [],\n current: curQualities,\n })\n }\n const prevUnfiltered = previous?.qualitiesUnfiltered ?? null\n const curUnfiltered = current?.qualitiesUnfiltered ?? null\n if (prevUnfiltered !== curUnfiltered && curUnfiltered) {\n this.dispatch('qualitiesUnfilteredChange', {\n previous: prevUnfiltered ?? [],\n current: curUnfiltered,\n })\n }\n }\n\n add(\n this.trackController.on('trackActivated', ({ track }) =>\n transition(track)\n )\n )\n add(\n this.trackController.on('trackDeactivated', ({ track }) => {\n // Clear to no-active-track only on a real teardown (unload). In\n // an ad-swap the ad's trackActivated drives the transition, so\n // skip to avoid an intermediate clear and preserve captions.\n if (\n track === activeTrack &&\n !this.deps.adController.currentAdBreak\n ) {\n transition(null)\n }\n })\n )\n }\n\n private initializeAutoResetHandling() {\n // Initializes the binding between the player and the reset handler.\n // On an error, notify the auto reset controller which will\n // monitor network changes and periodically request a reset.\n const { add } = this.disposer\n this.on('error', (event) => {\n this.autoResetController.setError(event.error)\n })\n add(this.autoResetController.on('reset', () => this.reset()))\n add(\n this.autoResetController.on('resetPendingChange', (event) =>\n this.dispatch('resetPendingChange', event)\n )\n )\n }\n\n /**\n * Returns the current player options.\n * Use `configure` to set.\n */\n get options(): OptionsType {\n return this.deps.options.value\n }\n\n /**\n * Sets options on this player.\n * Options will be merged shallowly, for example,\n * `configure({ abr: { strategy: AbrStrategy.BEST }})` will replace all previous `abr` options, and not\n * change other options such as `loudnessNormalization`.\n *\n * @param options\n */\n configure(options: Partial<OptionsType>): void {\n logDebug(this, 'configure', options)\n const newValue = { ...this.options, ...options }\n if (!equalDeep(newValue, this.options)) {\n this.deps.options.value = newValue\n }\n }\n\n get capabilities(): Capabilities {\n return this.deps.capabilities\n }\n\n //----------------------------------------------------\n // PlaybackController delegate methods\n //----------------------------------------------------\n\n get buffered(): ReadonlyRanges {\n return this.playbackController.buffered\n }\n\n get canPlay(): boolean {\n return this.playbackController.canPlay\n }\n\n get canPlayThrough(): boolean {\n return this.playbackController.canPlayThrough\n }\n\n get currentTime(): number {\n return this.playbackController.currentTime\n }\n\n get currentTimePercent(): number {\n return this.playbackController.currentTimePercent\n }\n\n get defaultPlaybackRate(): number {\n return this.playbackController.defaultPlaybackRate\n }\n\n set defaultPlaybackRate(value: number) {\n this.playbackController.defaultPlaybackRate = value\n }\n\n get duration(): number {\n return this.playbackController.duration\n }\n\n get ended(): boolean {\n return this.playbackController.ended\n }\n\n /**\n * The last error reported.\n */\n get error(): Error | null {\n return this._error\n }\n\n /**\n * True when an error has interrupted playback and an automatic reset\n * is scheduled. This distinguishes transient, potentially recoverable\n * errors (such as a brief network outage) from terminal errors that\n * will not trigger a reset on their own.\n *\n * Listen to `resetPendingChange` events for changes.\n */\n get resetPending(): boolean {\n return this.autoResetController.resetPending\n }\n\n get hasMetadata(): boolean {\n return this.playbackController.hasMetadata\n }\n\n get loop(): boolean {\n return this.playbackController.loop\n }\n\n set loop(value: boolean) {\n this.playbackController.loop = value\n }\n\n get muted(): boolean {\n return this.playbackController.muted\n }\n\n set muted(value: boolean) {\n this.playbackController.muted = value\n }\n\n get networkState(): PlaybackNetworkState {\n return this.playbackController.networkState\n }\n\n get paused(): boolean {\n return this.playbackController.paused\n }\n\n get playbackRate(): number {\n return this.playbackController.playbackRate\n }\n\n set playbackRate(value: number) {\n this.playbackController.playbackRate = value\n }\n\n get playIsPending(): boolean {\n return this.playbackController.playIsPending\n }\n\n get playing(): boolean {\n return this.playbackController.playing\n }\n\n get preservesPitch(): boolean {\n return this.playbackController.preservesPitch\n }\n\n set preservesPitch(value: boolean) {\n this.playbackController.preservesPitch = value\n }\n\n get readyState(): PlaybackReadyState {\n return this.playbackController.readyState\n }\n\n get seekable(): ReadonlyRanges {\n return this.playbackController.seekable\n }\n\n /**\n * The seekable range on the media timeline for the current track, or null\n * when no track is loaded or the timeline is not yet resolved.\n */\n get seekRange(): SeekRange | null {\n return this.activeTrack?.seekRange ?? null\n }\n\n get seeking(): boolean {\n return this.playbackController.seeking\n }\n\n get volume(): number {\n return this.playbackController.volume\n }\n\n set volume(value: number) {\n this.playbackController.volume = value\n }\n\n get waiting(): boolean {\n return this.playbackController.waiting\n }\n\n pause(): void {\n this.playbackController.pause()\n }\n\n play(): Promise<void> {\n return this.playbackController.play()\n }\n\n seekTo(time: number, tolerance?: number): Promise<void> {\n return this.playbackController.seekTo(time, tolerance)\n }\n\n reset(hard = false) {\n if (!this._error) {\n logDebug(this, 'reset no-op')\n return\n }\n logDebug(this, 'reset')\n this._error = null\n this.drmController.reset()\n this.playbackController.reset()\n this.trackController.reset(hard)\n this.autoResetController.clear()\n this.dispatch('reset', {})\n }\n\n //----------------------------------------------------\n // TrackController delegate methods\n //----------------------------------------------------\n\n get activeTrack(): ReadonlyTrack | null {\n return this.trackController.activeTrack\n }\n\n get queue(): readonly TrackLoadOptionsType[] {\n return this.trackController.queue\n }\n\n preload(...loadOptionsList: TrackLoadOptionsType[]): void {\n this.trackController.preload(...loadOptionsList)\n }\n\n load(...loadOptionsList: TrackLoadOptionsType[]): void {\n this.trackController.load(...loadOptionsList)\n }\n\n enqueue(...loadOptionsList: TrackLoadOptionsType[]): void {\n this.trackController.enqueue(...loadOptionsList)\n }\n\n unload(): void {\n this.trackController.unload()\n }\n\n hasNext(): boolean {\n return this.trackController.hasNext()\n }\n\n next(): void {\n return this.trackController.next()\n }\n\n isTrackCached(uri: TrackUri): boolean {\n return this.trackController.isTrackCached(uri)\n }\n\n getCachedTrack(uri: TrackUri): ReadonlyTrack | null {\n return this.trackController.getCachedTrack(uri)\n }\n\n getCachedTracks(): IterableIterator<ReadonlyTrack> {\n return this.trackController.getCachedTracks()\n }\n\n clearPrefetch(): void {\n this.trackController.clearPrefetch()\n }\n\n clearTrackCache(): void {\n this.trackController.clearTrackCache()\n }\n\n clearQueue(): void {\n this.trackController.clearQueue()\n }\n\n //----------------------------------------------------\n // CurrentTrackStreamingState methods\n //----------------------------------------------------\n\n /**\n * Returns the fetched ranges of the current track.\n * If there is no current track, empty ranges will be returned.\n *\n * Listen to {@link VinylPlayerEventMap.fetchedRangesChange} for changes.\n */\n get fetchedRanges(): ReadonlyRanges {\n return this.activeTrack?.fetchedRanges ?? emptyRanges\n }\n\n /**\n * Returns the time of the prefetch end.\n * If no data has been prefetched for the current track, 0 will be returned.\n *\n * The time given will be in seconds according to the media timeline.\n * It will represent the ending time of the continuous prefetch range from the current playhead time.\n */\n get fetchedTime(): number {\n const time = this.playbackController.currentTime\n const range = this.fetchedRanges.getRangeAt(time)\n if (!range) return 0\n return range[1]\n }\n\n /**\n * Returns current fetched time as a percent of the total duration.\n *\n * @return A number between 0-1\n */\n get fetchedTimePercent(): number {\n return this.duration > 0 ? this.fetchedTime / this.duration : 0\n }\n\n /**\n * Returns the current content types for active streams.\n */\n get contentTypes(): ReadonlySet<ContentType> {\n return this.activeTrack?.contentTypes ?? emptyContentTypes\n }\n\n /**\n * The available qualities for the current period of the current track, after filtering.\n * Null if no track is active or the timeline is not yet available.\n */\n get qualities(): readonly MediaQualityMetadata[] | null {\n return this.activeTrack?.qualities ?? null\n }\n\n /**\n * The available unfiltered qualities for the current period of the current track.\n * Null if no track is active or the timeline is not yet available.\n */\n get qualitiesUnfiltered(): readonly MediaQualityMetadata[] | null {\n return this.activeTrack?.qualitiesUnfiltered ?? null\n }\n\n /**\n * @deprecated Use `getStreamingQuality('audio')`\n */\n get streamingQuality(): MediaQualityMetadata | null {\n return this.getStreamingQuality('audio')\n }\n\n /**\n * @deprecated Use `getBufferingQuality('audio')\n */\n get bufferingQuality(): MediaQualityMetadata | null {\n return this.getStreamingQuality('audio')\n }\n\n /**\n * @deprecated Use `getPlaybackQuality('audio')\n */\n get playbackQuality(): MediaQualityMetadata | null {\n return this.getPlaybackQuality('audio')\n }\n\n /**\n * The streaming quality for the current track.\n * Note that this does not represent the quality of inactive preloading tracks.\n */\n getStreamingQuality(contentType: ContentType): MediaQualityMetadata | null {\n return this.activeTrack?.getStreamingQuality(contentType) ?? null\n }\n\n /**\n * The currently buffering quality, or null if no data is buffered.\n */\n getBufferingQuality(contentType: ContentType): MediaQualityMetadata | null {\n return this.activeTrack?.getBufferingQuality(contentType) ?? null\n }\n\n /**\n * The currently playing quality, or null if no media is playing.\n */\n getPlaybackQuality(contentType: ContentType): MediaQualityMetadata | null {\n return this.activeTrack?.getPlaybackQuality(contentType) ?? null\n }\n\n //----------------------------------------------------\n // Text track delegate methods\n //----------------------------------------------------\n\n /**\n * The list of currently discovered sidecar text tracks for the active\n * media. Empty when there is no current track or the current track\n * carries no text.\n */\n get textTracks(): readonly TextTrackInfo[] {\n return this.activeTrack?.textTrackController?.textTracks ?? []\n }\n\n /**\n * The currently active text track, or null if no track is selected.\n */\n get activeTextTrack(): TextTrackInfo | null {\n return this.activeTrack?.textTrackController?.activeTextTrack ?? null\n }\n\n /**\n * Selects the text track with the given id, or clears the active text\n * track when called with null. No-op when the current track does not\n * surface text tracks or the id is unknown.\n */\n setActiveTextTrack(id: string | null): void {\n // activeTrack exposes ReadonlyTrack, but the concrete controller is a\n // full TextTrackController.\n const controller = this.deps.trackController.activeTrack\n ?.textTrackController as TextTrackController | null\n controller?.setActiveTextTrack(id)\n }\n\n private emitTextTrackChangeEventsFor(\n previous: ReadonlyTrack | null,\n current: ReadonlyTrack | null\n ): void {\n // Bridge signals that lack their own redispatched event at track\n // boundaries. The current track's controller only emits\n // activeTextTrackChange when a selection is *made*; on becoming current\n // it never re-announces an already-active selection. That gap surfaces\n // after an ad break: the content track's caption selection is preserved\n // and re-rendered by resume() (silently), while the outgoing ad\n // controller emits a clearing activeTextTrackChange(null) \u2014 leaving\n // consumers that track state via events believing captions are off even\n // though the (forced or user-selected) content caption is showing. Emit\n // the current track's active selection so that final state is correct.\n const prevList = previous?.textTrackController?.textTracks\n const curList = current?.textTrackController?.textTracks\n if (prevList !== curList) {\n this.dispatch('textTracksChange', {\n previous: prevList ?? [],\n current: curList ?? [],\n })\n }\n const prevActive =\n previous?.textTrackController?.activeTextTrack ?? null\n const curActive = current?.textTrackController?.activeTextTrack ?? null\n if (prevActive?.id !== curActive?.id) {\n this.dispatch('activeTextTrackChange', {\n previous: prevActive,\n current: curActive,\n })\n }\n }\n\n //----------------------------------------------------\n // Ad break delegate methods\n //----------------------------------------------------\n\n /**\n * The current track's ad breaks.\n *\n * Listen to {@link AdEventMap.currentTrackAdsChange} for changes.\n */\n get currentTrackAds(): TrackAds | null {\n return this.deps.adController.currentTrackAds\n }\n\n /**\n * The ad break currently containing the playhead, or null when the\n * playhead is in primary content.\n *\n * Listen to {@link AdEventMap.adBreakEntered} and\n * {@link AdEventMap.adBreakCompleted} for transitions.\n */\n get currentAdBreak(): AdBreakInfo | null {\n return this.deps.adController.currentAdBreak\n }\n\n /**\n * The ad currently playing within the active break, or null when the\n * playhead is in primary content.\n *\n * Listen to {@link AdEventMap.adEntered} and {@link AdEventMap.adCompleted} for transitions.\n */\n get currentAd(): AdInfo | null {\n return this.deps.adController.currentAd\n }\n\n /**\n * Skips the currently playing ad. If there are more ads in the break,\n * the next ad begins; otherwise the break ends and content resumes.\n * No-op when no ad break is active.\n */\n skipAd(): void {\n this.deps.adController.skipAd()\n }\n\n /**\n * Skips the entire active ad break, advancing past all remaining ads\n * and resuming content playback.\n * No-op when no ad break is active.\n */\n skipAdBreak(): void {\n this.deps.adController.skipAdBreak()\n }\n\n //----------------------------------------------------\n\n /**\n * Returns true if this player has been disposed.\n */\n get disposed(): boolean {\n return this.disposer.disposed\n }\n\n /**\n * Disposes this player and sub-systems.\n */\n dispose(): void {\n logDebug(this, 'dispose')\n super.dispose()\n this.disposer.dispose()\n playerRegistryRef.value.removePlayer(this)\n }\n}\n\n/**\n * Constructs a new {@link VinylPlayer}.\n *\n * @param options Configuration for default dependencies.\n * @param factoryOverrides Dependency factory overrides.\n */\nexport function createVinylPlayer<\n DependencyOverridesType extends Factories | undefined,\n>(\n options: VinylDependencyOptions,\n factoryOverrides?: ValidFactoryOverrides<\n VinylDeps<any, AnyRecord>,\n DefaultVinylFactories,\n DependencyOverridesType\n >\n): VinylPlayer<\n // The player will accept the load options for the track factories, accounting for overrides.\n InferLoadOptionsFromFactory<\n InferVinylOverrideDependencyType<\n NoInfer<DependencyOverridesType>,\n 'trackFactory'\n >\n >,\n // Infer the options type.\n InferObservableValueType<\n InferVinylOverrideDependencyType<\n NoInfer<DependencyOverridesType>,\n 'options'\n >\n >\n> {\n const player = new (VinylPlayer as any)({\n ...createVinylFactories(options),\n ...factoryOverrides,\n })\n logInfo(player, `VinylPlayer initialized`)\n return player\n}\n\n/**\n * Do not redispatch reset events, only emit the reset event when `player.reset` is called.\n * @param type\n */\nfunction notResetEvent<T extends string>(type: T): type is Exclude<T, 'reset'> {\n return type !== 'reset'\n}\n\n/**\n * The player republishes `loadSpanMeasured` as the attributed `loadSpan`\n * event rather than redispatching the raw, unattributed measurement.\n * @param type\n */\nfunction notLoadSpanMeasuredEvent<T extends string>(\n type: T\n): type is Exclude<T, 'loadSpanMeasured'> {\n return type !== 'loadSpanMeasured'\n}\n\nconst qualityEventsAndGetters = [\n ['streamingQualityChange', 'getStreamingQuality'],\n ['bufferingQualityChange', 'getBufferingQuality'],\n ['playbackQualityChange', 'getPlaybackQuality'],\n] as const\n\nconst emptyContentTypes = /* @__PURE__ */ new Set<ContentType>()\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA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CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,CAAC,OAAO,IAAI;AAAA,EACZ,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",
6
+ "names": ["import_vinyl_util", "adBreakState", "time", "logTarget", "import_vinyl_util", "import_vinyl_util", "import_vinyl_util", "_a", "CanPlayTypeResult", "import_vinyl_util", "import_vinyl_util", "import_vinyl_util", "import_vinyl_util", "MediaKeySessionErrorType", "import_vinyl_util", "import_vinyl_util", "element", "import_vinyl_util", "import_vinyl_util", "element", "import_vinyl_util", "element", "import_vinyl_util", "import_vinyl_util", "import_vinyl_validation", "import_vinyl_validation", "DrmKeySystem", "import_vinyl_validation", "DrmRobustness", "import_vinyl_util", "element", "import_vinyl_util", "import_vinyl_util", "import_vinyl_util", "contentType", "import_vinyl_util", "import_vinyl_validation", "import_vinyl_util", "import_vinyl_util", "import_vinyl_util", "import_vinyl_util", "import_vinyl_util", "import_vinyl_util", "import_vinyl_util", "import_vinyl_util", "import_vinyl_util", "import_vinyl_util", "import_vinyl_util", "PlayedReason", "WaitedReason", "PlaybackReadyState", "PlaybackNetworkState", "import_vinyl_util", "locale", "import_vinyl_util", "import_vinyl_validation", "import_vinyl_util", "import_vinyl_util", "import_vinyl_util", "import_vinyl_validation", "AbrStrategy", "import_vinyl_util", "import_vinyl_util", "contentType", "onMediaSourceOpen", "import_vinyl_util", "import_vinyl_util", "import_vinyl_util", "contentType", "import_vinyl_util", "contentType", "data", "import_vinyl_util", "contentType", "contentType", "import_vinyl_observable", "import_vinyl_util", "import_vinyl_util", "import_vinyl_util", "locale", "contentType", "array", "import_vinyl_util", "array", "import_vinyl_util", "import_vinyl_util", "import_vinyl_util", "array", "array", "import_vinyl_validation", "import_vinyl_util", "record", "import_vinyl_observable", "import_vinyl_util", "promise", "import_vinyl_util", "import_vinyl_validation", "import_vinyl_util", "time", "period", "import_vinyl_util", "import_vinyl_util", "SegmentStatus", "import_vinyl_util", "contentType", "import_vinyl_util", "time", "element", "contentType", "data", "cachedSegment", "import_vinyl_util", "import_vinyl_util", "import_vinyl_util", "import_vinyl_util", "import_vinyl_util", "import_vinyl_hls_parser", "contentType", "import_vinyl_validation", "import_vinyl_util", "import_vinyl_util", "import_vinyl_mpd_parser", "import_vinyl_util", "import_vinyl_validation", "import_vinyl_util", "import_vinyl_validation", "import_vinyl_util", "import_vinyl_util", "contentType", "import_vinyl_util", "src", "contentType", "import_vinyl_util", "import_vinyl_validation", "loadOptionsValidator", "import_vinyl_util", "import_vinyl_validation", "import_vinyl_util", "import_vinyl_di", "contentType", "loadOptionsValidator", "import_vinyl_util", "import_vinyl_validation", "loadOptionsValidator", "import_vinyl_util", "contentType", "contentType", "fullMimeType", "time", "period", "_a", "contentType", "import_vinyl_util", "import_vinyl_util", "data", "import_vinyl_util", "import_vinyl_di", "contentType", "deps", "contentType", "import_vinyl_util", "import_vinyl_util", "_a", "import_vinyl_util", "import_vinyl_mpd_parser", "contentType", "_a", "_b", "import_vinyl_di", "import_vinyl_util", "import_vinyl_mpd_parser", "deps", "data", "contentType", "import_vinyl_util", "import_vinyl_util", "data", "contentType", "data", "import_vinyl_util", "import_vinyl_di", "contentType", "deps", "getContentTypes", "contentType", "import_vinyl_di", "import_vinyl_hls_parser", "import_vinyl_util", "deps", "data", "import_vinyl_util", "element", "_a", "import_vinyl_util", "import_vinyl_util", "import_vinyl_di", "import_vinyl_validation", "import_vinyl_observable", "data", "import_vinyl_util", "import_vinyl_di", "_a", "contentType"]
7
7
  }