const STORE_KEY = 'aigen-default-video-duration' export const VIDEO_DURATION_MIN = 0.5 export const VIDEO_DURATION_MAX = 120 export const VIDEO_DURATION_DEFAULT = 5 export function clampVideoDuration(raw: unknown, fallback = VIDEO_DURATION_DEFAULT) { const value = Number(raw) if (!Number.isFinite(value)) return fallback return Math.min(VIDEO_DURATION_MAX, Math.max(VIDEO_DURATION_MIN, Math.round(value * 10) / 10)) } export function defaultVideoDurationPref() { if (!import.meta.client) return VIDEO_DURATION_DEFAULT try { return clampVideoDuration(localStorage.getItem(STORE_KEY), VIDEO_DURATION_DEFAULT) } catch { return VIDEO_DURATION_DEFAULT } } export function setDefaultVideoDurationPref(raw: unknown) { const next = clampVideoDuration(raw, VIDEO_DURATION_DEFAULT) if (import.meta.client) { try { localStorage.setItem(STORE_KEY, String(next)) } catch { /* ignore */ } } return next } /** Length of one generated part (extension delta), not the stitched family total. */ export function clipPartDuration( clip: { duration?: number; parentClipId?: string | null }, parent?: { duration?: number } | null ) { const own = Number(clip.duration) const prior = Number(parent?.duration) if (clip.parentClipId && Number.isFinite(own) && Number.isFinite(prior) && own > prior + 0.4) { return clampVideoDuration(own - prior) } return clampVideoDuration(own) }