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",
"version": "0.1.2",
"version": "0.1.3",
"description": "Cross-framework video player package for React and Angular",
"license": "MIT",
"type": "module",

View File

@@ -1,10 +1,12 @@
export const formatTime = (seconds: number) => {
const safeSeconds =
Number.isFinite(seconds) && seconds > 0 ? seconds : 0;
const pad = (num: number) => String(num).padStart(2, "0");
const hrs = Math.floor(seconds / 3600);
const mins = Math.floor((seconds % 3600) / 60);
const secs = Math.floor(seconds % 60);
const hrs = Math.floor(safeSeconds / 3600);
const mins = Math.floor((safeSeconds % 3600) / 60);
const secs = Math.floor(safeSeconds % 60);
if (seconds < 3600) {
if (safeSeconds < 3600) {
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() {
const options = this.options;
const player = this.playerRef;
@@ -769,14 +794,8 @@ export class VideoPlayerRuntime {
live: details?.live,
});
if (details?.live) {
video.parentElement?.classList.add("vjs-hls-live", "vjs-live");
player.duration(Infinity);
if (player.liveTracker) {
player.liveTracker.isLive_ = true;
player.liveTracker.startTracking();
player.liveTracker.trigger("durationchange");
}
if (typeof details?.live === "boolean") {
this.syncLiveUi(player, video, details.live);
}
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, () => {
if (player.liveTracker) {
player.liveTracker.atLiveEdge = isAtLiveEdge;
@@ -1034,10 +1069,8 @@ export class VideoPlayerRuntime {
const videoElement = this.playerRef
.el()
?.querySelector("video") as HTMLVideoElement | null;
videoElement?.parentElement?.classList.remove("vjs-hls-live", "vjs-live");
if (this.playerRef.liveTracker) {
this.playerRef.liveTracker.isLive_ = false;
this.playerRef.liveTracker.trigger("durationchange");
if (videoElement) {
this.syncLiveUi(this.playerRef, videoElement, false);
}
}
}

View File

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