fix: dynamic video duration across ProductionForm + LivePreviewCanvas

- Expanded useVideoDurations to detect both form-sourced segments AND
  editable-slot video fields inside content scenes
- Wired videoDurations into ProductionForm (getTemplateDuration,
  compileExpressToTimeline, LivePreviewCanvas, ExportModal)
- LivePreviewCanvas now accepts videoDurations prop
- Simplified getTemplateDuration/compiler: any scene with a known
  video duration uses it, regardless of segmentSource type
- A 33s uploaded video now creates a 33s timeline, not 5s
This commit is contained in:
2026-06-02 09:58:37 -05:00
parent a21675e5fc
commit 560a413c1e
4 changed files with 73 additions and 36 deletions
+6 -3
View File
@@ -36,6 +36,8 @@ export interface LivePreviewCanvasProps {
statusLabel?: string;
/** Whether all required fields are complete */
isComplete?: boolean;
/** Video duration overrides per scene (from useVideoDurations) */
videoDurations?: Record<string, number>;
}
/** Format frame number to mm:ss */
@@ -66,6 +68,7 @@ export const LivePreviewCanvas: React.FC<LivePreviewCanvasProps> = ({
playerRef: externalRef,
statusLabel,
isComplete = false,
videoDurations,
}) => {
const internalRef = useRef<BradlyPlayerRef>(null);
const playerRef = externalRef || internalRef;
@@ -76,13 +79,13 @@ export const LivePreviewCanvas: React.FC<LivePreviewCanvasProps> = ({
const isScrubbing = useRef(false);
const fps = 30;
const totalDuration = getTemplateDuration(template);
const totalDuration = getTemplateDuration(template, videoDurations);
const totalFrames = Math.max(30, totalDuration * fps);
const dimensions = getAspectDimensions(template.aspectRatio);
// Compile template to timeline (reactive to fieldData + mediaFits)
const compiled = useMemo(() => {
const result = compileExpressToTimeline(template, fieldData, designMD, brand);
const result = compileExpressToTimeline(template, fieldData, designMD, brand, videoDurations);
// Strip transitions and apply mediaFit overrides
result.elements = result.elements.map(el => {
const fieldId = el.sourceFieldId;
@@ -97,7 +100,7 @@ export const LivePreviewCanvas: React.FC<LivePreviewCanvasProps> = ({
};
});
return result;
}, [template, fieldData, designMD, brand, mediaFits, containBgColors]);
}, [template, fieldData, designMD, brand, mediaFits, containBgColors, videoDurations]);
const playerInputProps = useMemo(() => ({
designMD,