/** * 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 { 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; }); }