@amazon/vinyl 3.1.0 → 3.2.1
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 +236 -187
- package/dist/index.cjs.map +4 -4
- package/dist/index.js +224 -174
- package/dist/index.js.map +4 -4
- package/dist/test/integ.es5.js +245 -231
- package/dist/test/integ.js +676 -271
- package/dist/test/integ.js.map +4 -4
- package/dist/types/current/ad/AdControllerImpl.d.ts +18 -2
- package/dist/types/current/ad/AdControllerImpl.d.ts.map +1 -1
- package/dist/types/current/ad/AdControllerImpl.js +42 -20
- package/dist/types/current/drm/DrmControllerImpl.d.ts +17 -1
- package/dist/types/current/drm/DrmControllerImpl.d.ts.map +1 -1
- package/dist/types/current/drm/DrmControllerImpl.js +45 -10
- package/dist/types/current/playback/createStallMonitor.d.ts.map +1 -1
- package/dist/types/current/playback/createStallMonitor.js +19 -14
- 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/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/track/filters/sampleRateFilter.d.ts +8 -4
- package/dist/types/current/track/filters/sampleRateFilter.d.ts.map +1 -1
- package/dist/types/current/track/filters/sampleRateFilter.js +31 -21
- package/dist/types/current/track/mse/MseTrack.d.ts +0 -9
- package/dist/types/current/track/mse/MseTrack.d.ts.map +1 -1
- package/dist/types/current/track/mse/MseTrack.js +2 -29
- package/dist/types/current/tsconfig.tsbuildinfo +1 -1
- 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/ts3.7/ad/AdControllerImpl.d.ts +18 -2
- package/dist/types/ts3.7/drm/DrmControllerImpl.d.ts +17 -1
- package/dist/types/ts3.7/streaming/LoadMetric.d.ts +15 -1
- package/dist/types/ts3.7/streaming/mediaTimelineFilter.d.ts +4 -2
- package/dist/types/ts3.7/track/filters/sampleRateFilter.d.ts +8 -4
- package/dist/types/ts3.7/track/mse/MseTrack.d.ts +0 -9
- package/dist/types/ts3.7/vinyl/VinylPlayer.d.ts +5 -0
- package/dist/types/ts4.1/ad/AdControllerImpl.d.ts +18 -2
- package/dist/types/ts4.1/drm/DrmControllerImpl.d.ts +17 -1
- package/dist/types/ts4.1/streaming/LoadMetric.d.ts +15 -1
- package/dist/types/ts4.1/streaming/mediaTimelineFilter.d.ts +4 -2
- package/dist/types/ts4.1/track/filters/sampleRateFilter.d.ts +8 -4
- package/dist/types/ts4.1/track/mse/MseTrack.d.ts +0 -9
- package/dist/types/ts4.1/vinyl/VinylPlayer.d.ts +5 -0
- package/dist/types/ts4.7/ad/AdControllerImpl.d.ts +18 -2
- package/dist/types/ts4.7/drm/DrmControllerImpl.d.ts +17 -1
- package/dist/types/ts4.7/streaming/LoadMetric.d.ts +15 -1
- package/dist/types/ts4.7/streaming/mediaTimelineFilter.d.ts +4 -2
- package/dist/types/ts4.7/track/filters/sampleRateFilter.d.ts +8 -4
- package/dist/types/ts4.7/track/mse/MseTrack.d.ts +0 -9
- package/dist/types/ts4.7/vinyl/VinylPlayer.d.ts +5 -0
- package/dist/unit/types/current/ad/AdControllerImpl.test.js +110 -4
- package/dist/unit/types/current/drm/DrmControllerImpl.test.js +53 -9
- package/dist/unit/types/current/playback/createStallMonitor.test.js +38 -0
- package/dist/unit/types/current/streaming/MseTrack.test.js +11 -8
- package/dist/unit/types/current/streaming/mediaTimelineFilter.test.js +60 -54
- package/dist/unit/types/current/track/filters/sampleRateFilter.test.js +75 -0
- package/dist/unit/types/current/tsconfig.tsbuildinfo +1 -1
- package/dist/unit/types/current/vinyl/VinylPlayer.test.js +33 -2
- package/dist/vinylTestUtil/index.js +10 -1
- package/dist/vinylTestUtil/index.js.map +2 -2
- package/dist/vinylTestUtil/types/current/assets/vinylTestAssets.d.ts +5 -0
- package/dist/vinylTestUtil/types/current/assets/vinylTestAssets.d.ts.map +1 -1
- package/dist/vinylTestUtil/types/current/assets/vinylTestAssets.js +9 -0
- package/dist/vinylTestUtil/types/current/tsconfig.tsbuildinfo +1 -1
- package/dist/vinylTestUtil/types/ts3.7/assets/vinylTestAssets.d.ts +5 -0
- package/dist/vinylTestUtil/types/ts4.1/assets/vinylTestAssets.d.ts +5 -0
- package/dist/vinylTestUtil/types/ts4.7/assets/vinylTestAssets.d.ts +5 -0
- package/package.json +10 -10
package/dist/index.js
CHANGED
|
@@ -68,6 +68,7 @@ var AdError = class _AdError extends ReportableError {
|
|
|
68
68
|
|
|
69
69
|
// src/ad/AdControllerImpl.ts
|
|
70
70
|
var AD_START_TOLERANCE = 0.05;
|
|
71
|
+
var PLAYOUT_LIMIT_TOLERANCE = 1;
|
|
71
72
|
var defaultAdControllerImplOptions = {
|
|
72
73
|
adLoadTimeout: 15,
|
|
73
74
|
preloadAheadTime: 10
|
|
@@ -558,23 +559,29 @@ var AdControllerImpl = class extends EventHostImpl {
|
|
|
558
559
|
});
|
|
559
560
|
}
|
|
560
561
|
/**
|
|
561
|
-
*
|
|
562
|
-
*
|
|
562
|
+
* Enforces the break-level playout limit (X-PLAYOUT-LIMIT): a budget shared
|
|
563
|
+
* across all of the break's ads. When cumulative playout reaches it, the
|
|
564
|
+
* whole break ends, dropping any ads that have not started.
|
|
565
|
+
*
|
|
566
|
+
* This is deliberately NOT a per-ad cap. Each ad asset is its own source and
|
|
567
|
+
* ends on its media `ended` (see the 'ended' handler), which is what advances
|
|
568
|
+
* a multi-ad break. Ending an ad at its declared per-ad DURATION instead would
|
|
569
|
+
* truncate the real asset whenever a packager under-declares it — e.g. rounds
|
|
570
|
+
* a 6.732s asset down to a whole-second 6 — cutting off the fractional tail.
|
|
563
571
|
*/
|
|
564
572
|
enforcePlayoutLimits(adState) {
|
|
573
|
+
if (!adState.started) return;
|
|
574
|
+
const { parentBreak } = adState;
|
|
575
|
+
const limit = parentBreak.adBreak.playoutLimit;
|
|
576
|
+
if (limit == null) return;
|
|
565
577
|
const pC = this.deps.playbackController;
|
|
566
|
-
const
|
|
567
|
-
if (
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
const limit = adBreak.playoutLimit;
|
|
571
|
-
if (limit != null && parentBreak.playoutElapsed + elapsed >= limit) {
|
|
572
|
-
parentBreak.clear();
|
|
573
|
-
this.endAd(adState);
|
|
574
|
-
} else if (ad.duration != null && elapsed >= ad.duration) {
|
|
575
|
-
this.endAd(adState);
|
|
576
|
-
}
|
|
578
|
+
const elapsed = Math.max(0, pC.currentTime - adState.timeStart);
|
|
579
|
+
if (parentBreak.playoutElapsed + elapsed < limit) return;
|
|
580
|
+
if (isFinite(pC.duration) && pC.duration > 0 && pC.duration - pC.currentTime <= PLAYOUT_LIMIT_TOLERANCE) {
|
|
581
|
+
return;
|
|
577
582
|
}
|
|
583
|
+
parentBreak.clear();
|
|
584
|
+
this.endAd(adState);
|
|
578
585
|
}
|
|
579
586
|
setPendingBreaks(newPending) {
|
|
580
587
|
this.pendingAdBreaks = newPending.filter(
|
|
@@ -1892,6 +1899,10 @@ var DrmControllerImpl = class extends EventHostImpl5 {
|
|
|
1892
1899
|
__publicField(this, "bufferingTrackUri", null);
|
|
1893
1900
|
__publicField(this, "sessionAbort", null);
|
|
1894
1901
|
__publicField(this, "pendingMessageProps", null);
|
|
1902
|
+
// Armed per track load; latches on the first session so only the
|
|
1903
|
+
// critical-path session's EME/CDM setup is measured.
|
|
1904
|
+
__publicField(this, "keySetupSpanArmed", true);
|
|
1905
|
+
__publicField(this, "keySetupSpanStart", null);
|
|
1895
1906
|
__publicField(this, "disposer", /* @__PURE__ */ createDisposer2());
|
|
1896
1907
|
__publicField(this, "checkIsSupportedCached", /* @__PURE__ */ memoize4(
|
|
1897
1908
|
async (params) => {
|
|
@@ -2057,6 +2068,7 @@ var DrmControllerImpl = class extends EventHostImpl5 {
|
|
|
2057
2068
|
if (!hasMimeType(drmInfo)) {
|
|
2058
2069
|
throw new DrmError("Encrypted content must have a mimeType.");
|
|
2059
2070
|
}
|
|
2071
|
+
this.markKeySetupStart();
|
|
2060
2072
|
const mediaKeys = await this.attachMediaKeys(drmInfo);
|
|
2061
2073
|
this.abortIfDisposed();
|
|
2062
2074
|
const keySystemOptions = (_a = this.options.keySystems[mediaKeys.keySystem]) != null ? _a : this.options.keySystems["*"];
|
|
@@ -2101,6 +2113,28 @@ var DrmControllerImpl = class extends EventHostImpl5 {
|
|
|
2101
2113
|
});
|
|
2102
2114
|
return newSession;
|
|
2103
2115
|
}
|
|
2116
|
+
/**
|
|
2117
|
+
* Captures the key-setup span start at the top of the session-creation path
|
|
2118
|
+
* (before media keys are attached), latching so only the first session of
|
|
2119
|
+
* the current track load is measured.
|
|
2120
|
+
*/
|
|
2121
|
+
markKeySetupStart() {
|
|
2122
|
+
if (!this.keySetupSpanArmed) return;
|
|
2123
|
+
this.keySetupSpanArmed = false;
|
|
2124
|
+
this.keySetupSpanStart = Date.now();
|
|
2125
|
+
}
|
|
2126
|
+
dispatchLoadSpan(kind, startTime, endTime, messageProps) {
|
|
2127
|
+
this.dispatch("loadSpanMeasured", __spreadValues(__spreadValues({
|
|
2128
|
+
kind,
|
|
2129
|
+
startTime,
|
|
2130
|
+
endTime,
|
|
2131
|
+
mimeType: messageProps.mimeType
|
|
2132
|
+
}, messageProps.trackUri != null && {
|
|
2133
|
+
trackUri: messageProps.trackUri
|
|
2134
|
+
}), messageProps.contentType != null && {
|
|
2135
|
+
contentType: messageProps.contentType
|
|
2136
|
+
}));
|
|
2137
|
+
}
|
|
2104
2138
|
initializeForPlayback(drmInfo, options) {
|
|
2105
2139
|
var _a;
|
|
2106
2140
|
logDebug3(this, "initializeForPlayback", drmInfo);
|
|
@@ -2124,6 +2158,8 @@ var DrmControllerImpl = class extends EventHostImpl5 {
|
|
|
2124
2158
|
this.drmInfo = drmInfo;
|
|
2125
2159
|
this.bufferingTrackUri = (_a = options == null ? void 0 : options.trackUri) != null ? _a : null;
|
|
2126
2160
|
this.sessionAbort = (_b = options == null ? void 0 : options.abort) != null ? _b : null;
|
|
2161
|
+
this.keySetupSpanArmed = true;
|
|
2162
|
+
this.keySetupSpanStart = null;
|
|
2127
2163
|
}
|
|
2128
2164
|
/**
|
|
2129
2165
|
* If the drm metadata contains initialization data for the current key system, create a new session.
|
|
@@ -2135,6 +2171,7 @@ var DrmControllerImpl = class extends EventHostImpl5 {
|
|
|
2135
2171
|
this.handleError(new DrmError("DRM not supported."));
|
|
2136
2172
|
return;
|
|
2137
2173
|
}
|
|
2174
|
+
this.markKeySetupStart();
|
|
2138
2175
|
const mediaKeys = await this.attachMediaKeys(drmInfo);
|
|
2139
2176
|
const drmProtection = (_a = drmInfo.contentProtections.find((cP) => {
|
|
2140
2177
|
return cP.keySystem === mediaKeys.keySystem;
|
|
@@ -2273,7 +2310,9 @@ var DrmControllerImpl = class extends EventHostImpl5 {
|
|
|
2273
2310
|
event,
|
|
2274
2311
|
// Captured per session, so a concurrent preloaded track's
|
|
2275
2312
|
// license exchange keeps its own attribution.
|
|
2276
|
-
trackUri
|
|
2313
|
+
trackUri,
|
|
2314
|
+
mimeType: drmInfo.mimeType,
|
|
2315
|
+
contentType: drmInfo.contentType
|
|
2277
2316
|
}),
|
|
2278
2317
|
LICENSE_TIMEOUT,
|
|
2279
2318
|
{ message: LICENSE_TIMEOUT_MESSAGE }
|
|
@@ -2295,6 +2334,15 @@ var DrmControllerImpl = class extends EventHostImpl5 {
|
|
|
2295
2334
|
this.pendingMessageProps = messageProps;
|
|
2296
2335
|
const keySystem = mediaKeys.keySystem;
|
|
2297
2336
|
logDebug3(this, "message", keySystem, event.message.byteLength);
|
|
2337
|
+
if (this.keySetupSpanStart != null) {
|
|
2338
|
+
this.dispatchLoadSpan(
|
|
2339
|
+
"keySetup",
|
|
2340
|
+
this.keySetupSpanStart,
|
|
2341
|
+
Date.now(),
|
|
2342
|
+
messageProps
|
|
2343
|
+
);
|
|
2344
|
+
this.keySetupSpanStart = null;
|
|
2345
|
+
}
|
|
2298
2346
|
const keySystemOptions = (_a = this.options.keySystems[keySystem]) != null ? _a : this.options.keySystems["*"];
|
|
2299
2347
|
const licenseServerOptionsProvider = keySystemOptions == null ? void 0 : keySystemOptions.licenseServer;
|
|
2300
2348
|
const licenseServerOptions = (_b = clone(await resolveValueProvider2(licenseServerOptionsProvider))) != null ? _b : {};
|
|
@@ -2316,13 +2364,12 @@ var DrmControllerImpl = class extends EventHostImpl5 {
|
|
|
2316
2364
|
challenge
|
|
2317
2365
|
);
|
|
2318
2366
|
if (this.disposed) return;
|
|
2319
|
-
this.
|
|
2320
|
-
|
|
2321
|
-
|
|
2322
|
-
|
|
2323
|
-
|
|
2324
|
-
|
|
2325
|
-
}));
|
|
2367
|
+
this.dispatchLoadSpan(
|
|
2368
|
+
"license",
|
|
2369
|
+
licenseSpanStart,
|
|
2370
|
+
Date.now(),
|
|
2371
|
+
messageProps
|
|
2372
|
+
);
|
|
2326
2373
|
this.pendingMessageProps = null;
|
|
2327
2374
|
if (session.disposed) return;
|
|
2328
2375
|
logDebug3(this, "update");
|
|
@@ -2581,7 +2628,7 @@ function configureVinylGlobal(options) {
|
|
|
2581
2628
|
import { parseVersion } from "@amazon/vinyl-util";
|
|
2582
2629
|
var vinylVersion = /* @__PURE__ */ parseVersion(
|
|
2583
2630
|
/* istanbul ignore next */
|
|
2584
|
-
"3.1
|
|
2631
|
+
"3.2.1"
|
|
2585
2632
|
);
|
|
2586
2633
|
|
|
2587
2634
|
// src/global/globalRef.ts
|
|
@@ -2786,6 +2833,7 @@ var PlaybackNetworkState = /* @__PURE__ */ ((PlaybackNetworkState2) => {
|
|
|
2786
2833
|
})(PlaybackNetworkState || {});
|
|
2787
2834
|
|
|
2788
2835
|
// src/playback/createStallMonitor.ts
|
|
2836
|
+
var PROGRESS_EPSILON = 1e-6;
|
|
2789
2837
|
function createStallMonitor(controller, callbacks, options = {}) {
|
|
2790
2838
|
var _a, _b;
|
|
2791
2839
|
const stallThresholdMs = ((_a = options.stallThreshold) != null ? _a : 1) * 1e3;
|
|
@@ -2794,6 +2842,7 @@ function createStallMonitor(controller, callbacks, options = {}) {
|
|
|
2794
2842
|
let lastProgressAt = Date.now();
|
|
2795
2843
|
let inStall = false;
|
|
2796
2844
|
let pollId = null;
|
|
2845
|
+
const { add, dispose } = createDisposer3();
|
|
2797
2846
|
const endStall = (reason) => {
|
|
2798
2847
|
if (!inStall) return;
|
|
2799
2848
|
inStall = false;
|
|
@@ -2810,6 +2859,7 @@ function createStallMonitor(controller, callbacks, options = {}) {
|
|
|
2810
2859
|
clearInterval(pollId);
|
|
2811
2860
|
pollId = null;
|
|
2812
2861
|
};
|
|
2862
|
+
add(stopPoll);
|
|
2813
2863
|
const startPoll = () => {
|
|
2814
2864
|
if (pollId != null) return;
|
|
2815
2865
|
pollId = setInterval(() => {
|
|
@@ -2825,17 +2875,18 @@ function createStallMonitor(controller, callbacks, options = {}) {
|
|
|
2825
2875
|
observedPlaying = false;
|
|
2826
2876
|
stopPoll();
|
|
2827
2877
|
};
|
|
2828
|
-
const { add, dispose } = createDisposer3();
|
|
2829
2878
|
add(
|
|
2830
2879
|
controller.on("playing", () => {
|
|
2831
2880
|
if (inStall) endStall("playing" /* PLAYING */);
|
|
2832
|
-
|
|
2881
|
+
lastProgressAt = Date.now();
|
|
2833
2882
|
observedPlaying = true;
|
|
2834
2883
|
startPoll();
|
|
2835
2884
|
})
|
|
2836
2885
|
);
|
|
2837
2886
|
add(
|
|
2838
|
-
controller.on("timeUpdate", () => {
|
|
2887
|
+
controller.on("timeUpdate", ({ previous, current }) => {
|
|
2888
|
+
if (previous != null && current - previous <= PROGRESS_EPSILON)
|
|
2889
|
+
return;
|
|
2839
2890
|
if (inStall) endStall("playing" /* PLAYING */);
|
|
2840
2891
|
lastProgressAt = Date.now();
|
|
2841
2892
|
})
|
|
@@ -2843,13 +2894,7 @@ function createStallMonitor(controller, callbacks, options = {}) {
|
|
|
2843
2894
|
add(controller.on("pause", () => suspend("pause" /* PAUSE */)));
|
|
2844
2895
|
add(controller.on("seeking", () => suspend("seeking" /* SEEKING */)));
|
|
2845
2896
|
add(controller.on("emptied", () => suspend("emptied" /* EMPTIED */)));
|
|
2846
|
-
|
|
2847
|
-
return () => {
|
|
2848
|
-
if (stopped) return;
|
|
2849
|
-
stopped = true;
|
|
2850
|
-
stopPoll();
|
|
2851
|
-
dispose();
|
|
2852
|
-
};
|
|
2897
|
+
return dispose;
|
|
2853
2898
|
}
|
|
2854
2899
|
|
|
2855
2900
|
// src/playback/error/InvalidSeekError.ts
|
|
@@ -5013,6 +5058,107 @@ function filterContentTypes(contentTypes, allowedContentTypes) {
|
|
|
5013
5058
|
// src/streaming/createDefaultMediaTimelineTransformer.ts
|
|
5014
5059
|
import { combineData as combineData2 } from "@amazon/vinyl-observable";
|
|
5015
5060
|
|
|
5061
|
+
// src/streaming/MediaQualityMetadata.ts
|
|
5062
|
+
import {
|
|
5063
|
+
createShortUid
|
|
5064
|
+
} from "@amazon/vinyl-util";
|
|
5065
|
+
import {
|
|
5066
|
+
array as array3,
|
|
5067
|
+
enumOf as enumOf3,
|
|
5068
|
+
isOneOf as isOneOf3,
|
|
5069
|
+
number as number6,
|
|
5070
|
+
object as object9,
|
|
5071
|
+
string as string6,
|
|
5072
|
+
tuple
|
|
5073
|
+
} from "@amazon/vinyl-validation";
|
|
5074
|
+
|
|
5075
|
+
// src/streaming/DescriptorRecord.ts
|
|
5076
|
+
import {
|
|
5077
|
+
array as array2,
|
|
5078
|
+
object as object8,
|
|
5079
|
+
record as record2,
|
|
5080
|
+
string as string5
|
|
5081
|
+
} from "@amazon/vinyl-validation";
|
|
5082
|
+
import { first } from "@amazon/vinyl-util";
|
|
5083
|
+
function getDescriptorValue(record4, uri, id) {
|
|
5084
|
+
var _a, _b;
|
|
5085
|
+
let arr = record4[uri];
|
|
5086
|
+
if (!arr) return null;
|
|
5087
|
+
if (id !== void 0) arr = arr.filter((descriptor) => descriptor.id === id);
|
|
5088
|
+
return (_b = (_a = first(arr)) == null ? void 0 : _a.value) != null ? _b : null;
|
|
5089
|
+
}
|
|
5090
|
+
var descriptorValidator = /* @__PURE__ */ object8({
|
|
5091
|
+
id: /* @__PURE__ */ string5().maybe().optional(),
|
|
5092
|
+
value: /* @__PURE__ */ string5().maybe().optional()
|
|
5093
|
+
});
|
|
5094
|
+
var descriptorRecordValidator = /* @__PURE__ */ record2(/* @__PURE__ */ string5(), /* @__PURE__ */ array2(descriptorValidator).readonly().orUndefined());
|
|
5095
|
+
|
|
5096
|
+
// src/streaming/MediaQualityMetadata.ts
|
|
5097
|
+
var ALL_CONTENT_TYPES = [
|
|
5098
|
+
"video",
|
|
5099
|
+
"audio",
|
|
5100
|
+
"text"
|
|
5101
|
+
];
|
|
5102
|
+
var RESTRICTABLE_CONTENT_TYPES = [
|
|
5103
|
+
"video",
|
|
5104
|
+
"audio"
|
|
5105
|
+
];
|
|
5106
|
+
var drmProtectionValidator = /* @__PURE__ */ descriptorValidator.extend({
|
|
5107
|
+
keySystem: /* @__PURE__ */ enumOf3(DrmKeySystem),
|
|
5108
|
+
pro: /* @__PURE__ */ string6().maybe().optional(),
|
|
5109
|
+
pssh: /* @__PURE__ */ string6().maybe().optional()
|
|
5110
|
+
});
|
|
5111
|
+
var mediaFormatMetadataValidator = /* @__PURE__ */ object9({
|
|
5112
|
+
contentProtections: /* @__PURE__ */ array3(drmProtectionValidator).readonly(),
|
|
5113
|
+
contentType: /* @__PURE__ */ isOneOf3("audio", "video", "text").orNull(),
|
|
5114
|
+
initDataType: /* @__PURE__ */ string6().orNull(),
|
|
5115
|
+
encryptionScheme: /* @__PURE__ */ string6().orNull(),
|
|
5116
|
+
mimeType: /* @__PURE__ */ string6().orNull()
|
|
5117
|
+
});
|
|
5118
|
+
function createEmptyMediaFormatMetadata() {
|
|
5119
|
+
return {
|
|
5120
|
+
contentType: null,
|
|
5121
|
+
mimeType: null,
|
|
5122
|
+
initDataType: null,
|
|
5123
|
+
encryptionScheme: null,
|
|
5124
|
+
contentProtections: []
|
|
5125
|
+
};
|
|
5126
|
+
}
|
|
5127
|
+
function createEmptyMediaQualityMetadata() {
|
|
5128
|
+
return __spreadProps(__spreadValues({}, createEmptyMediaFormatMetadata()), {
|
|
5129
|
+
decoderId: createShortUid(),
|
|
5130
|
+
qualityId: createShortUid(),
|
|
5131
|
+
codecs: null,
|
|
5132
|
+
bandwidth: null,
|
|
5133
|
+
bandwidthTotal: null,
|
|
5134
|
+
supplementalProperties: {},
|
|
5135
|
+
audioSamplingRate: null,
|
|
5136
|
+
frameRate: null,
|
|
5137
|
+
height: null,
|
|
5138
|
+
width: null,
|
|
5139
|
+
lang: null,
|
|
5140
|
+
characteristics: [],
|
|
5141
|
+
groupId: createShortUid(),
|
|
5142
|
+
switchingGroupIds: null
|
|
5143
|
+
});
|
|
5144
|
+
}
|
|
5145
|
+
var mediaQualityMetadataValidator = /* @__PURE__ */ mediaFormatMetadataValidator.extend({
|
|
5146
|
+
audioSamplingRate: /* @__PURE__ */ array3(/* @__PURE__ */ number6()).readonly().orNull(),
|
|
5147
|
+
bandwidth: /* @__PURE__ */ number6().orNull(),
|
|
5148
|
+
bandwidthTotal: /* @__PURE__ */ number6().orNull(),
|
|
5149
|
+
codecs: /* @__PURE__ */ string6().orNull(),
|
|
5150
|
+
decoderId: /* @__PURE__ */ string6(),
|
|
5151
|
+
frameRate: /* @__PURE__ */ tuple(/* @__PURE__ */ number6(), /* @__PURE__ */ number6()).readonly().orNull(),
|
|
5152
|
+
height: /* @__PURE__ */ number6().orNull(),
|
|
5153
|
+
qualityId: /* @__PURE__ */ string6(),
|
|
5154
|
+
supplementalProperties: descriptorRecordValidator,
|
|
5155
|
+
width: /* @__PURE__ */ number6().orNull(),
|
|
5156
|
+
lang: /* @__PURE__ */ string6().orNull(),
|
|
5157
|
+
characteristics: /* @__PURE__ */ array3(/* @__PURE__ */ string6()).readonly(),
|
|
5158
|
+
groupId: /* @__PURE__ */ string6(),
|
|
5159
|
+
switchingGroupIds: /* @__PURE__ */ array3(/* @__PURE__ */ string6()).readonly().orNull()
|
|
5160
|
+
});
|
|
5161
|
+
|
|
5016
5162
|
// src/streaming/mediaTimelineFilter.ts
|
|
5017
5163
|
import { map, memoize as memoize6 } from "@amazon/vinyl-util";
|
|
5018
5164
|
|
|
@@ -5301,6 +5447,13 @@ function createLanguageFilter(preferredLanguage, contentType2) {
|
|
|
5301
5447
|
}
|
|
5302
5448
|
|
|
5303
5449
|
// src/streaming/mediaTimelineFilter.ts
|
|
5450
|
+
function assertMediaStreamsRetained(original, filtered, throwError) {
|
|
5451
|
+
for (const contentType2 of RESTRICTABLE_CONTENT_TYPES) {
|
|
5452
|
+
if (original.some((q) => q.metadata.contentType === contentType2) && !filtered.some((q) => q.metadata.contentType === contentType2)) {
|
|
5453
|
+
throwError();
|
|
5454
|
+
}
|
|
5455
|
+
}
|
|
5456
|
+
}
|
|
5304
5457
|
function filterTimelineQualities(filter, throwError, timeline) {
|
|
5305
5458
|
if (!filter) return timeline;
|
|
5306
5459
|
const mapMetadataArray = memoize6(
|
|
@@ -5312,11 +5465,9 @@ function filterTimelineQualities(filter, throwError, timeline) {
|
|
|
5312
5465
|
const filtered = period.qualities.filter(
|
|
5313
5466
|
(q, index) => filter(q.metadata, index, mapMetadataArray(period.qualities))
|
|
5314
5467
|
);
|
|
5468
|
+
assertMediaStreamsRetained(period.qualities, filtered, throwError);
|
|
5315
5469
|
return __spreadProps(__spreadValues({}, period), { qualities: filtered });
|
|
5316
5470
|
});
|
|
5317
|
-
if (periods.some((p) => p.qualities.length === 0)) {
|
|
5318
|
-
throwError();
|
|
5319
|
-
}
|
|
5320
5471
|
return __spreadProps(__spreadValues({}, timeline), { periods });
|
|
5321
5472
|
}
|
|
5322
5473
|
async function filterTimelineQualitiesAsync(filter, throwError, timeline) {
|
|
@@ -5334,11 +5485,9 @@ async function filterTimelineQualitiesAsync(filter, throwError, timeline) {
|
|
|
5334
5485
|
filtered.push(period.qualities[i]);
|
|
5335
5486
|
}
|
|
5336
5487
|
}
|
|
5488
|
+
assertMediaStreamsRetained(period.qualities, filtered, throwError);
|
|
5337
5489
|
periods.push(__spreadProps(__spreadValues({}, period), { qualities: filtered }));
|
|
5338
5490
|
}
|
|
5339
|
-
if (periods.some((p) => p.qualities.length === 0)) {
|
|
5340
|
-
throwError();
|
|
5341
|
-
}
|
|
5342
5491
|
return __spreadProps(__spreadValues({}, timeline), { periods });
|
|
5343
5492
|
}
|
|
5344
5493
|
|
|
@@ -5412,7 +5561,6 @@ import {
|
|
|
5412
5561
|
Browser as Browser2,
|
|
5413
5562
|
last,
|
|
5414
5563
|
MediaUnsupportedError as MediaUnsupportedError6,
|
|
5415
|
-
every,
|
|
5416
5564
|
map as map2,
|
|
5417
5565
|
max as max2,
|
|
5418
5566
|
min
|
|
@@ -5425,23 +5573,28 @@ function withinAudioSampleRateRange(options, metadata, _index, array6) {
|
|
|
5425
5573
|
if (metadata.contentType !== "audio") return true;
|
|
5426
5574
|
const samplingRate = last(metadata.audioSamplingRate);
|
|
5427
5575
|
if (!samplingRate) return true;
|
|
5576
|
+
const { minSampleRate } = options;
|
|
5577
|
+
const maxSampleRate = (_a = options.maxSampleRate) != null ? _a : options.capabilities.sampleRate;
|
|
5428
5578
|
const audioRates = () => map2(
|
|
5429
5579
|
array6,
|
|
5430
5580
|
(item) => item.contentType === "audio" ? last(item.audioSamplingRate) : void 0
|
|
5431
5581
|
).filter((rate) => rate != null);
|
|
5432
|
-
const
|
|
5582
|
+
const outOfBandFallback = () => {
|
|
5583
|
+
const rates = audioRates();
|
|
5584
|
+
const inBand = (rate) => (minSampleRate == null || rate >= minSampleRate) && (!maxSampleRate || rate <= maxSampleRate);
|
|
5585
|
+
if (rates.some(inBand)) return void 0;
|
|
5586
|
+
const decodable = maxSampleRate ? rates.filter((rate) => rate <= maxSampleRate) : rates;
|
|
5587
|
+
return decodable.length ? max2(decodable) : min(rates);
|
|
5588
|
+
};
|
|
5433
5589
|
if (minSampleRate != null && samplingRate < minSampleRate) {
|
|
5434
|
-
|
|
5435
|
-
return every(rates2, (rate) => rate < minSampleRate) && samplingRate === max2(rates2);
|
|
5590
|
+
return samplingRate === outOfBandFallback();
|
|
5436
5591
|
}
|
|
5437
|
-
const maxSampleRate = (_a = options.maxSampleRate) != null ? _a : options.capabilities.sampleRate;
|
|
5438
5592
|
if (!maxSampleRate) return true;
|
|
5439
5593
|
if (hasBrowser2(Browser2.FIREFOX)) {
|
|
5440
5594
|
return samplingRate <= 48e3;
|
|
5441
5595
|
}
|
|
5442
5596
|
if (samplingRate <= maxSampleRate) return true;
|
|
5443
|
-
|
|
5444
|
-
return every(rates, (rate) => rate > maxSampleRate) && samplingRate === min(rates);
|
|
5597
|
+
return samplingRate === outOfBandFallback();
|
|
5445
5598
|
}
|
|
5446
5599
|
|
|
5447
5600
|
// src/util/media/codecOverrides.ts
|
|
@@ -5528,27 +5681,6 @@ function createDefaultMediaTimelineTransformer(deps) {
|
|
|
5528
5681
|
});
|
|
5529
5682
|
}
|
|
5530
5683
|
|
|
5531
|
-
// src/streaming/DescriptorRecord.ts
|
|
5532
|
-
import {
|
|
5533
|
-
array as array2,
|
|
5534
|
-
object as object8,
|
|
5535
|
-
record as record2,
|
|
5536
|
-
string as string5
|
|
5537
|
-
} from "@amazon/vinyl-validation";
|
|
5538
|
-
import { first } from "@amazon/vinyl-util";
|
|
5539
|
-
function getDescriptorValue(record4, uri, id) {
|
|
5540
|
-
var _a, _b;
|
|
5541
|
-
let arr = record4[uri];
|
|
5542
|
-
if (!arr) return null;
|
|
5543
|
-
if (id !== void 0) arr = arr.filter((descriptor) => descriptor.id === id);
|
|
5544
|
-
return (_b = (_a = first(arr)) == null ? void 0 : _a.value) != null ? _b : null;
|
|
5545
|
-
}
|
|
5546
|
-
var descriptorValidator = /* @__PURE__ */ object8({
|
|
5547
|
-
id: /* @__PURE__ */ string5().maybe().optional(),
|
|
5548
|
-
value: /* @__PURE__ */ string5().maybe().optional()
|
|
5549
|
-
});
|
|
5550
|
-
var descriptorRecordValidator = /* @__PURE__ */ record2(/* @__PURE__ */ string5(), /* @__PURE__ */ array2(descriptorValidator).readonly().orUndefined());
|
|
5551
|
-
|
|
5552
5684
|
// src/streaming/ManifestControllerImpl.ts
|
|
5553
5685
|
import { data } from "@amazon/vinyl-observable";
|
|
5554
5686
|
import {
|
|
@@ -5655,84 +5787,6 @@ var ManifestControllerImpl = class {
|
|
|
5655
5787
|
}
|
|
5656
5788
|
};
|
|
5657
5789
|
|
|
5658
|
-
// src/streaming/MediaQualityMetadata.ts
|
|
5659
|
-
import {
|
|
5660
|
-
createShortUid
|
|
5661
|
-
} from "@amazon/vinyl-util";
|
|
5662
|
-
import {
|
|
5663
|
-
array as array3,
|
|
5664
|
-
enumOf as enumOf3,
|
|
5665
|
-
isOneOf as isOneOf3,
|
|
5666
|
-
number as number6,
|
|
5667
|
-
object as object9,
|
|
5668
|
-
string as string6,
|
|
5669
|
-
tuple
|
|
5670
|
-
} from "@amazon/vinyl-validation";
|
|
5671
|
-
var ALL_CONTENT_TYPES = [
|
|
5672
|
-
"video",
|
|
5673
|
-
"audio",
|
|
5674
|
-
"text"
|
|
5675
|
-
];
|
|
5676
|
-
var RESTRICTABLE_CONTENT_TYPES = [
|
|
5677
|
-
"video",
|
|
5678
|
-
"audio"
|
|
5679
|
-
];
|
|
5680
|
-
var drmProtectionValidator = /* @__PURE__ */ descriptorValidator.extend({
|
|
5681
|
-
keySystem: /* @__PURE__ */ enumOf3(DrmKeySystem),
|
|
5682
|
-
pro: /* @__PURE__ */ string6().maybe().optional(),
|
|
5683
|
-
pssh: /* @__PURE__ */ string6().maybe().optional()
|
|
5684
|
-
});
|
|
5685
|
-
var mediaFormatMetadataValidator = /* @__PURE__ */ object9({
|
|
5686
|
-
contentProtections: /* @__PURE__ */ array3(drmProtectionValidator).readonly(),
|
|
5687
|
-
contentType: /* @__PURE__ */ isOneOf3("audio", "video", "text").orNull(),
|
|
5688
|
-
initDataType: /* @__PURE__ */ string6().orNull(),
|
|
5689
|
-
encryptionScheme: /* @__PURE__ */ string6().orNull(),
|
|
5690
|
-
mimeType: /* @__PURE__ */ string6().orNull()
|
|
5691
|
-
});
|
|
5692
|
-
function createEmptyMediaFormatMetadata() {
|
|
5693
|
-
return {
|
|
5694
|
-
contentType: null,
|
|
5695
|
-
mimeType: null,
|
|
5696
|
-
initDataType: null,
|
|
5697
|
-
encryptionScheme: null,
|
|
5698
|
-
contentProtections: []
|
|
5699
|
-
};
|
|
5700
|
-
}
|
|
5701
|
-
function createEmptyMediaQualityMetadata() {
|
|
5702
|
-
return __spreadProps(__spreadValues({}, createEmptyMediaFormatMetadata()), {
|
|
5703
|
-
decoderId: createShortUid(),
|
|
5704
|
-
qualityId: createShortUid(),
|
|
5705
|
-
codecs: null,
|
|
5706
|
-
bandwidth: null,
|
|
5707
|
-
bandwidthTotal: null,
|
|
5708
|
-
supplementalProperties: {},
|
|
5709
|
-
audioSamplingRate: null,
|
|
5710
|
-
frameRate: null,
|
|
5711
|
-
height: null,
|
|
5712
|
-
width: null,
|
|
5713
|
-
lang: null,
|
|
5714
|
-
characteristics: [],
|
|
5715
|
-
groupId: createShortUid(),
|
|
5716
|
-
switchingGroupIds: null
|
|
5717
|
-
});
|
|
5718
|
-
}
|
|
5719
|
-
var mediaQualityMetadataValidator = /* @__PURE__ */ mediaFormatMetadataValidator.extend({
|
|
5720
|
-
audioSamplingRate: /* @__PURE__ */ array3(/* @__PURE__ */ number6()).readonly().orNull(),
|
|
5721
|
-
bandwidth: /* @__PURE__ */ number6().orNull(),
|
|
5722
|
-
bandwidthTotal: /* @__PURE__ */ number6().orNull(),
|
|
5723
|
-
codecs: /* @__PURE__ */ string6().orNull(),
|
|
5724
|
-
decoderId: /* @__PURE__ */ string6(),
|
|
5725
|
-
frameRate: /* @__PURE__ */ tuple(/* @__PURE__ */ number6(), /* @__PURE__ */ number6()).readonly().orNull(),
|
|
5726
|
-
height: /* @__PURE__ */ number6().orNull(),
|
|
5727
|
-
qualityId: /* @__PURE__ */ string6(),
|
|
5728
|
-
supplementalProperties: descriptorRecordValidator,
|
|
5729
|
-
width: /* @__PURE__ */ number6().orNull(),
|
|
5730
|
-
lang: /* @__PURE__ */ string6().orNull(),
|
|
5731
|
-
characteristics: /* @__PURE__ */ array3(/* @__PURE__ */ string6()).readonly(),
|
|
5732
|
-
groupId: /* @__PURE__ */ string6(),
|
|
5733
|
-
switchingGroupIds: /* @__PURE__ */ array3(/* @__PURE__ */ string6()).readonly().orNull()
|
|
5734
|
-
});
|
|
5735
|
-
|
|
5736
5790
|
// src/streaming/MediaTimeline.ts
|
|
5737
5791
|
import { sortedInsertionIndex as sortedInsertionIndex2 } from "@amazon/vinyl-util";
|
|
5738
5792
|
function getMediaPeriodAtTime(timeline, time) {
|
|
@@ -7952,7 +8006,6 @@ import {
|
|
|
7952
8006
|
first as first2,
|
|
7953
8007
|
IntersectionRanges,
|
|
7954
8008
|
logDebug as logDebug16,
|
|
7955
|
-
MediaUnsupportedError as MediaUnsupportedError7,
|
|
7956
8009
|
redispatchEvents as redispatchEvents3
|
|
7957
8010
|
} from "@amazon/vinyl-util";
|
|
7958
8011
|
import { createContainer as createContainer2 } from "@amazon/vinyl-di";
|
|
@@ -7980,10 +8033,7 @@ var MseTrack = class extends TrackBase {
|
|
|
7980
8033
|
this.deps = deps;
|
|
7981
8034
|
add(
|
|
7982
8035
|
deps.contentTypesValue.onData((contentTypesPromise) => {
|
|
7983
|
-
contentTypesPromise.then((value) =>
|
|
7984
|
-
this.setContentTypes(value);
|
|
7985
|
-
this.validateRequiredContentTypesPlayable();
|
|
7986
|
-
}).catch(this.errorHandler);
|
|
8036
|
+
contentTypesPromise.then((value) => this.setContentTypes(value)).catch(this.errorHandler);
|
|
7987
8037
|
})
|
|
7988
8038
|
);
|
|
7989
8039
|
this.on("streamingQualityChange", (event) => {
|
|
@@ -8084,33 +8134,8 @@ var MseTrack = class extends TrackBase {
|
|
|
8084
8134
|
});
|
|
8085
8135
|
}
|
|
8086
8136
|
}
|
|
8087
|
-
this.validateRequiredContentTypesPlayable();
|
|
8088
8137
|
});
|
|
8089
8138
|
}
|
|
8090
|
-
/**
|
|
8091
|
-
* Fails fast when a media content type the manifest declared (audio/video)
|
|
8092
|
-
* has no playable qualities left after timeline filtering. Its stream can
|
|
8093
|
-
* never create a source buffer, so without this the track waits forever for
|
|
8094
|
-
* a source buffer that never arrives, surfacing only as an opaque
|
|
8095
|
-
* `readyToAppend` timeout. Runs once both the required content types and the
|
|
8096
|
-
* filtered timeline qualities are known (either order).
|
|
8097
|
-
*/
|
|
8098
|
-
validateRequiredContentTypesPlayable() {
|
|
8099
|
-
const qualities = this._qualities;
|
|
8100
|
-
if (!qualities) return;
|
|
8101
|
-
const present = new Set(qualities.map((q) => q.contentType));
|
|
8102
|
-
for (const contentType2 of this._contentTypes) {
|
|
8103
|
-
if (!present.has(contentType2)) {
|
|
8104
|
-
this.errorHandler(
|
|
8105
|
-
new MediaUnsupportedError7(
|
|
8106
|
-
`No playable ${contentType2} rendition`,
|
|
8107
|
-
`no-playable-${contentType2}`
|
|
8108
|
-
)
|
|
8109
|
-
);
|
|
8110
|
-
return;
|
|
8111
|
-
}
|
|
8112
|
-
}
|
|
8113
|
-
}
|
|
8114
8139
|
async getAds() {
|
|
8115
8140
|
const timeline = await this.deps.mediaTimeline.value;
|
|
8116
8141
|
return {
|
|
@@ -10550,8 +10575,11 @@ import {
|
|
|
10550
10575
|
emptyRanges as emptyRanges3,
|
|
10551
10576
|
equalDeep as equalDeep4,
|
|
10552
10577
|
EventHostImpl as EventHostImpl18,
|
|
10578
|
+
getLogLevel as getLogLevel2,
|
|
10553
10579
|
logDebug as logDebug18,
|
|
10554
10580
|
logInfo as logInfo3,
|
|
10581
|
+
LogLevel as LogLevel3,
|
|
10582
|
+
logVerbose as logVerbose5,
|
|
10555
10583
|
logWarn as logWarn6,
|
|
10556
10584
|
redispatchEvents as redispatchEvents4
|
|
10557
10585
|
} from "@amazon/vinyl-util";
|
|
@@ -10584,6 +10612,7 @@ var VinylPlayer = class extends EventHostImpl18 {
|
|
|
10584
10612
|
playerRegistryRef.value.addPlayer(this);
|
|
10585
10613
|
this.redispatchSubControllerEvents();
|
|
10586
10614
|
this.redispatchCurrentTrackEvents();
|
|
10615
|
+
this.initializeLoadSpanLogging();
|
|
10587
10616
|
this.initializeAutoResetHandling();
|
|
10588
10617
|
}
|
|
10589
10618
|
get [Symbol.toStringTag]() {
|
|
@@ -10601,6 +10630,26 @@ var VinylPlayer = class extends EventHostImpl18 {
|
|
|
10601
10630
|
get autoResetController() {
|
|
10602
10631
|
return this.deps.autoResetController;
|
|
10603
10632
|
}
|
|
10633
|
+
/**
|
|
10634
|
+
* Logs each republished load span once at the verbose level, formatting its
|
|
10635
|
+
* bounds as ISO date strings and its duration in milliseconds.
|
|
10636
|
+
*/
|
|
10637
|
+
initializeLoadSpanLogging() {
|
|
10638
|
+
this.disposer.add(
|
|
10639
|
+
this.on("loadSpan", (span) => {
|
|
10640
|
+
if (getLogLevel2() > LogLevel3.VERBOSE) return;
|
|
10641
|
+
logVerbose5(this, "loadSpan", {
|
|
10642
|
+
kind: span.kind,
|
|
10643
|
+
trackUri: span.trackUri,
|
|
10644
|
+
mimeType: span.mimeType,
|
|
10645
|
+
contentType: span.contentType,
|
|
10646
|
+
startTime: new Date(span.startTime).toISOString(),
|
|
10647
|
+
endTime: new Date(span.endTime).toISOString(),
|
|
10648
|
+
durationMs: (span.endTime - span.startTime).toFixed(2)
|
|
10649
|
+
});
|
|
10650
|
+
})
|
|
10651
|
+
);
|
|
10652
|
+
}
|
|
10604
10653
|
redispatchSubControllerEvents() {
|
|
10605
10654
|
const add = this.disposer.add;
|
|
10606
10655
|
add(
|
|
@@ -11221,6 +11270,7 @@ export {
|
|
|
11221
11270
|
MsCommonMediaKeySystemAccess,
|
|
11222
11271
|
MsCommonMediaKeys,
|
|
11223
11272
|
MseTrack,
|
|
11273
|
+
PLAYOUT_LIMIT_TOLERANCE,
|
|
11224
11274
|
PLAY_READY_KEY_SYSTEMS,
|
|
11225
11275
|
POLL_BUFFER_THROTTLE,
|
|
11226
11276
|
PREFETCH_POLL_THROTTLE,
|