Skip to content

fix(video): resolve playback freeze caused by aggressive re-seek - #4

Open
aldegad wants to merge 2 commits into
mainfrom
claude/fix-video-rendering-performance-qMbjm
Open

fix(video): resolve playback freeze caused by aggressive re-seek#4
aldegad wants to merge 2 commits into
mainfrom
claude/fix-video-rendering-performance-qMbjm

Conversation

@aldegad

@aldegad aldegad commented Mar 24, 2026

Copy link
Copy Markdown
Owner

Summary

  • 재생 중 비디오 프레임 스킵 제거: 렌더러가 drift > 0.1875s일 때 프레임을 완전히 건너뛰던 로직 제거. 재생 중에는 비디오 엘리먼트가 가진 현재 프레임을 항상 그리도록 변경
  • 미디어 동기화 re-seek 임계값 완화: 재생 중 drift threshold를 0.15s → 0.8s로 변경하여 디코더를 중단시키는 seek 폭풍 방지
  • 정지/스크럽 시 정밀도 유지: 기존 0.15s 임계값은 스크럽/정지 상태에서만 적용

원인 분석

배속 조정된 클립 재생 시 악순환 발생:

  1. 50ms 간격 sync 체크에서 drift > 0.15s 감지 → 강제 seek
  2. Seek이 디코더를 중단 → 비디오가 더 뒤처짐
  3. 렌더러도 drift > 0.1875s면 프레임 스킵 → committed frame(정지 화면)만 표시
  4. 결과: M4 Pro Max에서도 ~1 FPS 시각 출력

Test plan

  • 단일 비디오 클립을 1x, 2x, 5x, 10x 배속으로 재생하여 부드러운 프레임 출력 확인
  • 클립을 나눈 후 재생하여 클립 경계에서 끊김 없는지 확인
  • 오디오가 포함된 비디오에서 영상-음성 싱크가 크게 밀리지 않는지 확인
  • 타임라인 스크럽 시 프레임 정확도가 유지되는지 확인 (정지 상태 0.05s 임계값)
  • 루프 재생 시 루프 포인트에서 정상 동작하는지 확인

https://claude.ai/code/session_01JrQh18dyZyLDU5U8MCHQie

claude added 2 commits March 24, 2026 16:15
…frame skipping

During playback with speed-adjusted clips, the media sync was re-seeking
video elements every 50ms when drift exceeded 0.15s. This interrupted the
decoder, causing it to fall further behind, creating a vicious cycle that
resulted in ~1 FPS visual output on capable hardware.

Three changes fix this:
- Remove frame skip in renderer: always draw the current video frame during
  playback instead of skipping when drift > 0.1875s
- Relax sync drift threshold from 0.15s to 0.8s during playback to let
  the video decoder catch up naturally
- Keep strict 0.15s threshold for scrubbing/pause where accuracy matters

https://claude.ai/code/session_01JrQh18dyZyLDU5U8MCHQie

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: af8af4b770

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines 160 to +163
const videoSeekThreshold =
desiredState.isAudible && !isWebAudioReadyRef.current(clip.sourceUrl)
? Math.max(PLAYBACK.SEEK_DRIFT_THRESHOLD, 0.45)
: PLAYBACK.SEEK_DRIFT_THRESHOLD;
? Math.max(PLAYBACK.PLAYBACK_SEEK_DRIFT_THRESHOLD, 0.8)
: PLAYBACK.PLAYBACK_SEEK_DRIFT_THRESHOLD;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge 재생 중 0.8초 미만 seek를 즉시 재동기화하세요

재생 중 타임라인을 짧게 seek(예: ±0.2~0.7초)하면 videoSeekThreshold가 0.8초로 완화되어 video.currentTime 보정이 발생하지 않습니다. 이 경로에서 seek()는 재생을 멈추지 않고 타임라인 시간만 점프시키기 때문에, 비디오 엘리먼트와 타임라인이 같은 속도로 계속 진행되며 생긴 오프셋이 사라지지 않아 영구적인 A/V·플레이헤드 불일치가 됩니다(이전 임계값 0.15/0.45에서는 빠르게 복구되던 동작).

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants