@amazon/vinyl 3.0.0 → 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 +987 -969
  2. package/dist/index.cjs.map +4 -4
  3. package/dist/index.js +665 -638
  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 +2361 -1870
  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 +38 -32
  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 +97 -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
@@ -1,6 +1,6 @@
1
1
  import type { CapabilitiesImplDeps } from '../client/CapabilitiesImpl';
2
2
  import { CapabilitiesImpl } from '../client/CapabilitiesImpl';
3
- import type { Merge, PartialDeep, PatchedRef } from '@amazon/vinyl-util';
3
+ import type { Merge, PartialDeep } from '@amazon/vinyl-util';
4
4
  import { noop } from '@amazon/vinyl-util';
5
5
  import type { PlaybackControllerImplDeps, PlaybackControllerImplOptions } from '../playback/PlaybackControllerImpl';
6
6
  import { PlaybackControllerImpl } from '../playback/PlaybackControllerImpl';
@@ -9,7 +9,6 @@ import { PlaybackSourceImpl } from '../playback/PlaybackSourceImpl';
9
9
  import { type VinylTrackFactoryDeps } from '../track/createVinylTrackFactories';
10
10
  import type { TrackControllerImplDeps, TrackControllerImplOptions } from '../track/TrackController';
11
11
  import { TrackControllerImpl } from '../track/TrackController';
12
- import type { VinylPatchOptions } from './VinylPatchOptions';
13
12
  import { type QualitySelectorImplOptions } from '../streaming/abr/QualitySelectorImpl';
14
13
  import { AdControllerImpl, type AdControllerImplDeps, type AdControllerImplOptions } from '../ad/AdControllerImpl';
15
14
  import { type MediaTextTrackProvider } from '../text/mediaTextTrackProvider';
