@codenkay/video-nsgplayer-core 0.1.0 → 0.1.3
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/CHANGELOG.md +15 -0
- package/dist/index.cjs +176 -27
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +61 -7
- package/dist/index.d.ts +61 -7
- package/dist/index.js +172 -27
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import Hls, { LoaderContext, LoaderConfiguration, LoaderCallbacks } from 'hls.js';
|
|
2
|
+
|
|
1
3
|
/** Player lifecycle states. */
|
|
2
4
|
type PlayerState = "idle" | "loading" | "ready" | "playing" | "paused" | "buffering" | "renewing" | "ended" | "error" | "destroyed";
|
|
3
5
|
type HlsSupportMode = "hls.js" | "native" | "unsupported";
|
|
@@ -166,6 +168,7 @@ type PlayerConfig = Required<{
|
|
|
166
168
|
streaming: {
|
|
167
169
|
engine: "hls";
|
|
168
170
|
hls: Required<NonNullable<StreamingConfig["hls"]>>;
|
|
171
|
+
keyProxyUrlBuilder?: StreamingConfig["keyProxyUrlBuilder"];
|
|
169
172
|
};
|
|
170
173
|
logging: Required<LoggingConfig>;
|
|
171
174
|
debug: Required<DebugConfig>;
|
|
@@ -239,14 +242,30 @@ type PlayerEventMap = {
|
|
|
239
242
|
};
|
|
240
243
|
|
|
241
244
|
declare const PLAYBACK_RATES: readonly [0.5, 0.75, 1, 1.25, 1.5, 2];
|
|
242
|
-
declare const PACKAGE_VERSION = "0.1.
|
|
245
|
+
declare const PACKAGE_VERSION = "0.1.3";
|
|
243
246
|
declare const DEFAULT_PLAYER_BEHAVIOR: Required<PlayerBehaviorConfig>;
|
|
244
247
|
declare const DEFAULT_CONTROLS: Required<ControlsConfig>;
|
|
245
248
|
declare const DEFAULT_THEME: Required<ThemeConfig>;
|
|
246
249
|
declare const DEFAULT_WATERMARK: Required<WatermarkConfig>;
|
|
247
250
|
declare const DEFAULT_PLAYER_CONFIG: PlayerConfig;
|
|
251
|
+
/** Hard cap so pathological graphs cannot blow the stack. */
|
|
252
|
+
declare const SECRET_SCAN_MAX_DEPTH = 32;
|
|
253
|
+
/**
|
|
254
|
+
* True only for JSON-like plain objects (`{}` / `Object.create(null)`).
|
|
255
|
+
* Excludes DOM nodes, class instances, arrays, dates, etc.
|
|
256
|
+
*/
|
|
257
|
+
declare function isPlainObject(value: unknown): value is Record<string, unknown>;
|
|
258
|
+
/**
|
|
259
|
+
* Scans plain config objects for forbidden secret key names.
|
|
260
|
+
*
|
|
261
|
+
* Enterprise guarantees:
|
|
262
|
+
* - Never deep-walks DOM / host / class instances (plain-object only)
|
|
263
|
+
* - Does not descend into `mount` / `auth` / `playback` (shallow key check only)
|
|
264
|
+
* - Cycle-safe via WeakSet
|
|
265
|
+
* - Depth-capped + iterative (no call-stack recursion)
|
|
266
|
+
*/
|
|
248
267
|
declare function assertNoSecretsInConfig(raw: unknown): void;
|
|
249
|
-
|
|
268
|
+
type PlayerConfigPartial = Partial<{
|
|
250
269
|
player: Partial<PlayerBehaviorConfig>;
|
|
251
270
|
controls: Partial<ControlsConfig>;
|
|
252
271
|
theme: Partial<ThemeConfig>;
|
|
@@ -254,12 +273,13 @@ declare function mergePlayerConfig(partial?: Partial<{
|
|
|
254
273
|
streaming: {
|
|
255
274
|
engine?: "hls";
|
|
256
275
|
hls?: Partial<PlayerConfig["streaming"]["hls"]>;
|
|
257
|
-
keyProxyUrlBuilder?:
|
|
276
|
+
keyProxyUrlBuilder?: PlayerConfig["streaming"]["keyProxyUrlBuilder"];
|
|
258
277
|
};
|
|
259
278
|
logging: Partial<PlayerConfig["logging"]>;
|
|
260
279
|
debug: Partial<PlayerConfig["debug"]>;
|
|
261
280
|
accessibility: Partial<PlayerConfig["accessibility"]>;
|
|
262
|
-
}
|
|
281
|
+
}>;
|
|
282
|
+
declare function mergePlayerConfig(partial?: PlayerConfigPartial): PlayerConfig;
|
|
263
283
|
/** Maps theme colors to CSS custom properties for UI adapters. */
|
|
264
284
|
declare function themeToCssVars(theme: Required<ThemeConfig>): Record<string, string>;
|
|
265
285
|
|
|
@@ -326,7 +346,14 @@ declare class AuthParamsStore {
|
|
|
326
346
|
constructor(initial?: URLSearchParams | Record<string, string>);
|
|
327
347
|
getSnapshot(): URLSearchParams;
|
|
328
348
|
toRecord(): Record<string, string>;
|
|
349
|
+
/** True when at least one auth query param is stored. */
|
|
350
|
+
hasParams(): boolean;
|
|
351
|
+
toString(): string;
|
|
329
352
|
update(next: URLSearchParams | Record<string, string>): void;
|
|
353
|
+
/**
|
|
354
|
+
* Merges current auth params onto a target URL, preserving unrelated query keys.
|
|
355
|
+
* Critical for child HLS playlists/segments that omit signed query params.
|
|
356
|
+
*/
|
|
330
357
|
applyToUrl(rawUrl: string, baseOrigin?: string): string;
|
|
331
358
|
}
|
|
332
359
|
|
|
@@ -359,6 +386,8 @@ type HlsEngineOptions = {
|
|
|
359
386
|
startMuted: boolean;
|
|
360
387
|
startPosition?: number;
|
|
361
388
|
volume?: number;
|
|
389
|
+
videoId?: string;
|
|
390
|
+
keyProxyUrlBuilder?: StreamingConfig["keyProxyUrlBuilder"];
|
|
362
391
|
hlsConfig: {
|
|
363
392
|
enableWorker: boolean;
|
|
364
393
|
lowLatencyMode: boolean;
|
|
@@ -370,6 +399,11 @@ type HlsEngineOptions = {
|
|
|
370
399
|
};
|
|
371
400
|
/**
|
|
372
401
|
* Dual-path HLS engine: hls.js when supported, otherwise native Safari HLS.
|
|
402
|
+
*
|
|
403
|
+
* Signed CDN playback requires auth query params on *every* HLS request
|
|
404
|
+
* (master, media playlist, segments, keys). hls.js only receives the signed
|
|
405
|
+
* master URL via loadSource; child URIs are relative and unsigned unless a
|
|
406
|
+
* custom loader re-applies AuthParamsStore on each request.
|
|
373
407
|
*/
|
|
374
408
|
declare class HlsEngine {
|
|
375
409
|
private readonly options;
|
|
@@ -541,7 +575,27 @@ declare class RefreshManager {
|
|
|
541
575
|
private renew;
|
|
542
576
|
}
|
|
543
577
|
|
|
544
|
-
|
|
545
|
-
|
|
578
|
+
type HlsLoader = new (config: object) => {
|
|
579
|
+
load(context: LoaderContext, config: LoaderConfiguration, callbacks: LoaderCallbacks<LoaderContext>): void;
|
|
580
|
+
destroy(): void;
|
|
581
|
+
};
|
|
582
|
+
type AuthParamsLoaderOptions = {
|
|
583
|
+
videoId?: string;
|
|
584
|
+
keyProxyUrlBuilder?: StreamingConfig["keyProxyUrlBuilder"];
|
|
585
|
+
};
|
|
586
|
+
/**
|
|
587
|
+
* Rewrites an HLS request URL so signed auth query params are present.
|
|
588
|
+
* Master playlists are signed on loadSource; child playlists / segments / keys
|
|
589
|
+
* are relative and would otherwise be fetched unsigned → CDN 403.
|
|
590
|
+
*/
|
|
591
|
+
declare function rewriteHlsRequestUrl(rawUrl: string, store: AuthParamsStore, options?: AuthParamsLoaderOptions, baseOrigin?: string): string;
|
|
592
|
+
/**
|
|
593
|
+
* hls.js loader that re-applies live AuthParamsStore credentials on every
|
|
594
|
+
* manifest / level / fragment / key request.
|
|
595
|
+
*/
|
|
596
|
+
declare function createAuthParamsLoader(HlsClass: typeof Hls, store: AuthParamsStore, options?: AuthParamsLoaderOptions): HlsLoader;
|
|
597
|
+
|
|
598
|
+
declare function redactValue(key: string, value: unknown, seen?: WeakSet<object>, depth?: number): unknown;
|
|
599
|
+
declare function redactObject(obj: Record<string, unknown>, seen?: WeakSet<object>, depth?: number): Record<string, unknown>;
|
|
546
600
|
|
|
547
|
-
export { type AccessibilityConfig, type AnalyticsConfig, type AuthConfig, AuthManager, AuthParamsStore, type AuthToken, type AuthTokenProviderContext, type BufferedRange, type ControlsConfig, type CreateVideoPlayerOptions, DEFAULT_CONTROLS, DEFAULT_LIVE_EDGE_TOLERANCE_SECONDS, DEFAULT_PLAYER_BEHAVIOR, DEFAULT_PLAYER_CONFIG, DEFAULT_THEME, DEFAULT_WATERMARK, type DebugConfig, EventEmitter, type HlsQualityLevel, type HlsSupportMode, type LiveMediaSnapshot, type LoggingConfig, PACKAGE_VERSION, PLAYBACK_RATES, type PlayIconPreset, type PlaybackCredentialConfig, type PlaybackRate, type PlaybackSource, type PlaybackSourceContext, PlaybackSourceManager, type PlayerBehaviorConfig, type PlayerConfig, type PlayerDiagnostics, type PlayerError, PlayerErrorCode, type PlayerEventMap, type PlayerSkipSeconds, type PlayerState, type PlayerZoomLevel, type QualitySelection, RefreshManager, type SeekToLiveResult, type StreamingConfig, type ThemeConfig, type VideoPlayer, type WatermarkConfig, assertNoSecretsInConfig, createPlayerError, createVideoPlayer, getLiveEdgeTime, isAtLiveEdge, mergePlayerConfig, redactObject, redactSensitive, redactValue, seekToLiveEdge, themeToCssVars };
|
|
601
|
+
export { type AccessibilityConfig, type AnalyticsConfig, type AuthConfig, AuthManager, AuthParamsStore, type AuthToken, type AuthTokenProviderContext, type BufferedRange, type ControlsConfig, type CreateVideoPlayerOptions, DEFAULT_CONTROLS, DEFAULT_LIVE_EDGE_TOLERANCE_SECONDS, DEFAULT_PLAYER_BEHAVIOR, DEFAULT_PLAYER_CONFIG, DEFAULT_THEME, DEFAULT_WATERMARK, type DebugConfig, EventEmitter, type HlsQualityLevel, type HlsSupportMode, type LiveMediaSnapshot, type LoggingConfig, PACKAGE_VERSION, PLAYBACK_RATES, type PlayIconPreset, type PlaybackCredentialConfig, type PlaybackRate, type PlaybackSource, type PlaybackSourceContext, PlaybackSourceManager, type PlayerBehaviorConfig, type PlayerConfig, type PlayerDiagnostics, type PlayerError, PlayerErrorCode, type PlayerEventMap, type PlayerSkipSeconds, type PlayerState, type PlayerZoomLevel, type QualitySelection, RefreshManager, SECRET_SCAN_MAX_DEPTH, type SeekToLiveResult, type StreamingConfig, type ThemeConfig, type VideoPlayer, type WatermarkConfig, assertNoSecretsInConfig, createAuthParamsLoader, createPlayerError, createVideoPlayer, getLiveEdgeTime, isAtLiveEdge, isPlainObject, mergePlayerConfig, redactObject, redactSensitive, redactValue, rewriteHlsRequestUrl, seekToLiveEdge, themeToCssVars };
|
package/dist/index.js
CHANGED
|
@@ -146,7 +146,7 @@ var AuthManager = class {
|
|
|
146
146
|
|
|
147
147
|
// src/config/defaults.ts
|
|
148
148
|
var PLAYBACK_RATES = [0.5, 0.75, 1, 1.25, 1.5, 2];
|
|
149
|
-
var PACKAGE_VERSION = "0.1.
|
|
149
|
+
var PACKAGE_VERSION = "0.1.3";
|
|
150
150
|
var DEFAULT_PLAYER_BEHAVIOR = {
|
|
151
151
|
autoplay: true,
|
|
152
152
|
startMuted: true,
|
|
@@ -232,22 +232,83 @@ var FORBIDDEN_SECRET_KEYS = [
|
|
|
232
232
|
"basicauthpassword",
|
|
233
233
|
"password"
|
|
234
234
|
];
|
|
235
|
+
var SKIP_DEEP_SCAN_KEYS = /* @__PURE__ */ new Set([
|
|
236
|
+
"mount",
|
|
237
|
+
"auth",
|
|
238
|
+
"playback",
|
|
239
|
+
"gettoken",
|
|
240
|
+
"getsource",
|
|
241
|
+
"refreshsource",
|
|
242
|
+
"keyproxyurlbuilder"
|
|
243
|
+
]);
|
|
244
|
+
var SECRET_SCAN_MAX_DEPTH = 32;
|
|
245
|
+
function isPlainObject(value) {
|
|
246
|
+
if (value === null || typeof value !== "object") return false;
|
|
247
|
+
if (Array.isArray(value)) return false;
|
|
248
|
+
const proto = Object.getPrototypeOf(value);
|
|
249
|
+
return proto === Object.prototype || proto === null;
|
|
250
|
+
}
|
|
251
|
+
function normalizeConfigKey(key) {
|
|
252
|
+
return key.toLowerCase().replace(/[^a-z0-9]/g, "");
|
|
253
|
+
}
|
|
254
|
+
function isForbiddenSecretKey(key) {
|
|
255
|
+
const lower = normalizeConfigKey(key);
|
|
256
|
+
return FORBIDDEN_SECRET_KEYS.some((k) => lower.includes(k));
|
|
257
|
+
}
|
|
258
|
+
function throwForbidden(path, key) {
|
|
259
|
+
throw new Error(
|
|
260
|
+
`INVALID_CONFIGURATION: Forbidden secret key "${path}${key}" must never be passed to the browser SDK. Keep clientSecret on your server/BFF and use auth.getToken().`
|
|
261
|
+
);
|
|
262
|
+
}
|
|
235
263
|
function assertNoSecretsInConfig(raw) {
|
|
236
|
-
if (!raw
|
|
237
|
-
const
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
264
|
+
if (!isPlainObject(raw) && !Array.isArray(raw)) return;
|
|
265
|
+
const seen = /* @__PURE__ */ new WeakSet();
|
|
266
|
+
const stack = [
|
|
267
|
+
{ value: raw, path: "", depth: 0 }
|
|
268
|
+
];
|
|
269
|
+
while (stack.length > 0) {
|
|
270
|
+
const current = stack.pop();
|
|
271
|
+
if (current.depth > SECRET_SCAN_MAX_DEPTH) continue;
|
|
272
|
+
const { value, path, depth } = current;
|
|
273
|
+
if (Array.isArray(value)) {
|
|
274
|
+
if (seen.has(value)) continue;
|
|
275
|
+
seen.add(value);
|
|
276
|
+
for (let i = 0; i < value.length; i += 1) {
|
|
277
|
+
const item = value[i];
|
|
278
|
+
if (isPlainObject(item) || Array.isArray(item)) {
|
|
279
|
+
stack.push({ value: item, path: `${path}[${i}]`, depth: depth + 1 });
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
continue;
|
|
283
|
+
}
|
|
284
|
+
if (!isPlainObject(value)) continue;
|
|
285
|
+
if (seen.has(value)) continue;
|
|
286
|
+
seen.add(value);
|
|
287
|
+
for (const [key, child] of Object.entries(value)) {
|
|
288
|
+
const normalized = normalizeConfigKey(key);
|
|
289
|
+
if (isForbiddenSecretKey(key)) {
|
|
290
|
+
throwForbidden(path, key);
|
|
291
|
+
}
|
|
292
|
+
if (normalized === "mount") continue;
|
|
293
|
+
if (SKIP_DEEP_SCAN_KEYS.has(normalized)) {
|
|
294
|
+
if (isPlainObject(child)) {
|
|
295
|
+
for (const nestedKey of Object.keys(child)) {
|
|
296
|
+
if (isForbiddenSecretKey(nestedKey)) {
|
|
297
|
+
throwForbidden(`${path}${key}.`, nestedKey);
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
continue;
|
|
244
302
|
}
|
|
245
|
-
if (
|
|
246
|
-
|
|
303
|
+
if (isPlainObject(child) || Array.isArray(child)) {
|
|
304
|
+
stack.push({
|
|
305
|
+
value: child,
|
|
306
|
+
path: path ? `${path}${key}.` : `${key}.`,
|
|
307
|
+
depth: depth + 1
|
|
308
|
+
});
|
|
247
309
|
}
|
|
248
310
|
}
|
|
249
|
-
}
|
|
250
|
-
walk(raw, "");
|
|
311
|
+
}
|
|
251
312
|
}
|
|
252
313
|
function mergePlayerConfig(partial) {
|
|
253
314
|
assertNoSecretsInConfig(partial);
|
|
@@ -261,7 +322,8 @@ function mergePlayerConfig(partial) {
|
|
|
261
322
|
hls: {
|
|
262
323
|
...DEFAULT_PLAYER_CONFIG.streaming.hls,
|
|
263
324
|
...partial?.streaming?.hls
|
|
264
|
-
}
|
|
325
|
+
},
|
|
326
|
+
keyProxyUrlBuilder: partial?.streaming?.keyProxyUrlBuilder
|
|
265
327
|
},
|
|
266
328
|
logging: { ...DEFAULT_PLAYER_CONFIG.logging, ...partial?.logging },
|
|
267
329
|
debug: { ...DEFAULT_PLAYER_CONFIG.debug, ...partial?.debug },
|
|
@@ -335,7 +397,14 @@ var EventEmitter = class {
|
|
|
335
397
|
|
|
336
398
|
// src/security/redaction.ts
|
|
337
399
|
var SENSITIVE_KEYS = /^(authorization|cookie|set-cookie|x-api-key|token|accessToken|access_token|clientSecret|password)$/i;
|
|
338
|
-
|
|
400
|
+
var REDACT_MAX_DEPTH = 32;
|
|
401
|
+
function isPlainObject2(value) {
|
|
402
|
+
if (value === null || typeof value !== "object") return false;
|
|
403
|
+
if (Array.isArray(value)) return false;
|
|
404
|
+
const proto = Object.getPrototypeOf(value);
|
|
405
|
+
return proto === Object.prototype || proto === null;
|
|
406
|
+
}
|
|
407
|
+
function redactValue(key, value, seen = /* @__PURE__ */ new WeakSet(), depth = 0) {
|
|
339
408
|
if (SENSITIVE_KEYS.test(key)) return "[REDACTED]";
|
|
340
409
|
if (typeof value === "string") {
|
|
341
410
|
if (/^https?:\/\//i.test(value) && /[?&](token|expires)=/i.test(value)) {
|
|
@@ -352,15 +421,25 @@ function redactValue(key, value) {
|
|
|
352
421
|
}
|
|
353
422
|
}
|
|
354
423
|
}
|
|
355
|
-
if (
|
|
356
|
-
|
|
424
|
+
if (Array.isArray(value)) {
|
|
425
|
+
if (depth >= REDACT_MAX_DEPTH || seen.has(value)) return "[REDACTED_CYCLE]";
|
|
426
|
+
seen.add(value);
|
|
427
|
+
return value.map(
|
|
428
|
+
(item, index) => redactValue(String(index), item, seen, depth + 1)
|
|
429
|
+
);
|
|
430
|
+
}
|
|
431
|
+
if (isPlainObject2(value)) {
|
|
432
|
+
return redactObject(value, seen, depth + 1);
|
|
357
433
|
}
|
|
358
434
|
return value;
|
|
359
435
|
}
|
|
360
|
-
function redactObject(obj) {
|
|
436
|
+
function redactObject(obj, seen = /* @__PURE__ */ new WeakSet(), depth = 0) {
|
|
437
|
+
if (depth > REDACT_MAX_DEPTH) return { "[REDACTED]": "max_depth" };
|
|
438
|
+
if (seen.has(obj)) return { "[REDACTED]": "cycle" };
|
|
439
|
+
seen.add(obj);
|
|
361
440
|
const out = {};
|
|
362
441
|
for (const [key, value] of Object.entries(obj)) {
|
|
363
|
-
out[key] = redactValue(key, value);
|
|
442
|
+
out[key] = redactValue(key, value, seen, depth);
|
|
364
443
|
}
|
|
365
444
|
return out;
|
|
366
445
|
}
|
|
@@ -420,11 +499,25 @@ var AuthParamsStore = class {
|
|
|
420
499
|
});
|
|
421
500
|
return out;
|
|
422
501
|
}
|
|
502
|
+
/** True when at least one auth query param is stored. */
|
|
503
|
+
hasParams() {
|
|
504
|
+
return [...this.params.keys()].length > 0;
|
|
505
|
+
}
|
|
506
|
+
toString() {
|
|
507
|
+
return this.params.toString();
|
|
508
|
+
}
|
|
423
509
|
update(next) {
|
|
424
510
|
this.params = next instanceof URLSearchParams ? new URLSearchParams(next) : new URLSearchParams(next);
|
|
425
511
|
}
|
|
512
|
+
/**
|
|
513
|
+
* Merges current auth params onto a target URL, preserving unrelated query keys.
|
|
514
|
+
* Critical for child HLS playlists/segments that omit signed query params.
|
|
515
|
+
*/
|
|
426
516
|
applyToUrl(rawUrl, baseOrigin) {
|
|
427
|
-
const target = new URL(
|
|
517
|
+
const target = new URL(
|
|
518
|
+
rawUrl,
|
|
519
|
+
baseOrigin ?? (typeof location !== "undefined" ? location.origin : "http://localhost")
|
|
520
|
+
);
|
|
428
521
|
this.params.forEach((value, key) => {
|
|
429
522
|
target.searchParams.set(key, value);
|
|
430
523
|
});
|
|
@@ -659,6 +752,39 @@ function seekToLiveEdge(media, options) {
|
|
|
659
752
|
return { moved: true, edge };
|
|
660
753
|
}
|
|
661
754
|
|
|
755
|
+
// src/streaming/authParamsLoader.ts
|
|
756
|
+
var ENC_KEY_PATH_RE = /\/enc\.key$/i;
|
|
757
|
+
function rewriteHlsRequestUrl(rawUrl, store, options = {}, baseOrigin = typeof location !== "undefined" ? location.origin : "http://localhost") {
|
|
758
|
+
if (!rawUrl) return rawUrl;
|
|
759
|
+
const parsed = new URL(rawUrl, baseOrigin);
|
|
760
|
+
const isKey = ENC_KEY_PATH_RE.test(parsed.pathname);
|
|
761
|
+
if (isKey && options.keyProxyUrlBuilder && options.videoId) {
|
|
762
|
+
const snapshot = store.toRecord();
|
|
763
|
+
return options.keyProxyUrlBuilder({
|
|
764
|
+
videoId: options.videoId,
|
|
765
|
+
keyUrl: parsed.toString(),
|
|
766
|
+
token: snapshot.token,
|
|
767
|
+
expires: snapshot.expires
|
|
768
|
+
});
|
|
769
|
+
}
|
|
770
|
+
if (!store.hasParams()) return parsed.toString();
|
|
771
|
+
return store.applyToUrl(rawUrl, baseOrigin);
|
|
772
|
+
}
|
|
773
|
+
function createAuthParamsLoader(HlsClass, store, options = {}) {
|
|
774
|
+
const BaseLoader = HlsClass.DefaultConfig.loader;
|
|
775
|
+
return class AuthParamsLoader extends BaseLoader {
|
|
776
|
+
load(context, config, callbacks) {
|
|
777
|
+
if (context.url) {
|
|
778
|
+
try {
|
|
779
|
+
context.url = rewriteHlsRequestUrl(context.url, store, options);
|
|
780
|
+
} catch {
|
|
781
|
+
}
|
|
782
|
+
}
|
|
783
|
+
super.load(context, config, callbacks);
|
|
784
|
+
}
|
|
785
|
+
};
|
|
786
|
+
}
|
|
787
|
+
|
|
662
788
|
// src/streaming/HlsEngine.ts
|
|
663
789
|
var HlsEngine = class {
|
|
664
790
|
constructor(options) {
|
|
@@ -711,15 +837,16 @@ var HlsEngine = class {
|
|
|
711
837
|
}
|
|
712
838
|
}
|
|
713
839
|
async startWithHlsJs(Hls, playbackUrl) {
|
|
714
|
-
const { videoEl, authParams, hlsConfig, callbacks } = this.options;
|
|
840
|
+
const { videoEl, authParams, hlsConfig, callbacks, videoId, keyProxyUrlBuilder } = this.options;
|
|
841
|
+
const loader = createAuthParamsLoader(Hls, authParams, {
|
|
842
|
+
videoId,
|
|
843
|
+
keyProxyUrlBuilder
|
|
844
|
+
});
|
|
715
845
|
this.hls = new Hls({
|
|
716
846
|
enableWorker: hlsConfig.enableWorker,
|
|
717
847
|
lowLatencyMode: hlsConfig.lowLatencyMode,
|
|
718
848
|
backBufferLength: hlsConfig.backBufferLength,
|
|
719
|
-
|
|
720
|
-
void xhr;
|
|
721
|
-
void url;
|
|
722
|
-
}
|
|
849
|
+
loader
|
|
723
850
|
});
|
|
724
851
|
this.hls.attachMedia(videoEl);
|
|
725
852
|
this.hls.loadSource(authParams.applyToUrl(playbackUrl));
|
|
@@ -830,7 +957,18 @@ function generateSessionId() {
|
|
|
830
957
|
return `ps_${Date.now()}_${Math.random().toString(36).slice(2, 10)}`;
|
|
831
958
|
}
|
|
832
959
|
function createVideoPlayer(options) {
|
|
833
|
-
assertNoSecretsInConfig(
|
|
960
|
+
assertNoSecretsInConfig({
|
|
961
|
+
videoId: options.videoId,
|
|
962
|
+
sourceUrl: options.sourceUrl,
|
|
963
|
+
player: options.player,
|
|
964
|
+
controls: options.controls,
|
|
965
|
+
theme: options.theme,
|
|
966
|
+
watermark: options.watermark,
|
|
967
|
+
streaming: options.streaming,
|
|
968
|
+
logging: options.logging,
|
|
969
|
+
debug: options.debug,
|
|
970
|
+
accessibility: options.accessibility
|
|
971
|
+
});
|
|
834
972
|
let config = mergePlayerConfig({
|
|
835
973
|
player: options.player,
|
|
836
974
|
controls: options.controls,
|
|
@@ -916,6 +1054,8 @@ function createVideoPlayer(options) {
|
|
|
916
1054
|
startMuted: config.player.startMuted,
|
|
917
1055
|
startPosition: config.player.startPosition,
|
|
918
1056
|
volume: config.player.volume,
|
|
1057
|
+
videoId: options.videoId,
|
|
1058
|
+
keyProxyUrlBuilder: options.streaming?.keyProxyUrlBuilder,
|
|
919
1059
|
hlsConfig: config.streaming.hls,
|
|
920
1060
|
logger,
|
|
921
1061
|
callbacks: {
|
|
@@ -1176,7 +1316,8 @@ function createVideoPlayer(options) {
|
|
|
1176
1316
|
watermark: { ...config.watermark, ...partial?.watermark },
|
|
1177
1317
|
streaming: {
|
|
1178
1318
|
engine: "hls",
|
|
1179
|
-
hls: { ...config.streaming.hls, ...partial?.streaming?.hls }
|
|
1319
|
+
hls: { ...config.streaming.hls, ...partial?.streaming?.hls },
|
|
1320
|
+
keyProxyUrlBuilder: partial?.streaming?.keyProxyUrlBuilder ?? config.streaming.keyProxyUrlBuilder
|
|
1180
1321
|
},
|
|
1181
1322
|
logging: { ...config.logging, ...partial?.logging },
|
|
1182
1323
|
debug: { ...config.debug, ...partial?.debug },
|
|
@@ -1212,15 +1353,19 @@ export {
|
|
|
1212
1353
|
PlaybackSourceManager,
|
|
1213
1354
|
PlayerErrorCode,
|
|
1214
1355
|
RefreshManager,
|
|
1356
|
+
SECRET_SCAN_MAX_DEPTH,
|
|
1215
1357
|
assertNoSecretsInConfig,
|
|
1358
|
+
createAuthParamsLoader,
|
|
1216
1359
|
createPlayerError,
|
|
1217
1360
|
createVideoPlayer,
|
|
1218
1361
|
getLiveEdgeTime,
|
|
1219
1362
|
isAtLiveEdge,
|
|
1363
|
+
isPlainObject,
|
|
1220
1364
|
mergePlayerConfig,
|
|
1221
1365
|
redactObject,
|
|
1222
1366
|
redactSensitive,
|
|
1223
1367
|
redactValue,
|
|
1368
|
+
rewriteHlsRequestUrl,
|
|
1224
1369
|
seekToLiveEdge,
|
|
1225
1370
|
themeToCssVars
|
|
1226
1371
|
};
|