43 lines
1.4 KiB
TypeScript
43 lines
1.4 KiB
TypeScript
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)
|
|
}
|