iOS 웹뷰에서 video.js 풀스크린 깨짐 — playsinline 토글 꼼수
video.js 8.12.0 사용 중. 웹에서는 문제가 없는데 앱(iOS 웹뷰)에서 풀스크린을 하면 화면이 박살나는 문제가 있었음. 가로모드로 넘어가는 순간 레이아웃이 다 깨짐.
안 먹힌 시도들
- 풀스크린 할 때마다 width랑 height를 서로 바꿔치기
- 가로모드 대응한다는 깃허브에 올라온 소스들 참고
전부 소용없었음.
원인은 playsinline
playsinline을 없애면 문제가 없음. iOS는 playsinline이 없으면 비디오를 무조건 기본 HTML5 플레이어 전체화면으로 실행하는데, 이 기본 플레이어는 안 깨짐. 깨지는 건 웹뷰 안에서 인라인 상태로 풀스크린 흉내를 낼 때임.
근데 playsinline을 그냥 빼버릴 수는 없음. controls를 커스터마이징한 소스를 쓰고 있어서 평소엔 인라인으로 재생돼야 함. 그래서 꼼수를 씀.
꼼수: 풀스크린 순간에만 playsinline 떼기
평소엔 인라인으로 재생하다가, 풀스크린 버튼을 누르는 순간에만 playsinline을 떼서 iOS 기본 비디오 플레이어로 넘기는 방식.
<video id="my-video" class="video-js vjs-default-skin" preload="auto" playsinline>
this.player = videojs('my-video', this.options);
this.player.controlBar.fullscreenToggle.off('touchstart'); // 기존 터치 이벤트 삭제
this.player.controlBar.fullscreenToggle.on('touchstart', () => {
if (!this.player.isFullscreen()) {
$("video").removeAttr("playsinline"); // playsinline 제거 → iOS 기본 플레이어로
this.player.pause();
this.player.play(); // 다시 재생하면서 기본 플레이어 풀스크린 진입
$("video").attr("playsinline", "playsinline"); // 다음을 위해 미리 다시 달아둠
}
});
흐름을 풀면:
- 풀스크린 버튼의 기존
touchstart이벤트를 지우고 직접 가로챔 - 풀스크린이 감지되기 전에
playsinline을 제거 - pause → play로 다시 재생시키면 iOS가 기본 HTML5 플레이어 전체화면으로 띄움
playsinline은 바로 다시 달아서 다음 인라인 재생을 대기시켜놓음
이러면 평소엔 커스텀 컨트롤로 인라인 재생, 풀스크린만 iOS 기본 플레이어가 담당하게 됨. 화면 깨지는 문제 해결.
정리
- iOS 웹뷰에서 video.js 풀스크린 깨짐은 CSS로 잡으려 하면 답이 없음.
playsinline이 원인. - 풀스크린 순간에만
playsinline을 떼서 iOS 기본 플레이어에 넘기면 됨. 떼고 → pause/play → 바로 다시 붙이기. - 커스텀 컨트롤과 기본 플레이어 풀스크린의 하이브리드. 꼼수지만 잘 돌아감.