Daeseon Yoo
Back to project
·UX retro·3 min

쉐도잉 루프 고도화 — 한 줄 반복 / A-B 구간 / 자동 다음 줄을 폴링 하나로

import한 영상 화면에서 TubeShad급 쉐도잉을 만들었다. 한 줄 반복, A-B 구간 반복, 줄별 N회 자동 진행 + 0.5~1.5배속을, 단일 폴링 루프에 모드 분기로 통합했다.

목표

영상 import → 상세화면에서 그 자리에서 쉐도잉. 클립을 따로 만들지 않고, 자막 줄을 반복하고, 구간을 묶어 반복하고, 줄별로 N번씩 자동으로 내려가며 따라 말하기.

통합 모델 — 범위 + 플래그

세 기능을 세 갈래 코드로 짜면 엉킨다. 하나로 통합했다:

조작:

핵심 구현 — 폴링 하나, 모드 분기

YouTube IFrame은 영상 중간 경계에서 ENDED가 아니라 PAUSED를 쏜다. 그래서 onChangeState('ended')에 의존하면 짧은 구간이 다시 안 돈다. 해법은 getCurrentTime을 200ms로 폴링해서 직접 되감기. 단일 인터벌이 하이라이트 + 반복을 모두 구동한다:

함정 + 패턴: 인터벌이 빠르게 바뀌는 UI 상태(loop/auto/reps/cursor)에 반응해야 하는데, 그 값들을 effect 의존성에 넣으면 매 변경마다 타이머가 재구독돼 덜덜거린다. → 인터벌은 안정적인 의존성(playing) 하나로만 걸고, 변하는 값은 ref로 읽는다(loopRef/autoRef/repsRef/cursorRef/repCountRef). 이게 "빠른 상태 + 타이머"의 정석.

거기에 라이브러리의 playbackRate prop으로 0.5~1.5배속(느리게 쉐도잉/빠르게 스킵)을 얹어 전부 조합 가능하게 했다. 예: A=첫줄·B=끝줄 + 자동 + ×3 + 0.75× = "영상 전체를 한 줄씩 3번, 0.75배속으로" 자동 쉐도잉.

커밋

c2d2205(줄 반복) → ded87ba(속도) → ee8d78f(A-B + 자동). 전부 모바일 JS만(백엔드 무변경), 컴파일/타입 통과.