FullScreen 모드일 때 HTML5 Video 네이티브 컨트롤 감추기

Posted by in Research

 

 

HTML5 등장 이전까지 웹에서 동영상을 제공하기 위해서는 어도비의 플래시 플레이어나 MS의 실버라이트 같은 플러그인을 이용해야 했다. 하지만 이제는 HTML5 Video API를 이용하면 간단한 마크업만으로 동영상을 제공할 수 있다.

 

물론 어디까지나 ‘동영상만 제공할 때’  간단한 마크업으로 가능하다는 이야기다. 브라우저마다 플레이어를 렌더링하는 모습이 제각각이라 제품으로 포장하려면 커스터마이징을 해야 한다. 이 때 건드려야 할 영역 중 하나가 컨트롤이다. 컨트롤은 플레이어 재생, 탐색, 음량 조절 등의 기능을 제공하는 플레이어 가장 하단에 있는 컴포넌트 집합을 말한다.

 

Video Element in Chrome

 

Video Element in Internet Explorer

 

Video Element in Firefox

 

video.js, mediaElement.js, jwPalyer 같은 유명한 HTML5 Video 지원 플레이어들은 모두 네이티브 컨트롤을 감추고 커스텀 컨트롤을 제공한다. 그래서 마크업만 조금 추가하면 쉽게 커스텀 컨트롤을 만들 수 있을 줄 알았다. 그런데 웬걸. 프로토타이핑을 하다가 뜻하지 않은 문제를 만나서 해결하는 데 고생을 했다. 어떤 문제가 있었고 어떻게 해결했는지 구현 흐름을 따라가면서 하나씩 살펴보자.

 

 

커스텀 컨트롤 만들기

커스텀 컨트롤을 만들기 위해서는 우선 네이티브 컨트롤을 감춰야 한다. Video 엘리먼트의 속성중 controls에 false 값을 주면 브라우저가 알아서 네이티브 컨트롤을 숨긴다. controls 속성은 default 값이 false이기 때문에 아예 속성을 지정 안해도 된다. 네이티브 컨트롤을 감춘 다음에는 HTML + CSS로 만든 커스텀 컨트롤을 추가한다. 아래에 간단한 예제가 있다.

 

HTML :

 

CSS :

 

네이티브 컨트롤을 커스텀 컨트롤로 변경한 모습이다.

custom-controls

 

JavaScript로 DOM 이벤트를 받아서 HTML5 Video API를 요청하는 기능을 구현하면 끝이다.

 

HTML5 Video API에 대해서는 아래의 글에 잘 나와있다.

HTML5 Video – HTML5Rocks

 

보면 알겠지만 API가 잘 갖춰져 있어서 기능을 붙이는 것은 어렵지 않다. 문제는 UI다. 전체화면 보기 기능을 추가하면 문제가 발생한다.

 

FullScreen 상태일 때 네이티브 컨트롤 이슈

HTML5 FullScreen API를 이용하면 손쉽게 콘텐츠를 사용자에게 브라우저 전체보기 상태로 보여줄 수 있다. 참고로 인터넷 익스플로러는 버전 11 이상만 지원한다. 아직 표준이 확정된 상태가 아니라 브라우저 벤더 프리픽스가 붙다보니 크로스 브라우징을 위해서는 조금 더러운 코드를 감수해야 한다.

 

전체보기를 눌러서 Video 엘리먼트를 FullScreen 상태로 변경해보면 뭔가 이상한 것을 눈치챌 수 있다.

다시 등장한 네이티브 컨트롤

 

기껏 만들어놓은 커스텀 컨트롤이 가출했다. 심지어 크롬은 네이티브 컨트롤을 다시 꺼내서 보여준다. 힌트를 좀 얻어볼까 싶어 열심히 구글링을 했다. 그 중에 눈에 띄는 제목이 하나 있어 들어가봤다.

 

Hiding Native HTML5 Video Controls in Full-Screen Mode

 

Shadow DOM과 z-index를 이용해서 해결하는 방법인데 간단히 요약하면 다음과 같다.

  1. Video 엘리먼트 안에 있는 Shadow DOM의 display 값을 none으로 변경해서 감춘다.
  2. 커스텀 컨트롤을 감싸는 요소의 z-index를 최대값인 2147483647 로 설정해서 Video 엘리먼트 위에 위치시킨다.

 

