release(video-player): v0.1.3

This commit is contained in:
2026-03-20 12:10:56 +03:00
parent 81c5550311
commit 8ac6e00b68
4 changed files with 58 additions and 21 deletions

View File

@@ -1,6 +1,6 @@
{ {
"name": "@hublib-web/video-player", "name": "@hublib-web/video-player",
"version": "0.1.2", "version": "0.1.3",
"description": "Cross-framework video player package for React and Angular", "description": "Cross-framework video player package for React and Angular",
"license": "MIT", "license": "MIT",
"type": "module", "type": "module",

View File

@@ -1,10 +1,12 @@
export const formatTime = (seconds: number) => { export const formatTime = (seconds: number) => {
const safeSeconds =
Number.isFinite(seconds) && seconds > 0 ? seconds : 0;
const pad = (num: number) => String(num).padStart(2, "0"); const pad = (num: number) => String(num).padStart(2, "0");
const hrs = Math.floor(seconds / 3600); const hrs = Math.floor(safeSeconds / 3600);
const mins = Math.floor((seconds % 3600) / 60); const mins = Math.floor((safeSeconds % 3600) / 60);
const secs = Math.floor(seconds % 60); const secs = Math.floor(safeSeconds % 60);
if (seconds < 3600) { if (safeSeconds < 3600) {
return `${pad(mins)}:${pad(secs)}`; return `${pad(mins)}:${pad(secs)}`;
} }

View File

@@ -718,6 +718,31 @@ export class VideoPlayerRuntime {
}; };
} }
private syncLiveUi(
player: VideoPlayerRuntimePlayer,
video: HTMLVideoElement,
isLive: boolean,
) {
const wrapper = video.parentElement;
if (isLive) {
wrapper?.classList.add("vjs-hls-live", "vjs-live");
player.duration(Infinity);
if (player.liveTracker) {
player.liveTracker.isLive_ = true;
player.liveTracker.startTracking();
player.liveTracker.trigger("durationchange");
}
return;
}
wrapper?.classList.remove("vjs-hls-live", "vjs-live");
if (player.liveTracker) {
player.liveTracker.isLive_ = false;
player.liveTracker.trigger("durationchange");
}
}
private async loadHlsSource() { private async loadHlsSource() {
const options = this.options; const options = this.options;
const player = this.playerRef; const player = this.playerRef;
@@ -769,14 +794,8 @@ export class VideoPlayerRuntime {
live: details?.live, live: details?.live,
}); });
if (details?.live) { if (typeof details?.live === "boolean") {
video.parentElement?.classList.add("vjs-hls-live", "vjs-live"); this.syncLiveUi(player, video, details.live);
player.duration(Infinity);
if (player.liveTracker) {
player.liveTracker.isLive_ = true;
player.liveTracker.startTracking();
player.liveTracker.trigger("durationchange");
}
} }
if (options.initialTime > 0) { if (options.initialTime > 0) {
@@ -784,6 +803,22 @@ export class VideoPlayerRuntime {
} }
}); });
hls.on(Hls.Events.LEVEL_LOADED, (_event, data) => {
const details = data?.details;
if (!details) {
return;
}
this.emit("manifestloaded", {
engine: "hls",
duration: details.totalduration,
live: details.live,
});
if (typeof details.live === "boolean") {
this.syncLiveUi(player, video, details.live);
}
});
hls.on(Hls.Events.FRAG_CHANGED, () => { hls.on(Hls.Events.FRAG_CHANGED, () => {
if (player.liveTracker) { if (player.liveTracker) {
player.liveTracker.atLiveEdge = isAtLiveEdge; player.liveTracker.atLiveEdge = isAtLiveEdge;
@@ -1034,10 +1069,8 @@ export class VideoPlayerRuntime {
const videoElement = this.playerRef const videoElement = this.playerRef
.el() .el()
?.querySelector("video") as HTMLVideoElement | null; ?.querySelector("video") as HTMLVideoElement | null;
videoElement?.parentElement?.classList.remove("vjs-hls-live", "vjs-live"); if (videoElement) {
if (this.playerRef.liveTracker) { this.syncLiveUi(this.playerRef, videoElement, false);
this.playerRef.liveTracker.isLive_ = false;
this.playerRef.liveTracker.trigger("durationchange");
} }
} }
} }

View File

@@ -1,9 +1,11 @@
export const formatTime = (seconds: number) => { export const formatTime = (seconds: number) => {
const safeSeconds =
Number.isFinite(seconds) && seconds > 0 ? seconds : 0;
const pad = (num: number) => String(num).padStart(2, "0"); const pad = (num: number) => String(num).padStart(2, "0");
const hrs = Math.floor(seconds / 3600); const hrs = Math.floor(safeSeconds / 3600);
const mins = Math.floor((seconds % 3600) / 60); const mins = Math.floor((safeSeconds % 3600) / 60);
const secs = Math.floor(seconds % 60); const secs = Math.floor(safeSeconds % 60);
if (seconds < 3600) { if (safeSeconds < 3600) {
return `${pad(mins)}:${pad(secs)}`; return `${pad(mins)}:${pad(secs)}`;
} }
return `${pad(hrs)}:${pad(mins)}:${pad(secs)}`; return `${pad(hrs)}:${pad(mins)}:${pad(secs)}`;