@amazon/vinyl 3.0.1 → 3.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (250) hide show
  1. package/dist/index.cjs +972 -954
  2. package/dist/index.cjs.map +4 -4
  3. package/dist/index.js +646 -619
  4. package/dist/index.js.map +4 -4
  5. package/dist/test/benchmark.js.map +2 -2
  6. package/dist/test/integ.es5.js +357 -353
  7. package/dist/test/integ.js +2251 -1852
  8. package/dist/test/integ.js.map +4 -4
  9. package/dist/test/jasmine.css +50 -3
  10. package/dist/test/jasmineHtml.es5.js +195 -155
  11. package/dist/test/jasmineHtml.js +2938 -1833
  12. package/dist/test/jasmineHtml.js.map +3 -3
  13. package/dist/types/current/ad/AdControllerImpl.d.ts.map +1 -1
  14. package/dist/types/current/ad/AdControllerImpl.js +4 -1
  15. package/dist/types/current/ad/discoverHlsInterstitials.d.ts.map +1 -1
  16. package/dist/types/current/ad/discoverHlsInterstitials.js +2 -2
  17. package/dist/types/current/drm/DrmControllerImpl.d.ts +2 -0
  18. package/dist/types/current/drm/DrmControllerImpl.d.ts.map +1 -1
  19. package/dist/types/current/drm/DrmControllerImpl.js +56 -48
  20. package/dist/types/current/drm/licenseProvider/defaultLicenseProvider.d.ts.map +1 -1
  21. package/dist/types/current/drm/licenseProvider/defaultLicenseProvider.js +2 -2
  22. package/dist/types/current/index.d.ts +3 -6
  23. package/dist/types/current/index.d.ts.map +1 -1
  24. package/dist/types/current/index.js +3 -6
  25. package/dist/types/current/playback/PlaybackControllerImpl.d.ts +15 -0
  26. package/dist/types/current/playback/PlaybackControllerImpl.d.ts.map +1 -1
  27. package/dist/types/current/playback/PlaybackControllerImpl.js +100 -9
  28. package/dist/types/current/playback/ReadonlyPlaybackController.d.ts +27 -1
  29. package/dist/types/current/playback/ReadonlyPlaybackController.d.ts.map +1 -1
  30. package/dist/types/current/playback/ReadonlyPlaybackController.js +16 -0
  31. package/dist/types/current/playback/createStallDetector.d.ts +43 -0
  32. package/dist/types/current/playback/createStallDetector.d.ts.map +1 -0
  33. package/dist/types/current/playback/createStallDetector.js +101 -0
  34. package/dist/types/current/playback/createStallMonitor.d.ts +45 -0
  35. package/dist/types/current/playback/createStallMonitor.d.ts.map +1 -0
  36. package/dist/types/current/playback/createStallMonitor.js +94 -0
  37. package/dist/types/current/streaming/AudioOptions.d.ts +27 -0
  38. package/dist/types/current/streaming/AudioOptions.d.ts.map +1 -1
  39. package/dist/types/current/streaming/AudioOptions.js +5 -1
  40. package/dist/types/current/streaming/ContentStream.d.ts +0 -5
  41. package/dist/types/current/streaming/ContentStream.d.ts.map +1 -1
  42. package/dist/types/current/streaming/ContentStream.js +0 -4
  43. package/dist/types/current/streaming/LoadMetric.d.ts.map +1 -1
  44. package/dist/types/current/streaming/StreamingEventMap.d.ts +1 -5
  45. package/dist/types/current/streaming/StreamingEventMap.d.ts.map +1 -1
  46. package/dist/types/current/streaming/StreamingEventMap.js +0 -1
  47. package/dist/types/current/streaming/buffering/BufferingController.d.ts +0 -11
  48. package/dist/types/current/streaming/buffering/BufferingController.d.ts.map +1 -1
  49. package/dist/types/current/streaming/buffering/BufferingController.js +0 -13
  50. package/dist/types/current/streaming/createDefaultMediaTimelineTransformer.d.ts.map +1 -1
  51. package/dist/types/current/streaming/createDefaultMediaTimelineTransformer.js +13 -4
  52. package/dist/types/current/text/SidecarTextTrackLoader.d.ts.map +1 -1
  53. package/dist/types/current/text/SidecarTextTrackLoader.js +4 -4
  54. package/dist/types/current/text/TextTrack.d.ts.map +1 -1
  55. package/dist/types/current/track/TrackController.d.ts.map +1 -1
  56. package/dist/types/current/track/TrackController.js +8 -2
  57. package/dist/types/current/track/createSegmentDataProvider.d.ts.map +1 -1
  58. package/dist/types/current/track/createSegmentDataProvider.js +6 -3
  59. package/dist/types/current/track/dash/DashMediaQualityMetadataResolver.d.ts +10 -6
  60. package/dist/types/current/track/dash/DashMediaQualityMetadataResolver.d.ts.map +1 -1
  61. package/dist/types/current/track/dash/DashMediaQualityMetadataResolver.js +13 -8
  62. package/dist/types/current/track/dash/createDashFactories.d.ts +1 -1
  63. package/dist/types/current/track/dash/timeline/DashRepresentationSegmentProvider.d.ts.map +1 -1
  64. package/dist/types/current/track/dash/timeline/DashRepresentationSegmentProvider.js +71 -3
  65. package/dist/types/current/track/dash/urlDashManifestProvider.js +2 -2
  66. package/dist/types/current/track/dash/util/mpd.d.ts +6 -0
  67. package/dist/types/current/track/dash/util/mpd.d.ts.map +1 -1
  68. package/dist/types/current/track/dash/util/mpd.js +24 -3
  69. package/dist/types/current/track/filters/resourceTypeFilter.d.ts +4 -0
  70. package/dist/types/current/track/filters/resourceTypeFilter.d.ts.map +1 -1
  71. package/dist/types/current/track/filters/resourceTypeFilter.js +4 -0
  72. package/dist/types/current/track/filters/sampleRateFilter.d.ts +21 -7
  73. package/dist/types/current/track/filters/sampleRateFilter.d.ts.map +1 -1
  74. package/dist/types/current/track/filters/sampleRateFilter.js +42 -24
  75. package/dist/types/current/track/hls/createHlsFactories.d.ts +1 -1
  76. package/dist/types/current/track/hls/createUrlHlsManifestProvider.d.ts.map +1 -1
  77. package/dist/types/current/track/hls/createUrlHlsManifestProvider.js +3 -3
  78. package/dist/types/current/track/mse/MseTrack.d.ts +9 -17
  79. package/dist/types/current/track/mse/MseTrack.d.ts.map +1 -1
  80. package/dist/types/current/track/mse/MseTrack.js +29 -46
  81. package/dist/types/current/tsconfig.tsbuildinfo +1 -1
  82. package/dist/types/current/util/media/mimeType.d.ts +8 -0
  83. package/dist/types/current/util/media/mimeType.d.ts.map +1 -0
  84. package/dist/types/current/util/media/mimeType.js +13 -0
  85. package/dist/types/current/vinyl/createVinylFactories.d.ts +7 -16
  86. package/dist/types/current/vinyl/createVinylFactories.d.ts.map +1 -1
  87. package/dist/types/current/vinyl/createVinylFactories.js +2 -12
  88. package/dist/types/ts3.7/drm/DrmControllerImpl.d.ts +2 -0
  89. package/dist/types/ts3.7/index.d.ts +3 -6
  90. package/dist/types/ts3.7/playback/PlaybackControllerImpl.d.ts +15 -0
  91. package/dist/types/ts3.7/playback/ReadonlyPlaybackController.d.ts +28 -0
  92. package/dist/types/ts3.7/playback/createStallDetector.d.ts +43 -0
  93. package/dist/types/ts3.7/playback/createStallMonitor.d.ts +45 -0
  94. package/dist/types/ts3.7/streaming/AudioOptions.d.ts +27 -0
  95. package/dist/types/ts3.7/streaming/ContentStream.d.ts +0 -5
  96. package/dist/types/ts3.7/streaming/StreamingEventMap.d.ts +0 -5
  97. package/dist/types/ts3.7/streaming/buffering/BufferingController.d.ts +0 -11
  98. package/dist/types/ts3.7/track/dash/DashMediaQualityMetadataResolver.d.ts +10 -6
  99. package/dist/types/ts3.7/track/dash/createDashFactories.d.ts +1 -1
  100. package/dist/types/ts3.7/track/dash/util/mpd.d.ts +6 -0
  101. package/dist/types/ts3.7/track/filters/resourceTypeFilter.d.ts +4 -0
  102. package/dist/types/ts3.7/track/filters/sampleRateFilter.d.ts +21 -7
  103. package/dist/types/ts3.7/track/hls/createHlsFactories.d.ts +1 -1
  104. package/dist/types/ts3.7/track/mse/MseTrack.d.ts +9 -17
  105. package/dist/types/ts3.7/util/media/mimeType.d.ts +8 -0
  106. package/dist/types/ts3.7/vinyl/createVinylFactories.d.ts +7 -16
  107. package/dist/types/ts4.1/drm/DrmControllerImpl.d.ts +2 -0
  108. package/dist/types/ts4.1/index.d.ts +3 -6
  109. package/dist/types/ts4.1/playback/PlaybackControllerImpl.d.ts +15 -0
  110. package/dist/types/ts4.1/playback/ReadonlyPlaybackController.d.ts +28 -0
  111. package/dist/types/ts4.1/playback/createStallDetector.d.ts +43 -0
  112. package/dist/types/ts4.1/playback/createStallMonitor.d.ts +45 -0
  113. package/dist/types/ts4.1/streaming/AudioOptions.d.ts +27 -0
  114. package/dist/types/ts4.1/streaming/ContentStream.d.ts +0 -5
  115. package/dist/types/ts4.1/streaming/StreamingEventMap.d.ts +0 -5
  116. package/dist/types/ts4.1/streaming/buffering/BufferingController.d.ts +0 -11
  117. package/dist/types/ts4.1/track/dash/DashMediaQualityMetadataResolver.d.ts +10 -6
  118. package/dist/types/ts4.1/track/dash/createDashFactories.d.ts +1 -1
  119. package/dist/types/ts4.1/track/dash/util/mpd.d.ts +6 -0
  120. package/dist/types/ts4.1/track/filters/resourceTypeFilter.d.ts +4 -0
  121. package/dist/types/ts4.1/track/filters/sampleRateFilter.d.ts +21 -7
  122. package/dist/types/ts4.1/track/hls/createHlsFactories.d.ts +1 -1
  123. package/dist/types/ts4.1/track/mse/MseTrack.d.ts +9 -17
  124. package/dist/types/ts4.1/util/media/mimeType.d.ts +8 -0
  125. package/dist/types/ts4.1/vinyl/createVinylFactories.d.ts +7 -16
  126. package/dist/types/ts4.7/drm/DrmControllerImpl.d.ts +2 -0
  127. package/dist/types/ts4.7/index.d.ts +3 -6
  128. package/dist/types/ts4.7/playback/PlaybackControllerImpl.d.ts +15 -0
  129. package/dist/types/ts4.7/playback/ReadonlyPlaybackController.d.ts +28 -0
  130. package/dist/types/ts4.7/playback/createStallDetector.d.ts +43 -0
  131. package/dist/types/ts4.7/playback/createStallMonitor.d.ts +45 -0
  132. package/dist/types/ts4.7/streaming/AudioOptions.d.ts +27 -0
  133. package/dist/types/ts4.7/streaming/ContentStream.d.ts +0 -5
  134. package/dist/types/ts4.7/streaming/StreamingEventMap.d.ts +0 -5
  135. package/dist/types/ts4.7/streaming/buffering/BufferingController.d.ts +0 -11
  136. package/dist/types/ts4.7/track/dash/DashMediaQualityMetadataResolver.d.ts +10 -6
  137. package/dist/types/ts4.7/track/dash/createDashFactories.d.ts +1 -1
  138. package/dist/types/ts4.7/track/dash/util/mpd.d.ts +6 -0
  139. package/dist/types/ts4.7/track/filters/resourceTypeFilter.d.ts +4 -0
  140. package/dist/types/ts4.7/track/filters/sampleRateFilter.d.ts +21 -7
  141. package/dist/types/ts4.7/track/hls/createHlsFactories.d.ts +1 -1
  142. package/dist/types/ts4.7/track/mse/MseTrack.d.ts +9 -17
  143. package/dist/types/ts4.7/util/media/mimeType.d.ts +8 -0
  144. package/dist/types/ts4.7/vinyl/createVinylFactories.d.ts +7 -16
  145. package/dist/unit/types/current/ad/AdControllerImpl.test.js +27 -1
  146. package/dist/unit/types/current/drm/DrmControllerImpl.test.js +93 -0
  147. package/dist/unit/types/current/index.d.ts +3 -4
  148. package/dist/unit/types/current/index.d.ts.map +1 -1
  149. package/dist/unit/types/current/index.js +3 -4
  150. package/dist/unit/types/current/playback/PlaybackControllerImpl.test.js +165 -0
  151. package/dist/unit/types/current/playback/createStallDetector.test.d.ts +2 -0
  152. package/dist/unit/types/current/playback/createStallDetector.test.d.ts.map +1 -0
  153. package/dist/unit/types/current/playback/createStallDetector.test.js +163 -0
  154. package/dist/unit/types/current/playback/createStallMonitor.test.d.ts +2 -0
  155. package/dist/unit/types/current/playback/createStallMonitor.test.d.ts.map +1 -0
  156. package/dist/unit/types/current/playback/createStallMonitor.test.js +125 -0
  157. package/dist/unit/types/current/streaming/ContentStream.test.js +0 -11
  158. package/dist/unit/types/current/streaming/MseTrack.test.js +47 -74
  159. package/dist/unit/types/current/streaming/abr/QualitySelectorImpl.test.js +1 -1
  160. package/dist/unit/types/current/streaming/buffering/BufferingController.test.js +0 -21
  161. package/dist/unit/types/current/streaming/createDefaultMediaTimelineTransformer.test.js +133 -0
  162. package/dist/unit/types/current/track/TrackController.test.js +61 -1
  163. package/dist/unit/types/current/track/createSegmentDataProvider.test.js +18 -0
  164. package/dist/unit/types/current/track/dash/DashMediaQualityMetadataResolver.test.js +46 -14
  165. package/dist/unit/types/current/track/dash/createSegmentControllerFactory.test.js +1 -0
  166. package/dist/unit/types/current/track/dash/timeline/DashRepresentationSegmentProvider.test.js +114 -0
  167. package/dist/unit/types/current/track/dash/util/mpd.test.js +37 -0
  168. package/dist/unit/types/current/track/filters/resourceTypeFilter.test.js +7 -0
  169. package/dist/unit/types/current/track/filters/sampleRateFilter.test.js +136 -34
  170. package/dist/unit/types/current/track/source/SourceObjectTrack.test.js +1 -1
  171. package/dist/unit/types/current/tsconfig.tsbuildinfo +1 -1
  172. package/dist/unit/types/current/util/media/mimeType.test.d.ts +2 -0
  173. package/dist/unit/types/current/util/media/mimeType.test.d.ts.map +1 -0
  174. package/dist/unit/types/current/util/media/mimeType.test.js +22 -0
  175. package/dist/unit/types/current/vinyl/createVinylFactories.test.js +2 -36
  176. package/dist/vinylTestUtil/index.js +6 -4
  177. package/dist/vinylTestUtil/index.js.map +2 -2
  178. package/dist/vinylTestUtil/types/current/assets/vinylTestAssets.d.ts +1 -0
  179. package/dist/vinylTestUtil/types/current/assets/vinylTestAssets.d.ts.map +1 -1
  180. package/dist/vinylTestUtil/types/current/assets/vinylTestAssets.js +1 -0
  181. package/dist/vinylTestUtil/types/current/media/FrequencyAnalyzer.d.ts.map +1 -1
  182. package/dist/vinylTestUtil/types/current/mock/streaming/MockContentStream.d.ts +0 -1
  183. package/dist/vinylTestUtil/types/current/mock/streaming/MockContentStream.d.ts.map +1 -1
  184. package/dist/vinylTestUtil/types/current/mock/streaming/MockContentStream.js +0 -1
  185. package/dist/vinylTestUtil/types/current/mock/streaming/buffering/MockBufferingController.d.ts +0 -1
  186. package/dist/vinylTestUtil/types/current/mock/streaming/buffering/MockBufferingController.d.ts.map +1 -1
  187. package/dist/vinylTestUtil/types/current/mock/streaming/buffering/MockBufferingController.js +0 -1
  188. package/dist/vinylTestUtil/types/current/tsconfig.tsbuildinfo +1 -1
  189. package/dist/vinylTestUtil/types/current/util/playback/eventPromises.js +1 -1
  190. package/dist/vinylTestUtil/types/current/util/playback/expectTrackCanSeek.d.ts.map +1 -1
  191. package/dist/vinylTestUtil/types/current/util/playback/expectTrackCanSeek.js +9 -1
  192. package/dist/vinylTestUtil/types/ts3.7/assets/vinylTestAssets.d.ts +1 -0
  193. package/dist/vinylTestUtil/types/ts3.7/mock/streaming/MockContentStream.d.ts +0 -1
  194. package/dist/vinylTestUtil/types/ts3.7/mock/streaming/buffering/MockBufferingController.d.ts +0 -1
  195. package/dist/vinylTestUtil/types/ts4.1/assets/vinylTestAssets.d.ts +1 -0
  196. package/dist/vinylTestUtil/types/ts4.1/mock/streaming/MockContentStream.d.ts +0 -1
  197. package/dist/vinylTestUtil/types/ts4.1/mock/streaming/buffering/MockBufferingController.d.ts +0 -1
  198. package/dist/vinylTestUtil/types/ts4.7/assets/vinylTestAssets.d.ts +1 -0
  199. package/dist/vinylTestUtil/types/ts4.7/mock/streaming/MockContentStream.d.ts +0 -1
  200. package/dist/vinylTestUtil/types/ts4.7/mock/streaming/buffering/MockBufferingController.d.ts +0 -1
  201. package/docs/USAGE.md +29 -0
  202. package/package.json +11 -10
  203. package/dist/types/current/patch/media/HtmlMediaElementPatch.d.ts +0 -3
  204. package/dist/types/current/patch/media/HtmlMediaElementPatch.d.ts.map +0 -1
  205. package/dist/types/current/patch/media/HtmlMediaElementPatch.js +0 -5
  206. package/dist/types/current/patch/media/MediaElementPatchOptions.d.ts +0 -19
  207. package/dist/types/current/patch/media/MediaElementPatchOptions.d.ts.map +0 -1
  208. package/dist/types/current/patch/media/MediaElementPatchOptions.js +0 -16
  209. package/dist/types/current/patch/media/patchMediaElement.d.ts +0 -9
  210. package/dist/types/current/patch/media/patchMediaElement.d.ts.map +0 -1
  211. package/dist/types/current/patch/media/patchMediaElement.js +0 -15
  212. package/dist/types/current/patch/media/patches/createPreventStallsPatch.d.ts +0 -17
  213. package/dist/types/current/patch/media/patches/createPreventStallsPatch.d.ts.map +0 -1
  214. package/dist/types/current/patch/media/patches/createPreventStallsPatch.js +0 -55
  215. package/dist/types/current/patch/media/patches/createUnreliablePlaybackEventsPatch.d.ts +0 -26
  216. package/dist/types/current/patch/media/patches/createUnreliablePlaybackEventsPatch.d.ts.map +0 -1
  217. package/dist/types/current/patch/media/patches/createUnreliablePlaybackEventsPatch.js +0 -218
  218. package/dist/types/current/vinyl/VinylPatchOptions.d.ts +0 -10
  219. package/dist/types/current/vinyl/VinylPatchOptions.d.ts.map +0 -1
  220. package/dist/types/current/vinyl/VinylPatchOptions.js +0 -11
  221. package/dist/types/ts3.7/patch/media/HtmlMediaElementPatch.d.ts +0 -3
  222. package/dist/types/ts3.7/patch/media/MediaElementPatchOptions.d.ts +0 -19
  223. package/dist/types/ts3.7/patch/media/patchMediaElement.d.ts +0 -9
  224. package/dist/types/ts3.7/patch/media/patches/createPreventStallsPatch.d.ts +0 -17
  225. package/dist/types/ts3.7/patch/media/patches/createUnreliablePlaybackEventsPatch.d.ts +0 -26
  226. package/dist/types/ts3.7/vinyl/VinylPatchOptions.d.ts +0 -10
  227. package/dist/types/ts4.1/patch/media/HtmlMediaElementPatch.d.ts +0 -3
  228. package/dist/types/ts4.1/patch/media/MediaElementPatchOptions.d.ts +0 -19
  229. package/dist/types/ts4.1/patch/media/patchMediaElement.d.ts +0 -9
  230. package/dist/types/ts4.1/patch/media/patches/createPreventStallsPatch.d.ts +0 -17
  231. package/dist/types/ts4.1/patch/media/patches/createUnreliablePlaybackEventsPatch.d.ts +0 -26
  232. package/dist/types/ts4.1/vinyl/VinylPatchOptions.d.ts +0 -10
  233. package/dist/types/ts4.7/patch/media/HtmlMediaElementPatch.d.ts +0 -3
  234. package/dist/types/ts4.7/patch/media/MediaElementPatchOptions.d.ts +0 -19
  235. package/dist/types/ts4.7/patch/media/patchMediaElement.d.ts +0 -9
  236. package/dist/types/ts4.7/patch/media/patches/createPreventStallsPatch.d.ts +0 -17
  237. package/dist/types/ts4.7/patch/media/patches/createUnreliablePlaybackEventsPatch.d.ts +0 -26
  238. package/dist/types/ts4.7/vinyl/VinylPatchOptions.d.ts +0 -10
  239. package/dist/unit/types/current/patch/media/MediaElementPatchOptions.test.d.ts +0 -2
  240. package/dist/unit/types/current/patch/media/MediaElementPatchOptions.test.d.ts.map +0 -1
  241. package/dist/unit/types/current/patch/media/MediaElementPatchOptions.test.js +0 -17
  242. package/dist/unit/types/current/patch/media/patchMediaElement.test.d.ts +0 -2
  243. package/dist/unit/types/current/patch/media/patchMediaElement.test.d.ts.map +0 -1
  244. package/dist/unit/types/current/patch/media/patchMediaElement.test.js +0 -36
  245. package/dist/unit/types/current/patch/media/patches/createPreventStallsPatch.test.d.ts +0 -2
  246. package/dist/unit/types/current/patch/media/patches/createPreventStallsPatch.test.d.ts.map +0 -1
  247. package/dist/unit/types/current/patch/media/patches/createPreventStallsPatch.test.js +0 -93
  248. package/dist/unit/types/current/patch/media/patches/createUnreliablePlaybackEventsPatch.test.d.ts +0 -2
  249. package/dist/unit/types/current/patch/media/patches/createUnreliablePlaybackEventsPatch.test.d.ts.map +0 -1
  250. package/dist/unit/types/current/patch/media/patches/createUnreliablePlaybackEventsPatch.test.js +0 -423
