@amazon/vinyl 3.0.1 → 3.2.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.
- package/dist/index.cjs +1103 -1042
- package/dist/index.cjs.map +4 -4
- package/dist/index.js +810 -739
- package/dist/index.js.map +4 -4
- package/dist/test/benchmark.js.map +2 -2
- package/dist/test/integ.es5.js +394 -388
- package/dist/test/integ.js +2626 -2032
- package/dist/test/integ.js.map +4 -4
- package/dist/test/jasmine.css +50 -3
- package/dist/test/jasmineHtml.es5.js +195 -155
- package/dist/test/jasmineHtml.js +2938 -1833
- package/dist/test/jasmineHtml.js.map +3 -3
- package/dist/types/current/ad/AdControllerImpl.d.ts.map +1 -1
- package/dist/types/current/ad/AdControllerImpl.js +4 -1
- package/dist/types/current/ad/discoverHlsInterstitials.d.ts.map +1 -1
- package/dist/types/current/ad/discoverHlsInterstitials.js +2 -2
- package/dist/types/current/drm/DrmControllerImpl.d.ts +19 -1
- package/dist/types/current/drm/DrmControllerImpl.d.ts.map +1 -1
- package/dist/types/current/drm/DrmControllerImpl.js +101 -58
- package/dist/types/current/drm/licenseProvider/defaultLicenseProvider.d.ts.map +1 -1
- package/dist/types/current/drm/licenseProvider/defaultLicenseProvider.js +2 -2
- package/dist/types/current/index.d.ts +3 -6
- package/dist/types/current/index.d.ts.map +1 -1
- package/dist/types/current/index.js +3 -6
- package/dist/types/current/playback/PlaybackControllerImpl.d.ts +15 -0
- package/dist/types/current/playback/PlaybackControllerImpl.d.ts.map +1 -1
- package/dist/types/current/playback/PlaybackControllerImpl.js +100 -9
- package/dist/types/current/playback/ReadonlyPlaybackController.d.ts +27 -1
- package/dist/types/current/playback/ReadonlyPlaybackController.d.ts.map +1 -1
- package/dist/types/current/playback/ReadonlyPlaybackController.js +16 -0
- package/dist/types/current/playback/createStallDetector.d.ts +43 -0
- package/dist/types/current/playback/createStallDetector.d.ts.map +1 -0
- package/dist/types/current/playback/createStallDetector.js +101 -0
- package/dist/types/current/playback/createStallMonitor.d.ts +45 -0
- package/dist/types/current/playback/createStallMonitor.d.ts.map +1 -0
- package/dist/types/current/playback/createStallMonitor.js +94 -0
- package/dist/types/current/streaming/AudioOptions.d.ts +27 -0
- package/dist/types/current/streaming/AudioOptions.d.ts.map +1 -1
- package/dist/types/current/streaming/AudioOptions.js +5 -1
- package/dist/types/current/streaming/ContentStream.d.ts +0 -5
- package/dist/types/current/streaming/ContentStream.d.ts.map +1 -1
- package/dist/types/current/streaming/ContentStream.js +0 -4
- package/dist/types/current/streaming/LoadMetric.d.ts +15 -1
- package/dist/types/current/streaming/LoadMetric.d.ts.map +1 -1
- package/dist/types/current/streaming/StreamingEventMap.d.ts +1 -5
- package/dist/types/current/streaming/StreamingEventMap.d.ts.map +1 -1
- package/dist/types/current/streaming/StreamingEventMap.js +0 -1
- package/dist/types/current/streaming/buffering/BufferingController.d.ts +0 -11
- package/dist/types/current/streaming/buffering/BufferingController.d.ts.map +1 -1
- package/dist/types/current/streaming/buffering/BufferingController.js +0 -13
- package/dist/types/current/streaming/createDefaultMediaTimelineTransformer.d.ts.map +1 -1
- package/dist/types/current/streaming/createDefaultMediaTimelineTransformer.js +13 -4
- package/dist/types/current/streaming/mediaTimelineFilter.d.ts +4 -2
- package/dist/types/current/streaming/mediaTimelineFilter.d.ts.map +1 -1
- package/dist/types/current/streaming/mediaTimelineFilter.js +23 -8
- package/dist/types/current/text/SidecarTextTrackLoader.d.ts.map +1 -1
- package/dist/types/current/text/SidecarTextTrackLoader.js +4 -4
- package/dist/types/current/text/TextTrack.d.ts.map +1 -1
- package/dist/types/current/track/TrackController.d.ts.map +1 -1
- package/dist/types/current/track/TrackController.js +8 -2
- package/dist/types/current/track/createSegmentDataProvider.d.ts.map +1 -1
- package/dist/types/current/track/createSegmentDataProvider.js +6 -3
- package/dist/types/current/track/dash/DashMediaQualityMetadataResolver.d.ts +10 -6
- package/dist/types/current/track/dash/DashMediaQualityMetadataResolver.d.ts.map +1 -1
- package/dist/types/current/track/dash/DashMediaQualityMetadataResolver.js +13 -8
- package/dist/types/current/track/dash/createDashFactories.d.ts +1 -1
- package/dist/types/current/track/dash/timeline/DashRepresentationSegmentProvider.d.ts.map +1 -1
- package/dist/types/current/track/dash/timeline/DashRepresentationSegmentProvider.js +71 -3
- package/dist/types/current/track/dash/urlDashManifestProvider.js +2 -2
- package/dist/types/current/track/dash/util/mpd.d.ts +6 -0
- package/dist/types/current/track/dash/util/mpd.d.ts.map +1 -1
- package/dist/types/current/track/dash/util/mpd.js +24 -3
- package/dist/types/current/track/filters/resourceTypeFilter.d.ts +4 -0
- package/dist/types/current/track/filters/resourceTypeFilter.d.ts.map +1 -1
- package/dist/types/current/track/filters/resourceTypeFilter.js +4 -0
- package/dist/types/current/track/filters/sampleRateFilter.d.ts +25 -7
- package/dist/types/current/track/filters/sampleRateFilter.d.ts.map +1 -1
- package/dist/types/current/track/filters/sampleRateFilter.js +52 -24
- package/dist/types/current/track/hls/createHlsFactories.d.ts +1 -1
- package/dist/types/current/track/hls/createUrlHlsManifestProvider.d.ts.map +1 -1
- package/dist/types/current/track/hls/createUrlHlsManifestProvider.js +3 -3
- package/dist/types/current/track/mse/MseTrack.d.ts +0 -17
- package/dist/types/current/track/mse/MseTrack.d.ts.map +1 -1
- package/dist/types/current/track/mse/MseTrack.js +1 -45
- package/dist/types/current/tsconfig.tsbuildinfo +1 -1
- package/dist/types/current/util/media/mimeType.d.ts +8 -0
- package/dist/types/current/util/media/mimeType.d.ts.map +1 -0
- package/dist/types/current/util/media/mimeType.js +13 -0
- package/dist/types/current/vinyl/VinylPlayer.d.ts +5 -0
- package/dist/types/current/vinyl/VinylPlayer.d.ts.map +1 -1
- package/dist/types/current/vinyl/VinylPlayer.js +23 -1
- package/dist/types/current/vinyl/createVinylFactories.d.ts +7 -16
- package/dist/types/current/vinyl/createVinylFactories.d.ts.map +1 -1
- package/dist/types/current/vinyl/createVinylFactories.js +2 -12
- package/dist/types/ts3.7/drm/DrmControllerImpl.d.ts +19 -1
- package/dist/types/ts3.7/index.d.ts +3 -6
- package/dist/types/ts3.7/playback/PlaybackControllerImpl.d.ts +15 -0
- package/dist/types/ts3.7/playback/ReadonlyPlaybackController.d.ts +28 -0
- package/dist/types/ts3.7/playback/createStallDetector.d.ts +43 -0
- package/dist/types/ts3.7/playback/createStallMonitor.d.ts +45 -0
- package/dist/types/ts3.7/streaming/AudioOptions.d.ts +27 -0
- package/dist/types/ts3.7/streaming/ContentStream.d.ts +0 -5
- package/dist/types/ts3.7/streaming/LoadMetric.d.ts +15 -1
- package/dist/types/ts3.7/streaming/StreamingEventMap.d.ts +0 -5
- package/dist/types/ts3.7/streaming/buffering/BufferingController.d.ts +0 -11
- package/dist/types/ts3.7/streaming/mediaTimelineFilter.d.ts +4 -2
- package/dist/types/ts3.7/track/dash/DashMediaQualityMetadataResolver.d.ts +10 -6
- package/dist/types/ts3.7/track/dash/createDashFactories.d.ts +1 -1
- package/dist/types/ts3.7/track/dash/util/mpd.d.ts +6 -0
- package/dist/types/ts3.7/track/filters/resourceTypeFilter.d.ts +4 -0
- package/dist/types/ts3.7/track/filters/sampleRateFilter.d.ts +25 -7
- package/dist/types/ts3.7/track/hls/createHlsFactories.d.ts +1 -1
- package/dist/types/ts3.7/track/mse/MseTrack.d.ts +0 -17
- package/dist/types/ts3.7/util/media/mimeType.d.ts +8 -0
- package/dist/types/ts3.7/vinyl/VinylPlayer.d.ts +5 -0
- package/dist/types/ts3.7/vinyl/createVinylFactories.d.ts +7 -16
- package/dist/types/ts4.1/drm/DrmControllerImpl.d.ts +19 -1
- package/dist/types/ts4.1/index.d.ts +3 -6
- package/dist/types/ts4.1/playback/PlaybackControllerImpl.d.ts +15 -0
- package/dist/types/ts4.1/playback/ReadonlyPlaybackController.d.ts +28 -0
- package/dist/types/ts4.1/playback/createStallDetector.d.ts +43 -0
- package/dist/types/ts4.1/playback/createStallMonitor.d.ts +45 -0
- package/dist/types/ts4.1/streaming/AudioOptions.d.ts +27 -0
- package/dist/types/ts4.1/streaming/ContentStream.d.ts +0 -5
- package/dist/types/ts4.1/streaming/LoadMetric.d.ts +15 -1
- package/dist/types/ts4.1/streaming/StreamingEventMap.d.ts +0 -5
- package/dist/types/ts4.1/streaming/buffering/BufferingController.d.ts +0 -11
- package/dist/types/ts4.1/streaming/mediaTimelineFilter.d.ts +4 -2
- package/dist/types/ts4.1/track/dash/DashMediaQualityMetadataResolver.d.ts +10 -6
- package/dist/types/ts4.1/track/dash/createDashFactories.d.ts +1 -1
- package/dist/types/ts4.1/track/dash/util/mpd.d.ts +6 -0
- package/dist/types/ts4.1/track/filters/resourceTypeFilter.d.ts +4 -0
- package/dist/types/ts4.1/track/filters/sampleRateFilter.d.ts +25 -7
- package/dist/types/ts4.1/track/hls/createHlsFactories.d.ts +1 -1
- package/dist/types/ts4.1/track/mse/MseTrack.d.ts +0 -17
- package/dist/types/ts4.1/util/media/mimeType.d.ts +8 -0
- package/dist/types/ts4.1/vinyl/VinylPlayer.d.ts +5 -0
- package/dist/types/ts4.1/vinyl/createVinylFactories.d.ts +7 -16
- package/dist/types/ts4.7/drm/DrmControllerImpl.d.ts +19 -1
- package/dist/types/ts4.7/index.d.ts +3 -6
- package/dist/types/ts4.7/playback/PlaybackControllerImpl.d.ts +15 -0
- package/dist/types/ts4.7/playback/ReadonlyPlaybackController.d.ts +28 -0
- package/dist/types/ts4.7/playback/createStallDetector.d.ts +43 -0
- package/dist/types/ts4.7/playback/createStallMonitor.d.ts +45 -0
- package/dist/types/ts4.7/streaming/AudioOptions.d.ts +27 -0
- package/dist/types/ts4.7/streaming/ContentStream.d.ts +0 -5
- package/dist/types/ts4.7/streaming/LoadMetric.d.ts +15 -1
- package/dist/types/ts4.7/streaming/StreamingEventMap.d.ts +0 -5
- package/dist/types/ts4.7/streaming/buffering/BufferingController.d.ts +0 -11
- package/dist/types/ts4.7/streaming/mediaTimelineFilter.d.ts +4 -2
- package/dist/types/ts4.7/track/dash/DashMediaQualityMetadataResolver.d.ts +10 -6
- package/dist/types/ts4.7/track/dash/createDashFactories.d.ts +1 -1
- package/dist/types/ts4.7/track/dash/util/mpd.d.ts +6 -0
- package/dist/types/ts4.7/track/filters/resourceTypeFilter.d.ts +4 -0
- package/dist/types/ts4.7/track/filters/sampleRateFilter.d.ts +25 -7
- package/dist/types/ts4.7/track/hls/createHlsFactories.d.ts +1 -1
- package/dist/types/ts4.7/track/mse/MseTrack.d.ts +0 -17
- package/dist/types/ts4.7/util/media/mimeType.d.ts +8 -0
- package/dist/types/ts4.7/vinyl/VinylPlayer.d.ts +5 -0
- package/dist/types/ts4.7/vinyl/createVinylFactories.d.ts +7 -16
- package/dist/unit/types/current/ad/AdControllerImpl.test.js +27 -1
- package/dist/unit/types/current/drm/DrmControllerImpl.test.js +146 -9
- package/dist/unit/types/current/index.d.ts +3 -4
- package/dist/unit/types/current/index.d.ts.map +1 -1
- package/dist/unit/types/current/index.js +3 -4
- package/dist/unit/types/current/playback/PlaybackControllerImpl.test.js +165 -0
- package/dist/unit/types/current/playback/createStallDetector.test.d.ts +2 -0
- package/dist/unit/types/current/playback/createStallDetector.test.d.ts.map +1 -0
- package/dist/unit/types/current/playback/createStallDetector.test.js +163 -0
- package/dist/unit/types/current/playback/createStallMonitor.test.d.ts +2 -0
- package/dist/unit/types/current/playback/createStallMonitor.test.d.ts.map +1 -0
- package/dist/unit/types/current/playback/createStallMonitor.test.js +125 -0
- package/dist/unit/types/current/streaming/ContentStream.test.js +0 -11
- package/dist/unit/types/current/streaming/MseTrack.test.js +49 -73
- package/dist/unit/types/current/streaming/abr/QualitySelectorImpl.test.js +1 -1
- package/dist/unit/types/current/streaming/buffering/BufferingController.test.js +0 -21
- package/dist/unit/types/current/streaming/createDefaultMediaTimelineTransformer.test.js +133 -0
- package/dist/unit/types/current/streaming/mediaTimelineFilter.test.js +60 -54
- package/dist/unit/types/current/track/TrackController.test.js +61 -1
- package/dist/unit/types/current/track/createSegmentDataProvider.test.js +18 -0
- package/dist/unit/types/current/track/dash/DashMediaQualityMetadataResolver.test.js +46 -14
- package/dist/unit/types/current/track/dash/createSegmentControllerFactory.test.js +1 -0
- package/dist/unit/types/current/track/dash/timeline/DashRepresentationSegmentProvider.test.js +114 -0
- package/dist/unit/types/current/track/dash/util/mpd.test.js +37 -0
- package/dist/unit/types/current/track/filters/resourceTypeFilter.test.js +7 -0
- package/dist/unit/types/current/track/filters/sampleRateFilter.test.js +211 -34
- package/dist/unit/types/current/track/source/SourceObjectTrack.test.js +1 -1
- package/dist/unit/types/current/tsconfig.tsbuildinfo +1 -1
- package/dist/unit/types/current/util/media/mimeType.test.d.ts +2 -0
- package/dist/unit/types/current/util/media/mimeType.test.d.ts.map +1 -0
- package/dist/unit/types/current/util/media/mimeType.test.js +22 -0
- package/dist/unit/types/current/vinyl/VinylPlayer.test.js +33 -2
- package/dist/unit/types/current/vinyl/createVinylFactories.test.js +2 -36
- package/dist/vinylTestUtil/index.js +6 -4
- package/dist/vinylTestUtil/index.js.map +2 -2
- package/dist/vinylTestUtil/types/current/assets/vinylTestAssets.d.ts +1 -0
- package/dist/vinylTestUtil/types/current/assets/vinylTestAssets.d.ts.map +1 -1
- package/dist/vinylTestUtil/types/current/assets/vinylTestAssets.js +1 -0
- package/dist/vinylTestUtil/types/current/media/FrequencyAnalyzer.d.ts.map +1 -1
- package/dist/vinylTestUtil/types/current/mock/streaming/MockContentStream.d.ts +0 -1
- package/dist/vinylTestUtil/types/current/mock/streaming/MockContentStream.d.ts.map +1 -1
- package/dist/vinylTestUtil/types/current/mock/streaming/MockContentStream.js +0 -1
- package/dist/vinylTestUtil/types/current/mock/streaming/buffering/MockBufferingController.d.ts +0 -1
- package/dist/vinylTestUtil/types/current/mock/streaming/buffering/MockBufferingController.d.ts.map +1 -1
- package/dist/vinylTestUtil/types/current/mock/streaming/buffering/MockBufferingController.js +0 -1
- package/dist/vinylTestUtil/types/current/tsconfig.tsbuildinfo +1 -1
- package/dist/vinylTestUtil/types/current/util/playback/eventPromises.js +1 -1
- package/dist/vinylTestUtil/types/current/util/playback/expectTrackCanSeek.d.ts.map +1 -1
- package/dist/vinylTestUtil/types/current/util/playback/expectTrackCanSeek.js +9 -1
- package/dist/vinylTestUtil/types/ts3.7/assets/vinylTestAssets.d.ts +1 -0
- package/dist/vinylTestUtil/types/ts3.7/mock/streaming/MockContentStream.d.ts +0 -1
- package/dist/vinylTestUtil/types/ts3.7/mock/streaming/buffering/MockBufferingController.d.ts +0 -1
- package/dist/vinylTestUtil/types/ts4.1/assets/vinylTestAssets.d.ts +1 -0
- package/dist/vinylTestUtil/types/ts4.1/mock/streaming/MockContentStream.d.ts +0 -1
- package/dist/vinylTestUtil/types/ts4.1/mock/streaming/buffering/MockBufferingController.d.ts +0 -1
- package/dist/vinylTestUtil/types/ts4.7/assets/vinylTestAssets.d.ts +1 -0
- package/dist/vinylTestUtil/types/ts4.7/mock/streaming/MockContentStream.d.ts +0 -1
- package/dist/vinylTestUtil/types/ts4.7/mock/streaming/buffering/MockBufferingController.d.ts +0 -1
- package/docs/USAGE.md +29 -0
- package/package.json +11 -10
- package/dist/types/current/patch/media/HtmlMediaElementPatch.d.ts +0 -3
- package/dist/types/current/patch/media/HtmlMediaElementPatch.d.ts.map +0 -1
- package/dist/types/current/patch/media/HtmlMediaElementPatch.js +0 -5
- package/dist/types/current/patch/media/MediaElementPatchOptions.d.ts +0 -19
- package/dist/types/current/patch/media/MediaElementPatchOptions.d.ts.map +0 -1
- package/dist/types/current/patch/media/MediaElementPatchOptions.js +0 -16
- package/dist/types/current/patch/media/patchMediaElement.d.ts +0 -9
- package/dist/types/current/patch/media/patchMediaElement.d.ts.map +0 -1
- package/dist/types/current/patch/media/patchMediaElement.js +0 -15
- package/dist/types/current/patch/media/patches/createPreventStallsPatch.d.ts +0 -17
- package/dist/types/current/patch/media/patches/createPreventStallsPatch.d.ts.map +0 -1
- package/dist/types/current/patch/media/patches/createPreventStallsPatch.js +0 -55
- package/dist/types/current/patch/media/patches/createUnreliablePlaybackEventsPatch.d.ts +0 -26
- package/dist/types/current/patch/media/patches/createUnreliablePlaybackEventsPatch.d.ts.map +0 -1
- package/dist/types/current/patch/media/patches/createUnreliablePlaybackEventsPatch.js +0 -218
- package/dist/types/current/vinyl/VinylPatchOptions.d.ts +0 -10
- package/dist/types/current/vinyl/VinylPatchOptions.d.ts.map +0 -1
- package/dist/types/current/vinyl/VinylPatchOptions.js +0 -11
- package/dist/types/ts3.7/patch/media/HtmlMediaElementPatch.d.ts +0 -3
- package/dist/types/ts3.7/patch/media/MediaElementPatchOptions.d.ts +0 -19
- package/dist/types/ts3.7/patch/media/patchMediaElement.d.ts +0 -9
- package/dist/types/ts3.7/patch/media/patches/createPreventStallsPatch.d.ts +0 -17
- package/dist/types/ts3.7/patch/media/patches/createUnreliablePlaybackEventsPatch.d.ts +0 -26
- package/dist/types/ts3.7/vinyl/VinylPatchOptions.d.ts +0 -10
- package/dist/types/ts4.1/patch/media/HtmlMediaElementPatch.d.ts +0 -3
- package/dist/types/ts4.1/patch/media/MediaElementPatchOptions.d.ts +0 -19
- package/dist/types/ts4.1/patch/media/patchMediaElement.d.ts +0 -9
- package/dist/types/ts4.1/patch/media/patches/createPreventStallsPatch.d.ts +0 -17
- package/dist/types/ts4.1/patch/media/patches/createUnreliablePlaybackEventsPatch.d.ts +0 -26
- package/dist/types/ts4.1/vinyl/VinylPatchOptions.d.ts +0 -10
- package/dist/types/ts4.7/patch/media/HtmlMediaElementPatch.d.ts +0 -3
- package/dist/types/ts4.7/patch/media/MediaElementPatchOptions.d.ts +0 -19
- package/dist/types/ts4.7/patch/media/patchMediaElement.d.ts +0 -9
- package/dist/types/ts4.7/patch/media/patches/createPreventStallsPatch.d.ts +0 -17
- package/dist/types/ts4.7/patch/media/patches/createUnreliablePlaybackEventsPatch.d.ts +0 -26
- package/dist/types/ts4.7/vinyl/VinylPatchOptions.d.ts +0 -10
- package/dist/unit/types/current/patch/media/MediaElementPatchOptions.test.d.ts +0 -2
- package/dist/unit/types/current/patch/media/MediaElementPatchOptions.test.d.ts.map +0 -1
- package/dist/unit/types/current/patch/media/MediaElementPatchOptions.test.js +0 -17
- package/dist/unit/types/current/patch/media/patchMediaElement.test.d.ts +0 -2
- package/dist/unit/types/current/patch/media/patchMediaElement.test.d.ts.map +0 -1
- package/dist/unit/types/current/patch/media/patchMediaElement.test.js +0 -36
- package/dist/unit/types/current/patch/media/patches/createPreventStallsPatch.test.d.ts +0 -2
- package/dist/unit/types/current/patch/media/patches/createPreventStallsPatch.test.d.ts.map +0 -1
- package/dist/unit/types/current/patch/media/patches/createPreventStallsPatch.test.js +0 -93
- package/dist/unit/types/current/patch/media/patches/createUnreliablePlaybackEventsPatch.test.d.ts +0 -2
- package/dist/unit/types/current/patch/media/patches/createUnreliablePlaybackEventsPatch.test.d.ts.map +0 -1
- package/dist/unit/types/current/patch/media/patches/createUnreliablePlaybackEventsPatch.test.js +0 -423
|
@@ -480,6 +480,66 @@ describe('TrackControllerImpl', () => {
|
|
|
480
480
|
});
|
|
481
481
|
});
|
|
482
482
|
});
|
|
483
|
+
describe('guards async ad continuations after dispose', () => {
|
|
484
|
+
it('does not dispatch trackEnded when disposed before the postroll resolves', async () => {
|
|
485
|
+
let resolvePostroll = () => { };
|
|
486
|
+
deps.adController.enterPostroll.and.returnValue(new Promise((res) => {
|
|
487
|
+
resolvePostroll = res;
|
|
488
|
+
}));
|
|
489
|
+
trackController.load(...createLoadOptionsList(2));
|
|
490
|
+
await clock.tick(); // activate the first track
|
|
491
|
+
const endedSpy = jasmine.createSpy('trackEnded');
|
|
492
|
+
trackController.on('trackEnded', endedSpy);
|
|
493
|
+
deps.playbackController.dispatch('ended', {}); // onEnded → enterPostroll pending
|
|
494
|
+
trackController.dispose();
|
|
495
|
+
disposed = true;
|
|
496
|
+
resolvePostroll(null); // .then guarded by interrupted()
|
|
497
|
+
await clock.tick();
|
|
498
|
+
expect(endedSpy).not.toHaveBeenCalled();
|
|
499
|
+
});
|
|
500
|
+
it('does not advance the queue when disposed within the trackEnded handler', async () => {
|
|
501
|
+
trackController.load(...createLoadOptionsList(2));
|
|
502
|
+
await clock.tick(); // activate the first track
|
|
503
|
+
trackController.on('trackEnded', () => {
|
|
504
|
+
trackController.dispose(); // interrupt before the queued next()
|
|
505
|
+
disposed = true;
|
|
506
|
+
});
|
|
507
|
+
const activatedSpy = jasmine.createSpy('trackActivated');
|
|
508
|
+
trackController.on('trackActivated', activatedSpy);
|
|
509
|
+
deps.playbackController.dispatch('ended', {});
|
|
510
|
+
await clock.tick();
|
|
511
|
+
// The queued next() is skipped: interrupted() is true in the microtask.
|
|
512
|
+
expect(activatedSpy).not.toHaveBeenCalled();
|
|
513
|
+
});
|
|
514
|
+
it('swallows a postroll rejection after dispose', async () => {
|
|
515
|
+
let rejectPostroll = () => { };
|
|
516
|
+
deps.adController.enterPostroll.and.returnValue(new Promise((_res, rej) => {
|
|
517
|
+
rejectPostroll = rej;
|
|
518
|
+
}));
|
|
519
|
+
trackController.load(...createLoadOptionsList(1));
|
|
520
|
+
await clock.tick();
|
|
521
|
+
deps.playbackController.dispatch('ended', {});
|
|
522
|
+
trackController.dispose();
|
|
523
|
+
disposed = true;
|
|
524
|
+
rejectPostroll(new Error('late')); // .catch guarded by interrupted()
|
|
525
|
+
await clock.tick();
|
|
526
|
+
expect(trackController.disposed).toBeTrue();
|
|
527
|
+
});
|
|
528
|
+
it('does not activate when disposed before the preroll rejects', async () => {
|
|
529
|
+
let rejectPreroll = () => { };
|
|
530
|
+
deps.adController.enterPreroll.and.returnValue(new Promise((_res, rej) => {
|
|
531
|
+
rejectPreroll = rej;
|
|
532
|
+
}));
|
|
533
|
+
const activatedSpy = jasmine.createSpy('trackActivated');
|
|
534
|
+
trackController.on('trackActivated', activatedSpy);
|
|
535
|
+
trackController.load(...createLoadOptionsList(1)); // activation deferred behind enterPreroll
|
|
536
|
+
trackController.dispose();
|
|
537
|
+
disposed = true;
|
|
538
|
+
rejectPreroll(new Error('late')); // .catch guarded by interrupted()
|
|
539
|
+
await clock.tick();
|
|
540
|
+
expect(activatedSpy).not.toHaveBeenCalled();
|
|
541
|
+
});
|
|
542
|
+
});
|
|
483
543
|
describe('unload', () => {
|
|
484
544
|
it('unloads the active track and clears the queue', () => {
|
|
485
545
|
trackController.load(...createLoadOptionsList(3));
|
|
@@ -813,7 +873,7 @@ describe('TrackControllerImpl', () => {
|
|
|
813
873
|
expect(() => trackController.reset()).not.toThrow();
|
|
814
874
|
});
|
|
815
875
|
});
|
|
816
|
-
describe('reset', () => {
|
|
876
|
+
describe('reset (hard)', () => {
|
|
817
877
|
it('delegates a hard reset to the current track', async () => {
|
|
818
878
|
trackController.load(...createLoadOptionsList(1));
|
|
819
879
|
await clock.tick();
|
|
@@ -208,6 +208,24 @@ describe('createSegmentDataProvider', () => {
|
|
|
208
208
|
serviceId: 'example.com',
|
|
209
209
|
}));
|
|
210
210
|
});
|
|
211
|
+
it('does not report transfer entry when aborted before the metrics read', async () => {
|
|
212
|
+
const abort = new Abort();
|
|
213
|
+
const response = new Response(new ArrayBuffer(10));
|
|
214
|
+
spyOn(response, 'arrayBuffer').and.callFake(() => {
|
|
215
|
+
// Abort after the fetch resolves, before the metrics read.
|
|
216
|
+
abort.abort();
|
|
217
|
+
return Promise.resolve(new ArrayBuffer(10));
|
|
218
|
+
});
|
|
219
|
+
mockRequester.request.and.resolveTo(response);
|
|
220
|
+
const provider = createSegmentDataProvider(deps, {
|
|
221
|
+
url: 'https://example.com/seg0.mp4',
|
|
222
|
+
reportDownlinkMetrics: true,
|
|
223
|
+
});
|
|
224
|
+
const promise = provider(abort);
|
|
225
|
+
await clock.tick(2);
|
|
226
|
+
await promise;
|
|
227
|
+
expect(networkMetricsControllerRef.value.addDownlinkTransferEntry).not.toHaveBeenCalled();
|
|
228
|
+
});
|
|
211
229
|
});
|
|
212
230
|
describe('when reportDownlinkMetrics is false', () => {
|
|
213
231
|
it('does not report transfer entry', async () => {
|
|
@@ -422,7 +422,7 @@ describe('getPeriodSortedBandwidths', () => {
|
|
|
422
422
|
});
|
|
423
423
|
});
|
|
424
424
|
describe('estimatePeakBandwidth', () => {
|
|
425
|
-
it('pairs
|
|
425
|
+
it('pairs each tier with the cheapest peer in its bucket', () => {
|
|
426
426
|
// language=XML
|
|
427
427
|
const m = parseDashManifest(`<?xml version="1.0" ?>
|
|
428
428
|
<MPD minBufferTime="PT0S" profiles="" xmlns="urn:mpeg:dash:schema:mpd:2011">
|
|
@@ -441,20 +441,51 @@ describe('estimatePeakBandwidth', () => {
|
|
|
441
441
|
</MPD>`);
|
|
442
442
|
const as0 = m.MPD.Period[0].AdaptationSet[0];
|
|
443
443
|
const as1 = m.MPD.Period[0].AdaptationSet[1];
|
|
444
|
-
// video sorted: [4000, 3000, 2000, 1000], audio sorted: [200, 100]
|
|
445
|
-
//
|
|
444
|
+
// video sorted: [4000, 3000, 2000, 1000], audio sorted: [200, 100].
|
|
445
|
+
// Video's two audio buckets: v1,v2 → a1(200); v3,v4 → a2(100).
|
|
446
446
|
expect(estimatePeakBandwidth(as0.Representation[0], 'video')).toBe(4200);
|
|
447
|
-
// v2 pos=1/3=0.33 → audio index round(0.33*1)=0 → 200. total=3200
|
|
448
447
|
expect(estimatePeakBandwidth(as0.Representation[1], 'video')).toBe(3200);
|
|
449
|
-
// v3 pos=2/3=0.67 → audio index round(0.67*1)=1 → 100. total=2100
|
|
450
448
|
expect(estimatePeakBandwidth(as0.Representation[2], 'video')).toBe(2100);
|
|
451
|
-
// v4 pos=3/3=1.00 → audio index round(1.00*1)=1 → 100. total=1100
|
|
452
449
|
expect(estimatePeakBandwidth(as0.Representation[3], 'video')).toBe(1100);
|
|
453
|
-
// a1
|
|
454
|
-
|
|
455
|
-
|
|
450
|
+
// Audio's two video buckets: a1's bucket is v1,v2 so it pairs with the
|
|
451
|
+
// cheapest of those (v2=3000); a2's bucket is v3,v4 (cheapest v4=1000).
|
|
452
|
+
expect(estimatePeakBandwidth(as1.Representation[0], 'audio')).toBe(3200);
|
|
456
453
|
expect(estimatePeakBandwidth(as1.Representation[1], 'audio')).toBe(1100);
|
|
457
454
|
});
|
|
455
|
+
it('does not pin a small stream to its lowest tier across a finer peer', () => {
|
|
456
|
+
// 2 audio tiers alongside 10 video tiers: the top audio must stay
|
|
457
|
+
// affordable across the whole top half of video, not only at the very
|
|
458
|
+
// top. (Regression: it was priced with the single top video.)
|
|
459
|
+
// language=XML
|
|
460
|
+
const m = parseDashManifest(`<?xml version="1.0" ?>
|
|
461
|
+
<MPD minBufferTime="PT0S" profiles="" xmlns="urn:mpeg:dash:schema:mpd:2011">
|
|
462
|
+
<Period>
|
|
463
|
+
<AdaptationSet mimeType="video/mp4" codecs="avc1.640015">
|
|
464
|
+
<Representation bandwidth="10000" id="v1"/>
|
|
465
|
+
<Representation bandwidth="9000" id="v2"/>
|
|
466
|
+
<Representation bandwidth="8000" id="v3"/>
|
|
467
|
+
<Representation bandwidth="7000" id="v4"/>
|
|
468
|
+
<Representation bandwidth="6000" id="v5"/>
|
|
469
|
+
<Representation bandwidth="5000" id="v6"/>
|
|
470
|
+
<Representation bandwidth="4000" id="v7"/>
|
|
471
|
+
<Representation bandwidth="3000" id="v8"/>
|
|
472
|
+
<Representation bandwidth="2000" id="v9"/>
|
|
473
|
+
<Representation bandwidth="1000" id="v10"/>
|
|
474
|
+
</AdaptationSet>
|
|
475
|
+
<AdaptationSet mimeType="audio/mp4" codecs="mp4a.40.2">
|
|
476
|
+
<Representation bandwidth="200" id="a1"/>
|
|
477
|
+
<Representation bandwidth="100" id="a2"/>
|
|
478
|
+
</AdaptationSet>
|
|
479
|
+
</Period>
|
|
480
|
+
</MPD>`);
|
|
481
|
+
const audio = m.MPD.Period[0].AdaptationSet[1];
|
|
482
|
+
// Top audio's bucket is video[0..4]; it pairs with the cheapest of those
|
|
483
|
+
// (video[4]=6000), NOT video[0]=10000. So its total is 6200, keeping it
|
|
484
|
+
// affordable for the top half of video tiers.
|
|
485
|
+
expect(estimatePeakBandwidth(audio.Representation[0], 'audio')).toBe(6200);
|
|
486
|
+
// Bottom audio's bucket is video[5..9]; cheapest video[9]=1000 → 1100.
|
|
487
|
+
expect(estimatePeakBandwidth(audio.Representation[1], 'audio')).toBe(1100);
|
|
488
|
+
});
|
|
458
489
|
it('returns bandwidth as-is for single content type periods', () => {
|
|
459
490
|
// language=XML
|
|
460
491
|
const m = parseDashManifest(`<?xml version="1.0" ?>
|
|
@@ -482,7 +513,7 @@ describe('estimatePeakBandwidth', () => {
|
|
|
482
513
|
</MPD>`);
|
|
483
514
|
expect(estimatePeakBandwidth(m.MPD.Period[0].AdaptationSet[0].Representation[0], 'text')).toBe(50000);
|
|
484
515
|
});
|
|
485
|
-
it('pairs
|
|
516
|
+
it('pairs with the cheapest peer bucket across three content types', () => {
|
|
486
517
|
// language=XML
|
|
487
518
|
const m = parseDashManifest(`<?xml version="1.0" ?>
|
|
488
519
|
<MPD minBufferTime="PT0S" profiles="" xmlns="urn:mpeg:dash:schema:mpd:2011">
|
|
@@ -500,12 +531,13 @@ describe('estimatePeakBandwidth', () => {
|
|
|
500
531
|
</AdaptationSet>
|
|
501
532
|
</Period>
|
|
502
533
|
</MPD>`);
|
|
503
|
-
// v1
|
|
534
|
+
// v1 → cheapest audio in its bucket (200) + cheapest text (10). total=2210
|
|
504
535
|
expect(estimatePeakBandwidth(m.MPD.Period[0].AdaptationSet[0].Representation[0], 'video')).toBe(2210);
|
|
505
|
-
// v2
|
|
536
|
+
// v2 → audio bucket cheapest (100) + text (10). total=1110
|
|
506
537
|
expect(estimatePeakBandwidth(m.MPD.Period[0].AdaptationSet[0].Representation[1], 'video')).toBe(1110);
|
|
507
|
-
// t1
|
|
508
|
-
|
|
538
|
+
// t1 is the only text tier, so its bucket spans every peer — it pairs
|
|
539
|
+
// with the cheapest video (1000) and cheapest audio (100). total=1110
|
|
540
|
+
expect(estimatePeakBandwidth(m.MPD.Period[0].AdaptationSet[2].Representation[0], 'text')).toBe(1110);
|
|
509
541
|
});
|
|
510
542
|
it('handles single quality per content type', () => {
|
|
511
543
|
// language=XML
|
package/dist/unit/types/current/track/dash/timeline/DashRepresentationSegmentProvider.test.js
CHANGED
|
@@ -277,6 +277,120 @@ describe('createDashRepresentationSegmentProvider', () => {
|
|
|
277
277
|
});
|
|
278
278
|
});
|
|
279
279
|
});
|
|
280
|
+
describe('when SegmentBase is a WebM stream', () => {
|
|
281
|
+
// Minimal EBML builders for a synthetic WebM init + Cues.
|
|
282
|
+
const vintSize = (n) => n < 0x80 ? [0x80 | n] : [0x40 | (n >> 8), n & 0xff];
|
|
283
|
+
const el = (id, content) => [
|
|
284
|
+
...id,
|
|
285
|
+
...vintSize(content.length),
|
|
286
|
+
...content,
|
|
287
|
+
];
|
|
288
|
+
const bytesToArrayBuffer = (bytes) => new Uint8Array(bytes).buffer;
|
|
289
|
+
// EBML header (5 bytes) then Segment(Info > TimecodeScale=1_000_000);
|
|
290
|
+
// the Segment data starts at offset 10, so cue positions are + 10.
|
|
291
|
+
const initBuffer = bytesToArrayBuffer([
|
|
292
|
+
...el([0x1a, 0x45, 0xdf, 0xa3], []),
|
|
293
|
+
...el([0x18, 0x53, 0x80, 0x67], el([0x15, 0x49, 0xa9, 0x66], el([0x2a, 0xd7, 0xb1], [0x0f, 0x42, 0x40]))),
|
|
294
|
+
]);
|
|
295
|
+
const cuePoint = (time, pos) => el([0xbb], [
|
|
296
|
+
...el([0xb3], time),
|
|
297
|
+
...el([0xb7], [...el([0xf7], [0x01]), ...el([0xf1], pos)]),
|
|
298
|
+
]);
|
|
299
|
+
// Cue 0 @ t=0 → cluster pos 100; cue 1 @ t=2000ms → cluster pos 200.
|
|
300
|
+
const cuesBuffer = bytesToArrayBuffer(el([0x1c, 0x53, 0xbb, 0x6b], [
|
|
301
|
+
...cuePoint([0x00], [0x00, 0x64]),
|
|
302
|
+
...cuePoint([0x07, 0xd0], [0x00, 0xc8]),
|
|
303
|
+
]));
|
|
304
|
+
beforeEach(() => {
|
|
305
|
+
// WebM Cues don't carry the last segment's end, so a period end is
|
|
306
|
+
// required (VOD defines one).
|
|
307
|
+
manifest.MPD.mediaPresentationDuration = 60;
|
|
308
|
+
representation.BaseURL = [
|
|
309
|
+
{ _content: 'https://example.com/v.webm' },
|
|
310
|
+
];
|
|
311
|
+
representation.mimeType = 'video/webm';
|
|
312
|
+
representation.codecs = 'vp9';
|
|
313
|
+
representation.SegmentBase = {
|
|
314
|
+
indexRangeExact: false,
|
|
315
|
+
indexRange: [100, 199],
|
|
316
|
+
timescale: 1000000,
|
|
317
|
+
Initialization: { range: [0, 99] },
|
|
318
|
+
};
|
|
319
|
+
// The provider fetches the init and Cues ranges in parallel; return
|
|
320
|
+
// the matching buffer per Range header.
|
|
321
|
+
mockRequesterRef.value.request.and.callFake(((_input, init) => {
|
|
322
|
+
const range = init?.headers?.['Range'];
|
|
323
|
+
const body = range === 'bytes=0-99'
|
|
324
|
+
? initBuffer
|
|
325
|
+
: range === 'bytes=100-199'
|
|
326
|
+
? cuesBuffer
|
|
327
|
+
: new ArrayBuffer(0);
|
|
328
|
+
return Promise.resolve(new Response(body));
|
|
329
|
+
}));
|
|
330
|
+
});
|
|
331
|
+
it('creates a timeline from the WebM Cues', async () => {
|
|
332
|
+
const timeline = createTimeline();
|
|
333
|
+
// Prime the timeline (fetch init + Cues), then assert the segments.
|
|
334
|
+
await timeline.getSegment(0);
|
|
335
|
+
clearRequestCalls();
|
|
336
|
+
const info = await getSegmentRequestData(timeline);
|
|
337
|
+
expect(info).toEqual({
|
|
338
|
+
init: {
|
|
339
|
+
qualityId: any(String),
|
|
340
|
+
decoderId: any(String),
|
|
341
|
+
mimeType: 'video/webm; codecs="vp9"',
|
|
342
|
+
href: 'https://example.com/v.webm',
|
|
343
|
+
serviceId: 'example.com',
|
|
344
|
+
range: 'bytes=0-99',
|
|
345
|
+
},
|
|
346
|
+
segments: [
|
|
347
|
+
{
|
|
348
|
+
startTime: 0,
|
|
349
|
+
endTime: 2,
|
|
350
|
+
timestampOffset: 0,
|
|
351
|
+
href: 'https://example.com/v.webm',
|
|
352
|
+
serviceId: 'example.com',
|
|
353
|
+
// segmentDataStart(10) + cue positions 100..200.
|
|
354
|
+
range: 'bytes=110-209',
|
|
355
|
+
},
|
|
356
|
+
{
|
|
357
|
+
startTime: 2,
|
|
358
|
+
endTime: 60,
|
|
359
|
+
timestampOffset: 2,
|
|
360
|
+
href: 'https://example.com/v.webm',
|
|
361
|
+
serviceId: 'example.com',
|
|
362
|
+
// Last cluster runs open-ended to end of file.
|
|
363
|
+
range: 'bytes=210-',
|
|
364
|
+
},
|
|
365
|
+
],
|
|
366
|
+
});
|
|
367
|
+
});
|
|
368
|
+
it('indexes WebM without an explicit SegmentBase timescale', async () => {
|
|
369
|
+
delete representation.SegmentBase
|
|
370
|
+
.timescale;
|
|
371
|
+
const timeline = createTimeline();
|
|
372
|
+
const segment = await timeline.getSegment(0);
|
|
373
|
+
expect(segment).not.toBeNull();
|
|
374
|
+
// Cue 0 at ticks 0 → 0s (TimecodeScale-derived ticks-per-second).
|
|
375
|
+
expect(segment.startTime).toBe(0);
|
|
376
|
+
});
|
|
377
|
+
it('throws when the period has no determinable end', () => {
|
|
378
|
+
delete manifest.MPD
|
|
379
|
+
.mediaPresentationDuration;
|
|
380
|
+
const timeline = createTimeline();
|
|
381
|
+
return expectAsync(timeline.getSegment(0)).toBeRejectedWithError(/mediaPresentationDuration or Period\.duration required/);
|
|
382
|
+
});
|
|
383
|
+
it('throws when the Cues contain no cue points', () => {
|
|
384
|
+
// A Cues element whose only CuePoint lacks a cluster position.
|
|
385
|
+
const emptyCues = bytesToArrayBuffer(el([0x1c, 0x53, 0xbb, 0x6b], el([0xbb], el([0xb3], [0x00]))));
|
|
386
|
+
mockRequesterRef.value.request.and.callFake(((_input, init) => {
|
|
387
|
+
const range = init?.headers?.['Range'];
|
|
388
|
+
return Promise.resolve(new Response(range === 'bytes=0-99' ? initBuffer : emptyCues));
|
|
389
|
+
}));
|
|
390
|
+
const timeline = createTimeline();
|
|
391
|
+
return expectAsync(timeline.getSegment(0)).toBeRejectedWithError(/Cues contained no cue points/);
|
|
392
|
+
});
|
|
393
|
+
});
|
|
280
394
|
describe('when SegmentList is defined', () => {
|
|
281
395
|
let segmentList;
|
|
282
396
|
beforeEach(() => {
|
|
@@ -146,6 +146,31 @@ describe('mpd utils', () => {
|
|
|
146
146
|
expect(calculatePeriodStart(manifest.MPD.Period[0])).toEqual(0);
|
|
147
147
|
});
|
|
148
148
|
});
|
|
149
|
+
describe('when period.start is absent but periods have durations', () => {
|
|
150
|
+
it('derives the start from the preceding period durations', () => {
|
|
151
|
+
// language=XML
|
|
152
|
+
const manifest = parseDashManifest(`<?xml version="1.0" ?>
|
|
153
|
+
<MPD minBufferTime="PT0.0S" profiles="urn:mpeg:dash:profile:isoff-on-demand:2011" type="static" xmlns="urn:mpeg:dash:schema:mpd:2011">
|
|
154
|
+
<Period duration="888.053"/>
|
|
155
|
+
<Period duration="888.053"/>
|
|
156
|
+
<Period duration="888.053"/>
|
|
157
|
+
</MPD>`);
|
|
158
|
+
expect(manifest.MPD.Period.map(calculatePeriodStart)).toEqual([
|
|
159
|
+
0, 888.053, 1776.106,
|
|
160
|
+
]);
|
|
161
|
+
});
|
|
162
|
+
it('inherits the previous start when the previous period has no duration', () => {
|
|
163
|
+
// language=XML
|
|
164
|
+
const manifest = parseDashManifest(`<?xml version="1.0" ?>
|
|
165
|
+
<MPD minBufferTime="PT0.0S" profiles="urn:mpeg:dash:profile:isoff-on-demand:2011" type="static" xmlns="urn:mpeg:dash:schema:mpd:2011">
|
|
166
|
+
<Period/>
|
|
167
|
+
<Period/>
|
|
168
|
+
</MPD>`);
|
|
169
|
+
// The first period has neither start nor duration, so the
|
|
170
|
+
// second period cannot advance and inherits start 0.
|
|
171
|
+
expect(calculatePeriodStart(manifest.MPD.Period[1])).toEqual(0);
|
|
172
|
+
});
|
|
173
|
+
});
|
|
149
174
|
});
|
|
150
175
|
describe('getPeriodAtTime', () => {
|
|
151
176
|
it('returns the period spanning the given presentation time', () => {
|
|
@@ -331,6 +356,18 @@ describe('mpd utils', () => {
|
|
|
331
356
|
expect(calculateDuration(manifest)).toBe(50);
|
|
332
357
|
});
|
|
333
358
|
});
|
|
359
|
+
describe('when only per-period durations are present', () => {
|
|
360
|
+
it('sums the period durations across the presentation', () => {
|
|
361
|
+
// language=XML
|
|
362
|
+
const manifest = parseDashManifest(`<?xml version="1.0" ?>
|
|
363
|
+
<MPD minBufferTime="PT0.0S" profiles="urn:mpeg:dash:profile:isoff-on-demand:2011" type="static" xmlns="urn:mpeg:dash:schema:mpd:2011">
|
|
364
|
+
<Period duration="888.053"/>
|
|
365
|
+
<Period duration="888.053"/>
|
|
366
|
+
<Period duration="888.053"/>
|
|
367
|
+
</MPD>`);
|
|
368
|
+
expect(calculateDuration(manifest)).toBeCloseTo(2664.159, 3);
|
|
369
|
+
});
|
|
370
|
+
});
|
|
334
371
|
describe('when MPD type is dynamic', () => {
|
|
335
372
|
it('returns Infinity for live presentations', () => {
|
|
336
373
|
// language=XML
|
|
@@ -22,6 +22,13 @@ describe('canPlayMimeType', () => {
|
|
|
22
22
|
expect(canPlayMimeType({ capabilities }, metadata)).toBe(true);
|
|
23
23
|
expect(capabilities.canPlayTypeMse).toHaveBeenCalledWith('audio/mp4; codecs="opus"');
|
|
24
24
|
});
|
|
25
|
+
it('supports WebM when the browser reports support', () => {
|
|
26
|
+
capabilities.canPlayTypeMse.and.returnValue(true);
|
|
27
|
+
const metadata = createEmptyMediaQualityMetadata();
|
|
28
|
+
metadata.mimeType = 'video/webm; codecs="vp9"';
|
|
29
|
+
expect(canPlayMimeType({ capabilities }, metadata)).toBe(true);
|
|
30
|
+
expect(capabilities.canPlayTypeMse).toHaveBeenCalledWith('video/webm; codecs="vp9"');
|
|
31
|
+
});
|
|
25
32
|
it('returns false for null mime type', () => {
|
|
26
33
|
capabilities.canPlayTypeMse.and.returnValue(true);
|
|
27
34
|
const metadata = createEmptyMediaQualityMetadata();
|