From b93b662c02641e3538222d6b3697e9535f95ab80 Mon Sep 17 00:00:00 2001 From: Sebastien Castiel Date: Wed, 15 Apr 2026 13:08:46 -0400 Subject: [PATCH] Fix blank frames when speed > 1 (#26) The speed setting scaled the frame-sampling index (frame * speed) but left each sequence's durationInFrames unscaled, so at speed=2 the index ran past the pre-rendered frames array halfway through each typing sequence, rendering undefined (blank). Scale durationInFrames by 1/speed for non-transition sequences so the real timeline matches the content timeline, and clamp the sample index as a safety net. Transition sequences keep their fixed 20-frame slide timing. Co-Authored-By: Claude Opus 4.6 (1M context) --- src/components/remotion/code-composition.tsx | 9 ++++++++- src/components/remotion/composition-data.ts | 18 +++++++++++++++++- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/src/components/remotion/code-composition.tsx b/src/components/remotion/code-composition.tsx index 66a97ca..8dfac4f 100644 --- a/src/components/remotion/code-composition.tsx +++ b/src/components/remotion/code-composition.tsx @@ -152,7 +152,14 @@ function CodeSequences({ lang={seq.lang} filename={seq.filename} filenames={filenames} - codeForFrame={(frame) => seq.frames[Math.floor(frame * speed)]} + codeForFrame={(frame) => { + const effectiveSpeed = seq.isTransition ? 1 : speed + const index = Math.min( + Math.floor(frame * effectiveSpeed), + seq.frames.length - 1, + ) + return seq.frames[index] + }} watermark={watermark} scale={scale} font={font} diff --git a/src/components/remotion/composition-data.ts b/src/components/remotion/composition-data.ts index b7f618a..cc7c8e6 100644 --- a/src/components/remotion/composition-data.ts +++ b/src/components/remotion/composition-data.ts @@ -127,7 +127,23 @@ export function getCompositionData({ filename: steps[steps.length - 1]?.filename, }) - return { sequences, metadata } + const { speed } = metadata + const scaledSequences = + speed === 1 + ? sequences + : sequences.map((seq) => + seq.isTransition + ? seq + : { + ...seq, + durationInFrames: Math.max( + 1, + Math.ceil(seq.durationInFrames / speed), + ), + }, + ) + + return { sequences: scaledSequences, metadata } } export type CompositionData = ReturnType