Trong bài trước, chúng ta đã làm quen với việc sử dụng thẻ video và audio để phát các tập tin phim và nhạc trên web. Tuy nhiên, đó là player với UI mặc định của trình duyệt. Vậy, chúng ta có thể tự tạo cho mình một html 5 media player không? Vâng, việc đó hoàn toàn có thể. Các nhà phát triển đã cung cấp cho chúng ta một loạt các phương thức để chúng ta có thể làm chủ hoàn toàn các phần tử của player như nút play, pause, mute, volume, timeline,….

#Thiết kế UI với HTML 5

Trong phần này, tôi sẽ hướng dẫn các bạn tạo một phayer cực đơn giản với html5 API. Nhưng trước tiên chúng ta cần phải có ui của một media player cái đã.

<video id="video" poster="/poster.png">
<source id="mp4" src="/trailer.mp4" type="video/mp4">
<source id="webm" src="/trailer.webm" type="video/webm">
<source id="ogv" src="/trailer.ogv" type="video/ogg">
<p>Your user agent does not support the HTML5 Video element.</p>
</video>

Tất nhiên, cái đầu tiên chúng ta cần phải khai báo đó chính là thẻ video cùng với các source video khác nhau. Còn tại sau lại dùng nhiều source khác nhau thì tôi đã giải thích rồi. Bây giờ nếu chạy trên trình duyệt thì bạn đã thấy được một ô màu đen rồi, nhưng video vẫn chưa hoạt động. Tiếp theo thì chúng ta cần phải thêm các button cơ bản để điều khiển video như play, pause, fullscreen, timelife, volume,…

<button id="play">play</buton>
<button id="pause">pause</button>
<button id="fullscreen">full screen</button>
<input id="vol" type="range" min="0" max="100" step="1" value="50">
<input type="range" id="timeline" min="0" max="100" step="1" value="0">
Current: <span id="currentTime">0</span> / <span id=“durationTime">0</span>
Screen Shot 2014-07-10 at 2.20.55 PMKết quả sau khi code html và thêm các button vào.

#Tạo Media Player với HTML 5 Video API

Sử dụng HTML 5 Query Selector API

Bây giờ thì coi như chúng ta đã căn bản xây dựng được một UI cho một video player rồi. Việc cần làm tiếp theo là áp dụng vào các phương thức mà nhà phát triển họ cung cấp để chúng ta có thể kiểm soát toàn bộ các nút bấm mà chúng ta đã khai báo ở trên.
Ok! Lúc nào cũng thế, chúng ta phải tiến hành dùng query selector để tham chiếu đến các đối tượng sẽ sử dụng.

var video = document.querySelector("#video");
var play = document.querySelector("#play");
var pause = document.querySelector("#pause");
var full = document.querySelector("#fullscreen");
var vol = document.querySelector("#vol");
var timeline = document.querySelector("#timeline");
var curTime = document.querySelector("#currentTime");
var duraTime = document.querySelector("#durationTime");
Nút Play

Rồi, bây giờ chúng ta tiến hành xây dựng nút play trước. Rất đơn giản, khi click vào button play thì nó sẽ phát lệnh cho video bắt đầu chạy.

play.onclick = function(){
video.play(); // chạy video
}
Nút Pause

Tiếp theo, chúng ta sẽ thực hiện tiếp đến nút pause. Cũng tương tự, khi click vào button pause thì video sẽ ngưng phát.

pause.onclick = function(){
video.pause();
}
Nút âm lượng

Đó là hai nút bấm quan trọng và thiết yếu nhất của mọi media player. Bây giờ thì ta sẽ tiến hành làm tiếp đến phần điều chỉnh âm thanh lớn nhỏ – volume. Tôi sẽ sử dụng input kiểu range để tạo thanh tăng giảm volume cho video. Với input kiểu này thì chúng ta sẽ phải sử dụng sự kiện onchange của javascript để dùng.

vol.onchange = function(){
video.volume = vol.value/100;
}

Trong đoạn code trên video.volume = i. Trong đó i là một con số được giới hạn từ 0 đến 1. Ở mức 0 đồng nghĩa với mute; độ lớn của âm thanh trong video sẽ tăng dần 0.1, 0.2, 0.3,… đến 1 đồng nghĩa với max volume.

Code html tôi khai báo cho input volume với các giá trị min=0, max=100. Tuy nhiên, API volume nó chỉ nhận giá trị min=0, max=1. Do đó, tôi phải lấy giá trị hiện tại của thanh volume chia cho 100 (vol.value/100), thì mới thoả điều kiện.

Hiển thị thời gian phát video

Bây giờ chúng ta sẽ tiếp tục đến với phần hiển thị thời gian hiện tại và tổng thời gian của một video. Tất nhiên, video API cung cấp cho chúng ta 2 phương thức để thực hiện việc đó một cách đơn giản.

video.duration: trả về tổng thời gian phát của một tập tin video.
video.currentTime: trả về giá trị thời gian hiện tại đang phát của video.

Tuy nhiên, trong trường hợp này thì chúng ta sẽ làm quen với một sự kiện javascript mới là ondurationchange. Sự kiện này nằm trong nhóm các sự kiện mới của video api. Sự kiện này chỉ xảy ra khi dữ liệu về thời gian phát hiện tại của video bị thay đổi

video.ondurationchange = function(){
duraTime.innerHTML = Math.floor(video.duration);
setInterval(function(){
curTime.innerHTML = Math.floor(video.currentTime);
},100);
}

Chúng ta cần phải dùng Math.floor vì thời gian của video thường có nhiều số thập phân ở phía sau, ví dụ trong video demo thì thời gian là 52.209. Lưu ý, thời gian của video được tính bằng giây.

