release(video-player): v0.1.2

This commit is contained in:
2026-03-11 13:47:47 +03:00
parent 028ce21c4c
commit e4e6bc5af4
6 changed files with 118 additions and 51 deletions

View File

@@ -143,8 +143,12 @@ const detectIOS = () => {
const createAuthPlaylistLoader = ({
debug,
getToken,
refreshToken,
}: {
debug?: boolean;
getToken: () => string | null;
refreshToken: () => void;
}): PlaylistLoaderConstructor => {
const BaseLoader = Hls.DefaultConfig.loader as unknown as new (
config: HlsConfig,
@@ -155,37 +159,31 @@ const createAuthPlaylistLoader = ({
super({ ...config, debug: debug ?? false });
}
load(
override load(
context: PlaylistLoaderContext,
config: LoaderConfiguration,
callbacks: LoaderCallbacks<PlaylistLoaderContext>,
): void {
const start = async () => {
try {
const token = await resolveVideoPlayerToken();
if (token) {
context.headers = {
...(context.headers ?? {}),
Authorization: `Bearer ${token}`,
};
}
} catch (error) {
if (debug) {
console.warn(
"[VideoRuntime:HLS] Failed to append auth header to playlist request",
error,
);
}
} finally {
super.load(context, config, callbacks);
try {
const token = getToken();
if (token) {
context.headers = {
...(context.headers ?? {}),
Authorization: `Bearer ${token}`,
};
}
};
void start().catch(error => {
} catch (error) {
if (debug) {
console.error("[VideoRuntime:HLS] Playlist loader start failed", error);
console.warn(
"[VideoRuntime:HLS] Failed to append auth header to playlist request",
error,
);
}
});
}
// Critical path must stay sync for hls.js loader lifecycle.
super.load(context, config, callbacks);
refreshToken();
}
};
};
@@ -232,6 +230,8 @@ export class VideoPlayerRuntime {
private currentEngine: PlaybackEngine | null = null;
private currentSource: VideoPlayerRuntimeSource | null = null;
private vhsAuthTokenRef: string | null | undefined = null;
private hlsAuthTokenRef: string | null = null;
private hlsTokenResolvePromise: Promise<void> | null = null;
private vhsRequestCleanupRef: (() => void) | null = null;
private visibilityObserverRef: IntersectionObserver | null = null;
private originalPlayRef: VideoPlayerRuntimePlayer["play"] | null = null;
@@ -328,6 +328,8 @@ export class VideoPlayerRuntime {
this.vhsRequestCleanupRef?.();
this.vhsRequestCleanupRef = null;
this.vhsAuthTokenRef = null;
this.hlsAuthTokenRef = null;
this.hlsTokenResolvePromise = null;
if (this.playerRef) {
this.playerRef.dispose();
@@ -358,6 +360,34 @@ export class VideoPlayerRuntime {
return this.playerRef;
}
private async ensureHlsAuthToken(): Promise<void> {
if (this.hlsTokenResolvePromise !== null) {
await this.hlsTokenResolvePromise;
return;
}
this.hlsTokenResolvePromise = resolveVideoPlayerToken()
.then(token => {
this.hlsAuthTokenRef = token ?? null;
})
.catch(() => {
this.hlsAuthTokenRef = null;
})
.finally(() => {
this.hlsTokenResolvePromise = null;
});
await this.hlsTokenResolvePromise;
}
private refreshHlsAuthTokenInBackground(): void {
if (this.hlsTokenResolvePromise !== null) {
return;
}
void this.ensureHlsAuthToken();
}
private emit<K extends keyof VideoPlayerRuntimeEventMap>(
event: K,
payload: VideoPlayerRuntimeEventMap[K],
@@ -658,7 +688,11 @@ export class VideoPlayerRuntime {
? { abrEwmaDefaultEstimate: 10690560 * 1.2 }
: {};
const playlistLoader = createAuthPlaylistLoader({ debug: options.debug });
const playlistLoader = createAuthPlaylistLoader({
debug: options.debug,
getToken: () => this.hlsAuthTokenRef,
refreshToken: () => this.refreshHlsAuthTokenInBackground(),
});
return {
debug: options.debug,
@@ -702,6 +736,9 @@ export class VideoPlayerRuntime {
return;
}
// Resolve async token before starting HLS manifest load.
await this.ensureHlsAuthToken();
const setupHls = () => {
if (this.hlsLoaded) {
return;