@codenkay/video-nsgplayer-core 0.1.3 → 0.1.5
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 +12 -0
- package/dist/index.cjs +143 -55
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +26 -5
- package/dist/index.d.ts +26 -5
- package/dist/index.js +143 -55
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -117,12 +117,24 @@ type StreamingConfig = {
|
|
|
117
117
|
backBufferLength?: number;
|
|
118
118
|
fatalRecoveryLimit?: number;
|
|
119
119
|
};
|
|
120
|
+
/**
|
|
121
|
+
* Same-origin BFF proxy for `enc.key` (preferred in production when the
|
|
122
|
+
* server IP is allowlisted by the CDN / Cloudflare).
|
|
123
|
+
*/
|
|
120
124
|
keyProxyUrlBuilder?: (ctx: {
|
|
121
125
|
videoId: string;
|
|
122
126
|
keyUrl: string;
|
|
123
127
|
token?: string;
|
|
124
128
|
expires?: string;
|
|
129
|
+
username?: string;
|
|
130
|
+
mobile?: string;
|
|
125
131
|
}) => string;
|
|
132
|
+
/**
|
|
133
|
+
* Browser-direct AES key auth: returns the Video API access token so hls.js
|
|
134
|
+
* can send `Authorization: Bearer …` on `enc.key` requests.
|
|
135
|
+
* Use when the BFF cannot reach Appextech (Cloudflare challenge on server IP).
|
|
136
|
+
*/
|
|
137
|
+
getKeyAccessToken?: () => string | null | undefined;
|
|
126
138
|
};
|
|
127
139
|
type LoggingConfig = {
|
|
128
140
|
enabled?: boolean;
|
|
@@ -169,6 +181,7 @@ type PlayerConfig = Required<{
|
|
|
169
181
|
engine: "hls";
|
|
170
182
|
hls: Required<NonNullable<StreamingConfig["hls"]>>;
|
|
171
183
|
keyProxyUrlBuilder?: StreamingConfig["keyProxyUrlBuilder"];
|
|
184
|
+
getKeyAccessToken?: StreamingConfig["getKeyAccessToken"];
|
|
172
185
|
};
|
|
173
186
|
logging: Required<LoggingConfig>;
|
|
174
187
|
debug: Required<DebugConfig>;
|
|
@@ -242,7 +255,7 @@ type PlayerEventMap = {
|
|
|
242
255
|
};
|
|
243
256
|
|
|
244
257
|
declare const PLAYBACK_RATES: readonly [0.5, 0.75, 1, 1.25, 1.5, 2];
|
|
245
|
-
declare const PACKAGE_VERSION = "0.1.
|
|
258
|
+
declare const PACKAGE_VERSION = "0.1.5";
|
|
246
259
|
declare const DEFAULT_PLAYER_BEHAVIOR: Required<PlayerBehaviorConfig>;
|
|
247
260
|
declare const DEFAULT_CONTROLS: Required<ControlsConfig>;
|
|
248
261
|
declare const DEFAULT_THEME: Required<ThemeConfig>;
|
|
@@ -274,6 +287,7 @@ type PlayerConfigPartial = Partial<{
|
|
|
274
287
|
engine?: "hls";
|
|
275
288
|
hls?: Partial<PlayerConfig["streaming"]["hls"]>;
|
|
276
289
|
keyProxyUrlBuilder?: PlayerConfig["streaming"]["keyProxyUrlBuilder"];
|
|
290
|
+
getKeyAccessToken?: PlayerConfig["streaming"]["getKeyAccessToken"];
|
|
277
291
|
};
|
|
278
292
|
logging: Partial<PlayerConfig["logging"]>;
|
|
279
293
|
debug: Partial<PlayerConfig["debug"]>;
|
|
@@ -388,6 +402,7 @@ type HlsEngineOptions = {
|
|
|
388
402
|
volume?: number;
|
|
389
403
|
videoId?: string;
|
|
390
404
|
keyProxyUrlBuilder?: StreamingConfig["keyProxyUrlBuilder"];
|
|
405
|
+
getKeyAccessToken?: StreamingConfig["getKeyAccessToken"];
|
|
391
406
|
hlsConfig: {
|
|
392
407
|
enableWorker: boolean;
|
|
393
408
|
lowLatencyMode: boolean;
|
|
@@ -400,10 +415,9 @@ type HlsEngineOptions = {
|
|
|
400
415
|
/**
|
|
401
416
|
* Dual-path HLS engine: hls.js when supported, otherwise native Safari HLS.
|
|
402
417
|
*
|
|
403
|
-
* Signed CDN playback requires auth query params on
|
|
404
|
-
*
|
|
405
|
-
*
|
|
406
|
-
* custom loader re-applies AuthParamsStore on each request.
|
|
418
|
+
* Signed CDN playback requires auth query params on every HLS request.
|
|
419
|
+
* Encrypted VOD also requires a same-origin `enc.key` proxy (Bearer + query)
|
|
420
|
+
* via `streaming.keyProxyUrlBuilder` — browser CORS cannot fetch Video API keys.
|
|
407
421
|
*/
|
|
408
422
|
declare class HlsEngine {
|
|
409
423
|
private readonly options;
|
|
@@ -417,6 +431,8 @@ declare class HlsEngine {
|
|
|
417
431
|
constructor(options: HlsEngineOptions);
|
|
418
432
|
start(): Promise<void>;
|
|
419
433
|
private startWithHlsJs;
|
|
434
|
+
private handleHlsError;
|
|
435
|
+
private applyStartPositionAndAutoplay;
|
|
420
436
|
private bindMediaEvents;
|
|
421
437
|
updateAuthParams(): void;
|
|
422
438
|
resumeAfterAuthRenew(): void;
|
|
@@ -582,11 +598,16 @@ type HlsLoader = new (config: object) => {
|
|
|
582
598
|
type AuthParamsLoaderOptions = {
|
|
583
599
|
videoId?: string;
|
|
584
600
|
keyProxyUrlBuilder?: StreamingConfig["keyProxyUrlBuilder"];
|
|
601
|
+
getKeyAccessToken?: StreamingConfig["getKeyAccessToken"];
|
|
585
602
|
};
|
|
586
603
|
/**
|
|
587
604
|
* Rewrites an HLS request URL so signed auth query params are present.
|
|
588
605
|
* Master playlists are signed on loadSource; child playlists / segments / keys
|
|
589
606
|
* are relative and would otherwise be fetched unsigned → CDN 403.
|
|
607
|
+
*
|
|
608
|
+
* AES `enc.key` handling (pick one):
|
|
609
|
+
* 1. `keyProxyUrlBuilder` — same-origin BFF (needs Cloudflare-allowlisted server IP)
|
|
610
|
+
* 2. `getKeyAccessToken` — browser-direct CDN fetch with API Bearer header
|
|
590
611
|
*/
|
|
591
612
|
declare function rewriteHlsRequestUrl(rawUrl: string, store: AuthParamsStore, options?: AuthParamsLoaderOptions, baseOrigin?: string): string;
|
|
592
613
|
/**
|
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.5";
|
|
150
150
|
var DEFAULT_PLAYER_BEHAVIOR = {
|
|
151
151
|
autoplay: true,
|
|
152
152
|
startMuted: true,
|
|
@@ -239,7 +239,8 @@ var SKIP_DEEP_SCAN_KEYS = /* @__PURE__ */ new Set([
|
|
|
239
239
|
"gettoken",
|
|
240
240
|
"getsource",
|
|
241
241
|
"refreshsource",
|
|
242
|
-
"keyproxyurlbuilder"
|
|
242
|
+
"keyproxyurlbuilder",
|
|
243
|
+
"getkeyaccesstoken"
|
|
243
244
|
]);
|
|
244
245
|
var SECRET_SCAN_MAX_DEPTH = 32;
|
|
245
246
|
function isPlainObject(value) {
|
|
@@ -323,7 +324,8 @@ function mergePlayerConfig(partial) {
|
|
|
323
324
|
...DEFAULT_PLAYER_CONFIG.streaming.hls,
|
|
324
325
|
...partial?.streaming?.hls
|
|
325
326
|
},
|
|
326
|
-
keyProxyUrlBuilder: partial?.streaming?.keyProxyUrlBuilder
|
|
327
|
+
keyProxyUrlBuilder: partial?.streaming?.keyProxyUrlBuilder,
|
|
328
|
+
getKeyAccessToken: partial?.streaming?.getKeyAccessToken
|
|
327
329
|
},
|
|
328
330
|
logging: { ...DEFAULT_PLAYER_CONFIG.logging, ...partial?.logging },
|
|
329
331
|
debug: { ...DEFAULT_PLAYER_CONFIG.debug, ...partial?.debug },
|
|
@@ -753,7 +755,14 @@ function seekToLiveEdge(media, options) {
|
|
|
753
755
|
}
|
|
754
756
|
|
|
755
757
|
// src/streaming/authParamsLoader.ts
|
|
756
|
-
var ENC_KEY_PATH_RE =
|
|
758
|
+
var ENC_KEY_PATH_RE = /enc\.key$/i;
|
|
759
|
+
function isEncryptionKeyUrl(rawUrl, baseOrigin = typeof location !== "undefined" ? location.origin : "http://localhost") {
|
|
760
|
+
try {
|
|
761
|
+
return ENC_KEY_PATH_RE.test(new URL(rawUrl, baseOrigin).pathname);
|
|
762
|
+
} catch {
|
|
763
|
+
return /enc\.key/i.test(rawUrl);
|
|
764
|
+
}
|
|
765
|
+
}
|
|
757
766
|
function rewriteHlsRequestUrl(rawUrl, store, options = {}, baseOrigin = typeof location !== "undefined" ? location.origin : "http://localhost") {
|
|
758
767
|
if (!rawUrl) return rawUrl;
|
|
759
768
|
const parsed = new URL(rawUrl, baseOrigin);
|
|
@@ -764,7 +773,9 @@ function rewriteHlsRequestUrl(rawUrl, store, options = {}, baseOrigin = typeof l
|
|
|
764
773
|
videoId: options.videoId,
|
|
765
774
|
keyUrl: parsed.toString(),
|
|
766
775
|
token: snapshot.token,
|
|
767
|
-
expires: snapshot.expires
|
|
776
|
+
expires: snapshot.expires,
|
|
777
|
+
username: snapshot.username,
|
|
778
|
+
mobile: snapshot.mobile
|
|
768
779
|
});
|
|
769
780
|
}
|
|
770
781
|
if (!store.hasParams()) return parsed.toString();
|
|
@@ -776,7 +787,18 @@ function createAuthParamsLoader(HlsClass, store, options = {}) {
|
|
|
776
787
|
load(context, config, callbacks) {
|
|
777
788
|
if (context.url) {
|
|
778
789
|
try {
|
|
779
|
-
|
|
790
|
+
const originalUrl = context.url;
|
|
791
|
+
const isKey = isEncryptionKeyUrl(originalUrl);
|
|
792
|
+
context.url = rewriteHlsRequestUrl(originalUrl, store, options);
|
|
793
|
+
if (isKey && !options.keyProxyUrlBuilder && options.getKeyAccessToken) {
|
|
794
|
+
const accessToken = options.getKeyAccessToken();
|
|
795
|
+
if (accessToken) {
|
|
796
|
+
context.headers = {
|
|
797
|
+
...context.headers ?? {},
|
|
798
|
+
Authorization: `Bearer ${accessToken}`
|
|
799
|
+
};
|
|
800
|
+
}
|
|
801
|
+
}
|
|
780
802
|
} catch {
|
|
781
803
|
}
|
|
782
804
|
}
|
|
@@ -786,6 +808,9 @@ function createAuthParamsLoader(HlsClass, store, options = {}) {
|
|
|
786
808
|
}
|
|
787
809
|
|
|
788
810
|
// src/streaming/HlsEngine.ts
|
|
811
|
+
function isAuthHttpStatus(code) {
|
|
812
|
+
return code === 401 || code === 403;
|
|
813
|
+
}
|
|
789
814
|
var HlsEngine = class {
|
|
790
815
|
constructor(options) {
|
|
791
816
|
this.options = options;
|
|
@@ -798,49 +823,47 @@ var HlsEngine = class {
|
|
|
798
823
|
this.qualitySelection = "auto";
|
|
799
824
|
}
|
|
800
825
|
async start() {
|
|
801
|
-
const { videoEl, playbackUrl,
|
|
826
|
+
const { videoEl, playbackUrl, startMuted, volume } = this.options;
|
|
802
827
|
videoEl.muted = startMuted;
|
|
803
|
-
if (typeof volume === "number")
|
|
828
|
+
if (typeof volume === "number") {
|
|
829
|
+
videoEl.volume = Math.min(1, Math.max(0, volume));
|
|
830
|
+
}
|
|
804
831
|
const Hls = (await import("hls.js")).default;
|
|
805
832
|
if (Hls.isSupported()) {
|
|
806
833
|
this.supportMode = "hls.js";
|
|
807
834
|
this.options.callbacks.onSupportMode?.("hls.js");
|
|
808
835
|
await this.startWithHlsJs(Hls, playbackUrl);
|
|
809
|
-
|
|
836
|
+
return;
|
|
837
|
+
}
|
|
838
|
+
if (videoEl.canPlayType("application/vnd.apple.mpegurl")) {
|
|
810
839
|
this.supportMode = "native";
|
|
811
840
|
this.options.callbacks.onSupportMode?.("native");
|
|
812
841
|
videoEl.src = this.options.authParams.applyToUrl(playbackUrl);
|
|
813
842
|
this.bindMediaEvents();
|
|
814
843
|
this.options.callbacks.onStateChange?.("ready");
|
|
815
|
-
|
|
816
|
-
this.supportMode = "unsupported";
|
|
817
|
-
this.options.callbacks.onSupportMode?.("unsupported");
|
|
818
|
-
this.options.callbacks.onFatalError?.("HLS is not supported in this browser");
|
|
844
|
+
await this.applyStartPositionAndAutoplay();
|
|
819
845
|
return;
|
|
820
846
|
}
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
await videoEl.play();
|
|
827
|
-
} catch {
|
|
828
|
-
if (!videoEl.muted) {
|
|
829
|
-
videoEl.muted = true;
|
|
830
|
-
try {
|
|
831
|
-
await videoEl.play();
|
|
832
|
-
} catch {
|
|
833
|
-
this.options.logger.warn("Autoplay blocked");
|
|
834
|
-
}
|
|
835
|
-
}
|
|
836
|
-
}
|
|
837
|
-
}
|
|
847
|
+
this.supportMode = "unsupported";
|
|
848
|
+
this.options.callbacks.onSupportMode?.("unsupported");
|
|
849
|
+
this.options.callbacks.onFatalError?.(
|
|
850
|
+
"HLS is not supported in this browser"
|
|
851
|
+
);
|
|
838
852
|
}
|
|
839
853
|
async startWithHlsJs(Hls, playbackUrl) {
|
|
840
|
-
const {
|
|
854
|
+
const {
|
|
855
|
+
videoEl,
|
|
856
|
+
authParams,
|
|
857
|
+
hlsConfig,
|
|
858
|
+
callbacks,
|
|
859
|
+
videoId,
|
|
860
|
+
keyProxyUrlBuilder,
|
|
861
|
+
getKeyAccessToken
|
|
862
|
+
} = this.options;
|
|
841
863
|
const loader = createAuthParamsLoader(Hls, authParams, {
|
|
842
864
|
videoId,
|
|
843
|
-
keyProxyUrlBuilder
|
|
865
|
+
keyProxyUrlBuilder,
|
|
866
|
+
getKeyAccessToken
|
|
844
867
|
});
|
|
845
868
|
this.hls = new Hls({
|
|
846
869
|
enableWorker: hlsConfig.enableWorker,
|
|
@@ -851,6 +874,7 @@ var HlsEngine = class {
|
|
|
851
874
|
this.hls.attachMedia(videoEl);
|
|
852
875
|
this.hls.loadSource(authParams.applyToUrl(playbackUrl));
|
|
853
876
|
this.hls.on(Hls.Events.MANIFEST_PARSED, (_event, data) => {
|
|
877
|
+
if (this.destroyed) return;
|
|
854
878
|
this.qualities = (data.levels ?? []).map((level, index) => ({
|
|
855
879
|
index,
|
|
856
880
|
height: level.height ?? 0,
|
|
@@ -860,42 +884,95 @@ var HlsEngine = class {
|
|
|
860
884
|
}));
|
|
861
885
|
callbacks.onQualitiesChange?.(this.qualities);
|
|
862
886
|
callbacks.onStateChange?.("ready");
|
|
887
|
+
void this.applyStartPositionAndAutoplay();
|
|
863
888
|
});
|
|
864
889
|
this.hls.on(Hls.Events.ERROR, (_event, data) => {
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
890
|
+
this.handleHlsError(Hls, data);
|
|
891
|
+
});
|
|
892
|
+
this.bindMediaEvents();
|
|
893
|
+
}
|
|
894
|
+
handleHlsError(Hls, data) {
|
|
895
|
+
if (this.destroyed) return;
|
|
896
|
+
const { callbacks, hlsConfig, keyProxyUrlBuilder, getKeyAccessToken } = this.options;
|
|
897
|
+
const status = data.response?.code;
|
|
898
|
+
if (data.details === Hls.ErrorDetails.KEY_LOAD_ERROR && !keyProxyUrlBuilder && !getKeyAccessToken) {
|
|
899
|
+
callbacks.onFatalError?.(
|
|
900
|
+
"Encryption key load failed. Configure streaming.getKeyAccessToken (browser Bearer) or streaming.keyProxyUrlBuilder (Cloudflare-allowlisted BFF) for Appextech AES-encrypted HLS."
|
|
901
|
+
);
|
|
902
|
+
return;
|
|
903
|
+
}
|
|
904
|
+
const authFailure = isAuthHttpStatus(status) || data.details === Hls.ErrorDetails.KEY_LOAD_ERROR && (status === void 0 || status === 0 || isAuthHttpStatus(status));
|
|
905
|
+
if (!data.fatal) {
|
|
906
|
+
if (authFailure && data.type === Hls.ErrorTypes.NETWORK_ERROR && (data.details === Hls.ErrorDetails.FRAG_LOAD_ERROR || data.details === Hls.ErrorDetails.LEVEL_LOAD_ERROR || data.details === Hls.ErrorDetails.KEY_LOAD_ERROR)) {
|
|
907
|
+
callbacks.onAuthRecoveryNeeded?.(
|
|
908
|
+
data.details === Hls.ErrorDetails.KEY_LOAD_ERROR ? "key_error" : data.details === Hls.ErrorDetails.LEVEL_LOAD_ERROR ? "level_error" : "frag_error"
|
|
909
|
+
);
|
|
910
|
+
}
|
|
911
|
+
return;
|
|
912
|
+
}
|
|
913
|
+
if (data.type === Hls.ErrorTypes.NETWORK_ERROR) {
|
|
914
|
+
this.networkRecoveryCount += 1;
|
|
915
|
+
if (this.networkRecoveryCount <= hlsConfig.fatalRecoveryLimit) {
|
|
916
|
+
if (authFailure) {
|
|
917
|
+
callbacks.onAuthRecoveryNeeded?.("fatal_network");
|
|
870
918
|
}
|
|
919
|
+
this.hls?.startLoad();
|
|
871
920
|
return;
|
|
872
921
|
}
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
922
|
+
}
|
|
923
|
+
if (data.type === Hls.ErrorTypes.MEDIA_ERROR) {
|
|
924
|
+
this.mediaRecoveryCount += 1;
|
|
925
|
+
if (this.mediaRecoveryCount <= hlsConfig.fatalRecoveryLimit) {
|
|
926
|
+
this.hls?.recoverMediaError();
|
|
927
|
+
return;
|
|
928
|
+
}
|
|
929
|
+
}
|
|
930
|
+
callbacks.onFatalError?.(data.details || "Fatal HLS error");
|
|
931
|
+
}
|
|
932
|
+
async applyStartPositionAndAutoplay() {
|
|
933
|
+
if (this.destroyed) return;
|
|
934
|
+
const { videoEl, autoplay, startPosition } = this.options;
|
|
935
|
+
if (typeof startPosition === "number" && startPosition > 0) {
|
|
936
|
+
const seek = () => {
|
|
937
|
+
if (this.destroyed) return;
|
|
938
|
+
try {
|
|
939
|
+
videoEl.currentTime = startPosition;
|
|
940
|
+
} catch {
|
|
879
941
|
}
|
|
942
|
+
};
|
|
943
|
+
if (videoEl.seekable.length > 0) {
|
|
944
|
+
seek();
|
|
945
|
+
} else {
|
|
946
|
+
videoEl.addEventListener("loadedmetadata", seek, { once: true });
|
|
880
947
|
}
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
948
|
+
}
|
|
949
|
+
if (!autoplay) return;
|
|
950
|
+
try {
|
|
951
|
+
await videoEl.play();
|
|
952
|
+
} catch {
|
|
953
|
+
if (!videoEl.muted) {
|
|
954
|
+
videoEl.muted = true;
|
|
955
|
+
try {
|
|
956
|
+
await videoEl.play();
|
|
957
|
+
} catch {
|
|
958
|
+
this.options.logger.warn("Autoplay blocked");
|
|
886
959
|
}
|
|
887
960
|
}
|
|
888
|
-
|
|
889
|
-
});
|
|
890
|
-
this.bindMediaEvents();
|
|
961
|
+
}
|
|
891
962
|
}
|
|
892
963
|
bindMediaEvents() {
|
|
893
964
|
const { videoEl, callbacks } = this.options;
|
|
894
|
-
videoEl.addEventListener(
|
|
965
|
+
videoEl.addEventListener(
|
|
966
|
+
"playing",
|
|
967
|
+
() => callbacks.onStateChange?.("playing")
|
|
968
|
+
);
|
|
895
969
|
videoEl.addEventListener("pause", () => {
|
|
896
970
|
if (!videoEl.ended) callbacks.onStateChange?.("paused");
|
|
897
971
|
});
|
|
898
|
-
videoEl.addEventListener(
|
|
972
|
+
videoEl.addEventListener(
|
|
973
|
+
"waiting",
|
|
974
|
+
() => callbacks.onStateChange?.("buffering")
|
|
975
|
+
);
|
|
899
976
|
videoEl.addEventListener("ended", () => {
|
|
900
977
|
callbacks.onStateChange?.("ended");
|
|
901
978
|
callbacks.onEnded?.();
|
|
@@ -913,6 +990,7 @@ var HlsEngine = class {
|
|
|
913
990
|
}
|
|
914
991
|
}
|
|
915
992
|
resumeAfterAuthRenew() {
|
|
993
|
+
this.networkRecoveryCount = 0;
|
|
916
994
|
this.hls?.startLoad();
|
|
917
995
|
this.updateAuthParams();
|
|
918
996
|
}
|
|
@@ -1055,7 +1133,8 @@ function createVideoPlayer(options) {
|
|
|
1055
1133
|
startPosition: config.player.startPosition,
|
|
1056
1134
|
volume: config.player.volume,
|
|
1057
1135
|
videoId: options.videoId,
|
|
1058
|
-
keyProxyUrlBuilder:
|
|
1136
|
+
keyProxyUrlBuilder: config.streaming.keyProxyUrlBuilder,
|
|
1137
|
+
getKeyAccessToken: config.streaming.getKeyAccessToken,
|
|
1059
1138
|
hlsConfig: config.streaming.hls,
|
|
1060
1139
|
logger,
|
|
1061
1140
|
callbacks: {
|
|
@@ -1116,6 +1195,14 @@ function createVideoPlayer(options) {
|
|
|
1116
1195
|
onRenewing: () => setState("renewing"),
|
|
1117
1196
|
onRenewed: (nextExpiresAt) => {
|
|
1118
1197
|
engine?.resumeAfterAuthRenew();
|
|
1198
|
+
if (!destroyed) {
|
|
1199
|
+
const el2 = videoEl;
|
|
1200
|
+
if (el2 && !el2.paused && !el2.ended) {
|
|
1201
|
+
setState("playing");
|
|
1202
|
+
} else {
|
|
1203
|
+
setState("ready");
|
|
1204
|
+
}
|
|
1205
|
+
}
|
|
1119
1206
|
events.emit("tokenrefresh", { expiresAt: nextExpiresAt });
|
|
1120
1207
|
events.emit("sourcechange", { expiresAt: nextExpiresAt });
|
|
1121
1208
|
},
|
|
@@ -1317,7 +1404,8 @@ function createVideoPlayer(options) {
|
|
|
1317
1404
|
streaming: {
|
|
1318
1405
|
engine: "hls",
|
|
1319
1406
|
hls: { ...config.streaming.hls, ...partial?.streaming?.hls },
|
|
1320
|
-
keyProxyUrlBuilder: partial?.streaming?.keyProxyUrlBuilder ?? config.streaming.keyProxyUrlBuilder
|
|
1407
|
+
keyProxyUrlBuilder: partial?.streaming?.keyProxyUrlBuilder ?? config.streaming.keyProxyUrlBuilder,
|
|
1408
|
+
getKeyAccessToken: partial?.streaming?.getKeyAccessToken ?? config.streaming.getKeyAccessToken
|
|
1321
1409
|
},
|
|
1322
1410
|
logging: { ...config.logging, ...partial?.logging },
|
|
1323
1411
|
debug: { ...config.debug, ...partial?.debug },
|