mirror of
https://github.com/Sea-Haven-Industries/shoc-frontend-new.git
synced 2026-10-05 06:02:08 +00:00
37 lines
1.1 KiB
TypeScript
37 lines
1.1 KiB
TypeScript
|
|
/**
|
||
|
|
* Best-effort client-side video duration probe. Resolves null when the browser
|
||
|
|
* cannot decode the container's metadata — callers must not block the upload in
|
||
|
|
* that case (SH-116: duration is a client-side check only).
|
||
|
|
*/
|
||
|
|
export const VIDEO_DURATION_PROBE_TIMEOUT_MS = 10_000;
|
||
|
|
|
||
|
|
export function probeVideoDurationSeconds(file: File): Promise<number | null> {
|
||
|
|
return new Promise((resolve) => {
|
||
|
|
const url = URL.createObjectURL(file);
|
||
|
|
const video = document.createElement("video");
|
||
|
|
let settled = false;
|
||
|
|
|
||
|
|
const done = (value: number | null) => {
|
||
|
|
if (settled) return;
|
||
|
|
settled = true;
|
||
|
|
video.removeAttribute("src");
|
||
|
|
video.load();
|
||
|
|
URL.revokeObjectURL(url);
|
||
|
|
resolve(value);
|
||
|
|
};
|
||
|
|
|
||
|
|
const timeout = window.setTimeout(() => done(null), VIDEO_DURATION_PROBE_TIMEOUT_MS);
|
||
|
|
|
||
|
|
video.preload = "metadata";
|
||
|
|
video.onloadedmetadata = () => {
|
||
|
|
window.clearTimeout(timeout);
|
||
|
|
done(Number.isFinite(video.duration) ? video.duration : null);
|
||
|
|
};
|
||
|
|
video.onerror = () => {
|
||
|
|
window.clearTimeout(timeout);
|
||
|
|
done(null);
|
||
|
|
};
|
||
|
|
video.src = url;
|
||
|
|
});
|
||
|
|
}
|