From 1aaf89ce70985dd457c53c6823cc81b057028270 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miguel=20=C3=81ngel?= Date: Mon, 25 May 2026 19:01:49 -0400 Subject: [PATCH] fix(studio): clamp playhead to composition duration in RAF loop MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The studio player's RAF loop in useTimelinePlayer notified the playhead position via liveTime.notify(time) before checking the duration limit. When adapter.getTime() returned a value past the composition's data-duration (due to timing drift or delayed duration calculation), the playhead would visually overshoot — showing e.g. 0:19 on a 0:10 composition. The web player component already had this clamping (playback-state.ts line 42, direct-timeline-clock.ts line 56), but the studio player's forward loop was missing it. Fix: clamp time to dur before notifying, matching the pattern already used in the web player: Math.min(rawTime, dur) when dur > 0. --- packages/studio/src/player/hooks/useTimelinePlayer.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/studio/src/player/hooks/useTimelinePlayer.ts b/packages/studio/src/player/hooks/useTimelinePlayer.ts index f503e8299..10d830670 100644 --- a/packages/studio/src/player/hooks/useTimelinePlayer.ts +++ b/packages/studio/src/player/hooks/useTimelinePlayer.ts @@ -226,8 +226,9 @@ export function useTimelinePlayer() { const tick = () => { const adapter = getAdapter(); if (adapter) { - const time = adapter.getTime(); + const rawTime = adapter.getTime(); const dur = adapter.getDuration(); + const time = dur > 0 ? Math.min(rawTime, dur) : rawTime; liveTime.notify(time); // direct DOM updates, no React re-render const { inPoint, outPoint } = usePlayerStore.getState(); const rawLoopEnd = outPoint !== null ? outPoint : dur;