@amazon/vinyl 3.2.2 → 3.2.3-next.20261001143710
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/README.md +2 -2
- package/dist/index.cjs +62 -21
- package/dist/index.cjs.map +3 -3
- package/dist/index.js +65 -22
- package/dist/index.js.map +3 -3
- package/dist/test/benchmark.es5.js +7 -6
- package/dist/test/benchmark.js +35 -30
- package/dist/test/benchmark.js.map +3 -3
- package/dist/test/integ.es5.js +184 -171
- package/dist/test/integ.js +450 -165
- package/dist/test/integ.js.map +4 -4
- package/dist/types/current/ad/AdControllerImpl.d.ts.map +1 -1
- package/dist/types/current/ad/AdControllerImpl.js +15 -1
- package/dist/types/current/ad/discoverHlsInterstitials.js +13 -1
- package/dist/types/current/drm/commonEme/MsCommonEme.d.ts.map +1 -1
- package/dist/types/current/drm/commonEme/MsCommonEme.js +2 -2
- package/dist/types/current/drm/commonEme/StandardCommonEme.d.ts.map +1 -1
- package/dist/types/current/drm/commonEme/StandardCommonEme.js +3 -2
- package/dist/types/current/drm/commonEme/WebKitCommonEme.d.ts.map +1 -1
- package/dist/types/current/drm/commonEme/WebKitCommonEme.js +2 -2
- package/dist/types/current/drm/dom/MSMediaKeys.d.ts +1 -1
- package/dist/types/current/drm/dom/MSMediaKeys.d.ts.map +1 -1
- package/dist/types/current/drm/dom/WebKitMediaKeys.d.ts +1 -1
- package/dist/types/current/drm/dom/WebKitMediaKeys.d.ts.map +1 -1
- package/dist/types/current/drm/util/extractContentId.js +2 -2
- package/dist/types/current/playback/PlaybackControllerImpl.d.ts +1 -1
- package/dist/types/current/streaming/MediaQualityMetadata.d.ts +3 -1
- package/dist/types/current/streaming/MediaQualityMetadata.d.ts.map +1 -1
- package/dist/types/current/streaming/SegmentControllerImpl.d.ts +1 -1
- package/dist/types/current/streaming/buffering/BufferingController.d.ts +1 -1
- package/dist/types/current/streaming/buffering/BufferingController.d.ts.map +1 -1
- package/dist/types/current/streaming/buffering/BufferingController.js +14 -5
- package/dist/types/current/streaming/buffering/MediaSourceController.d.ts.map +1 -1
- package/dist/types/current/streaming/buffering/MediaSourceController.js +4 -0
- package/dist/types/current/text/discoverDashTextTracks.d.ts +2 -2
- package/dist/types/current/text/discoverDashTextTracks.js +4 -3
- package/dist/types/current/text/parseWebVtt.d.ts.map +1 -1
- package/dist/types/current/text/parseWebVtt.js +3 -2
- package/dist/types/current/track/TrackController.d.ts.map +1 -1
- package/dist/types/current/track/TrackController.js +7 -0
- package/dist/types/current/track/hls/HlsManifestData.d.ts +14 -1
- package/dist/types/current/track/hls/HlsManifestData.d.ts.map +1 -1
- package/dist/types/current/track/hls/buildHlsMediaTimeline.d.ts.map +1 -1
- package/dist/types/current/track/hls/buildHlsMediaTimeline.js +10 -2
- package/dist/types/current/track/hls/createUrlHlsManifestProvider.d.ts +3 -2
- package/dist/types/current/track/hls/createUrlHlsManifestProvider.d.ts.map +1 -1
- package/dist/types/current/track/hls/createUrlHlsManifestProvider.js +8 -3
- package/dist/types/current/tsconfig.tsbuildinfo +1 -1
- package/dist/types/ts3.7/playback/PlaybackControllerImpl.d.ts +1 -1
- package/dist/types/ts3.7/streaming/MediaQualityMetadata.d.ts +3 -1
- package/dist/types/ts3.7/streaming/SegmentControllerImpl.d.ts +1 -1
- package/dist/types/ts3.7/streaming/buffering/BufferingController.d.ts +1 -1
- package/dist/types/ts3.7/text/discoverDashTextTracks.d.ts +2 -2
- package/dist/types/ts3.7/track/hls/HlsManifestData.d.ts +14 -1
- package/dist/types/ts3.7/track/hls/createUrlHlsManifestProvider.d.ts +3 -2
- package/dist/types/ts4.1/playback/PlaybackControllerImpl.d.ts +1 -1
- package/dist/types/ts4.1/streaming/MediaQualityMetadata.d.ts +3 -1
- package/dist/types/ts4.1/streaming/SegmentControllerImpl.d.ts +1 -1
- package/dist/types/ts4.1/streaming/buffering/BufferingController.d.ts +1 -1
- package/dist/types/ts4.1/text/discoverDashTextTracks.d.ts +2 -2
- package/dist/types/ts4.1/track/hls/HlsManifestData.d.ts +14 -1
- package/dist/types/ts4.1/track/hls/createUrlHlsManifestProvider.d.ts +3 -2
- package/dist/types/ts4.7/playback/PlaybackControllerImpl.d.ts +1 -1
- package/dist/types/ts4.7/streaming/MediaQualityMetadata.d.ts +3 -1
- package/dist/types/ts4.7/streaming/SegmentControllerImpl.d.ts +1 -1
- package/dist/types/ts4.7/streaming/buffering/BufferingController.d.ts +1 -1
- package/dist/types/ts4.7/text/discoverDashTextTracks.d.ts +2 -2
- package/dist/types/ts4.7/track/hls/HlsManifestData.d.ts +14 -1
- package/dist/types/ts4.7/track/hls/createUrlHlsManifestProvider.d.ts +3 -2
- package/dist/unit/types/current/ad/AdControllerImpl.test.js +66 -0
- package/dist/unit/types/current/ad/discoverHlsInterstitials.test.js +29 -2
- package/dist/unit/types/current/drm/commonEme/StandardCommonEme.test.js +12 -4
- package/dist/unit/types/current/drm/util/extractContentId.test.js +7 -0
- package/dist/unit/types/current/index.d.ts +1 -0
- package/dist/unit/types/current/index.d.ts.map +1 -1
- package/dist/unit/types/current/index.js +1 -0
- package/dist/unit/types/current/streaming/MediaQualityMetadata.test.js +8 -0
- package/dist/unit/types/current/streaming/buffering/BufferingController.test.js +26 -0
- package/dist/unit/types/current/streaming/buffering/MediaSourceController.test.js +29 -0
- package/dist/unit/types/current/text/TextTrack.test.d.ts +2 -0
- package/dist/unit/types/current/text/TextTrack.test.d.ts.map +1 -0
- package/dist/unit/types/current/text/TextTrack.test.js +12 -0
- package/dist/unit/types/current/text/discoverDashTextTracks.test.js +17 -0
- package/dist/unit/types/current/text/parseWebVtt.test.js +26 -0
- package/dist/unit/types/current/track/TrackController.test.js +15 -60
- package/dist/unit/types/current/track/hls/buildHlsMediaTimeline.test.js +22 -0
- package/dist/unit/types/current/track/hls/createUrlHlsManifestProvider.test.js +23 -0
- package/dist/unit/types/current/tsconfig.tsbuildinfo +1 -1
- package/dist/vinylTestUtil/types/current/tsconfig.tsbuildinfo +1 -1
- package/docs/CUSTOMIZATION_GUIDE.md +310 -0
- package/package.json +10 -10
- package/docs/DASH_MANIFEST_TRANSFORM_GUIDE.md +0 -236
|
@@ -15,7 +15,7 @@ export interface PlaybackControllerImplOptions {
|
|
|
15
15
|
* The minimum number of seconds before the end of the next seekable range allowed for a seek
|
|
16
16
|
* operation. Some browsers will never complete a seek operation if the seek is too close to
|
|
17
17
|
* this end range.
|
|
18
|
-
* Default: getMinSeekableBufferDefault() which is
|
|
18
|
+
* Default: getMinSeekableBufferDefault(), which is 2 on Chromium and 5 elsewhere.
|
|
19
19
|
*/
|
|
20
20
|
readonly minSeekableBuffer: number;
|
|
21
21
|
/**
|
|
@@ -148,7 +148,9 @@ export interface MediaQualityMetadata extends MediaFormatMetadata {
|
|
|
148
148
|
* An array restricts switching to only the listed group IDs.
|
|
149
149
|
* Default behavior:
|
|
150
150
|
* - DASH: restricted to own group unless adaptation-set-switching property is present.
|
|
151
|
-
* - HLS:
|
|
151
|
+
* - HLS: unconstrained (null). Every variant is one group, and renditions are
|
|
152
|
+
* selected by the media timeline's language and accessibility filters
|
|
153
|
+
* rather than by a switching group.
|
|
152
154
|
*/
|
|
153
155
|
readonly switchingGroupIds: readonly string[] | null;
|
|
154
156
|
}
|
|
@@ -18,7 +18,7 @@ export interface SegmentControllerImplDeps {
|
|
|
18
18
|
export interface SegmentControllerImplOptions {
|
|
19
19
|
/**
|
|
20
20
|
* The amount of time ahead of the playhead to prefetch when the track is active.
|
|
21
|
-
* Default:
|
|
21
|
+
* Default: 180
|
|
22
22
|
*/
|
|
23
23
|
readonly prefetchActive: number;
|
|
24
24
|
/**
|
|
@@ -119,7 +119,7 @@ export interface BufferingControllerImplOptions {
|
|
|
119
119
|
readonly minBuffer: number;
|
|
120
120
|
/**
|
|
121
121
|
* The maximum number of bytes to append at a time per content type.
|
|
122
|
-
* Default: { audio:
|
|
122
|
+
* Default: { audio: 10MiB, video: 150MiB }
|
|
123
123
|
*/
|
|
124
124
|
readonly maxAppendSize: Partial<Record<ContentType, number>>;
|
|
125
125
|
}
|
|
@@ -5,8 +5,8 @@ import { TextTrackInfo } from './TextTrack';
|
|
|
5
5
|
*
|
|
6
6
|
* Considers an `<AdaptationSet>` to carry text when one of:
|
|
7
7
|
* - `contentType="text"`
|
|
8
|
-
* - `mimeType
|
|
9
|
-
*
|
|
8
|
+
* - its `mimeType`, or that of one of its `<Representation>`s, starts with
|
|
9
|
+
* `text/` (e.g. `text/vtt`)
|
|
10
10
|
*
|
|
11
11
|
* Within a text adaptation set, each `<Representation>` becomes one
|
|
12
12
|
* {@link TextTrackInfo}. The `BaseURL` chain (MPD → Period → AdaptationSet →
|
|
@@ -14,6 +14,19 @@ export interface HlsManifestData {
|
|
|
14
14
|
/**
|
|
15
15
|
* Lazily fetches and caches a media playlist by variant URI.
|
|
16
16
|
*/
|
|
17
|
-
readonly getMediaPlaylist: (uri: string) => Promise<
|
|
17
|
+
readonly getMediaPlaylist: (uri: string) => Promise<HlsMediaPlaylistData>;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* A media playlist with the URL its relative URIs resolve against.
|
|
21
|
+
*/
|
|
22
|
+
export interface HlsMediaPlaylistData extends HlsMediaPlaylist {
|
|
23
|
+
/**
|
|
24
|
+
* The media playlist's URL after redirects, against which its segment, map,
|
|
25
|
+
* and date range URIs resolve. Guaranteed to be absolute when set.
|
|
26
|
+
*
|
|
27
|
+
* When absent, the variant URI resolved against
|
|
28
|
+
* {@link HlsManifestData.baseUrl} is used instead.
|
|
29
|
+
*/
|
|
30
|
+
readonly baseUrl?: string;
|
|
18
31
|
}
|
|
19
32
|
//# sourceMappingURL=HlsManifestData.d.ts.map
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { HlsMainPlaylist
|
|
1
|
+
import { HlsMainPlaylist } from '@amazon/vinyl-hls-parser';
|
|
2
2
|
import { Maybe, ReadonlyAbort, RequestInitOptions } from '@amazon/vinyl-util';
|
|
3
|
+
import { HlsMediaPlaylistData } from './HlsManifestData';
|
|
3
4
|
import { HlsManifestProvider } from './createHlsManifestProvider';
|
|
4
5
|
export declare function createUrlHlsManifestProvider(url: string, requestInit?: RequestInitOptions): HlsManifestProvider;
|
|
5
6
|
export interface FetchMediaPlaylistOptions {
|
|
@@ -17,5 +18,5 @@ export interface FetchMediaPlaylistOptions {
|
|
|
17
18
|
/**
|
|
18
19
|
* Fetches and parses an HLS media playlist from a variant URI.
|
|
19
20
|
*/
|
|
20
|
-
export declare function fetchMediaPlaylist(options: FetchMediaPlaylistOptions): Promise<
|
|
21
|
+
export declare function fetchMediaPlaylist(options: FetchMediaPlaylistOptions): Promise<HlsMediaPlaylistData>;
|
|
21
22
|
//# sourceMappingURL=createUrlHlsManifestProvider.d.ts.map
|
|
@@ -17,7 +17,7 @@ export interface PlaybackControllerImplOptions {
|
|
|
17
17
|
* The minimum number of seconds before the end of the next seekable range allowed for a seek
|
|
18
18
|
* operation. Some browsers will never complete a seek operation if the seek is too close to
|
|
19
19
|
* this end range.
|
|
20
|
-
* Default: getMinSeekableBufferDefault() which is
|
|
20
|
+
* Default: getMinSeekableBufferDefault(), which is 2 on Chromium and 5 elsewhere.
|
|
21
21
|
*/
|
|
22
22
|
readonly minSeekableBuffer: number;
|
|
23
23
|
/**
|
|
@@ -148,7 +148,9 @@ export interface MediaQualityMetadata extends MediaFormatMetadata {
|
|
|
148
148
|
* An array restricts switching to only the listed group IDs.
|
|
149
149
|
* Default behavior:
|
|
150
150
|
* - DASH: restricted to own group unless adaptation-set-switching property is present.
|
|
151
|
-
* - HLS:
|
|
151
|
+
* - HLS: unconstrained (null). Every variant is one group, and renditions are
|
|
152
|
+
* selected by the media timeline's language and accessibility filters
|
|
153
|
+
* rather than by a switching group.
|
|
152
154
|
*/
|
|
153
155
|
readonly switchingGroupIds: readonly string[] | null;
|
|
154
156
|
}
|
|
@@ -19,7 +19,7 @@ export interface SegmentControllerImplDeps {
|
|
|
19
19
|
export interface SegmentControllerImplOptions {
|
|
20
20
|
/**
|
|
21
21
|
* The amount of time ahead of the playhead to prefetch when the track is active.
|
|
22
|
-
* Default:
|
|
22
|
+
* Default: 180
|
|
23
23
|
*/
|
|
24
24
|
readonly prefetchActive: number;
|
|
25
25
|
/**
|
|
@@ -120,7 +120,7 @@ export interface BufferingControllerImplOptions {
|
|
|
120
120
|
readonly minBuffer: number;
|
|
121
121
|
/**
|
|
122
122
|
* The maximum number of bytes to append at a time per content type.
|
|
123
|
-
* Default: { audio:
|
|
123
|
+
* Default: { audio: 10MiB, video: 150MiB }
|
|
124
124
|
*/
|
|
125
125
|
readonly maxAppendSize: Partial<Record<ContentType, number>>;
|
|
126
126
|
}
|
|
@@ -5,8 +5,8 @@ import type { TextTrackInfo } from './TextTrack';
|
|
|
5
5
|
*
|
|
6
6
|
* Considers an `<AdaptationSet>` to carry text when one of:
|
|
7
7
|
* - `contentType="text"`
|
|
8
|
-
* - `mimeType
|
|
9
|
-
*
|
|
8
|
+
* - its `mimeType`, or that of one of its `<Representation>`s, starts with
|
|
9
|
+
* `text/` (e.g. `text/vtt`)
|
|
10
10
|
*
|
|
11
11
|
* Within a text adaptation set, each `<Representation>` becomes one
|
|
12
12
|
* {@link TextTrackInfo}. The `BaseURL` chain (MPD → Period → AdaptationSet →
|
|
@@ -14,6 +14,19 @@ export interface HlsManifestData {
|
|
|
14
14
|
/**
|
|
15
15
|
* Lazily fetches and caches a media playlist by variant URI.
|
|
16
16
|
*/
|
|
17
|
-
readonly getMediaPlaylist: (uri: string) => Promise<
|
|
17
|
+
readonly getMediaPlaylist: (uri: string) => Promise<HlsMediaPlaylistData>;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* A media playlist with the URL its relative URIs resolve against.
|
|
21
|
+
*/
|
|
22
|
+
export interface HlsMediaPlaylistData extends HlsMediaPlaylist {
|
|
23
|
+
/**
|
|
24
|
+
* The media playlist's URL after redirects, against which its segment, map,
|
|
25
|
+
* and date range URIs resolve. Guaranteed to be absolute when set.
|
|
26
|
+
*
|
|
27
|
+
* When absent, the variant URI resolved against
|
|
28
|
+
* {@link HlsManifestData.baseUrl} is used instead.
|
|
29
|
+
*/
|
|
30
|
+
readonly baseUrl?: string;
|
|
18
31
|
}
|
|
19
32
|
//# sourceMappingURL=HlsManifestData.d.ts.map
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import type { HlsMainPlaylist
|
|
1
|
+
import type { HlsMainPlaylist } from '@amazon/vinyl-hls-parser';
|
|
2
2
|
import type { Maybe, ReadonlyAbort, RequestInitOptions } from '@amazon/vinyl-util';
|
|
3
|
+
import type { HlsMediaPlaylistData } from './HlsManifestData';
|
|
3
4
|
import type { HlsManifestProvider } from './createHlsManifestProvider';
|
|
4
5
|
export declare function createUrlHlsManifestProvider(url: string, requestInit?: RequestInitOptions): HlsManifestProvider;
|
|
5
6
|
export interface FetchMediaPlaylistOptions {
|
|
@@ -17,5 +18,5 @@ export interface FetchMediaPlaylistOptions {
|
|
|
17
18
|
/**
|
|
18
19
|
* Fetches and parses an HLS media playlist from a variant URI.
|
|
19
20
|
*/
|
|
20
|
-
export declare function fetchMediaPlaylist(options: FetchMediaPlaylistOptions): Promise<
|
|
21
|
+
export declare function fetchMediaPlaylist(options: FetchMediaPlaylistOptions): Promise<HlsMediaPlaylistData>;
|
|
21
22
|
//# sourceMappingURL=createUrlHlsManifestProvider.d.ts.map
|
|
@@ -15,7 +15,7 @@ export interface PlaybackControllerImplOptions {
|
|
|
15
15
|
* The minimum number of seconds before the end of the next seekable range allowed for a seek
|
|
16
16
|
* operation. Some browsers will never complete a seek operation if the seek is too close to
|
|
17
17
|
* this end range.
|
|
18
|
-
* Default: getMinSeekableBufferDefault() which is
|
|
18
|
+
* Default: getMinSeekableBufferDefault(), which is 2 on Chromium and 5 elsewhere.
|
|
19
19
|
*/
|
|
20
20
|
readonly minSeekableBuffer: number;
|
|
21
21
|
/**
|
|
@@ -148,7 +148,9 @@ export interface MediaQualityMetadata extends MediaFormatMetadata {
|
|
|
148
148
|
* An array restricts switching to only the listed group IDs.
|
|
149
149
|
* Default behavior:
|
|
150
150
|
* - DASH: restricted to own group unless adaptation-set-switching property is present.
|
|
151
|
-
* - HLS:
|
|
151
|
+
* - HLS: unconstrained (null). Every variant is one group, and renditions are
|
|
152
|
+
* selected by the media timeline's language and accessibility filters
|
|
153
|
+
* rather than by a switching group.
|
|
152
154
|
*/
|
|
153
155
|
readonly switchingGroupIds: readonly string[] | null;
|
|
154
156
|
}
|
|
@@ -18,7 +18,7 @@ export interface SegmentControllerImplDeps {
|
|
|
18
18
|
export interface SegmentControllerImplOptions {
|
|
19
19
|
/**
|
|
20
20
|
* The amount of time ahead of the playhead to prefetch when the track is active.
|
|
21
|
-
* Default:
|
|
21
|
+
* Default: 180
|
|
22
22
|
*/
|
|
23
23
|
readonly prefetchActive: number;
|
|
24
24
|
/**
|
|
@@ -119,7 +119,7 @@ export interface BufferingControllerImplOptions {
|
|
|
119
119
|
readonly minBuffer: number;
|
|
120
120
|
/**
|
|
121
121
|
* The maximum number of bytes to append at a time per content type.
|
|
122
|
-
* Default: { audio:
|
|
122
|
+
* Default: { audio: 10MiB, video: 150MiB }
|
|
123
123
|
*/
|
|
124
124
|
readonly maxAppendSize: Partial<Record<ContentType, number>>;
|
|
125
125
|
}
|
|
@@ -5,8 +5,8 @@ import type { TextTrackInfo } from './TextTrack';
|
|
|
5
5
|
*
|
|
6
6
|
* Considers an `<AdaptationSet>` to carry text when one of:
|
|
7
7
|
* - `contentType="text"`
|
|
8
|
-
* - `mimeType
|
|
9
|
-
*
|
|
8
|
+
* - its `mimeType`, or that of one of its `<Representation>`s, starts with
|
|
9
|
+
* `text/` (e.g. `text/vtt`)
|
|
10
10
|
*
|
|
11
11
|
* Within a text adaptation set, each `<Representation>` becomes one
|
|
12
12
|
* {@link TextTrackInfo}. The `BaseURL` chain (MPD → Period → AdaptationSet →
|
|
@@ -14,6 +14,19 @@ export interface HlsManifestData {
|
|
|
14
14
|
/**
|
|
15
15
|
* Lazily fetches and caches a media playlist by variant URI.
|
|
16
16
|
*/
|
|
17
|
-
readonly getMediaPlaylist: (uri: string) => Promise<
|
|
17
|
+
readonly getMediaPlaylist: (uri: string) => Promise<HlsMediaPlaylistData>;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* A media playlist with the URL its relative URIs resolve against.
|
|
21
|
+
*/
|
|
22
|
+
export interface HlsMediaPlaylistData extends HlsMediaPlaylist {
|
|
23
|
+
/**
|
|
24
|
+
* The media playlist's URL after redirects, against which its segment, map,
|
|
25
|
+
* and date range URIs resolve. Guaranteed to be absolute when set.
|
|
26
|
+
*
|
|
27
|
+
* When absent, the variant URI resolved against
|
|
28
|
+
* {@link HlsManifestData.baseUrl} is used instead.
|
|
29
|
+
*/
|
|
30
|
+
readonly baseUrl?: string;
|
|
18
31
|
}
|
|
19
32
|
//# sourceMappingURL=HlsManifestData.d.ts.map
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import type { HlsMainPlaylist
|
|
1
|
+
import type { HlsMainPlaylist } from '@amazon/vinyl-hls-parser';
|
|
2
2
|
import type { Maybe, ReadonlyAbort, RequestInitOptions } from '@amazon/vinyl-util';
|
|
3
|
+
import type { HlsMediaPlaylistData } from './HlsManifestData';
|
|
3
4
|
import type { HlsManifestProvider } from './createHlsManifestProvider';
|
|
4
5
|
export declare function createUrlHlsManifestProvider(url: string, requestInit?: RequestInitOptions): HlsManifestProvider;
|
|
5
6
|
export interface FetchMediaPlaylistOptions {
|
|
@@ -17,5 +18,5 @@ export interface FetchMediaPlaylistOptions {
|
|
|
17
18
|
/**
|
|
18
19
|
* Fetches and parses an HLS media playlist from a variant URI.
|
|
19
20
|
*/
|
|
20
|
-
export declare function fetchMediaPlaylist(options: FetchMediaPlaylistOptions): Promise<
|
|
21
|
+
export declare function fetchMediaPlaylist(options: FetchMediaPlaylistOptions): Promise<HlsMediaPlaylistData>;
|
|
21
22
|
//# sourceMappingURL=createUrlHlsManifestProvider.d.ts.map
|
|
@@ -526,6 +526,44 @@ describe('AdControllerImpl', () => {
|
|
|
526
526
|
await flush();
|
|
527
527
|
expect(c.currentAdBreak).toBeNull();
|
|
528
528
|
});
|
|
529
|
+
it('still enters a pending break when skipped while its ads resolve', async () => {
|
|
530
|
+
const c = createController();
|
|
531
|
+
let resolveAds = () => undefined;
|
|
532
|
+
const entered = [];
|
|
533
|
+
await setContent(c, trackAds(makeBreak({
|
|
534
|
+
id: 'b1',
|
|
535
|
+
startTime: 0,
|
|
536
|
+
duration: 30,
|
|
537
|
+
ads: () => new Promise((resolve) => {
|
|
538
|
+
resolveAds = resolve;
|
|
539
|
+
}),
|
|
540
|
+
}), makeBreak({
|
|
541
|
+
id: 'b2',
|
|
542
|
+
startTime: 1,
|
|
543
|
+
duration: 30,
|
|
544
|
+
ads: [
|
|
545
|
+
{
|
|
546
|
+
id: 'a2',
|
|
547
|
+
startTime: 1,
|
|
548
|
+
duration: 10,
|
|
549
|
+
uri: 'ad2.m3u8',
|
|
550
|
+
},
|
|
551
|
+
],
|
|
552
|
+
})));
|
|
553
|
+
c.on('adBreakEntered', (e) => entered.push(e.adBreak.id));
|
|
554
|
+
// Both breaks contain the playhead, so both become pending and the
|
|
555
|
+
// first is entered while its ad list is still in flight.
|
|
556
|
+
updateTime(2);
|
|
557
|
+
await flush();
|
|
558
|
+
expect(entered).toEqual(['b1']);
|
|
559
|
+
c.skipAdBreak();
|
|
560
|
+
resolveAds([]);
|
|
561
|
+
await flush();
|
|
562
|
+
// Nothing else drains the pending list, and a non-empty list blocks
|
|
563
|
+
// further midroll ingress, so b2 must be entered here.
|
|
564
|
+
expect(entered).toEqual(['b1', 'b2']);
|
|
565
|
+
expect(c.currentAdBreak?.id).toBe('b2');
|
|
566
|
+
});
|
|
529
567
|
});
|
|
530
568
|
describe('a break with no ads', () => {
|
|
531
569
|
it('completes immediately with a resume position and plays no ad', async () => {
|
|
@@ -753,6 +791,34 @@ describe('AdControllerImpl', () => {
|
|
|
753
791
|
await flush();
|
|
754
792
|
expect(thirds).toEqual(['a1']);
|
|
755
793
|
});
|
|
794
|
+
it('dispatches each quartile at most once per ad', async () => {
|
|
795
|
+
const c = createController();
|
|
796
|
+
const events = [];
|
|
797
|
+
c.on('adFirstQuartile', () => events.push('first'));
|
|
798
|
+
c.on('adMidpoint', () => events.push('mid'));
|
|
799
|
+
c.on('adThirdQuartile', () => events.push('third'));
|
|
800
|
+
await setContent(c, trackAds(makeBreak({ startTime: 0, duration: 10 })));
|
|
801
|
+
updateTime(0);
|
|
802
|
+
await flush();
|
|
803
|
+
playbackController.dispatch('playing', {});
|
|
804
|
+
playbackController.duration = 10;
|
|
805
|
+
playbackController.playbackRate = 1;
|
|
806
|
+
// Every subsequent timeUpdate is still past each threshold, so an
|
|
807
|
+
// unlatched check would report the quartile again.
|
|
808
|
+
for (const [percent, time] of [
|
|
809
|
+
[0.3, 3],
|
|
810
|
+
[0.4, 4],
|
|
811
|
+
[0.6, 6],
|
|
812
|
+
[0.7, 7],
|
|
813
|
+
[0.8, 8],
|
|
814
|
+
[0.9, 9],
|
|
815
|
+
]) {
|
|
816
|
+
playbackController.currentTimePercent = percent;
|
|
817
|
+
updateTime(time);
|
|
818
|
+
await flush();
|
|
819
|
+
}
|
|
820
|
+
expect(events).toEqual(['first', 'mid', 'third']);
|
|
821
|
+
});
|
|
756
822
|
it('does not emit quartiles or throw when the ad duration is zero', async () => {
|
|
757
823
|
// Regression: a zero reported duration must not divide-by-zero into
|
|
758
824
|
// NaN progress and must not emit bogus quartile events.
|
|
@@ -32,8 +32,9 @@ describe('discoverHlsInterstitials', () => {
|
|
|
32
32
|
* A minimal `fetch` Response stand-in that satisfies `requestWithRetry`
|
|
33
33
|
* (which reads `ok`/`status`/`headers` and rejects on non-ok responses).
|
|
34
34
|
*/
|
|
35
|
-
function okJsonResponse(body) {
|
|
35
|
+
function okJsonResponse(body, url = '') {
|
|
36
36
|
return {
|
|
37
|
+
url,
|
|
37
38
|
ok: true,
|
|
38
39
|
status: 200,
|
|
39
40
|
headers: { get: () => null },
|
|
@@ -199,7 +200,8 @@ describe('discoverHlsInterstitials', () => {
|
|
|
199
200
|
const ads = await resolveValueProvider(breaks[0].ads);
|
|
200
201
|
expect(fetchSpy.calls.argsFor(0)[0]).toBe('https://example.com/ads.json');
|
|
201
202
|
expect(ads.length).toBe(2);
|
|
202
|
-
|
|
203
|
+
// Relative to the asset list, not to the media playlist.
|
|
204
|
+
expect(ads[0].uri).toBe('https://example.com/mid1.m3u8');
|
|
203
205
|
expect(ads[0].duration).toBe(10);
|
|
204
206
|
expect(ads[1].uri).toBe('https://cdn.example.com/mid2.m3u8');
|
|
205
207
|
expect(ads[1].duration).toBeNull();
|
|
@@ -208,6 +210,31 @@ describe('discoverHlsInterstitials', () => {
|
|
|
208
210
|
globalThis.fetch = origFetch;
|
|
209
211
|
}
|
|
210
212
|
});
|
|
213
|
+
it('resolves relative asset URIs against the redirected asset list URL', async () => {
|
|
214
|
+
const origFetch = globalThis.fetch;
|
|
215
|
+
const fetchSpy = jasmine
|
|
216
|
+
.createSpy('fetch')
|
|
217
|
+
.and.resolveTo(okJsonResponse({ ASSETS: [{ URI: 'mid1.m3u8' }] }, 'https://ads.example.net/v2/ads.json'));
|
|
218
|
+
globalThis.fetch = fetchSpy;
|
|
219
|
+
try {
|
|
220
|
+
const playlist = makePlaylist({
|
|
221
|
+
dateRanges: [
|
|
222
|
+
makeRange({
|
|
223
|
+
duration: 10,
|
|
224
|
+
clientAttributes: {
|
|
225
|
+
'X-ASSET-LIST': 'https://example.com/redirected.json',
|
|
226
|
+
},
|
|
227
|
+
}),
|
|
228
|
+
],
|
|
229
|
+
});
|
|
230
|
+
const breaks = await discoverHlsInterstitials(playlist, BASE);
|
|
231
|
+
const ads = await resolveValueProvider(breaks[0].ads);
|
|
232
|
+
expect(ads[0].uri).toBe('https://ads.example.net/v2/mid1.m3u8');
|
|
233
|
+
}
|
|
234
|
+
finally {
|
|
235
|
+
globalThis.fetch = origFetch;
|
|
236
|
+
}
|
|
237
|
+
});
|
|
211
238
|
it('caches the X-ASSET-LIST fetch across calls', async () => {
|
|
212
239
|
const origFetch = globalThis.fetch;
|
|
213
240
|
const fetchSpy = jasmine
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
* SPDX-License-Identifier: Apache-2.0
|
|
4
4
|
*/
|
|
5
5
|
import { DrmKeySystem, StandardCommonEme, StandardCommonMediaKeys, StandardCommonMediaKeySession, StandardCommonMediaKeySystemAccess, } from '@amazon/vinyl';
|
|
6
|
-
import { Deferred, DisposedError, never, } from '@amazon/vinyl-util';
|
|
7
|
-
import { expectTypeEquals, flushPromises, implementEventFakes, mockEvent, MockHTMLAudioElement, MockMediaKeyMessageEvent, MockMediaKeys, MockMediaKeySession, MockMediaKeySystemAccess, } from '@amazon/vinyl-util/browserTestUtil';
|
|
6
|
+
import { bufferToArrayBuffer, Deferred, DisposedError, never, } from '@amazon/vinyl-util';
|
|
7
|
+
import { expectIterableEquals, expectTypeEquals, flushPromises, implementEventFakes, mockEvent, MockHTMLAudioElement, MockMediaKeyMessageEvent, MockMediaKeys, MockMediaKeySession, MockMediaKeySystemAccess, } from '@amazon/vinyl-util/browserTestUtil';
|
|
8
8
|
import { createEventSpy, setMockNavigator } from '@amazon/vinyl-util/testUtil';
|
|
9
9
|
var any = jasmine.any;
|
|
10
10
|
describe('StandardCommonEme', () => {
|
|
@@ -163,14 +163,22 @@ describe('StandardCommonEme', () => {
|
|
|
163
163
|
});
|
|
164
164
|
});
|
|
165
165
|
describe('when created', () => {
|
|
166
|
-
it('calls session.generateRequest() with the initData
|
|
167
|
-
expect(mediaKeySession.generateRequest).toHaveBeenCalledOnceWith('cenc', initData
|
|
166
|
+
it('calls session.generateRequest() with the initData', () => {
|
|
167
|
+
expect(mediaKeySession.generateRequest).toHaveBeenCalledOnceWith('cenc', initData);
|
|
168
168
|
mediaKeySession.generateRequest.calls.reset();
|
|
169
169
|
const arrayBuffer = new ArrayBuffer(0);
|
|
170
170
|
standardCommonMediaKeySession =
|
|
171
171
|
new StandardCommonMediaKeySession(mediaKeySession, mimeType, 'cenc', arrayBuffer);
|
|
172
172
|
expect(mediaKeySession.generateRequest).toHaveBeenCalledOnceWith('cenc', arrayBuffer);
|
|
173
173
|
});
|
|
174
|
+
it('passes only the bytes an offset initData view spans', () => {
|
|
175
|
+
mediaKeySession.generateRequest.calls.reset();
|
|
176
|
+
const view = new Uint8Array([1, 2, 3, 4, 5]).subarray(1, 4);
|
|
177
|
+
standardCommonMediaKeySession =
|
|
178
|
+
new StandardCommonMediaKeySession(mediaKeySession, mimeType, 'cenc', view);
|
|
179
|
+
const [, passed] = mediaKeySession.generateRequest.calls.mostRecent().args;
|
|
180
|
+
expectIterableEquals(new Uint8Array(bufferToArrayBuffer(passed)), [2, 3, 4]);
|
|
181
|
+
});
|
|
174
182
|
describe('when session.generateRequest rejects', () => {
|
|
175
183
|
it('emits an error event', async () => {
|
|
176
184
|
mediaKeySession.generateRequest.and.rejectWith(new Error('expected'));
|
|
@@ -14,6 +14,13 @@ describe('extractContentId', () => {
|
|
|
14
14
|
expect(extractContentId(createContentIdByteArray('skd://example0'))).toBe('example0');
|
|
15
15
|
});
|
|
16
16
|
});
|
|
17
|
+
describe('with an offset view', () => {
|
|
18
|
+
it('reads only the bytes the view spans', () => {
|
|
19
|
+
const padded = createContentIdByteArray('\0\0skd://example0\0\0');
|
|
20
|
+
const view = padded.subarray(4, padded.byteLength - 4);
|
|
21
|
+
expect(extractContentId(view)).toBe('example0');
|
|
22
|
+
});
|
|
23
|
+
});
|
|
17
24
|
describe('without match', () => {
|
|
18
25
|
it('throws ValidationError', () => {
|
|
19
26
|
expect(() => {
|
|
@@ -67,6 +67,7 @@ import './text/parseWebVtt.test';
|
|
|
67
67
|
import './text/pickPreferredTextTrack.test';
|
|
68
68
|
import './text/SidecarTextTrackController.test';
|
|
69
69
|
import './text/SidecarTextTrackLoader.test';
|
|
70
|
+
import './text/TextTrack.test';
|
|
70
71
|
import './text/VttCueStyle.test';
|
|
71
72
|
import './track/AutoResetController.test';
|
|
72
73
|
import './track/createSegmentDataProvider.test';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../test/unit/index.ts"],"names":[],"mappings":"AAAA,wCAAwC;AACxC,OAAO,wBAAwB,CAAA;AAC/B,OAAO,4BAA4B,CAAA;AACnC,OAAO,wCAAwC,CAAA;AAC/C,OAAO,oCAAoC,CAAA;AAC3C,OAAO,gCAAgC,CAAA;AACvC,cAAc,0CAA0C,CAAA;AACxD,OAAO,iCAAiC,CAAA;AACxC,OAAO,gCAAgC,CAAA;AACvC,OAAO,4CAA4C,CAAA;AACnD,OAAO,kCAAkC,CAAA;AACzC,OAAO,wCAAwC,CAAA;AAC/C,OAAO,sCAAsC,CAAA;AAC7C,OAAO,6BAA6B,CAAA;AACpC,OAAO,8BAA8B,CAAA;AACrC,OAAO,yBAAyB,CAAA;AAChC,OAAO,iCAAiC,CAAA;AACxC,OAAO,2BAA2B,CAAA;AAClC,OAAO,mDAAmD,CAAA;AAC1D,OAAO,+CAA+C,CAAA;AACtD,OAAO,kCAAkC,CAAA;AACzC,OAAO,0CAA0C,CAAA;AACjD,OAAO,0BAA0B,CAAA;AACjC,OAAO,oCAAoC,CAAA;AAC3C,OAAO,2BAA2B,CAAA;AAClC,OAAO,yBAAyB,CAAA;AAChC,OAAO,8BAA8B,CAAA;AACrC,OAAO,qCAAqC,CAAA;AAC5C,OAAO,oCAAoC,CAAA;AAC3C,OAAO,wCAAwC,CAAA;AAC/C,OAAO,4CAA4C,CAAA;AACnD,OAAO,0CAA0C,CAAA;AACjD,OAAO,qDAAqD,CAAA;AAC5D,OAAO,sCAAsC,CAAA;AAC7C,OAAO,wCAAwC,CAAA;AAC/C,OAAO,oCAAoC,CAAA;AAC3C,OAAO,4CAA4C,CAAA;AACnD,OAAO,SAAS,CAAA;AAChB,OAAO,0CAA0C,CAAA;AACjD,OAAO,gDAAgD,CAAA;AACvD,OAAO,0CAA0C,CAAA;AACjD,OAAO,oDAAoD,CAAA;AAC3D,OAAO,kDAAkD,CAAA;AACzD,OAAO,mDAAmD,CAAA;AAC1D,OAAO,gCAAgC,CAAA;AACvC,OAAO,iDAAiD,CAAA;AACxD,OAAO,wDAAwD,CAAA;AAC/D,OAAO,mCAAmC,CAAA;AAC1C,OAAO,+DAA+D,CAAA;AACtE,OAAO,yCAAyC,CAAA;AAChD,OAAO,uCAAuC,CAAA;AAC9C,OAAO,gCAAgC,CAAA;AACvC,OAAO,mDAAmD,CAAA;AAC1D,OAAO,sCAAsC,CAAA;AAC7C,OAAO,8CAA8C,CAAA;AACrD,OAAO,2BAA2B,CAAA;AAClC,OAAO,wCAAwC,CAAA;AAC/C,OAAO,kCAAkC,CAAA;AACzC,OAAO,kCAAkC,CAAA;AACzC,OAAO,oCAAoC,CAAA;AAC3C,OAAO,+BAA+B,CAAA;AACtC,OAAO,oCAAoC,CAAA;AAC3C,OAAO,mCAAmC,CAAA;AAC1C,OAAO,mCAAmC,CAAA;AAC1C,OAAO,oCAAoC,CAAA;AAC3C,OAAO,yBAAyB,CAAA;AAChC,OAAO,oCAAoC,CAAA;AAC3C,OAAO,wCAAwC,CAAA;AAC/C,OAAO,oCAAoC,CAAA;AAC3C,OAAO,yBAAyB,CAAA;AAChC,OAAO,kCAAkC,CAAA;AACzC,OAAO,wCAAwC,CAAA;AAC/C,OAAO,wCAAwC,CAAA;AAC/C,OAAO,0CAA0C,CAAA;AACjD,OAAO,oDAAoD,CAAA;AAC3D,OAAO,+CAA+C,CAAA;AACtD,OAAO,uCAAuC,CAAA;AAC9C,OAAO,8CAA8C,CAAA;AACrD,OAAO,wDAAwD,CAAA;AAC/D,OAAO,kDAAkD,CAAA;AACzD,OAAO,oDAAoD,CAAA;AAC3D,OAAO,6BAA6B,CAAA;AACpC,OAAO,0CAA0C,CAAA;AACjD,OAAO,8DAA8D,CAAA;AACrE,OAAO,2CAA2C,CAAA;AAClD,OAAO,iCAAiC,CAAA;AACxC,OAAO,4BAA4B,CAAA;AACnC,OAAO,sCAAsC,CAAA;AAC7C,OAAO,sCAAsC,CAAA;AAC7C,OAAO,qCAAqC,CAAA;AAC5C,OAAO,yCAAyC,CAAA;AAChD,OAAO,uCAAuC,CAAA;AAC9C,OAAO,wCAAwC,CAAA;AAC/C,OAAO,sDAAsD,CAAA;AAC7D,OAAO,kDAAkD,CAAA;AACzD,OAAO,6CAA6C,CAAA;AACpD,OAAO,qCAAqC,CAAA;AAC5C,OAAO,+CAA+C,CAAA;AACtD,OAAO,wCAAwC,CAAA;AAC/C,OAAO,kDAAkD,CAAA;AACzD,OAAO,2BAA2B,CAAA;AAClC,OAAO,gDAAgD,CAAA;AACvD,OAAO,sCAAsC,CAAA;AAC7C,OAAO,sCAAsC,CAAA;AAC7C,OAAO,wBAAwB,CAAA;AAC/B,OAAO,0CAA0C,CAAA;AACjD,OAAO,uCAAuC,CAAA;AAC9C,OAAO,iCAAiC,CAAA;AACxC,OAAO,qCAAqC,CAAA;AAC5C,OAAO,wBAAwB,CAAA;AAC/B,OAAO,8BAA8B,CAAA;AACrC,OAAO,2BAA2B,CAAA;AAClC,OAAO,kCAAkC,CAAA;AACzC,OAAO,gCAAgC,CAAA;AACvC,OAAO,mCAAmC,CAAA;AAC1C,OAAO,+BAA+B,CAAA;AACtC,OAAO,4BAA4B,CAAA;AACnC,OAAO,gCAAgC,CAAA;AACvC,OAAO,mCAAmC,CAAA;AAC1C,OAAO,kCAAkC,CAAA;AACzC,OAAO,0BAA0B,CAAA;AACjC,OAAO,kCAAkC,CAAA;AACzC,OAAO,oCAAoC,CAAA;AAC3C,OAAO,mDAAmD,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../test/unit/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -67,6 +67,7 @@ import './text/parseWebVtt.test';
|
|
|
67
67
|
import './text/pickPreferredTextTrack.test';
|
|
68
68
|
import './text/SidecarTextTrackController.test';
|
|
69
69
|
import './text/SidecarTextTrackLoader.test';
|
|
70
|
+
import './text/TextTrack.test';
|
|
70
71
|
import './text/VttCueStyle.test';
|
|
71
72
|
import './track/AutoResetController.test';
|
|
72
73
|
import './track/createSegmentDataProvider.test';
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
* SPDX-License-Identifier: Apache-2.0
|
|
4
4
|
*/
|
|
5
5
|
import { DrmKeySystem, drmProtectionValidator } from '@amazon/vinyl';
|
|
6
|
+
import { expectTypeStrictlyEquals } from '@amazon/vinyl-util/browserTestUtil';
|
|
6
7
|
describe('drmProtectionValidator', () => {
|
|
7
8
|
it('validates a complete DrmProtection', () => {
|
|
8
9
|
expect(drmProtectionValidator.isValid({
|
|
@@ -37,3 +38,10 @@ describe('drmProtectionValidator', () => {
|
|
|
37
38
|
expect(drmProtectionValidator.isValid({ keySystem: 123 })).toBeFalse();
|
|
38
39
|
});
|
|
39
40
|
});
|
|
41
|
+
describe('ALL_CONTENT_TYPES', () => {
|
|
42
|
+
it('provides a comprehensive list of all content types', () => {
|
|
43
|
+
// The player emits quality-change events per entry; a missing type
|
|
44
|
+
// silently emits none, and `satisfies` alone does not catch it.
|
|
45
|
+
expectTypeStrictlyEquals(true);
|
|
46
|
+
});
|
|
47
|
+
});
|
|
@@ -286,6 +286,32 @@ describe('BufferingControllerImpl', () => {
|
|
|
286
286
|
expect(sourceBufferController.append).toHaveBeenCalledTimes(1);
|
|
287
287
|
});
|
|
288
288
|
});
|
|
289
|
+
describe('when the append budget grows while a segment is partly appended', () => {
|
|
290
|
+
it('appends only the bytes remaining in the segment', async () => {
|
|
291
|
+
// A budget wide enough to hold a whole segment, so draining the
|
|
292
|
+
// buffer can lift it back above the segment size mid-append.
|
|
293
|
+
bufferingController.dispose();
|
|
294
|
+
bufferingController = createBufferingController({
|
|
295
|
+
maxAppendSize: { audio: 500 },
|
|
296
|
+
minBuffer: 6,
|
|
297
|
+
});
|
|
298
|
+
bufferingController.activate();
|
|
299
|
+
setSegmentList([200, 400]);
|
|
300
|
+
await open(); // segment 0 appends whole, buffering 0-10s
|
|
301
|
+
await setTime(5); // segment 1 partly appends: 300 of 400 bytes
|
|
302
|
+
expect(getMostRecentAppendData().byteLength).toBe(300);
|
|
303
|
+
sourceBufferController.append.calls.reset();
|
|
304
|
+
// The playhead drains the buffer, widening the budget past the
|
|
305
|
+
// segment's full size.
|
|
306
|
+
await setTime(15.5);
|
|
307
|
+
const appended = sourceBufferController.append.calls
|
|
308
|
+
.allArgs()
|
|
309
|
+
.map(([data]) => data.byteLength);
|
|
310
|
+
// Only the 100 unappended bytes; re-appending all 400 would
|
|
311
|
+
// duplicate the 300 already buffered.
|
|
312
|
+
expect(appended[0]).toBe(100);
|
|
313
|
+
});
|
|
314
|
+
});
|
|
289
315
|
describe('when contentType is undefined', () => {
|
|
290
316
|
it('uses DEFAULT_MAX_APPEND_SIZE for max byte length', async () => {
|
|
291
317
|
setSegmentList([DEFAULT_MAX_APPEND_SIZE * 2], 0, 'unknown');
|
|
@@ -89,6 +89,35 @@ describe('MediaSourceControllerImpl', () => {
|
|
|
89
89
|
URL.revokeObjectURL.and.throwError(new Error('revoke failed'));
|
|
90
90
|
expect(() => controller.deactivate()).not.toThrow();
|
|
91
91
|
});
|
|
92
|
+
it('does not report a re-activated media source as ready to append', async () => {
|
|
93
|
+
// A track is deactivated and reactivated whenever an ad plays over
|
|
94
|
+
// it, and each activation builds its own media source, whose
|
|
95
|
+
// duration has not been set yet.
|
|
96
|
+
open();
|
|
97
|
+
await flushPromises();
|
|
98
|
+
const firstRef = controller.createSourceBuffer('audio', 'audio/mp4');
|
|
99
|
+
expect(controller.readyToAppend)
|
|
100
|
+
.withContext('ready on the first media source')
|
|
101
|
+
.toBeTrue();
|
|
102
|
+
firstRef.dispose(); // the buffering controller drops its buffers
|
|
103
|
+
controller.deactivate();
|
|
104
|
+
const secondSource = new MockMediaSource();
|
|
105
|
+
implementEventFakes(secondSource);
|
|
106
|
+
secondSource.addSourceBuffer.and.callFake(() => new MockSourceBuffer());
|
|
107
|
+
mediaSourceFactory.and.returnValue(secondSource);
|
|
108
|
+
controller.activate();
|
|
109
|
+
await flushPromises();
|
|
110
|
+
controller.createSourceBuffer('audio', 'audio/mp4');
|
|
111
|
+
expect(controller.readyToAppend)
|
|
112
|
+
.withContext('duration not yet set on the new media source')
|
|
113
|
+
.toBeFalse();
|
|
114
|
+
secondSource.readyState = 'open';
|
|
115
|
+
secondSource.dispatchEvent(mockEvent('sourceopen'));
|
|
116
|
+
await flushPromises();
|
|
117
|
+
expect(controller.readyToAppend)
|
|
118
|
+
.withContext('ready once the new duration is set')
|
|
119
|
+
.toBeTrue();
|
|
120
|
+
});
|
|
92
121
|
});
|
|
93
122
|
describe('duration', () => {
|
|
94
123
|
it('sets media source duration after sourceopen', async () => {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TextTrack.test.d.ts","sourceRoot":"","sources":["../../../../../test/unit/text/TextTrack.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
import { expectTypeStrictlyEquals } from '@amazon/vinyl-util/browserTestUtil';
|
|
6
|
+
describe('ALL_TEXT_TRACK_EVENTS', () => {
|
|
7
|
+
it('provides a comprehensive list of all text track events', () => {
|
|
8
|
+
// The player redispatches exactly these; an omission silently stops an
|
|
9
|
+
// event reaching consumers, and `satisfies` alone does not catch it.
|
|
10
|
+
expectTypeStrictlyEquals(true);
|
|
11
|
+
});
|
|
12
|
+
});
|