package/dist/index.js CHANGED
@@ -236,7 +236,7 @@ var AdControllerImpl = class extends EventHostImpl {
236
236
  */
237
237
  providerInterrupted() {
238
238
  const provider = this.adsProvider;
239
- return () => provider !== this.adsProvider;
239
+ return () => this.disposed || provider !== this.adsProvider;
240
240
  }
241
241
  setAdsProvider(provider) {
242
242
  var _a;
@@ -615,7 +615,9 @@ var AdControllerImpl = class extends EventHostImpl {
615
615
  * Disposes this controller, removes all listeners.
616
616
  */
617
617
  dispose() {
618
+ var _a;
618
619
  super.dispose();
620
+ (_a = this.adsProviderSub) == null ? void 0 : _a.call(this);
619
621
  this.disposer.dispose();
620
622
  this.adBreakState = null;
621
623
  }
@@ -766,6 +768,7 @@ var UnresolvableAdError = class _UnresolvableAdError extends ReportableError2 {
766
768
  import { HLS_INTERSTITIAL_CLASS } from "@amazon/vinyl-hls-parser";
767
769
  import {
768
770
  memoize as memoize3,
771
+ readResponseBody,
769
772
  requestWithRetry as requestWithRetry2,
770
773
  resolveUrl
771
774
  } from "@amazon/vinyl-util";
@@ -928,7 +931,7 @@ async function resolveHlsAssetList({
928
931
  var _a;
929
932
  const url = resolveUrl(assetListUrl, baseUrl);
930
933
  const response = await requestWithRetry2(url);
931
- const json = await response.json();
934
+ const json = await readResponseBody(response, "json");
932
935
  const assets = (_a = json.ASSETS) != null ? _a : [];
933
936
  const ads = assets.map((asset, i) => {
934
937
  var _a2;
@@ -1805,7 +1808,11 @@ function parsePlayReadyKeyMessage(xmlStr) {
1805
1808
  }
1806
1809
 
1807
1810
  // src/drm/licenseProvider/defaultLicenseProvider.ts
1808
- import { requestWithRetry as requestWithRetry3, ValidationError } from "@amazon/vinyl-util";
1811
+ import {
1812
+ readResponseBody as readResponseBody2,
1813
+ requestWithRetry as requestWithRetry3,
1814
+ ValidationError
1815
+ } from "@amazon/vinyl-util";
1809
1816
  var defaultLicenseProvider = async (keySystem, serverOptions, challenge, abort) => {
1810
1817
  if (serverOptions.url == null) {
1811
1818
  throw new ValidationError(
@@ -1821,7 +1828,7 @@ var defaultLicenseProvider = async (keySystem, serverOptions, challenge, abort)
1821
1828
  }),
1822
1829
  { abort }
1823
1830
  );
1824
- return await res.arrayBuffer();
1831
+ return await readResponseBody2(res, "arrayBuffer");
1825
1832
  };
1826
1833
 
1827
1834
  // src/drm/util/extractContentId.ts
@@ -1919,6 +1926,11 @@ var DrmControllerImpl = class extends EventHostImpl5 {
1919
1926
  ));
1920
1927
  __publicField(this, "handleEncryptedEvent", (event) => {
1921
1928
  if (this.disposed) return;
1929
+ if (this.manifestProvidesInitData()) {
1930
+ logDebug3(this, "ignoring encrypted event; manifest provides pssh");
1931
+ return;
1932
+ }
1933
+ ;
1922
1934
  (async () => {
1923
1935
  var _a;
1924
1936
  const { initData, initDataType } = event;
@@ -2040,7 +2052,7 @@ var DrmControllerImpl = class extends EventHostImpl5 {
2040
2052
  * The new session will be added to the current sessions list.
2041
2053
  */
2042
2054
  async maybeCreateSession(options) {
2043
- var _a;
2055
+ var _a, _b;
2044
2056
  const { drmInfo, initDataType, initData, trackUri, abort } = options;
2045
2057
  if (!hasMimeType(drmInfo)) {
2046
2058
  throw new DrmError("Encrypted content must have a mimeType.");
@@ -2053,33 +2065,41 @@ var DrmControllerImpl = class extends EventHostImpl5 {
2053
2065
  licenseServerOptionsProvider != null ? licenseServerOptionsProvider : {}
2054
2066
  );
2055
2067
  this.abortIfDisposed();
2056
- const existingSession = this.getSessionByInitData(initData);
2068
+ const certBytes = toCertBytes(licenseServerOptions.serverCertificate);
2069
+ if (certBytes) {
2070
+ await mediaKeys.setServerCertificate(certBytes);
2071
+ this.abortIfDisposed();
2072
+ }
2073
+ const transform = (_b = keySystemOptions == null ? void 0 : keySystemOptions.initDataTransformer) != null ? _b : defaultInitDataTransformer(mediaKeys.keySystem, certBytes);
2074
+ const transformedInitData = transform(
2075
+ bufferToByteArray3(initData),
2076
+ initDataType,
2077
+ drmInfo
2078
+ );
2079
+ const existingSession = this.getSessionByInitData(transformedInitData);
2057
2080
  if (existingSession) {
2058
2081
  logDebug3(this, "reusing session");
2059
2082
  return existingSession;
2060
- } else {
2061
- const newSession = await this.createNewSession({
2062
- serverCertificate: licenseServerOptions.serverCertificate,
2063
- mediaKeys,
2064
- initData,
2065
- initDataType,
2066
- drmInfo,
2067
- trackUri,
2068
- initDataTransformer: keySystemOptions == null ? void 0 : keySystemOptions.initDataTransformer
2069
- });
2070
- this.sessions.push(newSession);
2071
- this.dispatch("sessionCreate", {
2072
- initDataType: newSession.initDataType,
2073
- mimeType: newSession.mimeType
2074
- });
2075
- newSession.on("closed", () => this.closeSession(newSession));
2076
- abort == null ? void 0 : abort.onAborted(() => {
2077
- if (this.disposed) return;
2078
- logDebug3(this, "abort session");
2079
- this.closeSession(newSession);
2080
- });
2081
- return newSession;
2082
2083
  }
2084
+ const newSession = this.createNewSession({
2085
+ mediaKeys,
2086
+ initData: transformedInitData,
2087
+ initDataType,
2088
+ drmInfo,
2089
+ trackUri
2090
+ });
2091
+ this.sessions.push(newSession);
2092
+ this.dispatch("sessionCreate", {
2093
+ initDataType: newSession.initDataType,
2094
+ mimeType: newSession.mimeType
2095
+ });
2096
+ newSession.on("closed", () => this.closeSession(newSession));
2097
+ abort == null ? void 0 : abort.onAborted(() => {
2098
+ if (this.disposed) return;
2099
+ logDebug3(this, "abort session");
2100
+ this.closeSession(newSession);
2101
+ });
2102
+ return newSession;
2083
2103
  }
2084
2104
  initializeForPlayback(drmInfo, options) {
2085
2105
  var _a;
@@ -2092,6 +2112,11 @@ var DrmControllerImpl = class extends EventHostImpl5 {
2092
2112
  ).catch(this.handleError);
2093
2113
  }
2094
2114
  }
2115
+ /** True when the manifest carried pssh (sessions come from it, not events). */
2116
+ manifestProvidesInitData() {
2117
+ var _a, _b;
2118
+ return (_b = (_a = this.drmInfo) == null ? void 0 : _a.contentProtections.some((cP) => cP.pssh != null)) != null ? _b : false;
2119
+ }
2095
2120
  setBufferingDrmInfo(drmInfo, options) {
2096
2121
  var _a, _b;
2097
2122
  logDebug3(this, "setBufferingDrmInfo", drmInfo);
@@ -2231,24 +2256,10 @@ var DrmControllerImpl = class extends EventHostImpl5 {
2231
2256
  /**
2232
2257
  * Creates a new key session and adds a message handler.
2233
2258
  */
2234
- async createNewSession(options) {
2235
- const {
2236
- serverCertificate,
2237
- mediaKeys,
2238
- initDataType,
2239
- drmInfo,
2240
- trackUri,
2241
- initDataTransformer
2242
- } = options;
2243
- let initData = options.initData;
2244
- const certBytes = serverCertificate ? typeof serverCertificate === "string" ? base64ToByteArray2(serverCertificate) : bufferToByteArray3(serverCertificate) : null;
2245
- if (certBytes) {
2246
- await mediaKeys.setServerCertificate(certBytes);
2247
- }
2248
- const transform = initDataTransformer != null ? initDataTransformer : defaultInitDataTransformer(mediaKeys.keySystem, certBytes);
2249
- initData = transform(bufferToByteArray3(initData), initDataType, drmInfo);
2259
+ createNewSession(options) {
2260
+ const { mediaKeys, initData, initDataType, drmInfo, trackUri } = options;
2250
2261
  this.abortIfDisposed();
2251
- logDebug3(this, "createSession", drmInfo.mimeType, initDataType);
2262
+ logDebug3(this, "createSession", drmInfo.mimeType, initDataType, drmInfo);
2252
2263
  const session = mediaKeys.createSession(
2253
2264
  drmInfo.mimeType,
2254
2265
  initDataType,
@@ -2278,15 +2289,15 @@ var DrmControllerImpl = class extends EventHostImpl5 {
2278
2289
  * Invoked when the content decryption module needs to interact with the license server.
2279
2290
  */
2280
2291
  async messageHandler(messageProps) {
2281
- var _a, _b;
2292
+ var _a, _b, _c;
2282
2293
  const { mediaKeys, session, event } = messageProps;
2283
2294
  messageEventValidator.assert(event);
2284
2295
  this.pendingMessageProps = messageProps;
2285
2296
  const keySystem = mediaKeys.keySystem;
2286
2297
  logDebug3(this, "message", keySystem, event.message.byteLength);
2287
- const keySystemOptions = this.options.keySystems[keySystem];
2298
+ const keySystemOptions = (_a = this.options.keySystems[keySystem]) != null ? _a : this.options.keySystems["*"];
2288
2299
  const licenseServerOptionsProvider = keySystemOptions == null ? void 0 : keySystemOptions.licenseServer;
2289
- const licenseServerOptions = (_a = clone(await resolveValueProvider2(licenseServerOptionsProvider))) != null ? _a : {};
2300
+ const licenseServerOptions = (_b = clone(await resolveValueProvider2(licenseServerOptionsProvider))) != null ? _b : {};
2290
2301
  this.abortIfDisposed();
2291
2302
  let challenge = event.message;
2292
2303
  if (isPlayReady(keySystem)) {
@@ -2295,7 +2306,7 @@ var DrmControllerImpl = class extends EventHostImpl5 {
2295
2306
  if (licenseServerOptions.init == null)
2296
2307
  licenseServerOptions.init = {};
2297
2308
  licenseServerOptions.init.headers = __spreadValues(__spreadValues({}, normalizeHeadersInit(
2298
- (_b = licenseServerOptions.init.headers) != null ? _b : {}
2309
+ (_c = licenseServerOptions.init.headers) != null ? _c : {}
2299
2310
  )), unpacked.headers);
2300
2311
  }
2301
2312
  const licenseSpanStart = Date.now();
@@ -2304,6 +2315,7 @@ var DrmControllerImpl = class extends EventHostImpl5 {
2304
2315
  licenseServerOptions,
2305
2316
  challenge
2306
2317
  );
2318
+ if (this.disposed) return;
2307
2319
  this.dispatch("loadSpanMeasured", __spreadValues({
2308
2320
  kind: "license",
2309
2321
  startTime: licenseSpanStart,
@@ -2393,9 +2405,9 @@ var DrmControllerImpl = class extends EventHostImpl5 {
2393
2405
  }
2394
2406
  getSessionByInitData(initData) {
2395
2407
  var _a;
2396
- return (_a = this.sessions.find((session) => {
2397
- return buffersEqual(session.initData, initData);
2398
- })) != null ? _a : null;
2408
+ return (_a = this.sessions.find(
2409
+ (session) => buffersEqual(session.initData, initData)
2410
+ )) != null ? _a : null;
2399
2411
  }
2400
2412
  };
2401
2413
  var messageEventValidator = /* @__PURE__ */ object3({
@@ -2404,6 +2416,10 @@ var messageEventValidator = /* @__PURE__ */ object3({
2404
2416
  function hasMimeType(drmInfo) {
2405
2417
  return drmInfo.mimeType != null;
2406
2418
  }
2419
+ function toCertBytes(serverCertificate) {
2420
+ if (!serverCertificate) return null;
2421
+ return typeof serverCertificate === "string" ? base64ToByteArray2(serverCertificate) : bufferToByteArray3(serverCertificate);
2422
+ }
2407
2423
  function defaultInitDataTransformer(keySystem, certBytes) {
2408
2424
  return (initData) => {
2409
2425
  if (keySystem === "com.apple.fps.1_0" /* FAIR_PLAY_1_0 */) {
@@ -2565,7 +2581,7 @@ function configureVinylGlobal(options) {
2565
2581
  import { parseVersion } from "@amazon/vinyl-util";
2566
2582
  var vinylVersion = /* @__PURE__ */ parseVersion(
2567
2583
  /* istanbul ignore next */
2568
- "3.0.1"
2584
+ "3.1.0"
2569
2585
  );
2570
2586
 
2571
2587
  // src/global/globalRef.ts
@@ -2620,237 +2636,220 @@ function initializeVinylGlobal() {
2620
2636
  vinylGlobalRef.initialize();
2621
2637
  }
2622
2638
 
2623
- // src/patch/media/MediaElementPatchOptions.ts
2624
- import { lazy as lazy2 } from "@amazon/vinyl-util";
2625
-
2626
- // src/patch/media/patches/createUnreliablePlaybackEventsPatch.ts
2627
- import { Browser, hasBrowser } from "@amazon/vinyl-util";
2628
- import {
2629
- closeTo,
2630
- createDisposer as createDisposer3,
2631
- DomEventHost,
2632
- onAny,
2633
- SignalImpl
2634
- } from "@amazon/vinyl-util";
2635
- var UNRELIABLE_EVENTS_POLL_INTERVAL = 0.2;
2636
- var MIN_STALLED_BEFORE_FAB = 0.8;
2637
- var MIN_PLAYING_BEFORE_FAB = 0.4;
2638
- var MIN_PLAYING_DELTA = 0.05;
2639
- var MIN_SEEKING_DELTA = 0.5;
2640
- function createUnreliablePlaybackEventsPatch(media) {
2641
- const { add, dispose } = createDisposer3();
2642
- const domEvents = add(new DomEventHost(media));
2643
- const eventFabricated = add(new SignalImpl());
2644
- let stateChangedAt = Date.now();
2645
- let currentApparentState = 1 /* STOPPED */;
2646
- function setApparentState(state, changedAt = Date.now()) {
2647
- if (currentApparentState !== state) {
2648
- currentApparentState = state;
2649
- stateChangedAt = changedAt;
2650
- }
2651
- }
2652
- function elapsedStateTime() {
2653
- return (Date.now() - stateChangedAt) / 1e3;
2654
- }
2655
- let lastTimestamp = Date.now();
2639
+ // src/playback/createStallDetector.ts
2640
+ function createStallDetector(media, options) {
2641
+ var _a, _b, _c, _d, _e, _f;
2642
+ const { fabricatePlaying } = options;
2643
+ const pollInterval = (_a = options.pollInterval) != null ? _a : 0.25;
2644
+ const stallThreshold = (_b = options.stallThreshold) != null ? _b : 0.75;
2645
+ const bufferEndMargin = (_c = options.bufferEndMargin) != null ? _c : 0.5;
2646
+ const stallSkip = (_d = options.stallSkip) != null ? _d : 0.1;
2647
+ const maxAttempts = (_e = options.maxAttempts) != null ? _e : 3;
2648
+ const nudgeUnbuffered = (_f = options.nudgeUnbuffered) != null ? _f : false;
2656
2649
  let lastTime = media.currentTime;
2657
- let waiting = false;
2658
- let seeking = false;
2659
- onAny(
2660
- domEvents,
2661
- ["emptied", "ended", "pause", "playing", "seeking"],
2662
- () => {
2663
- waiting = false;
2664
- }
2665
- );
2666
- let playing = false;
2667
- onAny(
2668
- domEvents,
2669
- ["emptied", "ended", "pause", "seeking", "waiting"],
2670
- () => {
2671
- playing = false;
2672
- }
2673
- );
2674
- domEvents.on("seeking", () => {
2675
- seeking = true;
2676
- });
2677
- domEvents.on("seeked", () => {
2678
- seeking = false;
2679
- setApparentState(2 /* SEEKING */);
2680
- });
2681
- domEvents.on("play", () => {
2682
- stateChangedAt = Date.now();
2683
- });
2684
- const readyStateEvents = [
2685
- "emptied",
2686
- "loadeddata",
2687
- "loadedmetadata",
2688
- "waiting"
2689
- ];
2690
- let lastReadyStateEvent = "emptied";
2691
- add(
2692
- onAny(domEvents, readyStateEvents, (_, type) => {
2693
- lastReadyStateEvent = type;
2694
- })
2695
- );
2696
- const checkApparentState = () => {
2697
- const progressed = (media.currentTime - lastTime) / media.playbackRate;
2698
- const now = Date.now();
2699
- if (Math.abs(progressed) > MIN_SEEKING_DELTA) {
2700
- setApparentState(2 /* SEEKING */, lastTimestamp);
2701
- } else if (progressed >= MIN_PLAYING_DELTA) {
2702
- setApparentState(0 /* PLAYING */, lastTimestamp);
2703
- } else if (closeTo(progressed, 0, MIN_PLAYING_DELTA)) {
2704
- setApparentState(1 /* STOPPED */, lastTimestamp);
2705
- }
2706
- lastTime = media.currentTime;
2707
- lastTimestamp = now;
2708
- if (!playing && !seeking && !media.paused && !media.ended && media.readyState >= media.HAVE_FUTURE_DATA && currentApparentState === 0 /* PLAYING */ && elapsedStateTime() >= MIN_PLAYING_BEFORE_FAB) {
2709
- waiting = false;
2710
- playing = true;
2711
- if (lastReadyStateEvent !== "canplay" && lastReadyStateEvent !== "canplaythrough") {
2712
- lastReadyStateEvent = "canplay";
2713
- eventFabricated.dispatch(new CustomEvent("canplay"));
2714
- }
2715
- if (media.readyState >= media.HAVE_ENOUGH_DATA) {
2716
- if (lastReadyStateEvent !== "canplaythrough") {
2717
- lastReadyStateEvent = "canplaythrough";
2718
- eventFabricated.dispatch(new CustomEvent("canplaythrough"));
2719
- }
2720
- }
2721
- eventFabricated.dispatch(new CustomEvent("playing"));
2722
- }
2723
- if (!waiting && !media.paused && !media.ended && currentApparentState === 1 /* STOPPED */ && elapsedStateTime() >= MIN_STALLED_BEFORE_FAB) {
2724
- waiting = true;
2725
- playing = false;
2726
- eventFabricated.dispatch(new CustomEvent("waiting"));
2727
- }
2650
+ let stalledFor = 0;
2651
+ let attempts = 0;
2652
+ let sawPlaying = false;
2653
+ let recovered = false;
2654
+ const onPlaying = () => {
2655
+ sawPlaying = true;
2728
2656
  };
2729
- const playbackWatchIntervalId = setInterval(
2730
- checkApparentState,
2731
- UNRELIABLE_EVENTS_POLL_INTERVAL * 1e3
2732
- );
2733
- add(() => {
2734
- clearInterval(playbackWatchIntervalId);
2735
- });
2736
- return {
2737
- eventFabricated,
2738
- properties: {
2739
- /**
2740
- * Platforms that have unreliable waiting events, also have unreliable ready state
2741
- * when the end of buffered data has been reached. If the media is in a waiting state,
2742
- * the highest ready state that is possible is HAVE_METADATA.
2743
- */
2744
- readyState: {
2745
- get() {
2746
- return waiting ? Math.min(media.readyState, media.HAVE_METADATA) : media.readyState;
2747
- }
2748
- }
2749
- },
2750
- events: {
2751
- canplay(event) {
2752
- const eventOrNull = lastReadyStateEvent === "canplay" ? null : event;
2753
- lastReadyStateEvent = "canplay";
2754
- return eventOrNull;
2755
- },
2756
- canplaythrough(event) {
2757
- const eventOrNull = lastReadyStateEvent === "canplaythrough" ? null : event;
2758
- lastReadyStateEvent = "canplaythrough";
2759
- return eventOrNull;
2760
- },
2761
- playing(event) {
2762
- if (playing) {
2763
- return null;
2764
- }
2765
- setApparentState(0 /* PLAYING */);
2766
- playing = true;
2767
- return event;
2768
- },
2769
- waiting(event) {
2770
- if (waiting) {
2771
- return null;
2772
- }
2773
- waiting = true;
2774
- setApparentState(1 /* STOPPED */);
2775
- return event;
2776
- }
2777
- },
2778
- dispose
2657
+ const onEmptied = () => stop();
2658
+ media.addEventListener("playing", onPlaying);
2659
+ media.addEventListener("emptied", onEmptied);
2660
+ const stop = () => {
2661
+ clearInterval(id);
2662
+ media.removeEventListener("playing", onPlaying);
2663
+ media.removeEventListener("emptied", onEmptied);
2779
2664
  };
2780
- }
2781
- function requiresUnreliablePlaybackEventsPatch() {
2782
- return hasBrowser(Browser.SAFARI) || hasBrowser(Browser.EDGE_LEGACY) || hasBrowser(Browser.CHROMIUM, null, "53");
2665
+ const id = setInterval(() => {
2666
+ if (media.paused || media.ended) return stop();
2667
+ if (media.currentTime !== lastTime) {
2668
+ lastTime = media.currentTime;
2669
+ if (!sawPlaying || recovered) fabricatePlaying();
2670
+ return stop();
2671
+ }
2672
+ if (!nudgeUnbuffered && !withinBufferedData(media, bufferEndMargin)) {
2673
+ stalledFor = 0;
2674
+ return;
2675
+ }
2676
+ stalledFor += pollInterval;
2677
+ if (stalledFor < stallThreshold) return;
2678
+ stalledFor = 0;
2679
+ if (attempts++ >= maxAttempts) return stop();
2680
+ recovered = true;
2681
+ media.currentTime += stallSkip;
2682
+ lastTime = media.currentTime;
2683
+ }, pollInterval * 1e3);
2684
+ return stop;
2685
+ }
2686
+ function withinBufferedData(media, endMargin) {
2687
+ const t = media.currentTime;
2688
+ const duration = media.duration;
2689
+ const buffered = media.buffered;
2690
+ for (let i = 0; i < buffered.length; i++) {
2691
+ const end = buffered.end(i);
2692
+ const isEndOfMedia = Number.isFinite(duration) && duration > 0 && end >= duration - endMargin;
2693
+ if (t >= buffered.start(i) && (t < end - endMargin || isEndOfMedia))
2694
+ return true;
2695
+ }
2696
+ return false;
2783
2697
  }
2784
2698
 
2785
- // src/patch/media/patches/createPreventStallsPatch.ts
2786
- import {
2787
- Browser as Browser2,
2788
- closeTo as closeTo2,
2789
- createDisposer as createDisposer4,
2790
- createLogPrefix as createLogPrefix2,
2791
- DomEventHost as DomEventHost2,
2792
- hasBrowser as hasBrowser2,
2793
- logInfo,
2794
- logWarn as logWarn2,
2795
- noop as noop4
2796
- } from "@amazon/vinyl-util";
2797
- var MAX_UNCHANGED_COUNT = 10;
2798
- function createPreventStallsPatch(media) {
2799
- const { add, dispose } = createDisposer4();
2800
- const domEvents = add(new DomEventHost2(media));
2801
- const pathTarget = {
2802
- logPrefix: createLogPrefix2("createPreventStallsPatch")
2699
+ // src/playback/createStallMonitor.ts
2700
+ import { createDisposer as createDisposer3 } from "@amazon/vinyl-util";
2701
+
2702
+ // src/playback/ReadonlyPlaybackController.ts
2703
+ var PlayedReason = /* @__PURE__ */ ((PlayedReason2) => {
2704
+ PlayedReason2["EMPTIED"] = "emptied";
2705
+ PlayedReason2["ENDED"] = "ended";
2706
+ PlayedReason2["PAUSE"] = "pause";
2707
+ PlayedReason2["SEEKING"] = "seeking";
2708
+ PlayedReason2["WAITING"] = "waiting";
2709
+ return PlayedReason2;
2710
+ })(PlayedReason || {});
2711
+ var playedReasons = [
2712
+ "emptied" /* EMPTIED */,
2713
+ "ended" /* ENDED */,
2714
+ "pause" /* PAUSE */,
2715
+ "seeking" /* SEEKING */,
2716
+ "waiting" /* WAITING */
2717
+ ];
2718
+ var WaitedReason = /* @__PURE__ */ ((WaitedReason2) => {
2719
+ WaitedReason2["PLAYING"] = "playing";
2720
+ WaitedReason2["PAUSE"] = "pause";
2721
+ WaitedReason2["EMPTIED"] = "emptied";
2722
+ WaitedReason2["SEEKING"] = "seeking";
2723
+ return WaitedReason2;
2724
+ })(WaitedReason || {});
2725
+ var waitedReasons = [
2726
+ "playing" /* PLAYING */,
2727
+ "pause" /* PAUSE */,
2728
+ "emptied" /* EMPTIED */,
2729
+ "seeking" /* SEEKING */
2730
+ ];
2731
+ var StallEndedReason = /* @__PURE__ */ ((StallEndedReason2) => {
2732
+ StallEndedReason2["PLAYING"] = "playing";
2733
+ StallEndedReason2["PAUSE"] = "pause";
2734
+ StallEndedReason2["SEEKING"] = "seeking";
2735
+ StallEndedReason2["EMPTIED"] = "emptied";
2736
+ return StallEndedReason2;
2737
+ })(StallEndedReason || {});
2738
+ var ALL_PLAYBACK_STATE_EVENTS = [
2739
+ "abort",
2740
+ "canPlay",
2741
+ "canPlayThrough",
2742
+ "durationChange",
2743
+ "emptied",
2744
+ "ended",
2745
+ "error",
2746
+ "playIsPendingChange",
2747
+ "loadedData",
2748
+ "loadedMetadata",
2749
+ "loadStart",
2750
+ "looped",
2751
+ "mutedChange",
2752
+ "pause",
2753
+ "play",
2754
+ "playRejected",
2755
+ "played",
2756
+ "playing",
2757
+ "progress",
2758
+ "rateChange",
2759
+ "readyStateChange",
2760
+ "reset",
2761
+ "resize",
2762
+ "seeked",
2763
+ "seeking",
2764
+ "stallEntered",
2765
+ "stallEnded",
2766
+ "timeUpdate",
2767
+ "volumeChange",
2768
+ "waited",
2769
+ "waiting",
2770
+ "waitingForKey"
2771
+ ];
2772
+ var PlaybackReadyState = /* @__PURE__ */ ((PlaybackReadyState2) => {
2773
+ PlaybackReadyState2[PlaybackReadyState2["HAVE_NOTHING"] = 0] = "HAVE_NOTHING";
2774
+ PlaybackReadyState2[PlaybackReadyState2["HAVE_METADATA"] = 1] = "HAVE_METADATA";
2775
+ PlaybackReadyState2[PlaybackReadyState2["HAVE_CURRENT_DATA"] = 2] = "HAVE_CURRENT_DATA";
2776
+ PlaybackReadyState2[PlaybackReadyState2["HAVE_FUTURE_DATA"] = 3] = "HAVE_FUTURE_DATA";
2777
+ PlaybackReadyState2[PlaybackReadyState2["HAVE_ENOUGH_DATA"] = 4] = "HAVE_ENOUGH_DATA";
2778
+ return PlaybackReadyState2;
2779
+ })(PlaybackReadyState || {});
2780
+ var PlaybackNetworkState = /* @__PURE__ */ ((PlaybackNetworkState2) => {
2781
+ PlaybackNetworkState2[PlaybackNetworkState2["NETWORK_EMPTY"] = 0] = "NETWORK_EMPTY";
2782
+ PlaybackNetworkState2[PlaybackNetworkState2["NETWORK_IDLE"] = 1] = "NETWORK_IDLE";
2783
+ PlaybackNetworkState2[PlaybackNetworkState2["NETWORK_LOADING"] = 2] = "NETWORK_LOADING";
2784
+ PlaybackNetworkState2[PlaybackNetworkState2["NETWORK_NO_SOURCE"] = 3] = "NETWORK_NO_SOURCE";
2785
+ return PlaybackNetworkState2;
2786
+ })(PlaybackNetworkState || {});
2787
+
2788
+ // src/playback/createStallMonitor.ts
2789
+ function createStallMonitor(controller, callbacks, options = {}) {
2790
+ var _a, _b;
2791
+ const stallThresholdMs = ((_a = options.stallThreshold) != null ? _a : 1) * 1e3;
2792
+ const pollIntervalMs = ((_b = options.pollInterval) != null ? _b : 0.25) * 1e3;
2793
+ let observedPlaying = false;
2794
+ let lastProgressAt = Date.now();
2795
+ let inStall = false;
2796
+ let pollId = null;
2797
+ const endStall = (reason) => {
2798
+ if (!inStall) return;
2799
+ inStall = false;
2800
+ const ended = Date.now();
2801
+ callbacks.onStallEnded({
2802
+ started: lastProgressAt,
2803
+ ended,
2804
+ duration: (ended - lastProgressAt) / 1e3,
2805
+ reason
2806
+ });
2803
2807
  };
2804
- let unchangedCount = 0;
2805
- let attemptedFix = false;
2806
- let previousTime = media.currentTime;
2807
- domEvents.on("timeupdate", () => {
2808
- if (media.paused) return;
2809
- if (closeTo2(media.currentTime, previousTime, 0.01)) {
2810
- if (++unchangedCount >= MAX_UNCHANGED_COUNT && !attemptedFix) {
2811
- logWarn2(
2812
- pathTarget,
2813
- `Detected stall at time ${media.currentTime}, attempting fix`
2814
- );
2815
- attemptedFix = true;
2816
- unchangedCount = 0;
2817
- media.pause();
2818
- media.play().catch(noop4);
2819
- }
2820
- } else {
2821
- if (attemptedFix) {
2822
- logInfo(pathTarget, "stall ended");
2823
- attemptedFix = false;
2808
+ const stopPoll = () => {
2809
+ if (pollId == null) return;
2810
+ clearInterval(pollId);
2811
+ pollId = null;
2812
+ };
2813
+ const startPoll = () => {
2814
+ if (pollId != null) return;
2815
+ pollId = setInterval(() => {
2816
+ if (inStall || !observedPlaying) return;
2817
+ if (Date.now() - lastProgressAt >= stallThresholdMs) {
2818
+ inStall = true;
2819
+ callbacks.onStallEntered();
2824
2820
  }
2825
- unchangedCount = 0;
2826
- previousTime = media.currentTime;
2827
- }
2828
- });
2829
- return {
2830
- dispose
2821
+ }, pollIntervalMs);
2831
2822
  };
2832
- }
2833
- function requiresPreventStallsPatch() {
2834
- return hasBrowser2(Browser2.EDGE_LEGACY);
2835
- }
2836
-
2837
- // src/patch/media/MediaElementPatchOptions.ts
2838
- var defaultMediaElementPatchOptions = /* @__PURE__ */ lazy2(() => {
2839
- return {
2840
- unreliablePlaybackEvents: requiresUnreliablePlaybackEventsPatch(),
2841
- preventStalls: requiresPreventStallsPatch()
2823
+ const suspend = (reason) => {
2824
+ endStall(reason);
2825
+ observedPlaying = false;
2826
+ stopPoll();
2842
2827
  };
2843
- });
2844
-
2845
- // src/patch/media/patchMediaElement.ts
2846
- import { patchTargetFromFlags } from "@amazon/vinyl-util";
2847
- function patchMediaElement(media, options) {
2848
- return patchTargetFromFlags(
2849
- media,
2850
- options,
2851
- ["unreliablePlaybackEvents", createUnreliablePlaybackEventsPatch],
2852
- ["preventStalls", createPreventStallsPatch]
2828
+ const { add, dispose } = createDisposer3();
2829
+ add(
2830
+ controller.on("playing", () => {
2831
+ if (inStall) endStall("playing" /* PLAYING */);
2832
+ else lastProgressAt = Date.now();
2833
+ observedPlaying = true;
2834
+ startPoll();
2835
+ })
2836
+ );
2837
+ add(
2838
+ controller.on("timeUpdate", () => {
2839
+ if (inStall) endStall("playing" /* PLAYING */);
2840
+ lastProgressAt = Date.now();
2841
+ })
2853
2842
  );
2843
+ add(controller.on("pause", () => suspend("pause" /* PAUSE */)));
2844
+ add(controller.on("seeking", () => suspend("seeking" /* SEEKING */)));
2845
+ add(controller.on("emptied", () => suspend("emptied" /* EMPTIED */)));
2846
+ let stopped = false;
2847
+ return () => {
2848
+ if (stopped) return;
2849
+ stopped = true;
2850
+ stopPoll();
2851
+ dispose();
2852
+ };
2854
2853
  }
2855
2854
 
2856
2855
  // src/playback/error/InvalidSeekError.ts
@@ -2953,90 +2952,11 @@ __publicField(_ReportableMediaError, "MEDIA_ERR_SRC_NOT_SUPPORTED", 4);
2953
2952
  var ReportableMediaError = _ReportableMediaError;
2954
2953
 
2955
2954
  // src/playback/logging/playbackStateLoggingHandler.ts
2956
- import { createDisposer as createDisposer5 } from "@amazon/vinyl-util";
2955
+ import { createDisposer as createDisposer4 } from "@amazon/vinyl-util";
2957
2956
  import { logDebug as logDebug4 } from "@amazon/vinyl-util";
2958
-
2959
- // src/playback/ReadonlyPlaybackController.ts
2960
- var PlayedReason = /* @__PURE__ */ ((PlayedReason2) => {
2961
- PlayedReason2["EMPTIED"] = "emptied";
2962
- PlayedReason2["ENDED"] = "ended";
2963
- PlayedReason2["PAUSE"] = "pause";
2964
- PlayedReason2["SEEKING"] = "seeking";
2965
- PlayedReason2["WAITING"] = "waiting";
2966
- return PlayedReason2;
2967
- })(PlayedReason || {});
2968
- var playedReasons = [
2969
- "emptied" /* EMPTIED */,
2970
- "ended" /* ENDED */,
2971
- "pause" /* PAUSE */,
2972
- "seeking" /* SEEKING */,
2973
- "waiting" /* WAITING */
2974
- ];
2975
- var WaitedReason = /* @__PURE__ */ ((WaitedReason2) => {
2976
- WaitedReason2["PLAYING"] = "playing";
2977
- WaitedReason2["PAUSE"] = "pause";
2978
- WaitedReason2["EMPTIED"] = "emptied";
2979
- WaitedReason2["SEEKING"] = "seeking";
2980
- return WaitedReason2;
2981
- })(WaitedReason || {});
2982
- var waitedReasons = [
2983
- "playing" /* PLAYING */,
2984
- "pause" /* PAUSE */,
2985
- "emptied" /* EMPTIED */,
2986
- "seeking" /* SEEKING */
2987
- ];
2988
- var ALL_PLAYBACK_STATE_EVENTS = [
2989
- "abort",
2990
- "canPlay",
2991
- "canPlayThrough",
2992
- "durationChange",
2993
- "emptied",
2994
- "ended",
2995
- "error",
2996
- "playIsPendingChange",
2997
- "loadedData",
2998
- "loadedMetadata",
2999
- "loadStart",
3000
- "looped",
3001
- "mutedChange",
3002
- "pause",
3003
- "play",
3004
- "playRejected",
3005
- "played",
3006
- "playing",
3007
- "progress",
3008
- "rateChange",
3009
- "readyStateChange",
3010
- "reset",
3011
- "resize",
3012
- "seeked",
3013
- "seeking",
3014
- "timeUpdate",
3015
- "volumeChange",
3016
- "waited",
3017
- "waiting",
3018
- "waitingForKey"
3019
- ];
3020
- var PlaybackReadyState = /* @__PURE__ */ ((PlaybackReadyState2) => {
3021
- PlaybackReadyState2[PlaybackReadyState2["HAVE_NOTHING"] = 0] = "HAVE_NOTHING";
3022
- PlaybackReadyState2[PlaybackReadyState2["HAVE_METADATA"] = 1] = "HAVE_METADATA";
3023
- PlaybackReadyState2[PlaybackReadyState2["HAVE_CURRENT_DATA"] = 2] = "HAVE_CURRENT_DATA";
3024
- PlaybackReadyState2[PlaybackReadyState2["HAVE_FUTURE_DATA"] = 3] = "HAVE_FUTURE_DATA";
3025
- PlaybackReadyState2[PlaybackReadyState2["HAVE_ENOUGH_DATA"] = 4] = "HAVE_ENOUGH_DATA";
3026
- return PlaybackReadyState2;
3027
- })(PlaybackReadyState || {});
3028
- var PlaybackNetworkState = /* @__PURE__ */ ((PlaybackNetworkState2) => {
3029
- PlaybackNetworkState2[PlaybackNetworkState2["NETWORK_EMPTY"] = 0] = "NETWORK_EMPTY";
3030
- PlaybackNetworkState2[PlaybackNetworkState2["NETWORK_IDLE"] = 1] = "NETWORK_IDLE";
3031
- PlaybackNetworkState2[PlaybackNetworkState2["NETWORK_LOADING"] = 2] = "NETWORK_LOADING";
3032
- PlaybackNetworkState2[PlaybackNetworkState2["NETWORK_NO_SOURCE"] = 3] = "NETWORK_NO_SOURCE";
3033
- return PlaybackNetworkState2;
3034
- })(PlaybackNetworkState || {});
3035
-
3036
- // src/playback/logging/playbackStateLoggingHandler.ts
3037
2957
  import { throttle } from "@amazon/vinyl-util";
3038
2958
  import { substitute as substitute2 } from "@amazon/vinyl-util";
3039
- import { createLogPrefix as createLogPrefix3 } from "@amazon/vinyl-util";
2959
+ import { createLogPrefix as createLogPrefix2 } from "@amazon/vinyl-util";
3040
2960
  var TIMEUPDATE_THROTTLE = 5;
3041
2961
  var locale2 = {
3042
2962
  /**
@@ -3050,9 +2970,9 @@ var locale2 = {
3050
2970
  };
3051
2971
  function playbackStateLoggingHandler(playbackState) {
3052
2972
  const target = {
3053
- logPrefix: createLogPrefix3("Playback")
2973
+ logPrefix: createLogPrefix2("Playback")
3054
2974
  };
3055
- const disposer = createDisposer5();
2975
+ const disposer = createDisposer4();
3056
2976
  const { add } = disposer;
3057
2977
  let timeUpdateCount = 0;
3058
2978
  let startTime = null;
@@ -3093,12 +3013,12 @@ function playbackStateLoggingHandler(playbackState) {
3093
3013
  }
3094
3014
 
3095
3015
  // src/playback/loudness/LoudnessNormalizationControllerImpl.ts
3096
- import { createDisposer as createDisposer6 } from "@amazon/vinyl-util";
3016
+ import { createDisposer as createDisposer5 } from "@amazon/vinyl-util";
3097
3017
  import {
3098
3018
  logDebug as logDebug5,
3099
- createLogPrefix as createLogPrefix4,
3019
+ createLogPrefix as createLogPrefix3,
3100
3020
  EventHostImpl as EventHostImpl6,
3101
- closeTo as closeTo3
3021
+ closeTo
3102
3022
  } from "@amazon/vinyl-util";
3103
3023
 
3104
3024
  // src/playback/loudness/LoudnessNormalizationControllerImplOptions.ts
@@ -3121,9 +3041,9 @@ var LoudnessNormalizationControllerImpl = class extends EventHostImpl6 {
3121
3041
  constructor(deps) {
3122
3042
  super();
3123
3043
  __publicField(this, "deps", deps);
3124
- __publicField(this, "logPrefix", /* @__PURE__ */ createLogPrefix4(this));
3044
+ __publicField(this, "logPrefix", /* @__PURE__ */ createLogPrefix3(this));
3125
3045
  __publicField(this, "_gain", MAX_GAIN_LEVEL);
3126
- __publicField(this, "disposer", /* @__PURE__ */ createDisposer6());
3046
+ __publicField(this, "disposer", /* @__PURE__ */ createDisposer5());
3127
3047
  __publicField(this, "trackLoudness", null);
3128
3048
  __publicField(this, "_options", defaultLoudnessNormalizationControllerImplOptions);
3129
3049
  const { add } = this.disposer;
@@ -3157,7 +3077,7 @@ var LoudnessNormalizationControllerImpl = class extends EventHostImpl6 {
3157
3077
  */
3158
3078
  set gain(value) {
3159
3079
  const previousGain = this._gain;
3160
- if (!closeTo3(previousGain, value)) {
3080
+ if (!closeTo(previousGain, value)) {
3161
3081
  this._gain = value;
3162
3082
  logDebug5(this, "loudness gain adjustment:", {
3163
3083
  trackLoudness: this.trackLoudness,
@@ -3211,22 +3131,22 @@ var LIVE_DURATION = 4294967296;
3211
3131
  import {
3212
3132
  Abort,
3213
3133
  AbortError as AbortError2,
3214
- Browser as Browser3,
3134
+ Browser,
3215
3135
  clamp,
3216
- closeTo as closeTo4,
3217
- createDisposer as createDisposer7,
3136
+ closeTo as closeTo2,
3137
+ createDisposer as createDisposer6,
3218
3138
  createTimeRangesReader,
3219
- DomEventHost as DomEventHost3,
3139
+ DomEventHost,
3220
3140
  ErrorLevel as ErrorLevel7,
3221
3141
  ErrorOrigin as ErrorOrigin12,
3222
3142
  EventHostImpl as EventHostImpl7,
3223
- getUserAgentInfo as getUserAgentInfo3,
3224
- hasBrowser as hasBrowser3,
3143
+ hasBrowser,
3225
3144
  logDebug as logDebug6,
3226
- logInfo as logInfo2,
3227
- logWarn as logWarn3,
3145
+ logInfo,
3146
+ logWarn as logWarn2,
3228
3147
  nextEventAsPromise as nextEventAsPromise2,
3229
- onAny as onAny2,
3148
+ noop as noop4,
3149
+ onAny,
3230
3150
  ownKeys,
3231
3151
  TimeoutSlot,
3232
3152
  toLowerCase,
@@ -3238,11 +3158,14 @@ var defaultPlaybackControllerImplOptions = {
3238
3158
  minSeekableBuffer: -1,
3239
3159
  // Default comes from getMinSeekableBufferDefault()
3240
3160
  playTimeout: 30,
3241
- seekTimeout: 30
3161
+ seekTimeout: 30,
3162
+ stallThreshold: 1
3242
3163
  };
3243
3164
  function getMinSeekableBufferDefault() {
3244
- return !hasBrowser3(Browser3.CHROMIUM) ? 5 : 2;
3165
+ return !hasBrowser(Browser.CHROMIUM) ? 5 : 2;
3245
3166
  }
3167
+ var SEEK_RETRY_LIMIT = 2;
3168
+ var SEEK_ATTEMPT_TIMEOUT = 4;
3246
3169
  var PlaybackControllerImpl = class extends EventHostImpl7 {
3247
3170
  constructor(deps, options) {
3248
3171
  super();
@@ -3250,12 +3173,14 @@ var PlaybackControllerImpl = class extends EventHostImpl7 {
3250
3173
  __publicField(this, "_error", null);
3251
3174
  __publicField(this, "media");
3252
3175
  __publicField(this, "domEvents");
3253
- __publicField(this, "disposer", /* @__PURE__ */ createDisposer7());
3176
+ __publicField(this, "disposer", /* @__PURE__ */ createDisposer6());
3254
3177
  __publicField(this, "_playing", false);
3255
3178
  __publicField(this, "_seeking", false);
3256
3179
  __publicField(this, "_waiting", false);
3257
3180
  // Monotonic counter identifying the most recent seekTo call.
3258
3181
  __publicField(this, "_seekId", 0);
3182
+ // Stops the stall detector started after the last seek, if any.
3183
+ __publicField(this, "stopStallDetection", null);
3259
3184
  // default user volume (0.0 to 1.0 scale)
3260
3185
  __publicField(this, "userVolume", 1);
3261
3186
  __publicField(this, "_pendingPlay", null);
@@ -3266,21 +3191,23 @@ var PlaybackControllerImpl = class extends EventHostImpl7 {
3266
3191
  minSeekableBuffer: getMinSeekableBufferDefault()
3267
3192
  }), options);
3268
3193
  this.loudnessNormalizationController = deps.loudnessNormalizationController;
3269
- logInfo2(this, "constructed", this.options);
3194
+ logInfo(this, "constructed", this.options);
3270
3195
  this.media = deps.media;
3271
3196
  const { add } = this.disposer;
3272
3197
  add(() => {
3198
+ var _a;
3273
3199
  this.disposeAbort.abort();
3274
3200
  this.disposeAbort.dispose();
3201
+ (_a = this.stopStallDetection) == null ? void 0 : _a.call(this);
3275
3202
  });
3276
3203
  this.domEvents = add(
3277
- new DomEventHost3(deps.media)
3204
+ new DomEventHost(deps.media)
3278
3205
  );
3279
3206
  add(playbackStateLoggingHandler(this));
3280
3207
  this.domEvents.on("error", (_) => {
3281
3208
  const error = new ReportableMediaError(this.media.error);
3282
3209
  if (error.level === ErrorLevel7.SILENT) {
3283
- logInfo2(this, error.message);
3210
+ logInfo(this, error.message);
3284
3211
  return;
3285
3212
  }
3286
3213
  this._error = error;
@@ -3290,6 +3217,16 @@ var PlaybackControllerImpl = class extends EventHostImpl7 {
3290
3217
  });
3291
3218
  });
3292
3219
  this.initializeEvents();
3220
+ add(
3221
+ createStallMonitor(
3222
+ this,
3223
+ {
3224
+ onStallEntered: () => this.dispatch("stallEntered", {}),
3225
+ onStallEnded: (info) => this.dispatch("stallEnded", info)
3226
+ },
3227
+ { stallThreshold: this.options.stallThreshold }
3228
+ )
3229
+ );
3293
3230
  add(
3294
3231
  this.loudnessNormalizationController.on("change", () => {
3295
3232
  this.refreshVolume();
@@ -3447,7 +3384,7 @@ var PlaybackControllerImpl = class extends EventHostImpl7 {
3447
3384
  started = true;
3448
3385
  startedAt = Date.now();
3449
3386
  });
3450
- onAny2(host, endEvents, (_, event) => {
3387
+ onAny(host, endEvents, (_, event) => {
3451
3388
  if (started) {
3452
3389
  started = false;
3453
3390
  const now = Date.now();
@@ -3496,9 +3433,8 @@ var PlaybackControllerImpl = class extends EventHostImpl7 {
3496
3433
  initializeLoopedEvent() {
3497
3434
  let lastTime = 0;
3498
3435
  this.on("timeUpdate", () => {
3499
- var _a;
3500
3436
  if (this.loop && !this.paused && this.currentTime <= this.options.loopTimeAffordance && lastTime >= this.duration - this.options.loopTimeAffordance) {
3501
- if (((_a = getUserAgentInfo3().browserLike) == null ? void 0 : _a.name) === Browser3.FIREFOX) {
3437
+ if (hasBrowser(Browser.FIREFOX)) {
3502
3438
  logDebug6(this, "fabricating Firefox playing event on loop");
3503
3439
  this.dispatch("playing", {});
3504
3440
  }
@@ -3612,8 +3548,25 @@ var PlaybackControllerImpl = class extends EventHostImpl7 {
3612
3548
  current: value != null
3613
3549
  });
3614
3550
  }
3551
+ /**
3552
+ * Starts (or restarts) the stall detector: recovers a play head that stays frozen when it
3553
+ * should be advancing — some WebKit versions never resume after a seek or a play, e.g. after a
3554
+ * buffer-flushing seek. Superseded by the next seek/play and stopped on dispose.
3555
+ * @private
3556
+ */
3557
+ startStallDetection() {
3558
+ var _a;
3559
+ (_a = this.stopStallDetection) == null ? void 0 : _a.call(this);
3560
+ this.stopStallDetection = createStallDetector(this.media, {
3561
+ fabricatePlaying: () => this.dispatch("playing", {}),
3562
+ // Safari/iOS can leave a seek on a freshly-attached source pending
3563
+ // with a stale empty `buffered`; re-issue the seek to un-stick it.
3564
+ nudgeUnbuffered: hasBrowser(Browser.WEBKIT)
3565
+ });
3566
+ }
3615
3567
  play() {
3616
3568
  logDebug6(this, "play");
3569
+ this.startStallDetection();
3617
3570
  if (!this.pendingPlay) {
3618
3571
  const playAbort = new Abort();
3619
3572
  this.playAbort = playAbort;
@@ -3655,16 +3608,20 @@ var PlaybackControllerImpl = class extends EventHostImpl7 {
3655
3608
  return this.pendingPlay != null;
3656
3609
  }
3657
3610
  async seekTo(time, tolerance = 0.5) {
3611
+ var _a;
3658
3612
  logDebug6(this, `seekTo: ${time}`);
3659
3613
  const seekId = ++this._seekId;
3614
+ (_a = this.stopStallDetection) == null ? void 0 : _a.call(this);
3615
+ this.stopStallDetection = null;
3660
3616
  const superseded = () => {
3661
3617
  if (this._seekId === seekId) return false;
3662
3618
  logDebug6(this, `seekTo: ${time} superseded by a newer seek`);
3663
3619
  return true;
3664
3620
  };
3665
- const nextEvent = (type) => {
3621
+ const nextEvent = (type, options) => {
3622
+ var _a2;
3666
3623
  return nextEventAsPromise2(this, type, {
3667
- timeout: this.options.seekTimeout,
3624
+ timeout: (_a2 = options == null ? void 0 : options.timeout) != null ? _a2 : this.options.seekTimeout,
3668
3625
  timeoutMessage: `seek timed out on ${type} event after {time}s`,
3669
3626
  timeoutOrigin: ErrorOrigin12.INTERNAL,
3670
3627
  timeoutLevel: ErrorLevel7.WARN,
@@ -3681,7 +3638,7 @@ var PlaybackControllerImpl = class extends EventHostImpl7 {
3681
3638
  tolerance
3682
3639
  );
3683
3640
  if (range == null) {
3684
- logWarn3(
3641
+ logWarn2(
3685
3642
  this,
3686
3643
  `seekTo: seek outside of seekable ranges, seek ignored`,
3687
3644
  seekable.ranges
@@ -3697,19 +3654,36 @@ var PlaybackControllerImpl = class extends EventHostImpl7 {
3697
3654
  this,
3698
3655
  `seekTo operation, requested: ${time}, actual: ${clampedTime}`
3699
3656
  );
3700
- if (closeTo4(clampedTime, this.currentTime, tolerance)) {
3657
+ if (closeTo2(clampedTime, this.currentTime, tolerance)) {
3701
3658
  logDebug6(
3702
3659
  this,
3703
3660
  `seekTo: requested: ${time}, actual: ${clampedTime} no-op`
3704
3661
  );
3705
3662
  } else {
3706
- const seeking = nextEvent("seeking");
3707
- this.media.currentTime = clampedTime;
3708
- await seeking;
3709
- const seekedEvent = await nextEvent("seeked");
3710
- if (seekedEvent.reason === "emptied") {
3663
+ const nullIfStuck = (error) => {
3664
+ if (this.disposeAbort.aborted()) throw error;
3665
+ return null;
3666
+ };
3667
+ const seekOnce = async (reSeeking) => {
3668
+ const seeking = reSeeking ? nextEvent("seeking", {
3669
+ timeout: SEEK_ATTEMPT_TIMEOUT
3670
+ }).catch(nullIfStuck) : nextEvent("seeking");
3671
+ this.media.currentTime = clampedTime;
3672
+ if (await seeking === null) return null;
3673
+ return nextEvent("seeked", {
3674
+ timeout: SEEK_ATTEMPT_TIMEOUT
3675
+ }).catch(nullIfStuck);
3676
+ };
3677
+ let seekedEvent = await seekOnce(false);
3678
+ for (let attempt = 0; !superseded() && attempt < SEEK_RETRY_LIMIT && (seekedEvent === null || seekedEvent.reason === "seeked" && !closeTo2(clampedTime, this.currentTime, tolerance)); attempt++) {
3679
+ if (seekedEvent === null) void this.media.play().catch(noop4);
3680
+ logDebug6(this, `seekTo: re-seeking to ${clampedTime}`);
3681
+ seekedEvent = await seekOnce(true);
3682
+ }
3683
+ if ((seekedEvent == null ? void 0 : seekedEvent.reason) === "emptied") {
3711
3684
  throw new AbortError2();
3712
3685
  }
3686
+ if (!this.paused) this.startStallDetection();
3713
3687
  }
3714
3688
  }
3715
3689
  /**
@@ -3718,7 +3692,7 @@ var PlaybackControllerImpl = class extends EventHostImpl7 {
3718
3692
  */
3719
3693
  initializeReadyStateChangeEvent() {
3720
3694
  let previous = this.readyState;
3721
- onAny2(
3695
+ onAny(
3722
3696
  this,
3723
3697
  [
3724
3698
  "canPlay",
@@ -3805,8 +3779,8 @@ var PlaybackSourceImpl = class {
3805
3779
  // src/streaming/abr/QualitySelectorImpl.ts
3806
3780
  import {
3807
3781
  clamp as clamp2,
3808
- createDisposer as createDisposer8,
3809
- createLogPrefix as createLogPrefix5,
3782
+ createDisposer as createDisposer7,
3783
+ createLogPrefix as createLogPrefix4,
3810
3784
  getNetworkMetrics as getNetworkMetrics2,
3811
3785
  lerp as lerp2
3812
3786
  } from "@amazon/vinyl-util";
@@ -3847,9 +3821,9 @@ var defaultQualitySelectorImplOptions = {
3847
3821
  };
3848
3822
  var QualitySelectorImpl = class {
3849
3823
  constructor(deps) {
3850
- __publicField(this, "logPrefix", /* @__PURE__ */ createLogPrefix5(this));
3824
+ __publicField(this, "logPrefix", /* @__PURE__ */ createLogPrefix4(this));
3851
3825
  __publicField(this, "_options", defaultQualitySelectorImplOptions);
3852
- __publicField(this, "disposer", /* @__PURE__ */ createDisposer8());
3826
+ __publicField(this, "disposer", /* @__PURE__ */ createDisposer7());
3853
3827
  const { add } = this.disposer;
3854
3828
  add(
3855
3829
  deps.options.onData((v) => {
@@ -3937,23 +3911,33 @@ var QualitySelectorImpl = class {
3937
3911
  };
3938
3912
 
3939
3913
  // src/streaming/AudioOptions.ts
3940
- import { array, boolean as boolean3, object as object7, string as string4 } from "@amazon/vinyl-validation";
3914
+ import {
3915
+ array,
3916
+ boolean as boolean3,
3917
+ number as number5,
3918
+ object as object7,
3919
+ string as string4
3920
+ } from "@amazon/vinyl-validation";
3941
3921
  var defaultAudioOptions = {
3942
- selection: { language: null, descriptive: false }
3922
+ selection: { language: null, descriptive: false },
3923
+ disableSampleRateFilter: false
3943
3924
  };
3944
3925
  var audioSelectionValidator = /* @__PURE__ */ object7({
3945
3926
  language: /* @__PURE__ */ string4().or(/* @__PURE__ */ array(/* @__PURE__ */ string4()).readonly()).orNull().optional(),
3946
3927
  descriptive: /* @__PURE__ */ boolean3().optional()
3947
3928
  });
3948
3929
  var audioOptionsValidator = /* @__PURE__ */ object7({
3949
- selection: /* @__PURE__ */ audioSelectionValidator.optional()
3930
+ selection: /* @__PURE__ */ audioSelectionValidator.optional(),
3931
+ disableSampleRateFilter: /* @__PURE__ */ boolean3().optional(),
3932
+ maxSampleRate: /* @__PURE__ */ number5().maybe().optional(),
3933
+ minSampleRate: /* @__PURE__ */ number5().maybe().optional()
3950
3934
  });
3951
3935
 
3952
3936
  // src/streaming/buffering/BufferingController.ts
3953
3937
  import {
3954
3938
  createAbortSlot,
3955
- createDisposer as createDisposer9,
3956
- createLogPrefix as createLogPrefix6,
3939
+ createDisposer as createDisposer8,
3940
+ createLogPrefix as createLogPrefix5,
3957
3941
  createTaskQueue,
3958
3942
  EventHostImpl as EventHostImpl8,
3959
3943
  getLogLevel,
@@ -3962,7 +3946,7 @@ import {
3962
3946
  logDebug as logDebug7,
3963
3947
  LogLevel as LogLevel2,
3964
3948
  logVerbose as logVerbose3,
3965
- logWarn as logWarn4,
3949
+ logWarn as logWarn3,
3966
3950
  throttle as throttle2
3967
3951
  } from "@amazon/vinyl-util";
3968
3952
 
@@ -4067,9 +4051,8 @@ var BufferingControllerImpl = class extends EventHostImpl8 {
4067
4051
  __publicField(this, "reopen", false);
4068
4052
  __publicField(this, "_error", null);
4069
4053
  __publicField(this, "_bufferingEnded", false);
4070
- __publicField(this, "_hasData", false);
4071
4054
  __publicField(this, "queue", /* @__PURE__ */ createTaskQueue());
4072
- __publicField(this, "disposer", /* @__PURE__ */ createDisposer9());
4055
+ __publicField(this, "disposer", /* @__PURE__ */ createDisposer8());
4073
4056
  __publicField(this, "_active", false);
4074
4057
  __publicField(this, "activateDisposer", null);
4075
4058
  __publicField(this, "segmentAbort", /* @__PURE__ */ createAbortSlot());
@@ -4123,7 +4106,7 @@ var BufferingControllerImpl = class extends EventHostImpl8 {
4123
4106
  const newAppendSize = this.getMaxAppendSize(contentType2) * QUOTA_REACHED_SCALE;
4124
4107
  if (newAppendSize >= MIN_APPEND_SIZE) {
4125
4108
  sourceBufferQuotas.set(contentType2, newAppendSize);
4126
- logWarn4(
4109
+ logWarn3(
4127
4110
  this,
4128
4111
  "QuotaExceededError, new source buffer limit:",
4129
4112
  (newAppendSize / 1024 / 1024).toFixed(1) + " MiB"
@@ -4156,7 +4139,7 @@ var BufferingControllerImpl = class extends EventHostImpl8 {
4156
4139
  await this.sourceBufferController.clear();
4157
4140
  logVerbose3(this, "finishAndClearBuffers complete");
4158
4141
  });
4159
- this.logPrefix = createLogPrefix6(`Buffering_${contentType2}`);
4142
+ this.logPrefix = createLogPrefix5(`Buffering_${contentType2}`);
4160
4143
  this.options = __spreadValues(__spreadValues({}, defaultBufferingControllerOptions), options);
4161
4144
  logDebug7(this, "constructed", this.options);
4162
4145
  this.mediaSourceController = deps.mediaSourceController;
@@ -4176,7 +4159,7 @@ var BufferingControllerImpl = class extends EventHostImpl8 {
4176
4159
  if (this._active) return;
4177
4160
  this._active = true;
4178
4161
  logDebug7(this, "activate");
4179
- this.activateDisposer = createDisposer9();
4162
+ this.activateDisposer = createDisposer8();
4180
4163
  const { add } = this.activateDisposer;
4181
4164
  this.sourceBufferController = add(
4182
4165
  this.deps.sourceBufferControllerFactory()
@@ -4316,7 +4299,6 @@ var BufferingControllerImpl = class extends EventHostImpl8 {
4316
4299
  this.buffered.push(streamingSegment);
4317
4300
  }
4318
4301
  if (!tail) this.refreshHead();
4319
- this.setHasData(true);
4320
4302
  }
4321
4303
  abortCurrentSegment() {
4322
4304
  this.segmentAbort.abort();
@@ -4400,15 +4382,6 @@ var BufferingControllerImpl = class extends EventHostImpl8 {
4400
4382
  get bufferingEnded() {
4401
4383
  return this._bufferingEnded;
4402
4384
  }
4403
- get hasData() {
4404
- return this._hasData;
4405
- }
4406
- setHasData(value) {
4407
- if (this._hasData === value) return;
4408
- const previous = this._hasData;
4409
- this._hasData = value;
4410
- this.dispatch("hasDataChange", { previous, current: value });
4411
- }
4412
4385
  /**
4413
4386
  * Attempts to recover from a SourceBuffer decode/append failure caused by a
4414
4387
  * codec the browser reported as supported but cannot actually decode.
@@ -4429,7 +4402,7 @@ var BufferingControllerImpl = class extends EventHostImpl8 {
4429
4402
  const contentType2 = quality == null ? void 0 : quality.contentType;
4430
4403
  if (!mimeType || !contentType2) return false;
4431
4404
  if (!denylistCodecsFromMimeType(mimeType)) return false;
4432
- logWarn4(
4405
+ logWarn3(
4433
4406
  this,
4434
4407
  "SourceBuffer append failed; denylisting codec and requesting reload:",
4435
4408
  mimeType
@@ -4483,7 +4456,6 @@ var BufferingControllerImpl = class extends EventHostImpl8 {
4483
4456
  this._bufferingEnded = false;
4484
4457
  this.bufferingQuality = null;
4485
4458
  this.playbackQuality = null;
4486
- this.setHasData(false);
4487
4459
  }
4488
4460
  get disposed() {
4489
4461
  return this.disposer.disposed;
@@ -4497,16 +4469,16 @@ var BufferingControllerImpl = class extends EventHostImpl8 {
4497
4469
 
4498
4470
  // src/streaming/buffering/MediaSourceController.ts
4499
4471
  import {
4500
- closeTo as closeTo5,
4501
- createDisposer as createDisposer10,
4502
- DomEventHost as DomEventHost4,
4472
+ closeTo as closeTo3,
4473
+ createDisposer as createDisposer9,
4474
+ DomEventHost as DomEventHost2,
4503
4475
  ErrorLevel as ErrorLevel8,
4504
4476
  ErrorOrigin as ErrorOrigin14,
4505
4477
  EventHostImpl as EventHostImpl9,
4506
4478
  IllegalStateError as IllegalStateError2,
4507
4479
  isSilentError as isSilentError3,
4508
4480
  logDebug as logDebug8,
4509
- logWarn as logWarn5,
4481
+ logWarn as logWarn4,
4510
4482
  ReportableError as ReportableError8,
4511
4483
  toJson as toJson2,
4512
4484
  toLowerCase as toLowerCase2
@@ -4581,12 +4553,12 @@ var MediaSourceControllerImpl = class extends EventHostImpl9 {
4581
4553
  return this.activateDisposer != null;
4582
4554
  }
4583
4555
  activate() {
4584
- this.activateDisposer = createDisposer10();
4556
+ this.activateDisposer = createDisposer9();
4585
4557
  const add = this.activateDisposer.add;
4586
4558
  const mediaSource = this.deps.mediaSourceFactory();
4587
4559
  this.mediaSource = mediaSource;
4588
4560
  const domEvents = add(
4589
- new DomEventHost4(mediaSource)
4561
+ new DomEventHost2(mediaSource)
4590
4562
  );
4591
4563
  domEvents.on("sourceopen", () => {
4592
4564
  this.refreshDuration().catch(this.errorHandler);
@@ -4629,7 +4601,7 @@ var MediaSourceControllerImpl = class extends EventHostImpl9 {
4629
4601
  try {
4630
4602
  URL.revokeObjectURL(this.objectUrl);
4631
4603
  } catch (error) {
4632
- logWarn5(this, "error revoking object url", error);
4604
+ logWarn4(this, "error revoking object url", error);
4633
4605
  }
4634
4606
  }
4635
4607
  get sourceBufferCount() {
@@ -4650,7 +4622,7 @@ var MediaSourceControllerImpl = class extends EventHostImpl9 {
4650
4622
  const duration = await timeline.getDuration();
4651
4623
  const value = duration === Infinity ? LIVE_DURATION : duration + DURATION_PADDING;
4652
4624
  await Promise.all(Array.from(this.sourceBuffers, nextSourceBufferIdle));
4653
- if (token !== this.durationToken || mediaSource.readyState !== "open" || closeTo5(mediaSource.duration, value, 0.1))
4625
+ if (token !== this.durationToken || mediaSource.readyState !== "open" || closeTo3(mediaSource.duration, value, 0.1))
4654
4626
  return;
4655
4627
  logDebug8(this, `setting duration: ${value}`);
4656
4628
  mediaSource.duration = value;
@@ -4733,7 +4705,7 @@ var MediaSourceError = class _MediaSourceError extends ReportableError8 {
4733
4705
 
4734
4706
  // src/streaming/buffering/SourceBufferController.ts
4735
4707
  import {
4736
- createLogPrefix as createLogPrefix7,
4708
+ createLogPrefix as createLogPrefix6,
4737
4709
  createTaskQueue as createTaskQueue2,
4738
4710
  createTimeRangesReader as createTimeRangesReader2,
4739
4711
  emptyRanges,
@@ -4767,7 +4739,7 @@ var SourceBufferControllerImpl = class {
4767
4739
  * @private
4768
4740
  */
4769
4741
  __publicField(this, "nextIdle", () => nextSourceBufferIdle(this.sourceBuffer).finally(this.clearBufferedCache));
4770
- this.logPrefix = createLogPrefix7(`SourceBuffer_${contentType2}`);
4742
+ this.logPrefix = createLogPrefix6(`SourceBuffer_${contentType2}`);
4771
4743
  logDebug9(this, "constructed, contentType:", contentType2);
4772
4744
  this.mediaSourceController = deps.mediaSourceController;
4773
4745
  }
@@ -4902,8 +4874,8 @@ var SourceBufferControllerImpl = class {
4902
4874
 
4903
4875
  // src/streaming/ContentStream.ts
4904
4876
  import {
4905
- createDisposer as createDisposer11,
4906
- createLogPrefix as createLogPrefix8,
4877
+ createDisposer as createDisposer10,
4878
+ createLogPrefix as createLogPrefix7,
4907
4879
  EventHostImpl as EventHostImpl10,
4908
4880
  logDebug as logDebug10,
4909
4881
  redispatchEvents
@@ -4916,10 +4888,10 @@ var ContentStreamImpl = class extends EventHostImpl10 {
4916
4888
  // Assigned in the constructor body: a field initializer runs before the
4917
4889
  // contentType param-property, so it would capture `undefined`.
4918
4890
  __publicField(this, "logPrefix");
4919
- __publicField(this, "disposer", /* @__PURE__ */ createDisposer11());
4891
+ __publicField(this, "disposer", /* @__PURE__ */ createDisposer10());
4920
4892
  __publicField(this, "segmentController");
4921
4893
  __publicField(this, "bufferingController");
4922
- this.logPrefix = createLogPrefix8(`ContentStream_${contentType2}`);
4894
+ this.logPrefix = createLogPrefix7(`ContentStream_${contentType2}`);
4923
4895
  const { add } = this.disposer;
4924
4896
  const deps = add(createContainer(dependencyFactories)).dependencies;
4925
4897
  this.segmentController = deps.segmentController;
@@ -4935,7 +4907,6 @@ var ContentStreamImpl = class extends EventHostImpl10 {
4935
4907
  "bufferingQualityChange",
4936
4908
  "playbackQualityChange",
4937
4909
  "bufferingEnded",
4938
- "hasDataChange",
4939
4910
  "error",
4940
4911
  "codecUnsupported"
4941
4912
  ]);
@@ -4965,9 +4936,6 @@ var ContentStreamImpl = class extends EventHostImpl10 {
4965
4936
  var _a;
4966
4937
  return (_a = this.bufferingController.playbackQuality) != null ? _a : null;
4967
4938
  }
4968
- get hasData() {
4969
- return this.bufferingController.hasData;
4970
- }
4971
4939
  get bufferingEnded() {
4972
4940
  return this.bufferingController.bufferingEnded;
4973
4941
  }
@@ -5440,39 +5408,40 @@ async function canPlayKeySystem(deps, metadata) {
5440
5408
 
5441
5409
  // src/track/filters/sampleRateFilter.ts
5442
5410
  import {
5443
- hasBrowser as hasBrowser4,
5444
- Browser as Browser4,
5411
+ hasBrowser as hasBrowser2,
5412
+ Browser as Browser2,
5445
5413
  last,
5446
5414
  MediaUnsupportedError as MediaUnsupportedError6,
5447
5415
  every,
5448
5416
  map as map2,
5417
+ max as max2,
5449
5418
  min
5450
5419
  } from "@amazon/vinyl-util";
5451
5420
  function throwSamplingRatesUnsupported() {
5452
5421
  throw new MediaUnsupportedError6("No supported sample rate", "sampling-rate");
5453
5422
  }
5454
- function supportsAudioSamplingRate(deps, metadata, _index, array6) {
5455
- const isFirefox = hasBrowser4(Browser4.FIREFOX);
5456
- const maxSampleRate = deps.capabilities.sampleRate;
5423
+ function withinAudioSampleRateRange(options, metadata, _index, array6) {
5424
+ var _a;
5425
+ if (metadata.contentType !== "audio") return true;
5457
5426
  const samplingRate = last(metadata.audioSamplingRate);
5458
- if (!samplingRate || !maxSampleRate) return true;
5459
- if (isFirefox) {
5427
+ if (!samplingRate) return true;
5428
+ const audioRates = () => map2(
5429
+ array6,
5430
+ (item) => item.contentType === "audio" ? last(item.audioSamplingRate) : void 0
5431
+ ).filter((rate) => rate != null);
5432
+ const { minSampleRate } = options;
5433
+ if (minSampleRate != null && samplingRate < minSampleRate) {
5434
+ const rates2 = audioRates();
5435
+ return every(rates2, (rate) => rate < minSampleRate) && samplingRate === max2(rates2);
5436
+ }
5437
+ const maxSampleRate = (_a = options.maxSampleRate) != null ? _a : options.capabilities.sampleRate;
5438
+ if (!maxSampleRate) return true;
5439
+ if (hasBrowser2(Browser2.FIREFOX)) {
5460
5440
  return samplingRate <= 48e3;
5461
5441
  }
5462
5442
  if (samplingRate <= maxSampleRate) return true;
5463
- const allAboveMax = every(array6, (item) => {
5464
- const itemSamplingRate = last(item.audioSamplingRate);
5465
- return itemSamplingRate != null && itemSamplingRate > maxSampleRate;
5466
- });
5467
- if (allAboveMax) {
5468
- const samplingRates = map2(
5469
- array6,
5470
- (item) => last(item.audioSamplingRate)
5471
- ).filter((rate) => rate != null);
5472
- const lowestSamplingRate = min(samplingRates);
5473
- return samplingRate === lowestSamplingRate;
5474
- }
5475
- return false;
5443
+ const rates = audioRates();
5444
+ return every(rates, (rate) => rate > maxSampleRate) && samplingRate === min(rates);
5476
5445
  }
5477
5446
 
5478
5447
  // src/util/media/codecOverrides.ts
@@ -5508,8 +5477,8 @@ function createDefaultMediaTimelineTransformer(deps) {
5508
5477
  return canPlayMimeType(deps, quality);
5509
5478
  }
5510
5479
  async function transformTimeline(timeline) {
5511
- var _a, _b;
5512
- const codecOverrides = deps.options.value.codecOverrides;
5480
+ var _a, _b, _c, _d;
5481
+ const { audio, codecOverrides } = deps.options.value;
5513
5482
  let t = filterTimelineQualities(
5514
5483
  (quality) => canPlayWithOverrides(quality, codecOverrides),
5515
5484
  throwMimeTypesUnsupported,
@@ -5520,19 +5489,31 @@ function createDefaultMediaTimelineTransformer(deps) {
5520
5489
  throwKeySystemsUnsupported,
5521
5490
  t
5522
5491
  );
5492
+ if (!audio.disableSampleRateFilter) {
5493
+ const sampleRateOptions = {
5494
+ capabilities: deps.capabilities,
5495
+ maxSampleRate: (_a = audio.maxSampleRate) != null ? _a : null,
5496
+ minSampleRate: (_b = audio.minSampleRate) != null ? _b : null
5497
+ };
5498
+ t = filterTimelineQualities(
5499
+ (quality, index, array6) => withinAudioSampleRateRange(
5500
+ sampleRateOptions,
5501
+ quality,
5502
+ index,
5503
+ array6
5504
+ ),
5505
+ throwSamplingRatesUnsupported,
5506
+ t
5507
+ );
5508
+ }
5509
+ const selection = audio.selection;
5523
5510
  t = filterTimelineQualities(
5524
- (quality, index, array6) => supportsAudioSamplingRate(deps, quality, index, array6),
5525
- throwSamplingRatesUnsupported,
5526
- t
5527
- );
5528
- const selection = deps.options.value.audio.selection;
5529
- t = filterTimelineQualities(
5530
- createAudioDescriptionFilter((_a = selection == null ? void 0 : selection.descriptive) != null ? _a : false),
5511
+ createAudioDescriptionFilter((_c = selection == null ? void 0 : selection.descriptive) != null ? _c : false),
5531
5512
  throwNoPlayableAudio,
5532
5513
  t
5533
5514
  );
5534
5515
  t = filterTimelineQualities(
5535
- createLanguageFilter((_b = selection == null ? void 0 : selection.language) != null ? _b : null, "audio"),
5516
+ createLanguageFilter((_d = selection == null ? void 0 : selection.language) != null ? _d : null, "audio"),
5536
5517
  throwLanguagesUnsupported,
5537
5518
  t
5538
5519
  );
@@ -5572,7 +5553,7 @@ var descriptorRecordValidator = /* @__PURE__ */ record2(/* @__PURE__ */ string5(
5572
5553
  import { data } from "@amazon/vinyl-observable";
5573
5554
  import {
5574
5555
  createAbortSlot as createAbortSlot2,
5575
- createDisposer as createDisposer12,
5556
+ createDisposer as createDisposer11,
5576
5557
  EventHostImpl as EventHostImpl11,
5577
5558
  logDebug as logDebug11
5578
5559
  } from "@amazon/vinyl-util";
@@ -5582,7 +5563,7 @@ var ManifestControllerImpl = class {
5582
5563
  __publicField(this, "_data");
5583
5564
  __publicField(this, "_error", null);
5584
5565
  __publicField(this, "abortSlot", /* @__PURE__ */ createAbortSlot2());
5585
- __publicField(this, "disposer", /* @__PURE__ */ createDisposer12());
5566
+ __publicField(this, "disposer", /* @__PURE__ */ createDisposer11());
5586
5567
  __publicField(this, "events", /* @__PURE__ */ new EventHostImpl11());
5587
5568
  __publicField(this, "manifestSpanArmed", true);
5588
5569
  __publicField(this, "__eventMapType", this.events.__eventMapType);
@@ -5682,7 +5663,7 @@ import {
5682
5663
  array as array3,
5683
5664
  enumOf as enumOf3,
5684
5665
  isOneOf as isOneOf3,
5685
- number as number5,
5666
+ number as number6,
5686
5667
  object as object9,
5687
5668
  string as string6,
5688
5669
  tuple
@@ -5736,16 +5717,16 @@ function createEmptyMediaQualityMetadata() {
5736
5717
  });
5737
5718
  }
5738
5719
  var mediaQualityMetadataValidator = /* @__PURE__ */ mediaFormatMetadataValidator.extend({
5739
- audioSamplingRate: /* @__PURE__ */ array3(/* @__PURE__ */ number5()).readonly().orNull(),
5740
- bandwidth: /* @__PURE__ */ number5().orNull(),
5741
- bandwidthTotal: /* @__PURE__ */ number5().orNull(),
5720
+ audioSamplingRate: /* @__PURE__ */ array3(/* @__PURE__ */ number6()).readonly().orNull(),
5721
+ bandwidth: /* @__PURE__ */ number6().orNull(),
5722
+ bandwidthTotal: /* @__PURE__ */ number6().orNull(),
5742
5723
  codecs: /* @__PURE__ */ string6().orNull(),
5743
5724
  decoderId: /* @__PURE__ */ string6(),
5744
- frameRate: /* @__PURE__ */ tuple(/* @__PURE__ */ number5(), /* @__PURE__ */ number5()).readonly().orNull(),
5745
- height: /* @__PURE__ */ number5().orNull(),
5725
+ frameRate: /* @__PURE__ */ tuple(/* @__PURE__ */ number6(), /* @__PURE__ */ number6()).readonly().orNull(),
5726
+ height: /* @__PURE__ */ number6().orNull(),
5746
5727
  qualityId: /* @__PURE__ */ string6(),
5747
5728
  supplementalProperties: descriptorRecordValidator,
5748
- width: /* @__PURE__ */ number5().orNull(),
5729
+ width: /* @__PURE__ */ number6().orNull(),
5749
5730
  lang: /* @__PURE__ */ string6().orNull(),
5750
5731
  characteristics: /* @__PURE__ */ array3(/* @__PURE__ */ string6()).readonly(),
5751
5732
  groupId: /* @__PURE__ */ string6(),
@@ -5767,9 +5748,9 @@ function getMediaPeriodAtTime(timeline, time) {
5767
5748
  import {
5768
5749
  Abort as Abort2,
5769
5750
  clone as clone2,
5770
- closeTo as closeTo6,
5771
- createDisposer as createDisposer13,
5772
- createLogPrefix as createLogPrefix9,
5751
+ closeTo as closeTo4,
5752
+ createDisposer as createDisposer12,
5753
+ createLogPrefix as createLogPrefix8,
5773
5754
  EventHostImpl as EventHostImpl12,
5774
5755
  getNetworkState,
5775
5756
  getOrSet,
@@ -5949,7 +5930,7 @@ var SegmentControllerImpl = class extends EventHostImpl12 {
5949
5930
  */
5950
5931
  __publicField(this, "cachedInitSegments", /* @__PURE__ */ new Map());
5951
5932
  __publicField(this, "cachedSegments", []);
5952
- __publicField(this, "disposer", /* @__PURE__ */ createDisposer13());
5933
+ __publicField(this, "disposer", /* @__PURE__ */ createDisposer12());
5953
5934
  __publicField(this, "options");
5954
5935
  __publicField(this, "prefetchingPriority", /* @__PURE__ */ clone2(defaultTrackPriority));
5955
5936
  /**
@@ -6020,7 +6001,7 @@ var SegmentControllerImpl = class extends EventHostImpl12 {
6020
6001
  }
6021
6002
  });
6022
6003
  __publicField(this, "_streamingQuality", null);
6023
- this.logPrefix = createLogPrefix9(`Segment_${contentType2}`);
6004
+ this.logPrefix = createLogPrefix8(`Segment_${contentType2}`);
6024
6005
  logDebug12(this, "constructed");
6025
6006
  const { add } = this.disposer;
6026
6007
  this.options = __spreadValues(__spreadValues({}, defaultSegmentControllerBaseOptions), options);
@@ -6290,7 +6271,7 @@ var SegmentControllerImpl = class extends EventHostImpl12 {
6290
6271
  );
6291
6272
  if (insertionIndex > 0) {
6292
6273
  const cachedSegment2 = this.cachedSegments[insertionIndex - 1];
6293
- if (closeTo6(newSlot.startTime, cachedSegment2.startTime)) {
6274
+ if (closeTo4(newSlot.startTime, cachedSegment2.startTime)) {
6294
6275
  return cachedSegment2;
6295
6276
  }
6296
6277
  }
@@ -6451,7 +6432,6 @@ var ALL_STREAMING_EVENTS = [
6451
6432
  "bufferingQualityChange",
6452
6433
  "playbackQualityChange",
6453
6434
  "bufferingEnded",
6454
- "hasDataChange",
6455
6435
  "error",
6456
6436
  "reset",
6457
6437
  "qualitiesChange",
@@ -6954,14 +6934,19 @@ function scoreTextTrack(track, prefs) {
6954
6934
  // src/text/SidecarTextTrackController.ts
6955
6935
  import {
6956
6936
  createAbortSlot as createAbortSlot4,
6957
- createDisposer as createDisposer14,
6937
+ createDisposer as createDisposer13,
6958
6938
  equalDeep,
6959
6939
  EventHostImpl as EventHostImpl13,
6960
6940
  logError as logError4
6961
6941
  } from "@amazon/vinyl-util";
6962
6942
 
6963
6943
  // src/text/SidecarTextTrackLoader.ts
6964
- import { requestWithRetry as requestWithRetry4, resolveUrl as resolveUrl4, sleep as sleep2 } from "@amazon/vinyl-util";
6944
+ import {
6945
+ readResponseBody as readResponseBody3,
6946
+ requestWithRetry as requestWithRetry4,
6947
+ resolveUrl as resolveUrl4,
6948
+ sleep as sleep2
6949
+ } from "@amazon/vinyl-util";
6965
6950
  import { parseMediaPlaylist } from "@amazon/vinyl-hls-parser";
6966
6951
  var DEFAULT_TEXT_LOOK_AHEAD = 10;
6967
6952
  var DEFAULT_TEXT_LOOK_BEHIND = 2;
@@ -6987,7 +6972,7 @@ async function loadWebVttCues(uri, options) {
6987
6972
  }
6988
6973
  const response = await requestWithRetry4(uri, init, { abort });
6989
6974
  const contentType2 = ((_c = response.headers.get("content-type")) != null ? _c : "").toLowerCase();
6990
- const body = await response.text();
6975
+ const body = await readResponseBody3(response, "text");
6991
6976
  if (contentType2.includes("mpegurl") || body.startsWith("#EXTM3U")) {
6992
6977
  return streamMediaPlaylistText({
6993
6978
  text: body,
@@ -7014,7 +6999,7 @@ async function streamMediaPlaylist(ctx) {
7014
6999
  const response = await requestWithRetry4(ctx.uri, ctx.init, {
7015
7000
  abort: ctx.abort
7016
7001
  });
7017
- const text = await response.text();
7002
+ const text = await readResponseBody3(response, "text");
7018
7003
  return streamMediaPlaylistText(__spreadProps(__spreadValues({}, ctx), {
7019
7004
  text,
7020
7005
  baseUrl: response.url || ctx.uri
@@ -7043,7 +7028,7 @@ async function streamMediaPlaylistText(ctx) {
7043
7028
  const res = await requestWithRetry4(segUri, ctx.init, {
7044
7029
  abort: ctx.abort
7045
7030
  });
7046
- const body = await res.text();
7031
+ const body = await readResponseBody3(res, "text");
7047
7032
  const doc = parseWebVtt(body);
7048
7033
  if (doc.cues.length > 0) ctx.onCues(doc.cues);
7049
7034
  if (ctx.onStyles && doc.styles.length > 0) ctx.onStyles(doc.styles);
@@ -7069,7 +7054,7 @@ function pickInWindow(pending, ranges, ctx) {
7069
7054
  }
7070
7055
 
7071
7056
  // src/text/VttCueStyle.ts
7072
- import { boolean as boolean4, isOneOf as isOneOf4, number as number6, object as object10 } from "@amazon/vinyl-validation";
7057
+ import { boolean as boolean4, isOneOf as isOneOf4, number as number7, object as object10 } from "@amazon/vinyl-validation";
7073
7058
  function isVttCue(cue) {
7074
7059
  return typeof VTTCue !== "undefined" && cue instanceof VTTCue;
7075
7060
  }
@@ -7086,16 +7071,16 @@ function applyVttCueStyle(cue, style) {
7086
7071
  }
7087
7072
  var vttCueStyleValidator = /* @__PURE__ */ object10({
7088
7073
  align: /* @__PURE__ */ isOneOf4("start", "center", "end", "left", "right").optional(),
7089
- line: /* @__PURE__ */ number6().or(/* @__PURE__ */ isOneOf4("auto")).optional(),
7074
+ line: /* @__PURE__ */ number7().or(/* @__PURE__ */ isOneOf4("auto")).optional(),
7090
7075
  lineAlign: /* @__PURE__ */ isOneOf4("start", "center", "end").optional(),
7091
- position: /* @__PURE__ */ number6().or(/* @__PURE__ */ isOneOf4("auto")).optional(),
7076
+ position: /* @__PURE__ */ number7().or(/* @__PURE__ */ isOneOf4("auto")).optional(),
7092
7077
  positionAlign: /* @__PURE__ */ isOneOf4(
7093
7078
  "line-left",
7094
7079
  "center",
7095
7080
  "line-right",
7096
7081
  "auto"
7097
7082
  ).optional(),
7098
- size: /* @__PURE__ */ number6().optional(),
7083
+ size: /* @__PURE__ */ number7().optional(),
7099
7084
  snapToLines: /* @__PURE__ */ boolean4().optional(),
7100
7085
  vertical: /* @__PURE__ */ isOneOf4("", "rl", "lr").optional()
7101
7086
  });
@@ -7130,7 +7115,7 @@ var SidecarTextTrackController = class extends EventHostImpl13 {
7130
7115
  // the provider (never created/removed here).
7131
7116
  __publicField(this, "_ref", null);
7132
7117
  __publicField(this, "loadAbort", /* @__PURE__ */ createAbortSlot4());
7133
- __publicField(this, "disposer", /* @__PURE__ */ createDisposer14());
7118
+ __publicField(this, "disposer", /* @__PURE__ */ createDisposer13());
7134
7119
  const { add } = this.disposer;
7135
7120
  add(deps.options.onData(() => this.refreshSelection()));
7136
7121
  add(
@@ -7319,11 +7304,11 @@ var ALL_TEXT_TRACK_EVENTS = [
7319
7304
 
7320
7305
  // src/track/AutoResetController.ts
7321
7306
  import {
7322
- createDisposer as createDisposer15,
7307
+ createDisposer as createDisposer14,
7323
7308
  EventHostImpl as EventHostImpl14,
7324
7309
  getNetworkState as getNetworkState2,
7325
7310
  logDebug as logDebug13,
7326
- onAny as onAny3,
7311
+ onAny as onAny2,
7327
7312
  RequestError
7328
7313
  } from "@amazon/vinyl-util";
7329
7314
  var defaultResetControllerOptions = {
@@ -7339,11 +7324,11 @@ var AutoResetControllerImpl = class extends EventHostImpl14 {
7339
7324
  __publicField(this, "_error", null);
7340
7325
  __publicField(this, "watchSub", null);
7341
7326
  __publicField(this, "currentRetry", 0);
7342
- __publicField(this, "disposer", /* @__PURE__ */ createDisposer15());
7327
+ __publicField(this, "disposer", /* @__PURE__ */ createDisposer14());
7343
7328
  logDebug13(this, "constructor");
7344
7329
  this.options = __spreadValues(__spreadValues({}, defaultResetControllerOptions), options);
7345
7330
  this.disposer.add(
7346
- onAny3(
7331
+ onAny2(
7347
7332
  deps.playbackController,
7348
7333
  ["play", "pause", "seeking", "playing"],
7349
7334
  (_event) => {
@@ -7377,7 +7362,7 @@ var AutoResetControllerImpl = class extends EventHostImpl14 {
7377
7362
  this.watchSub = null;
7378
7363
  if (value) {
7379
7364
  const networkState = getNetworkState2();
7380
- const { add, dispose: watchSub } = createDisposer15();
7365
+ const { add, dispose: watchSub } = createDisposer14();
7381
7366
  this.watchSub = watchSub;
7382
7367
  add(
7383
7368
  networkState.on("online", () => {
@@ -7428,6 +7413,7 @@ import {
7428
7413
  last as last2,
7429
7414
  networkMetricsController,
7430
7415
  normalizeHeadersInit as normalizeHeadersInit2,
7416
+ readResponseBody as readResponseBody4,
7431
7417
  requestWithRetry as requestWithRetry5
7432
7418
  } from "@amazon/vinyl-util";
7433
7419
  import { stringifyByteRange } from "@amazon/vinyl-mpd-parser";
@@ -7452,7 +7438,7 @@ function createSegmentDataProvider(deps, options) {
7452
7438
  abort
7453
7439
  });
7454
7440
  const responseEnd = Date.now();
7455
- const arrayBuffer = await response.arrayBuffer();
7441
+ const arrayBuffer = await readResponseBody4(response, "arrayBuffer");
7456
7442
  const contentEnd = Date.now();
7457
7443
  let responseStart = null;
7458
7444
  if ("getEntriesByName" in performance) {
@@ -7465,7 +7451,7 @@ function createSegmentDataProvider(deps, options) {
7465
7451
  }
7466
7452
  }
7467
7453
  }
7468
- if (options.reportDownlinkMetrics) {
7454
+ if (options.reportDownlinkMetrics && !(abort == null ? void 0 : abort.aborted())) {
7469
7455
  networkMetricsController.value.addDownlinkTransferEntry({
7470
7456
  bytes: arrayBuffer.byteLength,
7471
7457
  serviceId,
@@ -7487,13 +7473,13 @@ import {
7487
7473
  import {
7488
7474
  any as any2,
7489
7475
  isOneOf as isOneOf6,
7490
- number as number7,
7476
+ number as number8,
7491
7477
  object as object12,
7492
7478
  string as string8
7493
7479
  } from "@amazon/vinyl-validation";
7494
7480
  var trackConfigOptionsValidator = /* @__PURE__ */ object12({
7495
7481
  extra: /* @__PURE__ */ any2().optional(),
7496
- startTime: /* @__PURE__ */ number7().maybe().optional(),
7482
+ startTime: /* @__PURE__ */ number8().maybe().optional(),
7497
7483
  drm: /* @__PURE__ */ drmOptionsValidator.partial().optional()
7498
7484
  });
7499
7485
  var trackLoadOptionsValidator = /* @__PURE__ */ object12(
@@ -7523,7 +7509,7 @@ import { func as func2, isOneOf as isOneOf7 } from "@amazon/vinyl-validation";
7523
7509
  // src/track/TrackBase.ts
7524
7510
  import {
7525
7511
  createAbortSlot as createAbortSlot5,
7526
- createDisposer as createDisposer16,
7512
+ createDisposer as createDisposer15,
7527
7513
  emptyRanges as emptyRanges2,
7528
7514
  equalDeep as equalDeep2,
7529
7515
  EventHostImpl as EventHostImpl15,
@@ -7551,7 +7537,7 @@ var TrackBase = class extends EventHostImpl15 {
7551
7537
  });
7552
7538
  }
7553
7539
  });
7554
- __publicField(this, "disposer", /* @__PURE__ */ createDisposer16());
7540
+ __publicField(this, "disposer", /* @__PURE__ */ createDisposer15());
7555
7541
  __publicField(this, "drmSessionAbort", /* @__PURE__ */ createAbortSlot5());
7556
7542
  /**
7557
7543
  * Sets on handleError, cleared on 'reset'.
@@ -7781,7 +7767,7 @@ var FixedPlaybackQuality = class extends EventHostImpl16 {
7781
7767
 
7782
7768
  // src/track/source/SourceTrackBase.ts
7783
7769
  import {
7784
- createDisposer as createDisposer17,
7770
+ createDisposer as createDisposer16,
7785
7771
  logDebug as logDebug15,
7786
7772
  redispatchEvents as redispatchEvents2
7787
7773
  } from "@amazon/vinyl-util";
@@ -7840,7 +7826,7 @@ var SourceTrackBase = class extends TrackBase {
7840
7826
  return this.fixedPlaybackQuality.getPlaybackQuality(contentType2);
7841
7827
  }
7842
7828
  onActivated() {
7843
- const { add, dispose } = createDisposer17();
7829
+ const { add, dispose } = createDisposer16();
7844
7830
  this.activeSub = dispose;
7845
7831
  add(
7846
7832
  this.deps.playbackController.on("durationChange", (event) => {
@@ -7966,19 +7952,16 @@ import {
7966
7952
  first as first2,
7967
7953
  IntersectionRanges,
7968
7954
  logDebug as logDebug16,
7969
- noop as noop7,
7955
+ MediaUnsupportedError as MediaUnsupportedError7,
7970
7956
  redispatchEvents as redispatchEvents3
7971
7957
  } from "@amazon/vinyl-util";
7972
7958
  import { createContainer as createContainer2 } from "@amazon/vinyl-di";
7973
- var SEEKING_STALL_TIME_CHECK = 0.1;
7974
- var PLAYHEAD_NUDGE = 0.05;
7975
7959
  var MseTrack = class extends TrackBase {
7976
7960
  constructor(uri, type, dependencyFactories) {
7977
7961
  const depsContainer = createContainer2(dependencyFactories);
7978
7962
  const deps = depsContainer.dependencies;
7979
7963
  super(uri, type, deps);
7980
7964
  __publicField(this, "streams", []);
7981
- __publicField(this, "stallNudgeTimer", null);
7982
7965
  __publicField(this, "disposeAbort", /* @__PURE__ */ new Abort3());
7983
7966
  __publicField(this, "lastPreloadOptions", null);
7984
7967
  __publicField(this, "allFetchedRanges", []);
@@ -7997,7 +7980,10 @@ var MseTrack = class extends TrackBase {
7997
7980
  this.deps = deps;
7998
7981
  add(
7999
7982
  deps.contentTypesValue.onData((contentTypesPromise) => {
8000
- contentTypesPromise.then((value) => this.setContentTypes(value)).catch(this.errorHandler);
7983
+ contentTypesPromise.then((value) => {
7984
+ this.setContentTypes(value);
7985
+ this.validateRequiredContentTypesPlayable();
7986
+ }).catch(this.errorHandler);
8001
7987
  })
8002
7988
  );
8003
7989
  this.on("streamingQualityChange", (event) => {
@@ -8040,11 +8026,6 @@ var MseTrack = class extends TrackBase {
8040
8026
  if (previous !== void 0) this.reloadStreams();
8041
8027
  })
8042
8028
  );
8043
- add(
8044
- deps.allowedContentTypes.onData((_value, previous) => {
8045
- if (previous !== void 0) this.reloadStreams();
8046
- })
8047
- );
8048
8029
  add(
8049
8030
  deps.abr.onData((value, previous) => {
8050
8031
  if (previous === void 0) return;
@@ -8103,8 +8084,33 @@ var MseTrack = class extends TrackBase {
8103
8084
  });
8104
8085
  }
8105
8086
  }
8087
+ this.validateRequiredContentTypesPlayable();
8106
8088
  });
8107
8089
  }
8090
+ /**
8091
+ * Fails fast when a media content type the manifest declared (audio/video)
8092
+ * has no playable qualities left after timeline filtering. Its stream can
8093
+ * never create a source buffer, so without this the track waits forever for
8094
+ * a source buffer that never arrives, surfacing only as an opaque
8095
+ * `readyToAppend` timeout. Runs once both the required content types and the
8096
+ * filtered timeline qualities are known (either order).
8097
+ */
8098
+ validateRequiredContentTypesPlayable() {
8099
+ const qualities = this._qualities;
8100
+ if (!qualities) return;
8101
+ const present = new Set(qualities.map((q) => q.contentType));
8102
+ for (const contentType2 of this._contentTypes) {
8103
+ if (!present.has(contentType2)) {
8104
+ this.errorHandler(
8105
+ new MediaUnsupportedError7(
8106
+ `No playable ${contentType2} rendition`,
8107
+ `no-playable-${contentType2}`
8108
+ )
8109
+ );
8110
+ return;
8111
+ }
8112
+ }
8113
+ }
8108
8114
  async getAds() {
8109
8115
  const timeline = await this.deps.mediaTimeline.value;
8110
8116
  return {
@@ -8186,7 +8192,6 @@ var MseTrack = class extends TrackBase {
8186
8192
  this.dispatch("bufferingEnded", {});
8187
8193
  }
8188
8194
  });
8189
- stream.on("hasDataChange", () => this.checkStalledSeek());
8190
8195
  stream.on("fetchedRangesChange", () => {
8191
8196
  this._fetchedRanges.invalidate();
8192
8197
  });
@@ -8322,34 +8327,6 @@ var MseTrack = class extends TrackBase {
8322
8327
  get bufferingEnded() {
8323
8328
  return this.streams.every((stream) => stream.bufferingEnded);
8324
8329
  }
8325
- /**
8326
- * A seek only completes once every stream has data at the target, but on
8327
- * some platforms the element can stay stuck `seeking` even after that. Once
8328
- * all streams hold data, if we're still seeking a moment later, nudge the
8329
- * playhead to prod the element into completing the seek.
8330
- */
8331
- checkStalledSeek() {
8332
- const { playbackController } = this.deps;
8333
- if (this.stallNudgeTimer !== null || !playbackController.seeking) return;
8334
- if (!this.streams.length || !this.streams.every((s) => s.hasData)) {
8335
- return;
8336
- }
8337
- this.stallNudgeTimer = setTimeout(() => {
8338
- this.stallNudgeTimer = null;
8339
- if (this.disposed || !playbackController.seeking) return;
8340
- if (!this.streams.every((s) => s.hasData)) return;
8341
- const from = playbackController.currentTime;
8342
- const to = from + PLAYHEAD_NUDGE;
8343
- logDebug16(
8344
- this,
8345
- "nudging playhead to recover a stalled seek",
8346
- from,
8347
- "->",
8348
- to
8349
- );
8350
- playbackController.seekTo(to, 0).catch(noop7);
8351
- }, SEEKING_STALL_TIME_CHECK * 1e3);
8352
- }
8353
8330
  setContentTypes(contentTypes) {
8354
8331
  if (this.disposed) return;
8355
8332
  const previous = this.contentTypes;
@@ -8373,7 +8350,6 @@ var MseTrack = class extends TrackBase {
8373
8350
  }
8374
8351
  dispose() {
8375
8352
  logDebug16(this, "dispose");
8376
- if (this.stallNudgeTimer !== null) clearTimeout(this.stallNudgeTimer);
8377
8353
  this.clearStreams();
8378
8354
  super.dispose();
8379
8355
  }
@@ -8549,13 +8525,18 @@ function calculatePeriodTimeRange(period) {
8549
8525
  return [calculatePeriodStart(period), calculatePeriodEnd(period)];
8550
8526
  }
8551
8527
  function calculatePeriodStart(period) {
8552
- var _a;
8553
- return (_a = period.start) != null ? _a : 0;
8528
+ if (period.start != null) return period.start;
8529
+ const mpd = period.parent;
8530
+ const periodIndex = mpd.Period.indexOf(period);
8531
+ if (periodIndex <= 0) return 0;
8532
+ const previous = mpd.Period[periodIndex - 1];
8533
+ const previousStart = calculatePeriodStart(previous);
8534
+ return previous.duration != null ? previousStart + previous.duration : previousStart;
8554
8535
  }
8555
8536
  function calculatePeriodEnd(period) {
8556
8537
  var _a;
8557
- if (period.start != null && period.duration != null)
8558
- return period.start + period.duration;
8538
+ if (period.duration != null)
8539
+ return calculatePeriodStart(period) + period.duration;
8559
8540
  const mpd = period.parent;
8560
8541
  const periodIndex = mpd.Period.indexOf(period);
8561
8542
  if (periodIndex < mpd.Period.length - 1)
@@ -8611,6 +8592,8 @@ import {
8611
8592
  ErrorOrigin as ErrorOrigin23,
8612
8593
  getSidxSampleTimes,
8613
8594
  parseSidxBox,
8595
+ parseWebmCues,
8596
+ parseWebmInit,
8614
8597
  ValidationError as ValidationError5
8615
8598
  } from "@amazon/vinyl-util";
8616
8599
 
@@ -8722,9 +8705,13 @@ function createDashRepresentationSegmentProvider(deps, baseUrl, representation)
8722
8705
  segmentTemplate
8723
8706
  }));
8724
8707
  } else if (segmentBase) {
8725
- getSegmentReferences = () => createSegmentsFromSegmentBase(deps, __spreadProps(__spreadValues({}, options), {
8726
- segmentBase
8727
- }));
8708
+ getSegmentReferences = () => createSegmentsFromSegmentBase(
8709
+ deps,
8710
+ __spreadProps(__spreadValues({}, options), {
8711
+ segmentBase
8712
+ }),
8713
+ initData
8714
+ );
8728
8715
  }
8729
8716
  return {
8730
8717
  async getSegment(time, affordance = 0) {
@@ -8836,10 +8823,14 @@ function createSegmentsFromSegmentTemplate(deps, options) {
8836
8823
  }
8837
8824
  );
8838
8825
  }
8839
- async function createSegmentsFromSegmentBase(deps, options) {
8826
+ async function createSegmentsFromSegmentBase(deps, options, initData) {
8840
8827
  var _a;
8841
8828
  const { baseUrl, periodTimeRange, representation, segmentBase } = options;
8842
8829
  if (segmentBase.indexRange) {
8830
+ const { mimeType } = getRepresentationMimeInfo(representation);
8831
+ if (mimeType == null ? void 0 : mimeType.includes("webm")) {
8832
+ return createSegmentsFromWebmCues(deps, options, initData);
8833
+ }
8843
8834
  const indexRange = segmentBase.indexRange;
8844
8835
  const { url: indexUrl, serviceLocation: indexServiceLocation } = resolveDashUri(deps, { baseUrl, representation });
8845
8836
  const sidx = parseSidxBox(
@@ -8876,6 +8867,56 @@ async function createSegmentsFromSegmentBase(deps, options) {
8876
8867
  throw new ValidationError5("Manifest missing segments");
8877
8868
  }
8878
8869
  }
8870
+ async function createSegmentsFromWebmCues(deps, options, initData) {
8871
+ var _a, _b;
8872
+ const { baseUrl, periodTimeRange, representation, segmentBase } = options;
8873
+ const indexRange = segmentBase.indexRange;
8874
+ const { url, serviceLocation } = resolveDashUri(deps, {
8875
+ baseUrl,
8876
+ representation
8877
+ });
8878
+ const [{ segmentDataStart, timecodeScale }, cues] = await Promise.all([
8879
+ Promise.resolve(initData()).then(parseWebmInit),
8880
+ createSegmentDataProvider(deps, {
8881
+ url,
8882
+ mediaRange: indexRange,
8883
+ serviceId: serviceLocation,
8884
+ reportDownlinkMetrics: false
8885
+ })().then(parseWebmCues)
8886
+ ]);
8887
+ if (!cues.length) {
8888
+ throw new ValidationError5("WebM Cues contained no cue points");
8889
+ }
8890
+ const ticksPerSecond = Math.round(1e9 / timecodeScale);
8891
+ const manifestTimescale = (_a = segmentBase.timescale) != null ? _a : ticksPerSecond;
8892
+ const presentationTimeOffset = ((_b = segmentBase.presentationTimeOffset) != null ? _b : 0) * ticksPerSecond / manifestTimescale;
8893
+ const [, periodEnd] = periodTimeRange;
8894
+ if (periodEnd == null)
8895
+ throw new ValidationError5(
8896
+ "MPD.mediaPresentationDuration or Period.duration required",
8897
+ ErrorOrigin23.MEDIA
8898
+ );
8899
+ const sampleTimes = cues.map((cue) => cue.time);
8900
+ sampleTimes.push(periodEnd * ticksPerSecond);
8901
+ return createTimeline(
8902
+ {
8903
+ sampleTimes,
8904
+ periodTimeRange,
8905
+ presentationTimeOffset,
8906
+ timescale: ticksPerSecond
8907
+ },
8908
+ (i) => {
8909
+ const start = segmentDataStart + cues[i].clusterPosition;
8910
+ const end = i < cues.length - 1 ? segmentDataStart + cues[i + 1].clusterPosition - 1 : null;
8911
+ return createSegmentDataProvider(deps, {
8912
+ url,
8913
+ mediaRange: [start, end],
8914
+ serviceId: serviceLocation,
8915
+ reportDownlinkMetrics: true
8916
+ });
8917
+ }
8918
+ );
8919
+ }
8879
8920
  function calculateSegmentSampleTimes(options) {
8880
8921
  const { multipleSegmentBase, periodTimeRange } = options;
8881
8922
  const timescale = getTimescale(multipleSegmentBase);
@@ -9256,13 +9297,12 @@ function estimatePeakBandwidth(representation, contentType2) {
9256
9297
  0,
9257
9298
  sortedInsertionIndex5(own, representation.bandwidth, (a, b) => b - a) - 1
9258
9299
  );
9259
- const position = own.length <= 1 ? 0 : ownIndex / (own.length - 1);
9260
9300
  let total = representation.bandwidth;
9261
9301
  for (const [ct, bandwidths] of sortedByType) {
9262
9302
  if (ct === contentType2) continue;
9263
9303
  const peerIndex = Math.min(
9264
- Math.round(position * (bandwidths.length - 1)),
9265
- bandwidths.length - 1
9304
+ bandwidths.length - 1,
9305
+ Math.ceil((ownIndex + 1) / own.length * bandwidths.length) - 1
9266
9306
  );
9267
9307
  total += bandwidths[peerIndex];
9268
9308
  }
@@ -9337,11 +9377,11 @@ import {
9337
9377
  } from "@amazon/vinyl-di";
9338
9378
 
9339
9379
  // src/track/dash/urlDashManifestProvider.ts
9340
- import { noop as noop8 } from "@amazon/vinyl-util";
9380
+ import { noop as noop7 } from "@amazon/vinyl-util";
9341
9381
  import { clone as clone4, getLocation, resolveUrl as resolveUrl6 } from "@amazon/vinyl-util";
9342
- import { requestWithRetry as requestWithRetry6 } from "@amazon/vinyl-util";
9382
+ import { readResponseBody as readResponseBody5, requestWithRetry as requestWithRetry6 } from "@amazon/vinyl-util";
9343
9383
  import { parseDashManifest } from "@amazon/vinyl-mpd-parser";
9344
- function urlDashManifestProvider(input, init, requestInterceptor = noop8) {
9384
+ function urlDashManifestProvider(input, init, requestInterceptor = noop7) {
9345
9385
  return async (abort) => {
9346
9386
  var _a;
9347
9387
  const params = {
@@ -9352,7 +9392,7 @@ function urlDashManifestProvider(input, init, requestInterceptor = noop8) {
9352
9392
  const response = await requestWithRetry6(params.input, params.init, {
9353
9393
  abort
9354
9394
  });
9355
- const xml = await response.text();
9395
+ const xml = await readResponseBody5(response, "text");
9356
9396
  const manifest = parseDashManifest(xml);
9357
9397
  const baseInput = response.url || params.input;
9358
9398
  return {
@@ -9731,13 +9771,18 @@ import {
9731
9771
 
9732
9772
  // src/track/hls/createUrlHlsManifestProvider.ts
9733
9773
  import { parseMainPlaylist, parseMediaPlaylist as parseMediaPlaylist2 } from "@amazon/vinyl-hls-parser";
9734
- import { memoize as memoize11, requestWithRetry as requestWithRetry7, resolveUrl as resolveUrl9 } from "@amazon/vinyl-util";
9774
+ import {
9775
+ memoize as memoize11,
9776
+ readResponseBody as readResponseBody6,
9777
+ requestWithRetry as requestWithRetry7,
9778
+ resolveUrl as resolveUrl9
9779
+ } from "@amazon/vinyl-util";
9735
9780
  function createUrlHlsManifestProvider(url, requestInit) {
9736
9781
  return async (abort) => {
9737
9782
  const mainResponse = await requestWithRetry7(url, requestInit, {
9738
9783
  abort
9739
9784
  });
9740
- const mainText = await mainResponse.text();
9785
+ const mainText = await readResponseBody6(mainResponse, "text");
9741
9786
  const baseUrl = mainResponse.url || url;
9742
9787
  const mainPlaylist = parseMainPlaylist(
9743
9788
  mainText,
@@ -9764,7 +9809,7 @@ async function fetchMediaPlaylist(options) {
9764
9809
  const { uri, baseUrl, defines, requestInit, abort } = options;
9765
9810
  const variantUrl = resolveUrl9(uri, baseUrl);
9766
9811
  const response = await requestWithRetry7(variantUrl, requestInit, { abort });
9767
- const text = await response.text();
9812
+ const text = await readResponseBody6(response, "text");
9768
9813
  const queryParams = parseQueryParams(response.url || variantUrl);
9769
9814
  return parseMediaPlaylist2(text, defines, queryParams);
9770
9815
  }
@@ -9840,18 +9885,18 @@ function createHlsFactories(options) {
9840
9885
  // src/track/TrackController.ts
9841
9886
  import {
9842
9887
  countElements,
9843
- createDisposer as createDisposer18,
9888
+ createDisposer as createDisposer17,
9844
9889
  EventHostImpl as EventHostImpl17,
9845
9890
  first as first3,
9846
9891
  getOrSet as getOrSet3,
9847
9892
  IllegalStateError as IllegalStateError4,
9848
9893
  logDebug as logDebug17,
9849
9894
  logError as logError5,
9850
- logInfo as logInfo3,
9895
+ logInfo as logInfo2,
9851
9896
  logVerbose as logVerbose4,
9852
- logWarn as logWarn6,
9897
+ logWarn as logWarn5,
9853
9898
  LruCache,
9854
- noop as noop9,
9899
+ noop as noop8,
9855
9900
  resolveValueProvider as resolveValueProvider3
9856
9901
  } from "@amazon/vinyl-util";
9857
9902
  var ALL_TRACK_CONTROLLER_EVENTS = [
@@ -9891,7 +9936,7 @@ var TrackControllerImpl = class extends EventHostImpl17 {
9891
9936
  // Ad tracks keyed by parent content URI, kept out of the content cache.
9892
9937
  // Pegged to the parent: disposed when the parent is evicted (see onEvict).
9893
9938
  __publicField(this, "adTracksByParent", /* @__PURE__ */ new Map());
9894
- __publicField(this, "disposer", /* @__PURE__ */ createDisposer18());
9939
+ __publicField(this, "disposer", /* @__PURE__ */ createDisposer17());
9895
9940
  __publicField(this, "_options", defaultTrackControllerImplOptions);
9896
9941
  /**
9897
9942
  * The current track has ended naturally. On the next tick advance the queue or emit queue ended.
@@ -9901,11 +9946,12 @@ var TrackControllerImpl = class extends EventHostImpl17 {
9901
9946
  if (this.currentTrackIsAdTrack) return;
9902
9947
  const track = this._current;
9903
9948
  if (!track) {
9904
- logWarn6(this, "an ended event was received with no current track");
9949
+ logWarn5(this, "an ended event was received with no current track");
9905
9950
  return;
9906
9951
  }
9907
9952
  const interrupted = this.getQueueInterrupted();
9908
9953
  adController.enterPostroll().then((postroll) => {
9954
+ if (interrupted()) return;
9909
9955
  if (postroll) {
9910
9956
  logDebug17(this, "postroll entered");
9911
9957
  } else {
@@ -9916,12 +9962,13 @@ var TrackControllerImpl = class extends EventHostImpl17 {
9916
9962
  if (this.hasNext()) {
9917
9963
  this.next();
9918
9964
  } else {
9919
- logInfo3(this, "queueEnded");
9965
+ logInfo2(this, "queueEnded");
9920
9966
  this.dispatch("queueEnded", {});
9921
9967
  }
9922
9968
  });
9923
9969
  }
9924
9970
  }).catch((error) => {
9971
+ if (interrupted()) return;
9925
9972
  logError5(this, "enterPostroll failed", error);
9926
9973
  });
9927
9974
  });
@@ -9975,7 +10022,7 @@ var TrackControllerImpl = class extends EventHostImpl17 {
9975
10022
  config: {}
9976
10023
  }
9977
10024
  );
9978
- playbackController.play().catch(noop9);
10025
+ playbackController.play().catch(noop8);
9979
10026
  }
9980
10027
  }).catch((error) => {
9981
10028
  if (!interrupted()) adController.failAd(error);
@@ -10014,7 +10061,7 @@ var TrackControllerImpl = class extends EventHostImpl17 {
10014
10061
  return;
10015
10062
  }
10016
10063
  if (!noAdBegan) resumeContent(event.resumePosition);
10017
- logInfo3(this, "queueEnded after postroll");
10064
+ logInfo2(this, "queueEnded after postroll");
10018
10065
  this.dispatch("queueEnded", {});
10019
10066
  return;
10020
10067
  }
@@ -10025,7 +10072,7 @@ var TrackControllerImpl = class extends EventHostImpl17 {
10025
10072
  resumeContent(
10026
10073
  isPreroll ? (_a = adParentLoad.config) == null ? void 0 : _a.startTime : event.resumePosition
10027
10074
  );
10028
- playbackController.play().catch(noop9);
10075
+ playbackController.play().catch(noop8);
10029
10076
  })
10030
10077
  );
10031
10078
  }
@@ -10180,7 +10227,7 @@ var TrackControllerImpl = class extends EventHostImpl17 {
10180
10227
  var _a;
10181
10228
  const { adTrackLoadOptionsProvider } = this.deps;
10182
10229
  const loadOptions = await adTrackLoadOptionsProvider(ad);
10183
- if (parentTrack.disposed) return;
10230
+ if (parentTrack.disposed || this.disposed) return;
10184
10231
  logVerbose4(
10185
10232
  this,
10186
10233
  `preloading ad id=${ad.id} uri=${ad.uri} priority=${prefetchPriority}`
@@ -10296,7 +10343,7 @@ var TrackControllerImpl = class extends EventHostImpl17 {
10296
10343
  }
10297
10344
  );
10298
10345
  if (options == null ? void 0 : options.shouldPlay) {
10299
- playbackController.play().catch(noop9);
10346
+ playbackController.play().catch(noop8);
10300
10347
  }
10301
10348
  } else {
10302
10349
  this._queue = queue;
@@ -10335,7 +10382,7 @@ var TrackControllerImpl = class extends EventHostImpl17 {
10335
10382
  const previousTrack = this._currentTrack;
10336
10383
  const previousWasActive = (_a = previousTrack == null ? void 0 : previousTrack.active) != null ? _a : false;
10337
10384
  this._currentTrack = newTrack;
10338
- const interrupted = () => this._currentTrack !== newTrack;
10385
+ const interrupted = () => this.disposed || this._currentTrack !== newTrack;
10339
10386
  previousTrack == null ? void 0 : previousTrack.deactivate();
10340
10387
  if (previousTrack && previousWasActive) {
10341
10388
  this.dispatch("trackDeactivated", { track: previousTrack });
@@ -10363,6 +10410,7 @@ var TrackControllerImpl = class extends EventHostImpl17 {
10363
10410
  if (preroll) return;
10364
10411
  activate();
10365
10412
  }).catch((error) => {
10413
+ if (interrupted()) return;
10366
10414
  logError5(this, "enterPreroll failed", error);
10367
10415
  activate();
10368
10416
  });
@@ -10405,18 +10453,14 @@ var TrackControllerImpl = class extends EventHostImpl17 {
10405
10453
  }
10406
10454
  };
10407
10455
 
10408
- // src/vinyl/createVinylFactories.ts
10409
- import { mergeDeep, noop as noop10 } from "@amazon/vinyl-util";
10410
-
10411
- // src/vinyl/VinylPatchOptions.ts
10412
- import { lazy as lazy3 } from "@amazon/vinyl-util";
10413
- var defaultPatchOptions = /* @__PURE__ */ lazy3(() => {
10414
- return {
10415
- media: defaultMediaElementPatchOptions.value
10416
- };
10417
- });
10456
+ // src/util/media/mimeType.ts
10457
+ function mimeSubtype(mimeType) {
10458
+ var _a;
10459
+ return (_a = mimeType.split(";", 1)[0].trim().toLowerCase().split("/")[1]) != null ? _a : "";
10460
+ }
10418
10461
 
10419
10462
  // src/vinyl/createVinylFactories.ts
10463
+ import { noop as noop9 } from "@amazon/vinyl-util";
10420
10464
  import { validateFactories as validateFactories5 } from "@amazon/vinyl-di";
10421
10465
 
10422
10466
  // src/vinyl/VinylOptions.ts
@@ -10466,27 +10510,19 @@ function playerConfigFactory(defaults, validator) {
10466
10510
 
10467
10511
  // src/vinyl/createVinylFactories.ts
10468
10512
  function createVinylFactories(options) {
10469
- var _a;
10470
- const patches = mergeDeep([
10471
- defaultPatchOptions.value,
10472
- (_a = options.patches) != null ? _a : {}
10473
- ]);
10474
10513
  return validateFactories5({
10475
10514
  options: playerConfigFactory(
10476
10515
  defaultVinylOptions,
10477
10516
  vinylOptionsValidator
10478
10517
  ),
10479
- patchedMedia: () => {
10480
- return patchMediaElement(options.media, patches.media);
10481
- },
10482
- media: (deps) => deps.patchedMedia.patched,
10518
+ media: () => options.media,
10483
10519
  // One provider per media element (the player container creates each
10484
10520
  // dependency once), so text tracks are reused rather than accumulated.
10485
10521
  textTrackProvider: (deps) => createMediaTextTrackProvider({ media: deps.media }),
10486
10522
  // App-provided cue renderer (or null for native rendering).
10487
10523
  textTrackRenderer: () => {
10488
- var _a2;
10489
- return (_a2 = options.textTrackRenderer) != null ? _a2 : null;
10524
+ var _a;
10525
+ return (_a = options.textTrackRenderer) != null ? _a : null;
10490
10526
  },
10491
10527
  playbackController: (deps) => new PlaybackControllerImpl(deps, options.playbackController),
10492
10528
  playbackSource: (deps) => new PlaybackSourceImpl(deps),
@@ -10494,7 +10530,7 @@ function createVinylFactories(options) {
10494
10530
  options: deps.options.pick("loudnessNormalization")
10495
10531
  }),
10496
10532
  capabilities: (deps) => new CapabilitiesImpl(deps),
10497
- requestInterceptor: () => noop10,
10533
+ requestInterceptor: () => noop9,
10498
10534
  trackFactory: (deps) => createTrackFactory(createVinylTrackFactories(deps)),
10499
10535
  adTrackLoadOptionsProvider: () => defaultAdLoadOptionsResolver,
10500
10536
  trackController: (deps) => new TrackControllerImpl(deps, options.trackController),
@@ -10510,13 +10546,13 @@ function createVinylFactories(options) {
10510
10546
 
10511
10547
  // src/vinyl/VinylPlayer.ts
10512
10548
  import {
10513
- createDisposer as createDisposer19,
10549
+ createDisposer as createDisposer18,
10514
10550
  emptyRanges as emptyRanges3,
10515
10551
  equalDeep as equalDeep4,
10516
10552
  EventHostImpl as EventHostImpl18,
10517
10553
  logDebug as logDebug18,
10518
- logInfo as logInfo4,
10519
- logWarn as logWarn7,
10554
+ logInfo as logInfo3,
10555
+ logWarn as logWarn6,
10520
10556
  redispatchEvents as redispatchEvents4
10521
10557
  } from "@amazon/vinyl-util";
10522
10558
  import {
@@ -10539,7 +10575,7 @@ var VinylPlayer = class extends EventHostImpl18 {
10539
10575
  */
10540
10576
  __publicField(this, "client");
10541
10577
  __publicField(this, "_error", null);
10542
- __publicField(this, "disposer", /* @__PURE__ */ createDisposer19());
10578
+ __publicField(this, "disposer", /* @__PURE__ */ createDisposer18());
10543
10579
  const add = this.disposer.add;
10544
10580
  this.deps = add(createContainer3(factories)).dependencies;
10545
10581
  this.client = {
@@ -10597,7 +10633,7 @@ var VinylPlayer = class extends EventHostImpl18 {
10597
10633
  add(
10598
10634
  this.on("codecUnsupported", (event) => {
10599
10635
  if (this.deps.adController.currentAdBreak) return;
10600
- logWarn7(
10636
+ logWarn6(
10601
10637
  this,
10602
10638
  "codec unsupported, reloading track:",
10603
10639
  event.mimeType
@@ -11123,7 +11159,7 @@ var VinylPlayer = class extends EventHostImpl18 {
11123
11159
  };
11124
11160
  function createVinylPlayer(options, factoryOverrides) {
11125
11161
  const player = new VinylPlayer(__spreadValues(__spreadValues({}, createVinylFactories(options)), factoryOverrides));
11126
- logInfo4(player, `VinylPlayer initialized`);
11162
+ logInfo3(player, `VinylPlayer initialized`);
11127
11163
  return player;
11128
11164
  }
11129
11165
  function notResetEvent(type) {
@@ -11175,10 +11211,7 @@ export {
11175
11211
  LICENSE_TIMEOUT,
11176
11212
  LIVE_DURATION,
11177
11213
  LoudnessNormalizationControllerImpl,
11178
- MAX_UNCHANGED_COUNT,
11179
11214
  MIN_APPEND_SIZE,
11180
- MIN_PLAYING_BEFORE_FAB,
11181
- MIN_STALLED_BEFORE_FAB,
11182
11215
  ManifestControllerImpl,
11183
11216
  MediaKeySessionErrorType,
11184
11217
  MediaSourceControllerImpl,
@@ -11188,7 +11221,6 @@ export {
11188
11221
  MsCommonMediaKeySystemAccess,
11189
11222
  MsCommonMediaKeys,
11190
11223
  MseTrack,
11191
- PLAYHEAD_NUDGE,
11192
11224
  PLAY_READY_KEY_SYSTEMS,
11193
11225
  POLL_BUFFER_THROTTLE,
11194
11226
  PREFETCH_POLL_THROTTLE,
@@ -11203,7 +11235,6 @@ export {
11203
11235
  READY_TO_APPEND_TIMEOUT,
11204
11236
  RESTRICTABLE_CONTENT_TYPES,
11205
11237
  ReportableMediaError,
11206
- SEEKING_STALL_TIME_CHECK,
11207
11238
  SEGMENT_START_AFFORDANCE,
11208
11239
  SegmentControllerImpl,
11209
11240
  SegmentDataSlot,
@@ -11214,6 +11245,7 @@ export {
11214
11245
  SourceObjectTrack,
11215
11246
  SourceTrack,
11216
11247
  SourceTrackBase,
11248
+ StallEndedReason,
11217
11249
  StandardCommonEme,
11218
11250
  StandardCommonMediaKeySession,
11219
11251
  StandardCommonMediaKeySystemAccess,
@@ -11221,7 +11253,6 @@ export {
11221
11253
  TIMEUPDATE_THROTTLE,
11222
11254
  TrackBase,
11223
11255
  TrackControllerImpl,
11224
- UNRELIABLE_EVENTS_POLL_INTERVAL,
11225
11256
  UnresolvableAdError,
11226
11257
  VinylGlobal,
11227
11258
  VinylPlayer,
@@ -11283,14 +11314,14 @@ export {
11283
11314
  createMediaQualityMetadataFromDashRepresentation,
11284
11315
  createMediaSource,
11285
11316
  createMediaTextTrackProvider,
11286
- createPreventStallsPatch,
11287
11317
  createSegmentControllerFactory,
11288
11318
  createSegmentDataProvider,
11289
11319
  createSourceObjectTrackFactory,
11290
11320
  createSourceTrackFactory,
11321
+ createStallDetector,
11322
+ createStallMonitor,
11291
11323
  createTrackFactory,
11292
11324
  createTrackLoadOptionsFromUrl,
11293
- createUnreliablePlaybackEventsPatch,
11294
11325
  createUrlHlsManifestProvider,
11295
11326
  createVinylFactories,
11296
11327
  createVinylPlayer,
@@ -11301,8 +11332,6 @@ export {
11301
11332
  defaultDrmKeySystemResolver,
11302
11333
  defaultLicenseProvider,
11303
11334
  defaultLoudnessNormalizationControllerImplOptions,
11304
- defaultMediaElementPatchOptions,
11305
- defaultPatchOptions,
11306
11335
  defaultPlaybackControllerImplOptions,
11307
11336
  defaultQualitySelectorImplOptions,
11308
11337
  defaultResetControllerOptions,
@@ -11372,6 +11401,7 @@ export {
11372
11401
  mediaFormatMetadataValidator,
11373
11402
  mediaKeySupportRef,
11374
11403
  mediaQualityMetadataValidator,
11404
+ mimeSubtype,
11375
11405
  msErrorCodeToStr,
11376
11406
  nextHasMetadata,
11377
11407
  nextMediaSourceEnded,
@@ -11382,7 +11412,6 @@ export {
11382
11412
  parseCencEncryptionScheme,
11383
11413
  parsePlayReadyKeyMessage,
11384
11414
  parseWebVtt,
11385
- patchMediaElement,
11386
11415
  pickFirstBaseUrlSelector,
11387
11416
  pickPreferredTextTrack,
11388
11417
  playbackStateLoggingHandler,
@@ -11392,8 +11421,6 @@ export {
11392
11421
  prefetchPriorityQueuesRef,
11393
11422
  qualitySelectorImplOptionsValidator,
11394
11423
  renderCueText,
11395
- requiresPreventStallsPatch,
11396
- requiresUnreliablePlaybackEventsPatch,
11397
11424
  resolveCodecOverride,
11398
11425
  resolveDashUri,
11399
11426
  resolvePreferredLanguages,
@@ -11404,7 +11431,6 @@ export {
11404
11431
  sortDashAdaptationSets,
11405
11432
  sortDashRepresentations,
11406
11433
  sourceTrackBaseOptionsValidator,
11407
- supportsAudioSamplingRate,
11408
11434
  supportsMsEme,
11409
11435
  supportsMse,
11410
11436
  supportsStandardEme,
@@ -11425,6 +11451,7 @@ export {
11425
11451
  vinylVersion,
11426
11452
  vttCueStyleValidator,
11427
11453
  waitedReasons,
11428
- webkitErrorCodeToStr
11454
+ webkitErrorCodeToStr,
11455
+ withinAudioSampleRateRange
11429
11456
  };
11430
11457
  //# sourceMappingURL=index.js.map