@@ -41,11 +40,6 @@ export interface VinylDependencyOptions {
41
40
  * `'hidden'`; without one they render natively. See `TextTrackRenderer`.
42
41
  */
43
42
  readonly textTrackRenderer?: TextTrackRenderer;
44
- /**
45
- * Flags for patches that should be applied browser-specifically.
46
- * These will be defaulted based on the user-agent.
47
- */
48
- readonly patches?: PartialDeep<VinylPatchOptions>;
49
43
  /**
50
44
  * Configuration for the track controller.
51
45
  */
@@ -82,12 +76,7 @@ export interface VinylDependencyOptions {
82
76
  */
83
77
  export declare function createVinylFactories(options: VinylDependencyOptions): {
84
78
  options: (_deps: import("@amazon/vinyl-util").AnyRecord, add: import("@amazon/vinyl-util").AddDisposable) => import("@amazon/vinyl-observable").MutableValue<VinylOptions>;
85
- patchedMedia: () => PatchedRef<HTMLMediaElement>;
86
- media: (deps: {
87
- readonly patchedMedia: {
88
- readonly patched: HTMLMediaElement;
89
- };
90
- }) => HTMLMediaElement;
79
+ media: () => HTMLMediaElement;
91
80
  textTrackProvider: (deps: {
92
81
  readonly media: HTMLMediaElement;
93
82
  }) => MediaTextTrackProvider;
@@ -153,7 +142,7 @@ export declare function createVinylFactories(options: VinylDependencyOptions): {
153
142
  readonly manifestTransformed: ObservableValue<Promise<import("..").DashManifestData>>;
154
143
  readonly options: ObservableValue<Pick<VinylOptions, "text">>;
155
144
  }) => import("..").SidecarTextTrackController;
156
- options: import("@amazon/vinyl-di").Factory<ObservableValue<Pick<VinylOptions, "audio" | "text" | "abr" | "allowedContentTypes">>>;
145
+ options: import("@amazon/vinyl-di").Factory<ObservableValue<Pick<VinylOptions, "text" | "audio" | "abr" | "allowedContentTypes">>>;
157
146
  playbackController: import("@amazon/vinyl-di").Factory<import("..").PlaybackController>;
158
147
  playbackSource: import("@amazon/vinyl-di").Factory<import("..").PlaybackSource>;
159
148
  drmKeySystemResolver: import("@amazon/vinyl-di").Factory<import("..").DrmKeySystemResolver>;
@@ -165,7 +154,9 @@ export declare function createVinylFactories(options: VinylDependencyOptions): {
165
154
  textTrackRenderer: import("@amazon/vinyl-di").Factory<TextTrackRenderer | null>;
166
155
  adController: import("@amazon/vinyl-di").Factory<import("..").AdController>;
167
156
  };
168
- createHlsFactories: (deps: import("..").HlsFactoryDeps) => (loadOptions: import("..").HlsTrackLoadOptions) => {
157
+ createHlsFactories: (deps: import("..").HlsFactoryDeps) => (loadOptions: import("..").HlsTrackLoadOptions /**
158
+ * Configuration for adaptive bitrate switching.
159
+ */) => {
169
160
  baseContentTypesValue: typeof import("..").createHlsContentTypesValue;
170
161
  contentTypesValue: typeof import("..").createAllowedContentTypesValue;
171
162
  manifestProvider: () => import("..").HlsManifestProvider;
@@ -208,7 +199,7 @@ export declare function createVinylFactories(options: VinylDependencyOptions): {
208
199
  readonly manifestTransformed: ObservableValue<Promise<import("..").HlsManifestData>>;
209
200
  readonly options: ObservableValue<Pick<VinylOptions, "text">>;
210
201
  }) => import("..").SidecarTextTrackController;
211
- options: import("@amazon/vinyl-di").Factory<ObservableValue<Pick<VinylOptions, "audio" | "text" | "abr" | "allowedContentTypes">>>;
202
+ options: import("@amazon/vinyl-di").Factory<ObservableValue<Pick<VinylOptions, "text" | "audio" | "abr" | "allowedContentTypes">>>;
212
203
  playbackController: import("@amazon/vinyl-di").Factory<import("..").PlaybackController>;
213
204
  playbackSource: import("@amazon/vinyl-di").Factory<import("..").PlaybackSource>;
214
205
  drmKeySystemResolver: import("@amazon/vinyl-di").Factory<import("..").DrmKeySystemResolver>;
@@ -6,11 +6,22 @@ import { AdControllerImpl } from '@amazon/vinyl';
6
6
  import { MockPlaybackController, MockTrack } from '@amazon/vinyl/vinylTestUtil';
7
7
  describe('AdControllerImpl', () => {
8
8
  let playbackController;
9
+ let controllers;
9
10
  beforeEach(() => {
10
11
  playbackController = new MockPlaybackController();
12
+ controllers = [];
13
+ });
14
+ // Dispose every controller a spec created. An activated-but-unstarted ad
15
+ // arms a `sleep(adLoadTimeout)` timer.
16
+ afterEach(() => {
17
+ for (const c of controllers)
18
+ if (!c.disposed)
19
+ c.dispose();
11
20
  });
12
21
  function createController() {
13
- return new AdControllerImpl({ playbackController });
22
+ const c = new AdControllerImpl({ playbackController });
23
+ controllers.push(c);
24
+ return c;
14
25
  }
15
26
  function updateTime(time) {
16
27
  playbackController.currentTime = time;
@@ -301,6 +312,21 @@ describe('AdControllerImpl', () => {
301
312
  await flush();
302
313
  expect(c.currentAdBreak).toBeNull();
303
314
  });
315
+ it('ignores a late provider ad-discovery resolution after dispose', async () => {
316
+ const c = createController();
317
+ let resolveAds = () => { };
318
+ const track = new MockTrack();
319
+ track.uri = 't1';
320
+ track.active = true;
321
+ track.getAds = () => new Promise((res) => {
322
+ resolveAds = res;
323
+ });
324
+ c.setAdsProvider(track); // refreshAds() runs; getAds() stays pending
325
+ c.dispose();
326
+ resolveAds(trackAds(makeBreak())); // refreshAds .then: interrupted (disposed)
327
+ await flush();
328
+ expect(c.currentTrackAds).toBeNull();
329
+ });
304
330
  });
305
331
  it('emits currentTrackAdsChange with the TrackAds when a parent track is set', async () => {
306
332
  const c = createController();
@@ -389,6 +389,58 @@ describe('DrmControllerImpl', () => {
389
389
  expect(errorSpy).not.toHaveBeenCalled();
390
390
  expect(mediaKeys.createSession).toHaveBeenCalledTimes(1); // reused
391
391
  });
392
+ it('reuses the session when a transformer alters the CDM init data', async () => {
393
+ // A non-identity initDataTransformer changes the bytes handed to the
394
+ // CDM (always the case for FairPlay, or any custom transformer). The
395
+ // reuse check must compare the ORIGINAL init data, not the
396
+ // transformed bytes — otherwise every re-appended init segment fires
397
+ // `encrypted` and spins up a brand-new session instead of recycling.
398
+ const transformed = new Uint8Array([9, 9, 9]);
399
+ const controller = new DrmControllerImpl(deps, {
400
+ licenseProvider,
401
+ keySystems: {
402
+ [DrmKeySystem.WIDEVINE]: {
403
+ initDataTransformer: () => transformed,
404
+ },
405
+ },
406
+ });
407
+ const localErrors = createEventSpy(controller, 'error');
408
+ const encryptedCb = commonEme.addEncryptedListener.calls.mostRecent().args[1];
409
+ controller.setBufferingDrmInfo(drmInfo);
410
+ encryptedCb({
411
+ initData: new Uint8Array([1, 2, 3]),
412
+ initDataType: 'cenc',
413
+ });
414
+ await flushPromises();
415
+ expect(mediaKeys.createSession).toHaveBeenCalledTimes(1);
416
+ // The session stored the transformed bytes handed to the CDM.
417
+ expect(getSession(0).initData).toEqual(transformed);
418
+ // The same raw init data fires again (e.g. a quality switch
419
+ // re-appends the init segment) — the session must be reused.
420
+ encryptedCb({
421
+ initData: new Uint8Array([1, 2, 3]),
422
+ initDataType: 'cenc',
423
+ });
424
+ await flushPromises();
425
+ expect(localErrors).not.toHaveBeenCalled();
426
+ expect(mediaKeys.createSession).toHaveBeenCalledTimes(1); // reused
427
+ controller.dispose();
428
+ });
429
+ it('ignores encrypted events when the manifest supplies pssh', async () => {
430
+ // The proactive manifest-pssh path owns session creation, so in-band
431
+ // `encrypted` events (e.g. a re-appended init segment on an ABR
432
+ // switch) must not spawn a duplicate session.
433
+ const drmInfoWithPssh = {
434
+ ...drmInfo,
435
+ contentProtections: [
436
+ { keySystem: DrmKeySystem.WIDEVINE, pssh: 'AAAA' },
437
+ ],
438
+ };
439
+ drmController.setBufferingDrmInfo(drmInfoWithPssh);
440
+ await emitEncrypted(new Uint8Array([1, 2, 3]));
441
+ expect(errorSpy).not.toHaveBeenCalled();
442
+ expect(mediaKeys.createSession).not.toHaveBeenCalled();
443
+ });
392
444
  describe('and the drm controller is disposed', () => {
393
445
  it('does nothing', async () => {
394
446
  drmController.dispose();
@@ -613,6 +665,29 @@ describe('DrmControllerImpl', () => {
613
665
  });
614
666
  });
615
667
  describe('when a session message event is observed', () => {
668
+ it('does not update the session when disposed before the license resolves', async () => {
669
+ let resolveLicense = () => { };
670
+ licenseProvider.and.returnValue(new Promise((res) => {
671
+ resolveLicense = res;
672
+ }));
673
+ drmController = new DrmControllerImpl(deps, {
674
+ keySystems: {
675
+ [DrmKeySystem.WIDEVINE]: {
676
+ licenseServer: { url: 'http://example.com/widevine' },
677
+ },
678
+ },
679
+ licenseProvider,
680
+ });
681
+ drmController.setBufferingDrmInfo(drmInfo);
682
+ await emitEncrypted(new Uint8Array([1, 2, 3]), 'cenc');
683
+ getSession(0).dispatch('message', { message: new ArrayBuffer(1) });
684
+ await flushPromises();
685
+ // License in flight — dispose, then let it resolve.
686
+ drmController.dispose();
687
+ resolveLicense(new ArrayBuffer(2));
688
+ await flushPromises();
689
+ expect(getSession(0).update).not.toHaveBeenCalled();
690
+ });
616
691
  it('calls the licenseProvider with resolved licenseServer options', async () => {
617
692
  drmController = new DrmControllerImpl(deps, {
618
693
  keySystems: {
@@ -666,6 +741,24 @@ describe('DrmControllerImpl', () => {
666
741
  }, message);
667
742
  }
668
743
  });
744
+ it('falls back to the wildcard key system license server', async () => {
745
+ drmController = new DrmControllerImpl(deps, {
746
+ keySystems: {
747
+ // Only a wildcard entry — no per-key-system configuration.
748
+ '*': {
749
+ licenseServer: () => ({
750
+ url: 'http://example.com/wildcard',
751
+ }),
752
+ },
753
+ },
754
+ licenseProvider,
755
+ });
756
+ drmController.setBufferingDrmInfo(drmInfo);
757
+ await emitEncrypted(new Uint8Array([1, 2, 3]), 'cenc');
758
+ const message = new ArrayBuffer(1);
759
+ await emitMessage(0, message);
760
+ expect(licenseProvider).toHaveBeenCalledOnceWith(DrmKeySystem.WIDEVINE, { url: 'http://example.com/wildcard' }, message);
761
+ });
669
762
  describe('when license takes too long to resolve', () => {
670
763
  it('emits an error event', async () => {
671
764
  drmController = new DrmControllerImpl(deps, {
@@ -25,10 +25,8 @@ import './global/configureVinylGlobal.test';
25
25
  import './global/environment.test';
26
26
  import './global/globalRef.test';
27
27
  import './global/PlayerRegistry.test';
28
- import './patch/media/MediaElementPatchOptions.test';
29
- import './patch/media/patches/createPreventStallsPatch.test';
30
- import './patch/media/patches/createUnreliablePlaybackEventsPatch.test';
31
- import './patch/media/patchMediaElement.test';
28
+ import './playback/createStallDetector.test';
29
+ import './playback/createStallMonitor.test';
32
30
  import './playback/error/InvalidSeekError.test';
33
31
  import './playback/error/ReportableMediaError.test';
34
32
  import './playback/logging/mediaErrorToJson.test';
@@ -116,6 +114,7 @@ import './util/media/codecOverrides.test';
116
114
  import './util/media/codecSupport.test';
117
115
  import './util/media/getAudioContext.test';
118
116
  import './util/media/mediaSource.test';
117
+ import './util/media/mimeType.test';
119
118
  import './util/media/sourceBuffer.test';
120
119
  import './vinyl/createVinylFactories.test';
121
120
  import './vinyl/playerConfigFactory.test';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../test/unit/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../test/unit/index.ts"],"names":[],"mappings":"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"}
@@ -25,10 +25,8 @@ import './global/configureVinylGlobal.test';
25
25
  import './global/environment.test';
26
26
  import './global/globalRef.test';
27
27
  import './global/PlayerRegistry.test';
28
- import './patch/media/MediaElementPatchOptions.test';
29
- import './patch/media/patches/createPreventStallsPatch.test';
30
- import './patch/media/patches/createUnreliablePlaybackEventsPatch.test';
31
- import './patch/media/patchMediaElement.test';
28
+ import './playback/createStallDetector.test';
29
+ import './playback/createStallMonitor.test';
32
30
  import './playback/error/InvalidSeekError.test';
33
31
  import './playback/error/ReportableMediaError.test';
34
32
  import './playback/logging/mediaErrorToJson.test';
@@ -116,6 +114,7 @@ import './util/media/codecOverrides.test';
116
114
  import './util/media/codecSupport.test';
117
115
  import './util/media/getAudioContext.test';
118
116
  import './util/media/mediaSource.test';
117
+ import './util/media/mimeType.test';
119
118
  import './util/media/sourceBuffer.test';
120
119
  import './vinyl/createVinylFactories.test';
121
120
  import './vinyl/playerConfigFactory.test';
@@ -78,6 +78,29 @@ describe('PlaybackController', () => {
78
78
  if (!controller.disposed)
79
79
  controller.dispose();
80
80
  });
81
+ describe('stall detection', () => {
82
+ it('does not emit stallEntered before playback is observed', async () => {
83
+ const enteredSpy = createEventSpy(controller, 'stallEntered');
84
+ await clock.tick(2);
85
+ expect(enteredSpy).not.toHaveBeenCalled();
86
+ });
87
+ it('emits stallEntered when the play head freezes while playing and stallEnded on resume', async () => {
88
+ const enteredSpy = createEventSpy(controller, 'stallEntered');
89
+ const endedSpy = createEventSpy(controller, 'stallEnded');
90
+ media.dispatchEvent(mockEvent('playing'));
91
+ media.currentTime = 1;
92
+ media.dispatchEvent(mockEvent('timeupdate'));
93
+ // Frozen for the 1s default threshold.
94
+ await clock.tick(1);
95
+ expect(enteredSpy).toHaveBeenCalledTimes(1);
96
+ expect(endedSpy).not.toHaveBeenCalled();
97
+ // Play head advances -> stall ends with reason 'playing'.
98
+ media.currentTime = 2;
99
+ media.dispatchEvent(mockEvent('timeupdate'));
100
+ expect(endedSpy).toHaveBeenCalledTimes(1);
101
+ expect(endedSpy.calls.mostRecent().args[0].reason).toBe('playing');
102
+ });
103
+ });
81
104
  it('assigns properties, methods, and events directly to a media object', () => {
82
105
  expect(controller.buffered).toBeInstanceOf(ReadonlyRangesImpl);
83
106
  testDelegate(controller, 'currentTime', 2);
@@ -191,6 +214,135 @@ describe('PlaybackController', () => {
191
214
  },
192
215
  });
193
216
  }
217
+ /**
218
+ * Simulates WebKit reverting a seek: the first `revertCount`
219
+ * seeks land at `revertTo` instead of the requested time; later
220
+ * seeks land on the requested time.
221
+ */
222
+ function enableSeekWithReverts(revertTo, revertCount) {
223
+ let currentTime = 0;
224
+ let reverts = revertCount;
225
+ Object.defineProperty(media, 'currentTime', {
226
+ get() {
227
+ return currentTime;
228
+ },
229
+ set(value) {
230
+ currentTime = reverts-- > 0 ? revertTo : value;
231
+ media.dispatchEvent(mockEvent('seeking'));
232
+ void (async () => {
233
+ await flushPromises();
234
+ media.dispatchEvent(mockEvent('seeked'));
235
+ })();
236
+ },
237
+ });
238
+ }
239
+ /**
240
+ * Simulates a WebKit cold-seek stall: `seeking` fires but
241
+ * `seeked` does not for the first `stuckAttempts` attempts, then
242
+ * completes.
243
+ */
244
+ function enableStuckSeek(stuckAttempts) {
245
+ let currentTime = 0;
246
+ let attempt = 0;
247
+ Object.defineProperty(media, 'currentTime', {
248
+ get() {
249
+ return currentTime;
250
+ },
251
+ set(value) {
252
+ currentTime = value;
253
+ media.dispatchEvent(mockEvent('seeking'));
254
+ if (attempt++ >= stuckAttempts) {
255
+ void (async () => {
256
+ await flushPromises();
257
+ media.dispatchEvent(mockEvent('seeked'));
258
+ })();
259
+ }
260
+ },
261
+ });
262
+ }
263
+ it('warms the decoder and retries when a seek stalls', async () => {
264
+ enableStuckSeek(1); // first attempt hangs, retry completes
265
+ setSeekable([[0, 30]]);
266
+ media.paused = false;
267
+ const seek = controller.seekTo(5);
268
+ // Flush to arm the first attempt's seeked timeout, then
269
+ // advance to fire it; the retry lands via its seeked event.
270
+ await clock.tick(0, 4);
271
+ await seek;
272
+ // Warmed the decoder with play(), then landed on retry.
273
+ expect(media.play).toHaveBeenCalled();
274
+ expect(media.currentTime).toBe(5);
275
+ });
276
+ it('gives up after the retry limit when a seek never completes', async () => {
277
+ enableStuckSeek(99); // never completes
278
+ setSeekable([[0, 30]]);
279
+ media.paused = false;
280
+ const seek = controller.seekTo(5);
281
+ // Leading flush arms the initial attempt's seeked timeout;
282
+ // each subsequent tick fires one and arms the next retry
283
+ // (initial + SEEK_RETRY_LIMIT attempts all time out).
284
+ await clock.tick(0, 4, 4, 4);
285
+ await seek;
286
+ expect(media.play).toHaveBeenCalled();
287
+ });
288
+ it('stops retrying when a re-seek never re-enters seeking', async () => {
289
+ let sets = 0;
290
+ let currentTime = 0;
291
+ Object.defineProperty(media, 'currentTime', {
292
+ get() {
293
+ return currentTime;
294
+ },
295
+ set(value) {
296
+ currentTime = value;
297
+ // Only the first attempt emits `seeking`; re-seeks to
298
+ // the same position stay silent (WebKit), so their
299
+ // seeking wait times out and returns null.
300
+ if (sets++ === 0) {
301
+ media.dispatchEvent(mockEvent('seeking'));
302
+ }
303
+ },
304
+ });
305
+ setSeekable([[0, 30]]);
306
+ media.paused = false;
307
+ const seek = controller.seekTo(5);
308
+ await clock.tick(0, 4, 4, 4);
309
+ await seek;
310
+ expect(media.currentTime).toBe(5);
311
+ });
312
+ it('rejects a seek disposed while awaiting seeked', async () => {
313
+ setSeekable([[0, 30]]);
314
+ media.paused = false;
315
+ const seek = controller.seekTo(5);
316
+ media.dispatchEvent(mockEvent('seeking'));
317
+ await flushPromises();
318
+ controller.dispose();
319
+ await expectAsync(seek).toBeRejectedWithError(AbortError);
320
+ });
321
+ it('re-seeks when WebKit lands the play head off target', async () => {
322
+ enableSeekWithReverts(20, 1);
323
+ setSeekable([[0, 30]]);
324
+ media.paused = true;
325
+ await controller.seekTo(5);
326
+ expect(media.currentTime).toBeCloseTo(5);
327
+ });
328
+ it('gives up re-seeking after the retry limit', async () => {
329
+ enableSeekWithReverts(20, 99);
330
+ setSeekable([[0, 30]]);
331
+ media.paused = true;
332
+ await controller.seekTo(5);
333
+ expect(media.currentTime).toBe(20);
334
+ });
335
+ it('stops re-seeking when a newer seek supersedes', async () => {
336
+ enableSeekWithReverts(20, 99);
337
+ setSeekable([[0, 30]]);
338
+ media.paused = true;
339
+ const first = controller.seekTo(5);
340
+ const second = controller.seekTo(9);
341
+ await Promise.allSettled([first, second]);
342
+ // Both landed at the reverted position; the first stopped
343
+ // re-seeking once superseded rather than fighting the newer.
344
+ expect(media.currentTime).toBe(20);
345
+ });
194
346
  it('waits for metadata before initiating seek', async () => {
195
347
  enableSeekAutoComplete();
196
348
  const seeked = controller.seekTo(3);
@@ -199,6 +351,19 @@ describe('PlaybackController', () => {
199
351
  await seeked;
200
352
  expect(media.currentTime).toBe(3);
201
353
  });
354
+ it('fabricates a playing event if playback resumes after a seek without one', async () => {
355
+ enableSeekAutoComplete();
356
+ setSeekable([[0, 10]]);
357
+ media.paused = false;
358
+ const playingSpy = createSpy('playing');
359
+ controller.on('playing', playingSpy);
360
+ await controller.seekTo(3);
361
+ // The play head advances but no 'playing' event fires; the
362
+ // post-seek stall detector fabricates one.
363
+ media.currentTime = 3.5;
364
+ await clock.tick(0.25);
365
+ expect(playingSpy).toHaveBeenCalled();
366
+ });
202
367
  it('does not let a metadata-deferred seek clobber a newer seek', async () => {
203
368
  // Reproduces the real race: the activate-time seek to the
204
369
  // track start parks waiting for the `loadedmetadata` EVENT.
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=createStallDetector.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createStallDetector.test.d.ts","sourceRoot":"","sources":["../../../../../test/unit/playback/createStallDetector.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,163 @@
1
+ /*
2
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3
+ * SPDX-License-Identifier: Apache-2.0
4
+ */
5
+ import { createStallDetector } from '@amazon/vinyl';
6
+ import { implementEventFakes, MockHTMLAudioElement, mockEvent, MockTimeRanges, useMockTime, } from '@amazon/vinyl-util/browserTestUtil';
7
+ describe('createStallDetector', () => {
8
+ const clock = useMockTime();
9
+ let media;
10
+ let fabricatePlaying;
11
+ let stop;
12
+ beforeEach(() => {
13
+ media = new MockHTMLAudioElement();
14
+ implementEventFakes(media);
15
+ media.play.and.returnValue(Promise.resolve());
16
+ media.paused = false;
17
+ media.ended = false;
18
+ media.readyState = media.HAVE_ENOUGH_DATA;
19
+ media.currentTime = 10;
20
+ media.buffered = new MockTimeRanges([[0, 100]]);
21
+ fabricatePlaying = jasmine.createSpy('fabricatePlaying');
22
+ });
23
+ afterEach(() => {
24
+ stop?.();
25
+ });
26
+ function detect(overrides = {}) {
27
+ stop = createStallDetector(media, { fabricatePlaying, ...overrides });
28
+ }
29
+ /** Advances the mock clock by `n` default poll intervals. */
30
+ async function poll(n) {
31
+ for (let i = 0; i < n; i++) {
32
+ await clock.tick(0.25);
33
+ }
34
+ }
35
+ describe('a stall inside ready buffered data', () => {
36
+ it('nudges the play head once frozen past the stall threshold', async () => {
37
+ detect();
38
+ // Threshold is 0.75s = three polls; the third nudges by stallSkip.
39
+ await poll(3);
40
+ expect(media.currentTime).toBeCloseTo(10.1);
41
+ });
42
+ it('does not recover before the stall threshold', async () => {
43
+ detect();
44
+ await poll(2);
45
+ expect(media.currentTime).toBe(10);
46
+ expect(media.play).not.toHaveBeenCalled();
47
+ });
48
+ it('nudges even when the ready state is low (iOS reports a stale readyState)', async () => {
49
+ media.readyState = media.HAVE_METADATA;
50
+ detect();
51
+ await poll(3);
52
+ expect(media.currentTime).toBeCloseTo(10.1);
53
+ expect(media.play).not.toHaveBeenCalled();
54
+ });
55
+ it('keeps nudging, then gives up after maxAttempts', async () => {
56
+ detect();
57
+ // Default maxAttempts is 3, so at most three nudges (one every 3 polls).
58
+ await poll(12);
59
+ expect(media.currentTime).toBeCloseTo(10.3);
60
+ // Further polls do nothing; the detector has stopped.
61
+ await poll(6);
62
+ expect(media.currentTime).toBeCloseTo(10.3);
63
+ });
64
+ });
65
+ describe('a stall with no data at the playhead', () => {
66
+ it('does not recover when the playhead is outside all buffered ranges', async () => {
67
+ media.buffered = new MockTimeRanges([[50, 100]]);
68
+ detect();
69
+ await poll(6);
70
+ expect(media.currentTime).toBe(10);
71
+ expect(fabricatePlaying).not.toHaveBeenCalled();
72
+ });
73
+ it('does not recover at the end of buffered data', async () => {
74
+ // Within the default end margin (0.5s) of the buffer end.
75
+ media.buffered = new MockTimeRanges([[0, 10.3]]);
76
+ detect();
77
+ await poll(6);
78
+ expect(media.currentTime).toBe(10);
79
+ });
80
+ it('nudges at the end of the media (stuck end-of-track on src)', async () => {
81
+ // Buffer ends at the media duration: no more data is coming, so a
82
+ // freeze here is a stuck end-of-track and a nudge drives it to end.
83
+ media.buffered = new MockTimeRanges([[0, 10.3]]);
84
+ media.duration = 10.3;
85
+ detect();
86
+ await poll(3);
87
+ expect(media.currentTime).toBeCloseTo(10.1);
88
+ });
89
+ it('nudges outside buffered ranges when nudgeUnbuffered is set', async () => {
90
+ // WebKit path: re-issue the seek even though buffered looks empty.
91
+ media.buffered = new MockTimeRanges([[50, 100]]);
92
+ detect({ nudgeUnbuffered: true });
93
+ await poll(3);
94
+ expect(media.currentTime).toBeCloseTo(10.1);
95
+ });
96
+ it('stops when the source is emptied', async () => {
97
+ detect();
98
+ media.dispatchEvent(mockEvent('emptied'));
99
+ // Stopped: a later freeze in buffered data is not nudged.
100
+ await poll(6);
101
+ expect(media.currentTime).toBe(10);
102
+ });
103
+ });
104
+ describe('fabricating a playing event', () => {
105
+ it('fabricates when the head progresses without a playing event', async () => {
106
+ detect();
107
+ media.currentTime = 20;
108
+ await poll(1);
109
+ expect(fabricatePlaying).toHaveBeenCalledTimes(1);
110
+ // Detector stopped; a later freeze is not recovered.
111
+ await poll(6);
112
+ expect(media.play).not.toHaveBeenCalled();
113
+ });
114
+ it('does not fabricate when a real playing event fired and it keeps progressing', async () => {
115
+ detect();
116
+ media.dispatchEvent(mockEvent('playing'));
117
+ media.currentTime = 20;
118
+ await poll(6);
119
+ expect(fabricatePlaying).not.toHaveBeenCalled();
120
+ });
121
+ it('fabricates after reviving a stall even if a playing event fired earlier', async () => {
122
+ // iOS pattern: a playing event fires, then playback stalls.
123
+ media.readyState = media.HAVE_METADATA;
124
+ detect();
125
+ media.dispatchEvent(mockEvent('playing'));
126
+ await poll(3);
127
+ expect(media.currentTime).toBeCloseTo(10.1); // nudged (recovered)
128
+ // The recovery revives playback.
129
+ media.currentTime = 11;
130
+ await poll(1);
131
+ expect(fabricatePlaying).toHaveBeenCalledTimes(1);
132
+ });
133
+ });
134
+ describe('when the element is not advancing by design', () => {
135
+ it('does not recover while paused', async () => {
136
+ media.paused = true;
137
+ detect();
138
+ await poll(6);
139
+ expect(media.play).not.toHaveBeenCalled();
140
+ expect(media.currentTime).toBe(10);
141
+ });
142
+ it('does not recover once ended', async () => {
143
+ media.ended = true;
144
+ detect();
145
+ await poll(6);
146
+ expect(media.play).not.toHaveBeenCalled();
147
+ expect(media.currentTime).toBe(10);
148
+ });
149
+ });
150
+ it('honors provided options', async () => {
151
+ detect({
152
+ pollInterval: 0.5,
153
+ stallThreshold: 1,
154
+ bufferEndMargin: 0.2,
155
+ stallSkip: 0.25,
156
+ maxAttempts: 1,
157
+ });
158
+ // Threshold 1s = two 0.5s polls; one nudge of 0.25, then it gives up.
159
+ for (let i = 0; i < 6; i++)
160
+ await clock.tick(0.5);
161
+ expect(media.currentTime).toBeCloseTo(10.25);
162
+ });
163
+ });
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=createStallMonitor.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createStallMonitor.test.d.ts","sourceRoot":"","sources":["../../../../../test/unit/playback/createStallMonitor.test.ts"],"names":[],"mappings":""}