-
HTML5 Video 소개DEV/HTML 2021. 4. 28. 10:26
옛날에 네이버 광고 마크업 담당할 때, 영상 광고에서 사용할 플레이어를 만들어야 했다. 그 때 리서치 하면서 번역한 자료.
HTML5 Video 소개
원문: Introduction to HTML5 Video by Bruce Lawson, Patrick H. Lauke, 11 Feb 2016
업데이트 기록
- 2010년 5월 14일: 사소한 변경사항 몇가지 적용함. 구글의 VP8 코덱이 사용 가능해졌다는 정보, VP8을 지원하는 Opera Labs 실험 버전이 빌드되었다는 정보 추가.
- 2010년 7월 1일: 다운로드 링크를 우리가 한 실험을 받아볼 수 있는 링크로 대체함.
- 2012년 1월 14일: webM과 H.264를 집중적으로 다루는 것으로 글을 수정함. Ogg Theora와 관련된 설명은 사이드 노트에서만 다루기로 함.
- 2012년 7월 31일: 이 글과 동일한 내용을 가지지만 외부 잡지에 기고하기 위해 내용을 보충한 글을 원본 글과 합침. 스크립트와 관련된 부분을 좀 더 심도 있게 다루었고, 비디오 소스를 교체하는 방법에 관한 설명을 추가함.
autobuffer
속성이preload
로 대체되었다는 정보도 추가함.
도입부
옛날 옛날, 아주 멀리 멀리 떨어져 있는 한 은하계의 웹에서는 멀티미디어라고는 고작 째깍거리는 MIDI음과 GIF 애니메이션이 다였답니다. 점차 대역폭이 증가하고 압축 기술이 발전하면서 MP3 음악이 MIDI를 대체하고 '진짜' 비디오가 대세로 떠오르기 시작했습니다. 온갖 괜찮아 보이던 플레이어들(리얼 플레이어, 윈도우 미디어 플레이어 등)이 서로 우위를 차지하려고 하루가 멀다하고 싸움을 벌였는데, 2005년에 한 명의 승자가 나타남으로써 싸움이 종결되기 전까지 계속 싸웠습니다. 바로 어도비 플래시입니다. 어도비 플래시가 승자가 되는데 막대한 영향을 끼친 이유로는 플래시 플러그인의 범용성도 있었고, 유투브가 선택한 전송 기술이였기 때문입니다. 플래시는 웹 비디오 전송에 있어서 사실상 하나의 표준이 되었습니다.
<video>
요소는 HTML5의 흥미진진한 기능 중 하나인데, 이를 사용하면 플러그인을 사용할 필요 없이 웹 페이지에 비디오를 바로 띄울 수 있습니다.이 글에서는 여러분께
<video>
요소를 안내하면서 관련 API도 함께 소개해 드립니다. 왜 브라우저가 네이티브 비디오를 지원하는 것이 중요한지, 그리고 자바스크립트를 사용해 비디오를 조작할 수 있는 가장 핵심적인 방법을 간략하게 살펴보도록 하겠습니다.목차
- 왜
<video>
요소가 필요한가요? <video>
요소 해부- 옥에 티, 코덱
- 더 이상의 이등 웹 시민은 없습니다
- 격이 다른 키보드 접근성
- 페이지의 다른 요소들과도 잘 어울리는
<video>
- CSS로
<video>
스타일링하기 <video>
와<canvas>
합치기
- CSS로
- 스크립트로 나만의 컨트롤을 만들어보자
- 미디어 소스 교체하기
- 더 읽어보기
왜
<video>
요소가 필요한가요?여태까지 웹에 비디오를 올리려면 상당히 요상한 마크업과 씨름을 벌여야만 했습니다. 다음 예시는 유투브에서 바로 가져온 코드입니다.
<object width="425" height="344"> <param name="movie" value="https://www.youtube.com/v/9sEI1AUFJKw&hl=en_GB&fs=1&"></param> <param name="allowFullScreen" value="true"></param> <param name="allowscriptaccess" value="always"></param> <embed src="https://www.youtube.com/v/9sEI1AUFJKw&hl=en_GB&fs=1&" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"></embed> </object>
제일 먼저, 플래시 영상을 불러오기 위해
<object>
요소를 사용합니다. 외부 오브젝트를 담는데 일반적으로 사용된 컨테이너 요소입니다. 브라우저마다 지원 상황이 상이했기 때문에 이에 대비해<embed>
요소를 폴백 콘텐츠로 넣어두었습니다. 이 요소에는<object>
요소의 파라미터가 거의 다 중복되어 들어갑니다. 결과 코드는 볼품없게 생겼고 가독성도 매우 떨어집니다. 게다가 다른 문제도 있습니다. 플러그인 콘텐츠가 페이지에 있는 다른 기술들과 호환이 잘 안되었기 때문에 접근성 문제가 내재되어 있었습니다. (이와 관련해서는 나중에 다룹니다.)<video>
요소 해부플래시 때문에 얽히고 설킨 마크업 구조를 만들어야 했던 상황에 비하면 HTML5의
<video>
요소 사용에 필요한 마크업 구조는 산뜻할 정도로 직관적입니다.<video src=myVideo.webm width=320 height=240 controls poster=image.jpg> </video>
위 예시에서는 예전보다 덜 엄격해진 HTML5 문법을 사용했습니다. 속성값을 쌍따옴표로 두르지 않아도 되고
autoplay
같은 간단한 불리언 속성은 이름만 써도 유효합니다. 물론 원하신다면 XHTML 문법을 따라도 됩니다.controls
대신에controls="controls"
라고 써주고, 모든 속성값을 쌍따옴표 안에 써주시면 됩니다. 코드가 일관성을 유지하도록, 그리고 유지보수하기 쉽도록 여러분에게 맞는 코딩 스타일을 하나 정해서 계속 그것을 지키도록 노력해야 합니다. XHTML5에서는 반드시 XHTML 문법을 따라야 합니다. (그리고 올바른 MIME 타입을 써 넣은 XML 페이지를 만들어야 합니다. 그러나 현재 IE에서 지원되지 않습니다.)위 예시에서 사용한
<video>
요소 속성들은 상당히 자기 기술적(self-explanatory)인 성격을 띄고 있습니다.src
: 비디오 소스입니다. 비디오 파일의 URL이 값으로 들어갑니다.width
,height
:img
요소에서 쓰이는 것과 마찬가지로 비디오의 크기를 명시적으로 지정할 수 있습니다. 만약 이 속성들의 값을 지정하지 않는다면 기본값으로 비디오 파일 내에 지정된 크기가 지정됩니다. 이 값 중 하나만 쓰고 다른 하나는 쓰지 않는다면, 브라우저가 비디오 파일의 화면비율에 맞추어 나머지 값을 조정합니다.controls
: 이 속성이 불리언 값을 가지고 있으면 브라우저가 재생상태와 볼륨을 조절할 수 있는 내장 비디오 컨트롤을 화면에 표시합니다. 이 속성을 제거하면 오직 비디오의 첫번째 프레임만 (혹은poster
이미지만)화면 상에 나타나며 비디오 재생은 불가능해집니다. 자바스크립트로 영상 재생을 시작하도록 만들거나 커스텀 컨트롤을 만들어 띄우기 전까지 말이죠. 커스텀 컨트롤에 대해서는 나중 부분에서 다루겠습니다.poster
:poster
속성값으로 들어가는 이미지는 비디오가 다운로드 중이거나 사용자가 비디오를 재생하라고 명령을 내리기 전까지 브라우저가 플레이어에 띄우는 이미지입니다. 만약 이 속성값이 존재하지 않는다면 비디오의 첫번째 프레임이 대신 사용됩니다.
현재
<video>
를 지원하지 않는 웹 브라우저 용으로 대체 콘텐츠를 포함시킬 수 있습니다. 최소한 텍스트를 몇 자 적어 넣거나 비디오 파일 자체로 연결되는 링크를 넣어 사용자가 다운받아 미디어 플레이어 애플리케이션에서 재생하도록 할 수 있습니다.<video src=myVideo.webm width=320 height=240 controls poster=image.jpg> Download my awesome video in <a href=myVideo.webm>WebM</a> or <a href=myVideo.mp4>MP4</a> format </video>
![](https://dev.opera.com/articles/introduction-html5-video/opera-standard-video-controls.jpg)
오페라 브라우저에서 본 `video` 요소와 내장 컨트롤
위 예시에서 다루지 않은 속성이 몇가지 남아 있습니다.
autoplay
: 브라우저에게 비디오 재생을 자동으로 시작하도록 설정하는 속성입니다. 심각한 문제거리는 아니지만 사용자에게 방해가 될 가능성이 매우 높으므로, 이 속성은 주의를 기울여서 사용해야 합니다. 특히 스크린리더기와 같은 보조 기기를 사용하거나 저대역폭 접속(모바일 기기 등)을 하는 사용자에게 방해가 될 수 있습니다.preload
: 이 속성을 사용해서 브라우저가 비디오를 미리 불러오는 시도를 해도 될지 아니면 안되는지 설정할 수 있습니다. 속성값으로는none
(재생이 시작되기 전까지 아무 영상도 미리 다운로드하면 안됨),metadata
(비디오 자체 크기나 재생 시간 등 메타데이터와 관련된 작업만 할 수 있을 정도로 파일을 다운받을 수 있음),auto
(브라우저가 기본 설정대로 동작하게 함. 예를 들면 모바일 기기에서는none
속성처럼 특별한 이유가 없는 한 다운로드를 미리 하지 않지만, 데스크탑 브라우저에서는metadata
정도만 미리 받아 놓음.)가 있습니다.loop
:loop
속성은 불리언 속성입니다. 짐작하셨듯이, 이 속성은 비디오를 반복해서 재생합니다.
옥에 티, 코덱
안타깝게도 브라우저가 다룰 수 있는 비디오 타입에 대해 얘기하자면, 브라우저마다 다룰 수 있는 타입이 제각각인 상태입니다. HTML5 명세서에는
<video>
요소 및 관련 API에 대해 명확하게 정의를 해 놓은 상태이나, 브라우저가 기본적으로 지원해야 하는 특정 비디오 코덱에 관해서는 명시하지 않았습니다. 오페라와 모질라 파이어폭스에서는 webM 코덱을 기본적으로 지원합니다. webM은 고품질의 오픈 비디오 포맷으로 별도의 라이센스나 저작권료를 낼 필요없이 모두가 무료로 사용하고 재배포할 수 있는 포맷입니다. 이에 반해 사파리와 인터넷 익스플로러 9는 H.264 코덱을 채택해서 사용중인데, MPEG LA라는 단체로부터 라이선스를 발급받아 사용중인 포맷이라서 이들에게 저작권료를 지급하고 있습니다. 구글 크롬 브라우저에서는 이 두가지 코덱 형식을 모두 지원합니다. IE에서는 사용자가 webM을 자신의 컴퓨터에 따로 설치한다면 사용할 수 있도록 할 예정입니다.(크롬, 오페라, 파이어폭스에서는 저작권료 지급을 하지 않아도 되는 Ogg Theora라는 포맷 역시 지원중입니다. 그러나 이 포맷은 webM으로 대체되었으므로 더 이상 다루지 않겠습니다.)
그러므로 이 상황이 의미하는 바는 바로 모든 브라우저에서 비디오 재생을 지원하려면 인코딩을 두 번할 필요가 있다는 것을 뜻합니다. 한번은 webM으로, 또 한번은 H.264로 말입니다. 다행히도
<video>
요소에서는 영상의 버전을 구분하여 명시해 놓을 수 있습니다. 알맞은type
속성과 함께 대체<source>
요소를 비디오에 추가해 놓으면, 브라우저가 적당한 포맷의 소스를 골라 다운받습니다. 이 경우에는<video>
요소 자체에다가는src
속성을 쓰지 않습니다.<video width=320 height=240 controls poster=image.jpg> <source src=myVideo.webm type=video.webm> <source src=myVideo.mp4 type=video/mp4> Download my awesome video in <a href=myVideo.webm>WebM</a> or <a href=myVideo.mp4>MP4</a> format </video>
인코딩 과정을 반복해서 두 번 거치고 나면 흥미롭게도 오래된 브라우저 지원 준비 역시 반절 정도 마친 셈이 됩니다. 플래시는 MP4 포맷 영상 파일로 로딩 및 재생이 가능하기 때문에 인터넷 익스플로러와 같은 예전 브라우저 대비책으로 마련해 두시면 됩니다. Kroc Camen은 이와 같은 테크닉을 효과적으로 구현할 수 있는 방법을 모두를 위한 비디오!(Video for Everybody!)라는 글에 담아 두었습니다.
<video>
요소의 대체 콘텐츠 부분에object
와embed
요소를 꾹꾹 눌러 담는 식으로 말입니다.당연한 얘기지만, 브라우저가
<video>
요소를 지원하지 않는다면 그 대안으로 퀵타임이나 플래시 플러그인을 사용하도록 합니다. 덕분에 처음으로 되돌아갔네요. 그리고 이제부터 살펴보고자 하는 여러 새로운 기능들과 구현사항을 아무것도 사용할 수 없게 됩니다. *"이게 뭔 의미가 있는 겁니까?"*라고 물어보고 싶을 것입니다. 저희가 드릴 수 있는 답변은 이 방법이 모든 주요 브라우저에서 네이티브 비디오 지원이 이루어지기 전까지 사용할 수 있는 과도기적인 방법이라는 것입니다. 우아한 성능 저하(graceful degradation)의 한 실례라고 할 수 있습니다. 뭔가 좀 덜 떨어져 보이는 페이지를 사용자가 받아 볼 수도 있으나 최소한 영상 시청은 가능한 상태입니다.더 이상의 이등(second-class) 웹 시민은 없습니다
자, 이제 여태까지 살펴본 HTML5
<video>
마크업 구조는 플래시 영상을 마크업에 담을 때 했던 것보다 열배는 더 읽기 쉽고 이해하기 쉽다는 것을 알았습니다. 그러나 예전 마크업 방식이 끔찍했던지 어쨌던지 간에, 일단 이 옛날 방식은 모든 상황에 대부분 적용이 됩니다. 그렇지 않나요? 상황이 이러한데도 굳이 플래시와 같은 서드파티 플러그인을 사용해 비디오를 재생하도록 하는 방법을 버려야 하는 이유가 있나요?HTML5
<video>
요소 덕분에 얻은 주요 이점 중 하나는 바로 마침내 비디오가 웹에서 완전히 자격을 갖춘 정식 시민으로 거듭날 수 있는 계기가 되었다는 것입니다.object
나 유효성이 없는embed
요소(비록 HTML5에서는 유효하다고 하지만)처럼 외딴 내륙 지방으로 유배가지 않아도 됩니다. 이러한 장점들을 좀 더 폭넓게 다뤄보도록 하겠습니다.격이 다른(out-of-the-box) 키보드 접근성
플래시로는 풀리지 않는 역대급 난제 중에 하나가 키보드 접근성입니다. 윈도우 운영체제 위에서 돌아가는 인터넷 익스플로러를 제외하고는 키보드 사용자가 탭키를 사용해서 플래시 영상 안으로 초점을 옮기는 일이 거의 불가능했습니다. 게다가 심지어 사용자가 어찌어찌해서(보조 기술을 추가적으로 사용해서) 초점을 영상 안으로 옮겼다 하더라도 다시 초점을 이전으로 되돌리는 일이 쉽지 않았습니다. (영상에 액션스크립트 코드를 추가해 초점을 플러그인 밖으로 빼내어 페이지 위로 되돌릴 수 있도록 하지 않는 이상 불가능했습니다.) 이와는 대조적으로 브라우저가
<video>
요소를 직접 다루도록 책임을 부과해 놓는다면, 브라우저는 영상 컨트롤러의 버튼을 마치 웹 페이지의 일반 버튼인마냥 다룰 테고 탭 흐름에도 포함시킬 것입니다.아직까지는 모든 브라우저에서 네이티브 비디오 키보드 지원이 이루어지지 않은 상태입니다. 하지만... 격이 다른 오페라 브라우저에서는 제대로 동작합니다.
페이지의 다른 요소들과도 잘 어울리는
<video>
간단히 말하자면, 페이지에 플러그인을 넣을 때 마다 플러그인에게 양도되는 특정 표시 영역이 브러우저 내에 할당 되는 셈입니다. 브라우저가 신경 쓰는 한도 내에서는 플러그인 영역이 블랙 박스처럼 취급됩니다. 그 안에서 무슨 일이 벌어지든 브라우저는 신경 쓰지 않습니다.
대부분의 경우 이는 문제가 되지 않으나 플러그인 표시 영역이 페이지 레이아웃과 겹쳐진다면 문제가 생깁니다. 플래시 영상이 들어간 사이트가 하나 있다고 예를 들어 봅시다. 여기에는 자바스크립트나 CSS를 기반으로 제작된 드롭다운 메뉴 역시 있는데, 영상 위에서 접혀져야 합니다. 기본 설정에 의해 플러그인 표시 영역은 웹 페이지의 맨 앞에 자리 잡고 있으므로 드롭다운 메뉴는 영상 뒤에서 이상하게 나타날 것입니다. 페이지에서 라이트박스(모달 창) UI를 구현해도 비슷하게 볼품없는 모습이 연출됩니다. 플래시 영상이 여전히 딤드 처리용 페이지 오버레이 위에 떠 있을 것입니다. 이런 이유 때문에 대부분의 라이트박스 관련 스크립트 라이브러리들이 오버레이를 화면에 띄우기 전에 먼저 플러그인 오브젝트를 제거합니다. 그런 후에 오버레이가 닫으면 플러그인 오브젝트를 다시 불러들입니다.
위의 화면 표시 이슈는 플래시 플러그인에 한해서 고칠 수 있는데,
wmode="opaque"
속성을<object>
요소에 추가한 후<param name="wmode" value="opaque">
속성을<embed>
에 추가하면 됩니다. 그러나 이 해결 방법 역시 스크린 리더기기 사용자의 접근을 원천적으로 차단시켜 버리므로 되도록이면 사용해서는 안됩니다.페이지 레이아웃이 동적으로 변하는 상황에서도 역시 문제점과 버그가 발생할 수 있습니다. 플러그인 표시 영역의 크기가 바뀌면, 플러그인에서 재생되는 영상 자체의 크기는 따라서 바뀌지 않고 그냥 잘리거나 추가적으로 하얀 여백이 생기는 등 예측 밖의 현상이 생깁니다.
<video>
요소를 사용하면 브라우저가 자체적으로 렌더링을 신경씁니다. 그러므로<video>
요소는 페이지 상의 다른 요소들과 비교했을 때 다르게 동작하지 않습니다. 별다른 꼼수를 부릴 필요 없이 위치를 옮길 수 있고, 플로트 설정을 할 수 있으며, 겹쳐지게 하거나 동적으로 크기를 변경할 수 있습니다. 심지어 간단하게 CSS로 요소의 투명도를 변경해서 흥미로운 반투명 비디오 효과를 만들어 낼 수도 있습니다.CSS로
<video>
스타일링하기이제는 비디오가 Open Web 기술 목록 안에 들어가게 되었으므로, 믿음을 가지고 비디오 요소에 CSS를 사용할 수 있습니다. CSS로 어떤 효과를 만들어 낼 수 있는지 간단히 시연해 보기 위해 트랜지션 속성을 비디오에 적용하여
:hover
와:focus
를 사용했을 때 크기가 바뀌도록 예제를 만들어 보았습니다. (저희가 쓴 CSS3 트랜지션 및 2D 트랜스폼 튜토리얼을 읽어보세요.)<video>
와<canvas>
합치기브라우저가 비디오 요소의 위치를 설정하고 렌더링 하는 역할을 담당하고 있으므로 우리는 이제 손쉽게 다른 요소를 그 위에 겹쳐 놓거나 합칠 수 있습니다. 이 예제에서는
<canvas>
요소를 비디오 위에 겹쳐 놓았습니다. (역 -mouse.png
파일이 유실되어서 제대로 동작하지 않습니다.) (경고: 이 비디오에는 잘생긴 오페라 직원과 그의 아이들이 거대한 마우스 포인터 때문에 신변의 위협을 느끼는 이미지가 들어 있어서 보는 사람에 따라 당황할 수도 있습니다.)<canvas>
가 비디오를 전부 덮고 있지는 않습니다. 캔버스의 높이는 비디오 높이보다 40 픽셀 짧게 설정되어서 비디오 컨트롤 영역 위에는 겹쳐지지 않도록 했습니다. 덕분에 마우스를 비디오 하단에 가져다 대어도hover
이벤트를 받을 영역이 캔버스 영역 너머로<video>
요소에 충분이 존재하기 때문에 사용자가 컨트롤 조작을 할 수 있습니다. 어떤 요소로 덮었든간에 키보드로 컨트롤 접근이 가능해야 하지만 브라우저마다 키보드 지원 상태가 현재는 제각각입니다.스크립트로 나만의 컨트롤을 만들어보자
<video>
와<audio>
(나중에 다른 글에서 다룰 예정입니다)는 HTML5 DOM 미디어 요소의 인스턴스 입니다. 개발자들은 이제 미디어 요소의 API에서 제공하는 수많은 자바스크립트 메소드와 속성을 사용해서 영상 재생을 제어할 수 있습니다. 간단한 커스텀 컨트롤을 만들기 위해 가장 필요해 보이는 메소드와 속성을 몇가지 살펴보겠습니다.play()
와pause()
: 이 메소드들이 영상 재생과 일시정지를 담당하고 있음은 꽤 자명하게 알아볼 수 있습니다.play()
메소드를 사용하면 언제나 현재 재생 위치에서 영상이 시작합니다. 영상이 처음으로 로딩된 상태라면 맨 첫째 프레임부터 시작됩니다.stop()
메소드가 없는 것에 주의하세요. 재생을 멈추고 영상의 맨 처음으로 되감기 하고 싶다면pause()
를 사용하고 현재 재생 위치를 바꾸는 코드를 작성해서 구현해야 합니다.volume
: 이 속성을 사용하면 비디오 음성 트랙의 볼륨값을 얻어 오거나 설정할 수 있습니다. 0.0(음소거)와 1.0(최대 음량) 사이의float
를 값으로 가집니다.muted
:volume
속성에 상관없이 음소거가 됩니다.currentTime
: 값으로 현재 재생 위치를 초 단위로 반환하며,float
단위로 표현됩니다. 이 속성의 값을 설정하면, (변경이 가능한 경우) 재생 위치를 특정 시간으로 옮깁니다.
이를 위해 필요한 것은 단지
<video>
오브젝트 레퍼런스 입니다. 이것만 있다면 자바스크립트를 통해 영상을 조작할 수 있습니다.<video width=320 height=240 controls poster=image.jpg id=videoPlayer> … </video> <script> var v = document.getElementById('videoPlayer'); v.volume = 0.5; v.play(); </script>
미디어 요소에서는 비디오 프로세싱 모델의 일환으로 일련의 이벤트 또한 발생시키는데, 이 이벤트를 받아들여서 코드에서 엮어서(hook into) 사용할 수 있습니다. 예시에서는 이 중 몇가지만 살펴보도록 하겠습니다.
loadeddata
: 브라우저가 현재 시점에서 재생을 시작해도 될 만큼 충분한 비디오 데이터를 불러들였음을 뜻합니다.play
,pause
: 비디오 재생이 시작되었음, 혹은 멈췄음을 나타냅니다. 자바스크립트로 비디오를 제어 중이라면play()
와pause()
메소드 호출이 성공적으로 끝났는지 이 이벤트들을 받아봄으로써 확신할 수 있습니다.timeupdate
: 비디오가 재생 중이여서, 혹은 스크립트에 의해, 아니면 사용자가 다른 시점으로 건너뛰었기 때문에 현재 재생 위치가 변경되었음을 나타냅니다.ended
: 비디오의 끝에 다다랐고,<video>
요소에loop
설정이 되어 있지 않으며 거꾸로 재생하기 설정(이 글에서는 다루지 않습니다) 또한 되어 있지 않음을 나타냅니다.
다음은
timeupdate
이벤트를 엮어서 비디오의currentTime
(초 단위)을 표시하는 코드입니다.<video width=320 height=240 controls poster=image.jpg id=videoPlayer> … </video> <p> Current time is: <span id=timeDisplay></span></p> <script> var v = document.getElementById('videoPlayer'); v.addEventListener('timeupdate',updateTimeDisplay,true); function updateTimeDisplay(e) { document.getElementById('timeDisplay').innerHTML = e.target.currentTime; } </script>
이제 간단한 컨트롤러를 만들기 위해 필요한 기본 건축 블록 준비를 마쳤습니다. 매우 정리된 코드로 새로운 API 메소드와 이벤트 사용법을 보여드리도록 하겠습니다. 상당히 간단한 예시이기 때문에 자바스크립트 코드를 인라인으로 포함시켰고 익명 함수 몇가지만 추가해둔 상태입니다. 개발 환경에서는 이것 보다 훨씬 더 복잡해질 것이 자명합니다.
<video src=myVideo.webm width=320 height=240 controls id=videoPlayer> … </video> <div> <button id=buttonPlay>Play</button> <button id=buttonPause>Pause</button> Current time is: <span id="timeDisplay"></span> </div> <script> /* use global variable for ease */ var v = document.getElementById('videoPlayer'); /* play button */ document.getElementById('buttonPlay').addEventListener('click',function(e){ v.play(); },true); /* pause button */ document.getElementById('buttonPause').addEventListener('click',function(e){ v.pause(); },true); /* current time display (rounded to nearest second) */ v.addEventListener('timeupdate',function(e){ document.getElementById('timeDisplay').innerHTML = Math.floor(e.target.currentTime); },true); </script>
이걸로 디자인 상에 도전해 본다는 것은 어불성설이고, 기능저하 역시 우아하게 이루어지지 않았습니다... 만약 사용자가 자바스크립트 사용을 막아두었다면 아무런 동작도 하지 않는
<button>
무더기만 마주하게 될 것입니다. 그러나 지금은 CSS를 살짝 추가하고 솜씨를 부려 자바스크립트를 적용하기만 하면 됩니다. (먼저 브라우저에서 실제 지원이 되는지 테스트해보고, 프로그래밍으로 컨트롤을 만들어 낸 후에 훨씬 더 세련되게 보이도록 스타일링 합니다.) 어떤 식으로 하면 되는지 예시를 보고 싶다면(여전히 상당히 밋밋하기는 하나) 예시 2: 자바스크립트로 구현한 이쁜 비디오 컨트롤을 살펴보시면 됩니다.![](https://dev.opera.com/articles/introduction-html5-video/fancy-javascript-controls.jpg)
HTML, CSS, 자바스크립트 말고는 아무것도 사용하지 않은 커스텀 `
` 컨트롤
자바스크립트 코드량이 훨씬 많아져서 약간의 정리와 리팩토링이 필요해 보이기는 하지만, HTML5 비디오가 가져다 줄 새롭고 뛰어난 가능성을 조금이나마 살펴보셨기를 바랍니다. 약간의 웹 표준에 관한 지식만 가지고 있다면, 이제는 웹 개발자들이 맞춤형 플래시 비디오 플레이어를 만드는 대신에 사이트 디자인과 완벽하게 부합하는 커스텀 비디오 컨트롤을 쉽게 만들어 낼 수 있습니다.
미디어 소스 교체하기
사용자가 마우스를 이미지 위에 올려두면 동적으로 이미지가 바뀌는 효과를 만들어 내기 위해 짰던 고전적인 스크립트를 기억하시나요? 혹시 간단한 슬라이드쇼 갤러리도 기억하시나요? 자바스크립트로 이미지를 바꾸는 법의 핵심은
<img>
요소의src
속성 조작입니다. 그렇게만 하면 브라우저가 새로운 이미지를 불러와 화면에 표시합니다. 음, 그런데 말입니다, HTML5에서 새로 등장한 네이티브 미디어 요소를 사용한다면 비디오에서도 손쉽게 이런 동작을 할 수 있게 되었습니다.간단한 경우로 시작해 봅시다. 하나의
src
속성만 가지고 있는<video>
의 경우 입니다. 프로그래밍을 통해 여기서의 속성은 다른 비디오 파일을 바라보도록 수정할 수 있습니다만, 브라우저가 실제로 비디오를 교체하도록 만들려면 추가적으로 단계를 밟아서 새로운 메소드를 호출해야 합니다.load()
:<video>
요소를 초기화하여 새로운 미디어 리소스를 선택해서 처음부터 불러옵니다.
아래 예시에서는 하드코딩으로 파일명을 써 두었고 스크립트 역시 대강 윤곽만 잡아두었습니다. (커스텀 데이터 속성을 사용했는데 이것 역시 HTML5의 새로운 기능입니다. 파일명과 각각의
<button>
요소 사이의 관계를 형성하고 스크립트를 좀 더 쉽게 만들기 위해 사용했습니다.) 처음에는 아무 영상도 나타나지 않습니다. 좀 더 구체적으로 말하자면<video>
요소는 존재하나 실제적인src
속성이 부재한 상태입니다. 버튼 중에 아무거나 누르면 연관 비디오가 플레이어에 로드됩니다.<video width=320 height=240 controls id=videoPlayer></video> <button data-file=video1.webm>Video 1</button> <button data-file=video2.webm>Video 2</button> <button data-file=video3.webm>Video 3</button> <script> /* 쉽게 가기 위해 전역 변수를 사용합니다 */ var v = document.getElementById('videoPlayer'); /* 모든 버튼에 클릭 이벤트를 붙입니다 */ var b = document.getElementsByTagName('button'); for(i = 0; i<b.length; i++) { b[i].addEventListener('click',swapVideo,true); } function swapVideo(e) { /* 비디오 src 속성을 누르는 버튼의 data-file 속성값에 따라 바뀌도록 합니다 */ v.src = e.target.getAttribute('data-file'); v.load(); } </script>
그러나 이미 말씀드린 바와 같이 모든 브라우저가 똑같이 잘 알아듣는 비디오 포맷과 코덱은 존재하지 않습니다. 크롬, 파이어폭스, 오페라, 그리고 사파리에서 비디오가 동일하게 잘 나오도록 하려면
<source>
요소를 연속적으로 사용해서 브라우저가 webM과 MP4 사이의 옵션 중에 하나를 선택할 수 있도록 선택지를 제공해 주어야 합니다. 따라서 여기서 사용할 수 있는 우직한 방법(그러나 여전히 사용가능합니다)은src
만 교체하는 것이 아니라 각각의<source>
를 코드가 생성하도록 하는 것입니다. 간단하게 설명하기 위해 비디오의 webM과 MP4 버전이 모두 같은 위치에 있고 완전히 같은 파일명을 가지고 있다고 가정해 봅시다. 오직 파일 확장자(.webm
,.mp4
)만이 다릅니다. 실제 상황에서는<video>
안에 꼭 넣어주어야 하는 예비 콘텐츠 역시 여기서는 무시하도록 하겠습니다.<video width=320 height=240 controls id=videoPlayer></video> <button data-file=video1>Video 1</button> <button data-file=video2>Video 2</button> <button data-file=video3>Video 3</button> <script> /* 쉽게 가기 위해 전역 변수를 사용합니다 */ var v = document.getElementById('videoPlayer'); /* 모든 버튼에 클릭 이벤트를 붙입니다 */ var b = document.getElementsByTagName('button'); for(i = 0; i<b.length; i++) { b[i].addEventListener('click',swapVideo,true); } function swapVideo(e) { /* 비디오에 두가지 소스 요소를 넣습니다. 하나는 webM이고, 다른 하나는 MP4입니다. */ v.innerHTML = '<source src='+e.target.getAttribute('data-file')+'.webm type=video.webm>'; v.innerHTML += '<source src='+e.target.getAttribute('data-file')+'.mp4 type=video/mp4>'; v.load(); } </script>
잘 동작하기는 하지만 한가지 빼먹은 팁이 있습니다. 브라우저가 내부 알고리즘과 자기 스스로의 판단 결과를 바탕으로 재생 파일 타입을 선택할 수 있도록 옵션을 제공해주기 위해, 정적인 HTML을 작성할 때 그 안에
<source>
요소를 분리해서 넣었습니다. 그러나 이미 자바스크립트로 작업을 하고 있으므로, 이와 동일한 로직을 가져다가 브라우저가 제공하는 타입을 스크립트 보고 알아내라고 지시해서 환경에 가장 알맞는 포맷/코덱으로<video>
를 업데이트 하도록 하면 됩니다.canPlayType(type)
: 이 메소드의 반환값은 빈 스트링값(부정 반응),maybe
혹은probably
중에 하나로써 브라우저가 특정type
재생 여부를 얼마나 확신하고 있는지 그 정도를 알려줍니다.
이 메소드가 반환하는 조금은 이상해 보이는 값들을 살펴보고 있자니, 아까 작성한 코드를 살짝 수정해서 하나의
src
속성만 사용하여 현재 브라우저에서 재생될 만한 최적의 파일 타입이 자리잡도록 어떻게 하면 되는지 알 것 같네요.<video width=320 height=240 controls id=videoPlayer></video> <button data-file=video1>Video 1</button> <button data-file=video2>Video 2</button> <button data-file=video3>Video 3</button> <script> /* 쉽게 가기 위해 전역 변수를 사용합니다 */ var v = document.getElementById('videoPlayer'); /* 모든 버튼에 클릭 이벤트를 붙입니다 */ var b = document.getElementsByTagName('button'); for(i = 0; i<b.length; i++) { b[i].addEventListener('click',swapVideo,true); } function swapVideo(e) { /* 비디오 src 속성을 누른 버튼의 data-file 속성값에 따라 바꿉니다. webM과 MP4 중에 가장 적절한 포맷을 선택하도록 합니다. */ if (v.canPlayType("video.webm") == 'maybe' || v.canPlayType("video.webm") == 'probably') { v.src = e.target.getAttribute('data-file')+'.webm'; } else if (v.canPlayType("video/mp4") == 'maybe' || v.canPlayType("video/mp4") == 'probably') { v.src = e.target.getAttribute('data-file')+'.mp4'; } v.load(); } </script>
위 방법을 지금까지 본 것 중 가장 시각적인 즐거움을 선사해주는 커스텀 컨트롤러에 적용해 보면 이제 좀 더 스타일리시한 비디오 플레이어를 만들기 위한 기초를 마련해 둔 셈입니다... 순수하게 웹 표준적인 방법과 HTML5의 네이티브 비디오 지원 능력 이외에는 필요한게 없었습니다. (그리고 이건 매우 간단한 예시에 불과하다는 것을 기억해주세요. 훨씬 우아한 방법으로 비슷한 문제를 해결한 사례들이 많이 있습니다.)
![](https://dev.opera.com/articles/introduction-html5-video/fancy-swap.jpg)
`
` 요소로 만든 기본적인 비디오 갤러리/플레이리스트
이로써 플러그인 기반의 옛날 비디오 지원 방식의 종말이 고해진 셈인가요? 단기적으로 보면 플래시 플레이어를 걷어내기 시작하는 것이 좀 시기상조일 수도 있습니다. 네이티브 비디오를 볼 수 없는 브라우저를 사용하는 사용자들이 아직 상당수 있고, 마땅히 모든 모던 브라우저에서 HTML5
<video>
요소를 사용하고 싶은 사람들로 하여금 골치를 앓게 아는 코덱 문제가 존재합니다. 그러나 이제부터 우리는 생애 최초로 웹 개발자로써 맘대로 사용할 수 있는 대안적인 도구를 지니게 된 셈입니다. 그리고 선택지가 늘어난다는 것은 언제나 좋은 일이지요.더 읽어보기
- HTML 비디오와 오디오에 관해 알아두어야 할 모든 것 - 정말 모든 것이 들어있습니다!
<video>
명세서- Opera에서
<video>
를 구현한 방법에 대하여(링크 없음) - 자바스크립트로 자막 처리하여 HTML5에 접근성 부여하기