@amazon/vinyl 3.2.1 → 3.2.2
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 +36 -22
- package/dist/index.cjs.map +2 -2
- package/dist/index.js +61 -46
- package/dist/index.js.map +3 -3
- package/dist/test/integ.es5.js +285 -281
- package/dist/test/integ.js +69 -22
- package/dist/test/integ.js.map +2 -2
- package/dist/types/current/drm/DrmControllerImpl.d.ts +6 -0
- package/dist/types/current/drm/DrmControllerImpl.d.ts.map +1 -1
- package/dist/types/current/drm/DrmControllerImpl.js +11 -1
- package/dist/types/current/playback/PlaybackControllerImpl.d.ts +8 -2
- package/dist/types/current/playback/PlaybackControllerImpl.d.ts.map +1 -1
- package/dist/types/current/playback/PlaybackControllerImpl.js +38 -33
- package/dist/types/current/track/mse/MseTrack.d.ts +0 -1
- package/dist/types/current/track/mse/MseTrack.d.ts.map +1 -1
- package/dist/types/current/track/mse/MseTrack.js +5 -6
- package/dist/types/current/tsconfig.tsbuildinfo +1 -1
- package/dist/types/ts3.7/drm/DrmControllerImpl.d.ts +6 -0
- package/dist/types/ts3.7/playback/PlaybackControllerImpl.d.ts +8 -2
- package/dist/types/ts3.7/track/mse/MseTrack.d.ts +0 -1
- package/dist/types/ts4.1/drm/DrmControllerImpl.d.ts +6 -0
- package/dist/types/ts4.1/playback/PlaybackControllerImpl.d.ts +8 -2
- package/dist/types/ts4.1/track/mse/MseTrack.d.ts +0 -1
- package/dist/types/ts4.7/drm/DrmControllerImpl.d.ts +6 -0
- package/dist/types/ts4.7/playback/PlaybackControllerImpl.d.ts +8 -2
- package/dist/types/ts4.7/track/mse/MseTrack.d.ts +0 -1
- package/dist/unit/types/current/drm/DrmControllerImpl.test.js +19 -1
- package/dist/unit/types/current/playback/PlaybackControllerImpl.test.js +15 -0
- package/dist/unit/types/current/streaming/MseTrack.test.js +15 -0
- package/dist/unit/types/current/tsconfig.tsbuildinfo +1 -1
- package/dist/vinylTestUtil/types/current/tsconfig.tsbuildinfo +1 -1
- package/package.json +10 -10
|
@@ -12,6 +12,12 @@ import { TrackUri } from '../track/Track';
|
|
|
12
12
|
* indicates a stalled promise result from the license provider.
|
|
13
13
|
*/
|
|
14
14
|
export declare const LICENSE_TIMEOUT = 90;
|
|
15
|
+
/**
|
|
16
|
+
* An excessive number of concurrent key sessions. Sessions are expected to be
|
|
17
|
+
* closed as tracks deactivate; a count this high signals sessions are leaking
|
|
18
|
+
* (never closing) rather than a legitimate playback need.
|
|
19
|
+
*/
|
|
20
|
+
export declare const EXCESSIVE_SESSION_COUNT = 20;
|
|
15
21
|
/**
|
|
16
22
|
* Dependencies for creating DrmController.
|
|
17
23
|
*/
|
|
@@ -63,12 +63,11 @@ export declare class PlaybackControllerImpl extends EventHostImpl<PlaybackContro
|
|
|
63
63
|
private _playing;
|
|
64
64
|
private _seeking;
|
|
65
65
|
private _waiting;
|
|
66
|
-
private
|
|
66
|
+
private readonly seekAbortSlot;
|
|
67
67
|
private stopStallDetection;
|
|
68
68
|
private userVolume;
|
|
69
69
|
private _pendingPlay;
|
|
70
70
|
private playAbort;
|
|
71
|
-
private disposeAbort;
|
|
72
71
|
readonly options: PlaybackControllerImplOptions;
|
|
73
72
|
constructor(deps: PlaybackControllerImplDeps, options?: Partial<PlaybackControllerImplOptions>);
|
|
74
73
|
/**
|
|
@@ -174,6 +173,13 @@ export declare class PlaybackControllerImpl extends EventHostImpl<PlaybackContro
|
|
|
174
173
|
get hasMetadata(): boolean;
|
|
175
174
|
get playIsPending(): boolean;
|
|
176
175
|
seekTo(time: number, tolerance?: number): Promise<void>;
|
|
176
|
+
/**
|
|
177
|
+
* The body of a single {@link seekTo} attempt. Extracted so {@link seekTo}
|
|
178
|
+
* can wrap it with per-seek abort/supersession handling. `seekAbort` is
|
|
179
|
+
* aborted when a newer seek supersedes this one (or on dispose).
|
|
180
|
+
* @private
|
|
181
|
+
*/
|
|
182
|
+
private doSeek;
|
|
177
183
|
/**
|
|
178
184
|
* Dispatches a readyStateChange event when {@link readyState} changes.
|
|
179
185
|
* @private
|
|
@@ -45,7 +45,6 @@ export declare class MseTrack extends TrackBase {
|
|
|
45
45
|
protected readonly deps: MseTrackDeps;
|
|
46
46
|
get textTrackController(): (TextTrackController | null);
|
|
47
47
|
private readonly streams;
|
|
48
|
-
private readonly disposeAbort;
|
|
49
48
|
private lastPreloadOptions;
|
|
50
49
|
private readonly allFetchedRanges;
|
|
51
50
|
private readonly _fetchedRanges;
|
|
@@ -13,6 +13,12 @@ import type { TrackUri } from '../track/Track';
|
|
|
13
13
|
* indicates a stalled promise result from the license provider.
|
|
14
14
|
*/
|
|
15
15
|
export declare const LICENSE_TIMEOUT = 90;
|
|
16
|
+
/**
|
|
17
|
+
* An excessive number of concurrent key sessions. Sessions are expected to be
|
|
18
|
+
* closed as tracks deactivate; a count this high signals sessions are leaking
|
|
19
|
+
* (never closing) rather than a legitimate playback need.
|
|
20
|
+
*/
|
|
21
|
+
export declare const EXCESSIVE_SESSION_COUNT = 20;
|
|
16
22
|
/**
|
|
17
23
|
* Dependencies for creating DrmController.
|
|
18
24
|
*/
|
|
@@ -65,12 +65,11 @@ export declare class PlaybackControllerImpl extends EventHostImpl<PlaybackContro
|
|
|
65
65
|
private _playing;
|
|
66
66
|
private _seeking;
|
|
67
67
|
private _waiting;
|
|
68
|
-
private
|
|
68
|
+
private readonly seekAbortSlot;
|
|
69
69
|
private stopStallDetection;
|
|
70
70
|
private userVolume;
|
|
71
71
|
private _pendingPlay;
|
|
72
72
|
private playAbort;
|
|
73
|
-
private disposeAbort;
|
|
74
73
|
readonly options: PlaybackControllerImplOptions;
|
|
75
74
|
constructor(deps: PlaybackControllerImplDeps, options?: Partial<PlaybackControllerImplOptions>);
|
|
76
75
|
/**
|
|
@@ -176,6 +175,13 @@ export declare class PlaybackControllerImpl extends EventHostImpl<PlaybackContro
|
|
|
176
175
|
get hasMetadata(): boolean;
|
|
177
176
|
get playIsPending(): boolean;
|
|
178
177
|
seekTo(time: number, tolerance?: number): Promise<void>;
|
|
178
|
+
/**
|
|
179
|
+
* The body of a single {@link seekTo} attempt. Extracted so {@link seekTo}
|
|
180
|
+
* can wrap it with per-seek abort/supersession handling. `seekAbort` is
|
|
181
|
+
* aborted when a newer seek supersedes this one (or on dispose).
|
|
182
|
+
* @private
|
|
183
|
+
*/
|
|
184
|
+
private doSeek;
|
|
179
185
|
/**
|
|
180
186
|
* Dispatches a readyStateChange event when {@link readyState} changes.
|
|
181
187
|
* @private
|
|
@@ -46,7 +46,6 @@ export declare class MseTrack extends TrackBase {
|
|
|
46
46
|
protected readonly deps: MseTrackDeps;
|
|
47
47
|
get textTrackController(): (TextTrackController | null);
|
|
48
48
|
private readonly streams;
|
|
49
|
-
private readonly disposeAbort;
|
|
50
49
|
private lastPreloadOptions;
|
|
51
50
|
private readonly allFetchedRanges;
|
|
52
51
|
private readonly _fetchedRanges;
|
|
@@ -12,6 +12,12 @@ import type { TrackUri } from '../track/Track';
|
|
|
12
12
|
* indicates a stalled promise result from the license provider.
|
|
13
13
|
*/
|
|
14
14
|
export declare const LICENSE_TIMEOUT = 90;
|
|
15
|
+
/**
|
|
16
|
+
* An excessive number of concurrent key sessions. Sessions are expected to be
|
|
17
|
+
* closed as tracks deactivate; a count this high signals sessions are leaking
|
|
18
|
+
* (never closing) rather than a legitimate playback need.
|
|
19
|
+
*/
|
|
20
|
+
export declare const EXCESSIVE_SESSION_COUNT = 20;
|
|
15
21
|
/**
|
|
16
22
|
* Dependencies for creating DrmController.
|
|
17
23
|
*/
|
|
@@ -63,12 +63,11 @@ export declare class PlaybackControllerImpl extends EventHostImpl<PlaybackContro
|
|
|
63
63
|
private _playing;
|
|
64
64
|
private _seeking;
|
|
65
65
|
private _waiting;
|
|
66
|
-
private
|
|
66
|
+
private readonly seekAbortSlot;
|
|
67
67
|
private stopStallDetection;
|
|
68
68
|
private userVolume;
|
|
69
69
|
private _pendingPlay;
|
|
70
70
|
private playAbort;
|
|
71
|
-
private disposeAbort;
|
|
72
71
|
readonly options: PlaybackControllerImplOptions;
|
|
73
72
|
constructor(deps: PlaybackControllerImplDeps, options?: Partial<PlaybackControllerImplOptions>);
|
|
74
73
|
/**
|
|
@@ -174,6 +173,13 @@ export declare class PlaybackControllerImpl extends EventHostImpl<PlaybackContro
|
|
|
174
173
|
get hasMetadata(): boolean;
|
|
175
174
|
get playIsPending(): boolean;
|
|
176
175
|
seekTo(time: number, tolerance?: number): Promise<void>;
|
|
176
|
+
/**
|
|
177
|
+
* The body of a single {@link seekTo} attempt. Extracted so {@link seekTo}
|
|
178
|
+
* can wrap it with per-seek abort/supersession handling. `seekAbort` is
|
|
179
|
+
* aborted when a newer seek supersedes this one (or on dispose).
|
|
180
|
+
* @private
|
|
181
|
+
*/
|
|
182
|
+
private doSeek;
|
|
177
183
|
/**
|
|
178
184
|
* Dispatches a readyStateChange event when {@link readyState} changes.
|
|
179
185
|
* @private
|
|
@@ -45,7 +45,6 @@ export declare class MseTrack extends TrackBase {
|
|
|
45
45
|
protected readonly deps: MseTrackDeps;
|
|
46
46
|
get textTrackController(): TextTrackController | null;
|
|
47
47
|
private readonly streams;
|
|
48
|
-
private readonly disposeAbort;
|
|
49
48
|
private lastPreloadOptions;
|
|
50
49
|
private readonly allFetchedRanges;
|
|
51
50
|
private readonly _fetchedRanges;
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
3
3
|
* SPDX-License-Identifier: Apache-2.0
|
|
4
4
|
*/
|
|
5
|
-
import { createEmptyMediaQualityMetadata, DrmControllerImpl, DrmError, DrmKeySystem, DrmRobustness, LICENSE_TIMEOUT, ReportableMediaError, } from '@amazon/vinyl';
|
|
5
|
+
import { createEmptyMediaQualityMetadata, DrmControllerImpl, DrmError, DrmKeySystem, DrmRobustness, EXCESSIVE_SESSION_COUNT, LICENSE_TIMEOUT, ReportableMediaError, } from '@amazon/vinyl';
|
|
6
6
|
import { createEventSpy, useMockLogger } from '@amazon/vinyl-util/testUtil';
|
|
7
7
|
import { Abort, base64ToByteArray, bufferToBase64, Deferred, ErrorLevel, ErrorOrigin, never, nextEventAsPromise, ReportableError, setUserAgent, utf16ToUint16Array, } from '@amazon/vinyl-util';
|
|
8
8
|
import { flushPromises, implementEventFakes, MockHTMLAudioElement, MockMediaError, useMockTime, } from '@amazon/vinyl-util/browserTestUtil';
|
|
@@ -1321,6 +1321,24 @@ describe('DrmControllerImpl', () => {
|
|
|
1321
1321
|
expect(drmController.isEmeSupported()).toBeFalse();
|
|
1322
1322
|
});
|
|
1323
1323
|
});
|
|
1324
|
+
describe('excessive sessions', () => {
|
|
1325
|
+
it('warns once when the open session count exceeds the threshold', async () => {
|
|
1326
|
+
drmController.setBufferingDrmInfo(drmInfo);
|
|
1327
|
+
// Distinct init data per event so each opens its own session.
|
|
1328
|
+
for (let i = 0; i < EXCESSIVE_SESSION_COUNT; i++) {
|
|
1329
|
+
await emitEncrypted(new Uint8Array([i]));
|
|
1330
|
+
}
|
|
1331
|
+
expect(drmController.activeSessions).toBe(EXCESSIVE_SESSION_COUNT);
|
|
1332
|
+
expect(logger.value.warn).not.toHaveBeenCalled();
|
|
1333
|
+
// Crossing the threshold warns.
|
|
1334
|
+
await emitEncrypted(new Uint8Array([EXCESSIVE_SESSION_COUNT]));
|
|
1335
|
+
expect(drmController.activeSessions).toBe(EXCESSIVE_SESSION_COUNT + 1);
|
|
1336
|
+
expect(logger.value.warn).toHaveBeenCalledTimes(1);
|
|
1337
|
+
// Further sessions past the threshold don't re-warn.
|
|
1338
|
+
await emitEncrypted(new Uint8Array([EXCESSIVE_SESSION_COUNT + 1]));
|
|
1339
|
+
expect(logger.value.warn).toHaveBeenCalledTimes(1);
|
|
1340
|
+
});
|
|
1341
|
+
});
|
|
1324
1342
|
describe('closeSessions', () => {
|
|
1325
1343
|
it('clears active sessions', async () => {
|
|
1326
1344
|
const sessionCloseSpy = createEventSpy(drmController, 'sessionClose');
|
|
@@ -496,6 +496,21 @@ describe('PlaybackController', () => {
|
|
|
496
496
|
await clock.tick(controller.options.seekTimeout);
|
|
497
497
|
await seekExpectation;
|
|
498
498
|
});
|
|
499
|
+
it('resolves a superseded seek at once when its seeking event never fires', async () => {
|
|
500
|
+
// A source swap can leave the original seek's `seeking`
|
|
501
|
+
// event unfired (the default mock never emits it). A newer
|
|
502
|
+
// seek supersedes it; the stale one must resolve immediately
|
|
503
|
+
// rather than hang for the full seekTimeout.
|
|
504
|
+
setSeekable([[0, 100]]);
|
|
505
|
+
const first = controller.seekTo(50);
|
|
506
|
+
const second = controller.seekTo(60);
|
|
507
|
+
// No clock tick: the newer seek's abort resolves `first` now.
|
|
508
|
+
// (A full-timeout hang would require clock.tick(seekTimeout).)
|
|
509
|
+
await expectAsync(first).toBeResolved();
|
|
510
|
+
// `second`'s own `seeking` never fires either; park its
|
|
511
|
+
// rejection (settled on dispose) so it isn't unhandled.
|
|
512
|
+
second.catch(() => undefined);
|
|
513
|
+
});
|
|
499
514
|
it('times out pending seeks after seekTimeout', async () => {
|
|
500
515
|
const pendingSeekExpectation = expectAsync(controller.seekTo(60)).toBeRejectedWithError('seek timed out on seeking event after 30s');
|
|
501
516
|
setSeekable([[0, 100]]);
|
|
@@ -224,6 +224,21 @@ describe('MseTrack', () => {
|
|
|
224
224
|
abort: any(Abort),
|
|
225
225
|
});
|
|
226
226
|
});
|
|
227
|
+
it('aborts the drm session abort so key sessions close', async () => {
|
|
228
|
+
// Regression: MSE key sessions must be tied to the per-activation
|
|
229
|
+
// drmSessionAbort (fired by closeDrmSessions on deactivate), not a
|
|
230
|
+
// separate abort that never fires — otherwise sessions leak.
|
|
231
|
+
track = createTrack();
|
|
232
|
+
await awaitContentTypes();
|
|
233
|
+
getAudioStream().streamingQuality =
|
|
234
|
+
createEmptyMediaQualityMetadata();
|
|
235
|
+
track.activate({});
|
|
236
|
+
const { abort } = deps.drmController.initializeForPlayback.calls.mostRecent()
|
|
237
|
+
.args[1];
|
|
238
|
+
expect(abort.aborted()).toBeFalse();
|
|
239
|
+
track.deactivate();
|
|
240
|
+
expect(abort.aborted()).toBeTrue();
|
|
241
|
+
});
|
|
227
242
|
});
|
|
228
243
|
describe('error', () => {
|
|
229
244
|
it('returns the first emitted error', async () => {
|