기존 GhiVideo 저장소 HEAD의 트래킹 소스 362개 파일을 복제. (node_modules·storage·빌드 산출물·대용량 미디어는 .gitignore 규칙대로 제외) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
43 lines
2.3 KiB
Markdown
43 lines
2.3 KiB
Markdown
# 라벨이 영상보다 먼저 뜨는 현상 — 영상 첫 프레임 표시 후로 게이트
|
|
|
|
**날짜**: 2026-06-24
|
|
**수정 파일**: `client/src/store/playerStore.ts`, `client/src/hooks/useVideoPlayer.ts`,
|
|
`client/src/components/player/VideoPlayer.tsx`, `client/src/components/overlay/StationOverlay.tsx`
|
|
**관련**: [2026-06-24_1019_라벨-재생즉시표시-증분게시.md](2026-06-24_1019_라벨-재생즉시표시-증분게시.md)
|
|
|
|
## 증상
|
|
재생 시 라벨이 **영상보다 살짝 먼저** 표시됨. (직전 작업으로 라벨이 즉시 게시되면서,
|
|
영상 첫 프레임이 디코드·표시되기 전 검은 화면 위에 라벨이 먼저 보임.)
|
|
|
|
## 원인
|
|
StationOverlay RAF는 데이터/캐시만 준비되면 영상 표시 여부와 무관하게 캔버스에 그림.
|
|
영상 `<video>`의 첫 프레임 표시 시점과 동기화하는 신호가 없었음.
|
|
|
|
## 조치 — "영상 첫 프레임 표시 가능" 신호로 오버레이 게이트
|
|
1. **playerStore**: `videoReady: boolean`(기본 false) + `setVideoReady` 추가.
|
|
`setSource` 시 false 로 리셋(영상 교체 때 다시 게이트).
|
|
2. **useVideoPlayer**: Video.js 이벤트 연결
|
|
- `loadstart` → `setVideoReady(false)` (새 소스 로드 시작)
|
|
- `loadeddata` → `setVideoReady(true)` (첫 프레임 표시 가능)
|
|
- `playing` → `setVideoReady(true)` (폴백)
|
|
3. **VideoPlayer**: store `videoReady` 를 StationOverlay 에 prop 전달.
|
|
4. **StationOverlay**: `videoReady` prop(기본 true=하위호환) → `videoReadyRef`. RAF draw 에서
|
|
`clearRect` 직후 **`if (!videoReadyRef.current) return;`** → 첫 프레임 전엔 라벨/선/나침반 미표시.
|
|
|
|
```ts
|
|
// StationOverlay draw()
|
|
ctx.clearRect(0, 0, W, H);
|
|
if (!videoReadyRef.current) return; // 영상 첫 프레임 전 오버레이 차단
|
|
```
|
|
|
|
## 효과
|
|
- 영상 첫 프레임이 표시된 뒤에야 오버레이가 그려짐 → 라벨이 먼저 뜨는 깜빡임 제거.
|
|
- 영상 교체(폴더 재로드) 시 `loadstart` 로 다시 게이트되어 새 영상 첫 프레임까지 대기.
|
|
- prop 기본값 true 라 StationOverlay 단독 사용처(있다면)는 기존대로 동작.
|
|
|
|
## 검증
|
|
- `npm run build -w client` (node20) tsc + vite build 통과.
|
|
|
|
**소요 시간**: 약 12분
|
|
**Context 사용량**: input ~235k / output ~5k tokens
|