🕐 커밋 시간: 2025. 11. 12. 20:57:22 📊 변경 통계: • 총 파일: 2개 📁 추가된 파일: + com.twin.app.shoptime/.docs/ProductVideoV2-YouTube-Video-Type-Issue-Analysis.md + com.twin.app.shoptime/.docs/ProductVideoV2-YouTube-iframe-Event-Problem-Analysis.md 🔧 함수 변경 내용: 📄 com.twin.app.shoptime/.docs/ProductVideoV2-YouTube-Video-Type-Issue-Analysis.md (md파일): ✅ Added: useMemo(), toLowerCase() 📄 com.twin.app.shoptime/.docs/ProductVideoV2-YouTube-iframe-Event-Problem-Analysis.md (md파일): ✅ Added: postMessage(), setTimeout(), useEffect(), setInterval() 🔧 주요 변경 내용: • 타입 시스템 안정성 강화 • 개발 문서 및 가이드 개선
6.8 KiB
6.8 KiB
ProductVideoV2 YouTube iframe 이벤트 문제 분석 및 해결 방안
문제 현상
YouTube 비디오가 전체화면 모드로 전환되면 iframe 내부의 YouTube 컨트롤 오버레이가 나타나서 키보드/마우스 이벤트를 가로채서 일반 모드로 돌아올 수 없음
🔥 근본 원인 분석
1. YouTube iframe의 독립적 이벤트 처리
문제점
- YouTube iframe은 독립적인 문서 컨텍스트를 가짐
- iframe 내부의 YouTube 플레이어 컨트롤이 자체적인 이벤트 핸들링을 함
- 부모 문서의
window.addEventListener('keydown', ...)가 iframe 내부까지 전파되지 않음
증거
window.addEventListener('keydown', handleFullscreenKeyDown, true)(capture phase)로 설정했지만 iframe 내부까지는 도달하지 못함- YouTube iframe의 native event handling이 더 높은 우선순위를 가짐
2. Spotlight 포커스 시스템의 한계
문제점
- 현재 Spotlight 시스템은 React 컴포넌트 DOM 요소에만 동작
- YouTube iframe 내부의 요소는 Spotlight가 제어할 수 없는 영역
spotlightRestrict="self-only"가 iframe 내부까지 적용되지 않음
3. TReactPlayer의 내부 동작 방식
문제점
- TReactPlayer는 react-player 라이브러리를 사용
- YouTube iframe을 생성할 때 내부적으로 설정을 덮어쓸 수 있음
- YOUTUBECONFIG가 react-player에 제대로 전달되지 않을 가능성
4. webOS 환경 특성
문제점
- webOS TV 환경에서는 키코드가 다르게 동작
- 리모컨 버튼의 키코드: Back(461), Return(10009), ArrowUp/Down(37/40) 등
- 이벤트 처리 순서가 웹 브라우저와 다를 수 있음
🎯 구체적인 문제 시나리오
시나리오 1: ESC 키 문제
- 사용자가 ESC 키 누름
- YouTube iframe이 이벤트를 먼저 처리
- 부모 문서의
handleFullscreenKeyDown가 호출되지 않음 - 결과: 일반 모드로 돌아갈 수 없음
시나리오 2: Back 버튼(리모컨) 문제
- 리모컨 Back 버튼 누름 (keyCode: 461)
- YouTube iframe이 이벤트를 가로챔
- 결과: 포커스를 벗어나지 못함
시나리오 3: Spotlight 포커스 문제
- Spotlight가 전체화면 컨테이너에 포커스 설정
- YouTube iframe이 포커스를 훔쳐감
- 결과: Spotlight 제어 불가
시나리오 4: 클릭/터치 이벤트 문제
- 전체화면에서 사용자가 화면 클릭
- YouTube iframe이 클릭 이벤트를 처리
- 결과: 전체화면 해제 불가
🛠️ 해결 방안 분석
방안 1: YouTube 컨트롤 완전 제거 (현재 시도 중)
구현 내용
const YOUTUBECONFIG = {
playerVars: {
controls: 0, // ✅ 플레이어 컨트롤 완전 숨김
disablekb: 1, // ✅ 키보드 입력 완전 비활성화 (핵심)
fs: 0, // ✅ 전체화면 버튼 비활성화
rel: 0, // ✅ 관련 동영상 비활성화
// ... 기타 설정
},
};
예상 효과
- YouTube iframe이 내부 이벤트를 처리하지 않음
- 부모 문서가 완전히 이벤트 제어
- Spotlight 포커스 시스템 정상 동작
현재 문제점
- YOUTUBECONFIG가 react-player에 제대로 전달되지 않을 수 있음
- TReactPlayer가 내부적으로 설정을 덮어쓸 가능성
방안 2: YouTube PostMessage API 활용
구현 방식
const sendYouTubeCommand = (command, args = []) => {
const iframe = document.querySelector('iframe[src*="youtube"]');
if (iframe) {
iframe.contentWindow.postMessage({
event: 'command',
func: command,
args: args
}, '*');
}
};
// ESC 키 처리
sendYouTubeCommand('pauseVideo');
setTimeout(() => setIsFullscreen(false), 100);
장점
- YouTube iframe과 직접 통신 가능
- 더 정교한 제어 가능
단점
- 복잡성 증가
- iframe 로드 타이밍 이슈
방안 3: 강제 포커스 회수
구현 방식
useEffect(() => {
if (isFullscreen && isYoutube) {
const interval = setInterval(() => {
Spotlight.focus('product-video-v2-fullscreen-portal');
}, 1000);
return () => clearInterval(interval);
}
}, [isFullscreen, isYoutube]);
장점
- 포커스 유지 보장
- 간단한 구현
단점
- 리소스 낭비
- 근본적인 해결책 아님
방안 4: TReactPlayer 대신 직접 제어
구현 방식
- react-player 라이브러리 대신 직접 YouTube iframe 제어
- iframe 생성과 제어를 완전히 직접 관리
장점
- 완벽한 제어 가능
- 의도치 않은 동작 방지
단점
- 복잡성 급증
- 유지보수 어려움
🔍 진단을 위한 확인 사항
1. 로그 확인
// reactPlayerSubtitleConfig 설정 확인
console.log('🎥 [reactPlayerSubtitleConfig] 설정 생성', {
isYoutube: isYoutube,
hasSubtitle: !!subtitleUrl,
youtubeConfig: YOUTUBECONFIG,
});
2. DOM 확인
- YouTube iframe이 실제로 생성되는지 확인
- TReactPlayer가 iframe을 제대로 감싸고 있는지 확인
- iframe에 적용된 설정 확인
3. 이벤트 전파 확인
// 전체화면 키보드 이벤트 로깅
console.log('🖥️ [Fullscreen Container] 키보드 이벤트 감지', {
key: e.key,
keyCode: e.keyCode,
isYoutube: isYoutube,
});
🎯 추천 해결 순서
1단계: 현재 방안 1 완료
- YOUTUBECONFIG가 react-player에 제대로 전달되는지 확인
- YouTube iframe이 실제로 컨트롤이 비활성화되는지 확인
2단계: 강화된 이벤트 핸들링
- 리모컨 버튼 키코드 확장 (461, 10009 등)
- Capture phase 이벤트 처리 강화
3단계: 방안 2 전환 (필요 시)
- PostMessage API로 직접 YouTube 제어
4단계: 방안 3 보조
- 주기적 포커스 회수로 안정성 확보
🔄 롤백 계획
롤백 1: YOUTUBECONFIG 복원
const YOUTUBECONFIG = {
playerVars: {
controls: 0,
autoplay: 1,
disablekb: 0, // 키보드 활성화로 복원
fs: 1, // 전체화면 버튼 활성화로 복원
// ... 기존 설정
},
};
롤백 2: 이벤트 핸들러 복원
// Back 버튼 처리 로직 제거
// return toggleOverlayVisibility();
롤백 3: reactPlayerSubtitleConfig 복원
// isYoutube 의존성 제거
}, [productInfo?.prdtMediaSubtitlUrl]);
결론
가장 현실적인 해결책은 **방안 1 (YouTube 컨트롤 완전 제거)**과 **방안 2 (PostMessage API)**의 조합입니다:
- 일단 YOUTUBECONFIG를 통해 컨트롤 완전 비활성화
- 필요시 PostMessage API로 직접 YouTube 제어
- Spotlight 포커스 시스템 보강으로 안정성 확보
이렇게 하면 YouTube iframe이 이벤트를 가로채지 못하고, 기존의 키보드 핸들링 로직이 정상 동작할 것입니다.