Tuy rằng video.currentTime sẽ hiển thị thời gian hiện tại của video. Tuy nhiên, nó không thể tự thay đổi được, mà chúng ta cần phải dùng kèm với hàm setInterval() để cứ 100ms thì sẽ chạy video.currentTime một lần để cập nhật thời gian hiện tại của video. Bây giờ chúng ta sẽ tiến hành thực hiện phần khó nhất và đòi hỏi kỹ năng tư duy để có thể suy luận chính xác để làm phần hiển thị timeline của video.

Xây dựng time-line

Vấn đề tôi quan tâm lúc này là khi tôi kéo điểm neo đến vị trí có giá trị là 25, 50 hay bất kỳ một vị trí nào đó trong khoản giá trị của input range timeline thì thời gian của video tại chổ điểm neo đó là đó là giây thứ bao nhiêu? Nói nghe hầm hố thế thôi chứ thực sự thì thuật toán suy luận hoàn toàn đơn giản. Chúng ta chỉ cần áp dụng phương pháp toán bật tiểu học “nhân chéo” để tìm kết quả.

Giả sử, tôi có 1 đoạn video dài 20 giây. Thanh timeline của tôi dài 100 đơn vị. Câu hỏi đặt ra là: Nếu điểm neo của tôi ở đơn vị thứ 25 thì lúc đó thời gian hiện tại của video là bao nhiêu? Đơn giản cách giải phép toán chỉ là 25*20/100
. Rút ra công thức: current time = (total time * curent range )/ max range

Từ đó, chúng ta áp dụng ngay vào trong code javascript, ngay trong sự kiện onclick play.

play.onclick = function(){
video.play();
// begin run timeline
var percent = video.duration/100;
setInterval(function(){
// ấn định vị trí điểm neo mới cho input range
timeline.value = video.currentTime/percent;
},100)				
}

Tại sao lại phải nằm trong play? Đơn giản vì khi chúng ta ấn vào nút play, thì timeline sẽ bắt đầu hoạt động rồi. Tuy nhiên, còn một điểm mà chúng ta cần giải quyết đó là? Chuyện gì xảy ra nếu người dùng muốn tua nhanh video bằng cách kéo điểm neo? Bây giờ chúng ta sẽ giải quyết vấn đề đó.

timeline.onchange = function(){
video.currentTime = timeline.value*video.duration/100;
video.play();
}

Khi kéo điểm neo đi thì ta sẽ có được giá trị của mới của điểm neo đó timeline.value và áp dụng vào công thức thì ta sẽ xác định được thời gian hiện tại của video. Sau đó thì chạy dự kiện video.play() để video tiến hành phát ngay sau đó tại móc thời gian mới.

Screen Shot 2014-07-10 at 2.25.27 PMThanh time line và Volume khi chưa dùng CSS 3

CSS 3 Tip: Các bạn thấy rằng, giao diện UI mặc định của input range khá là xấu phải không nhỉ? Và liệu nó có thể thay đổi được không? Tất nhiên là được, bạn hoàn toàn có thể dùng CSS 3 để thay đổi nó.

input[type=range] {
-webkit-appearance: none;
background-color: silver;
width: 200px;
height:20px;
}
input[type="range"]::-webkit-slider-thumb {
-webkit-appearance: none;
background-color: #666;
opacity: 0.5;
width: 10px;
height: 20px;
}

Tất nhiên, hiện tại thì nó chỉ hoạt động được trên trình duyệt chrome và safari. Tôi nghĩ chắc từ từ các trình duyệt khác cũng sẽ áp dụng vào bộ selector này để cho các lập trình viên có thể thoải mái thiết kế lại UI của input range.

Lưu ý: Bạn hãy tham khảo bài viết HTML 5 APIs: Fullscreen để làm được nút Fullscreen nhé!

#Kết luận

Nói hay thì cũng được, nhưng mà tự code 1 cái media player thì cũng mất khối thời gian phải không nhỉ? Tôi ngồi làm cái player xấu như thế thôi mà cũng phải mất cả nữa buổi rồi đấy. Vậy, cho nên, bạn chỉ nên tự code 1 media player riêng bằng HTML 5 API chỉ khi nào thật cần thiết mà thôi nhé. Tất nhiên, khi code 1 lần rồi thì các lần sau này chúng ta chỉ cần thay đổi UI thôi, khỏi code js thêm nữa chi cho mệt. Do đó, tốt nhất, bạn hãy chọn cho mình một HTML 5 player mà người ta đã code sẵn rồi, đem về mà dùng thôi. Ngại gì mà không thử nhỉ? Tôi sẽ giới thiệu với các bạn thêm một số HTML 5 player có giao diện UI khá đẹp tiện dụng.

jwplayer
Screen Shot 2014-07-10 at 2.42.43 PMThằng này thì khỏi phải nói rồi, nổi từ khi còn dùng Flash cơ mà. Giờ nó support cả HTML 5 và FLash luôn, tự detect thiết bị và trình duyệt để render ra player phù hợp. Hầu như các site phim online của Việt Nam mình đều dùng player này cả.
videojs
Screen Shot 2014-07-10 at 2.41.29 PMThằng này thì cũng mới xíu, nhưng mà được cái là nó rất đơn giản và gọn nhẹ. Tự edit được color, size cái UI của player luôn, chỉ kéo thả thôi, cái này rất thích hợp với mấy bạn lười.
Sublime Video
Screen Shot 2014-07-10 at 2.40.10 PMChú này cũng rất tiện dụng, nhiều UI khác nhau tha hồ lựa chọn. Cũng có nhiều tính năng khá hay nữa. Như Social Share, Subtitle, Lightbox, Embed,… Thử dùng đi sẽ biết. Cơ mà không biết thằng này có liên cmn quan gì tới cái Sublime Text không nữa.