import { AbsoluteFill, Audio, Sequence, spring, useCurrentFrame, useVideoConfig } from "remotion"; import { FPS, type ShortVerticalProps } from "../schema"; import { theme } from "../theme"; import { Captions, Logo, ProgressBar, SceneCard } from "./shared"; import { Starfield } from "./Starfield"; const HOOK_S = 2; // hook lands in the first 2 seconds export function shortVerticalDuration(props: ShortVerticalProps): number { return Math.round((HOOK_S + props.scenes.reduce((s, sc) => s + sc.durationS, 0)) * FPS); } function Hook({ text, accent }: { text: string; accent: string }) { const frame = useCurrentFrame(); const { fps } = useVideoConfig(); const s = spring({ frame, fps, config: { damping: 14 } }); return (

{text}

); } export function ShortVertical(props: ShortVerticalProps) { const accent = props.brand.accent ?? theme.blue; let cursor = HOOK_S * FPS; return ( {props.scenes.map((scene, i) => { const from = cursor; const dur = Math.round(scene.durationS * FPS); cursor += dur; return ( ); })} {/* Narration and caption timings start with the first scene, after the hook. */} {props.audioUrl && ); }