Shadow DOM 이야기가 나오다니. 브라우저 호환성 때문에 갸우뚱했지만 간단한 방법이라 일단 적용해봤다.

chrome에서 멋지게 동작

 

멋지게 동작한다. 단, 크롬에서만…

익스플로러, 파이어폭스에서는 정상 동작하지 않는다. Shadow DOM 익스펙터를 아직 지원하지 않는 데다가 브라우저마다 내부 구현 방식이 다를테니까 당연한 현상이다. 게다가 커스텀 컨트롤의 z-index 값을 최대로 줬음에도 크롬을 제외한 다른 브라우저에서는 커스텀 컨트롤이 Video 엘리먼트 위로 올라오지 않는 문제도 있다. 어떻게 해결해야 할지 다시 고민에 빠졌다.

 

 

그래서 해결책은…

잠시 음료수 한 잔 마시고 뒹굴거리다가 문득 좋은 생각이 하나 떠올랐다. Video를 FullScreen 상태로 변경했기 때문에 발생하는 문제라면 다른 요소를 FullScreen 상태로 만들면 되지 않을까?

 

이번에는 감싸고 있는 Video 엘리먼트가 아닌 div#video-container를 FullScreen 상태로 변경했다.

 

실행하면 브라우저 화면이 FullScreen 상태로 바뀐 상태에서 Video 엘리먼트는 본래의 설정을 그대로 유지하고 있는 것을 볼 수 있다.

부모를 fullscreen으로

 

오, Video 엘리먼트의 사이즈가 FullScreen 이전과 그대로인 점만 해결하면 될 것 같다. 안 되면 어쩌지? 뭘 고민하나. 그냥 해보면 될 걸.

Video 엘리먼트의 width, height는 100%로 브라우저는 부모인 div#video-container의 크기에 따라 Video 엘리먼트의 실제 크기를 결정한다. 그렇다면 div#video-container의 width 값을 100%로 지정하면 Video 엘리먼트의 크기도 자동으로 늘어나겠지?

 

코드를 추가하고 실행해보면…

fullscreen성공

 

성공했다. 이제 브라우저에 상관없이 FullScreen 상태에서 커스텀 컨트롤을 볼 수 있다.

 

그런데 아직 해야할 일이 한 가지 남아있다. 아래 스크린 샷에 보이는 것처럼 FullScreen 상태로 변경하면서 div#video-container의 사이즈를 임의로 늘렸기 때문에 FullScreen 상태를 해제해도 div#video-container가 자신의 이전 사이즈를 유지한다.

원래상태

 

 

FullScreen을 해제할 때 div#video-container의 크기를 원래대로 돌려 줘야한다. 이거 하나 구현하는데 신경써야 할 것이 왜 이리 많은지.  HTML5의 갈 길이 아직 멀었음을 다시 한 번 느낀다.

FullScreen API를 이용하면  쉽게 해결할 수 있다.  단지 귀찮을 뿐. 아래의 링크를 따라가면 FullScreen API를 이용하는 간단한 튜토리얼을 볼 수 있다. 거기에 나와있는 정도의 내용이면 이 문제를 충분히 해결할 수 있다.

 

How to Use the HTML5 Full-Screen API (Again)

 

방법은 FullScreen 상태 변경을 감시하고 있다가 FullScreen 모드를 해제할 때 div#video-container를 원래 크기로 돌려놓는 것이다. 역시나 이번에도 크로스 브라우징 문제는 존재한다. 이벤트의 이름과  FullScreen 상태값을 가져오는 API가 브라우저 벤더마다 다르다. 백세시대 무병장수하려면 이정도의 수고로움에는 익숙해져야한다. 스트레스는 건강에 치명적이다. 건강해야 은퇴 후에 치킨 집도 할 수 있다.

 

div#video-container의 크기를 화면 사이즈만큼 늘렸기 때문에 video-container의 값을 되돌린다. 프로토타이핑용 코드이기 때문에 브라우저 호환성 처리를 단순무식하게 했음을 이해해주길 바란다. 이제 FullScreen을 해제하면 원래 상태로 돌아가는 모습을 볼 수 있다.

 

 

끝

 

 

 

삽질한 시간에 비해 해결책이 너무 간단해서 허무하고 슬프다. 모를 때는 그저 어렵게 느껴지다가 알고나면 별거 아닌 일이 어디 이것 뿐이겠는가. 내가 남긴 기록이 누군가에게 도움이 되길 바라며 글을 마친다.