Hướng dẫn javascript video player timeline - dòng thời gian của trình phát video javascript

I created a player using HTML/JS/CSS, which I uploaded , specific use on the real server , the player works correctly on high resolution (PC), but not working properly on mobile, for example, the preview does not work when hovering over the timeline with finger. I would like advice on how to fix it.

js - timeline part

// Timeline

timelineContainer.addEventListener("mousemove", handleTimeLineUpdate)
timelineContainer.addEventListener("mousedown", toggleScrubbing);

document.addEventListener("mouseup", e => {
    if(isScrubbing) toggleScrubbing(e)
})

document.addEventListener("mousemove", e => {
    if(isScrubbing) handleTimeLineUpdate(e)
})


let isScrubbing = false;
let wasPaused;

function toggleScrubbing(e){
    const rect = timelineContainer.getBoundingClientRect();
    const percent = Math.min(Math.max(0, e.x - rect.x), rect.width)/rect.width;

    isScrubbing = (e.buttons & 1) === 1;
    videoContainer.classList.toggle("scrubbing", isScrubbing)
    if(isScrubbing){
        wasPaused = video.paused;
        video.pause();
    } else {
        video.currentTime = percent * video.duration;
        if(!wasPaused) video.play();
    }
    handleTimeLineUpdate(e);
}


function handleTimeLineUpdate(e){
    const rect = timelineContainer.getBoundingClientRect();
    // e.x = position mous, rect.x = position timeline
    const percent = Math.min(Math.max(0, e.x - rect.x), rect.width)/rect.width;

    // /10 protože mám po 10 vterinach 
    const previewImgNumber = Math.max(1, Math.floor((percent*video.duration)/10));
    const previewImgSrc = `video/preview${previewImgNumber}.jpg`;
    // Uložení cesty k obrazku
    previewImg.src = previewImgSrc;
    timelineContainer.style.setProperty("--preview-position",percent);

    if(isScrubbing)
    {
        e.preventDefault();
        thumbnailImg.src = previewImgSrc;
        timelineContainer.style.setProperty("--progress-position", percent);
    }
}

This work on PC browser but not well on mobile

Hướng dẫn javascript video player timeline - dòng thời gian của trình phát video javascript

Thằ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
Trong phần này, mình sẽ hướng dẫn các bạn tạo một phayer cực đơn giản với API của HTML 5. Nhưng trước tiên chúng ta cần phải có ui của một media player cái đã.

Mã:

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 đề đó.

Mã:





Current: 0 / 0


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 đề đó.

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.
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.

Mã:

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.
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.

Mã:

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.
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.

Mã:

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. Mình 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.
Đó 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. Mình 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.

Mã:

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 mình 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 đó, mình 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.
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.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 đổiondurationchange. 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

Mã:

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 đề chúng ta quan tâm lúc này là khi 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à 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ậc tiểu học “nhân chéo” để tìm kết quả.
Vấn đề chúng ta quan tâm lúc này là khi 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à 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ậc 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.

Mã:

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 đề đó.

Mã:

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.

Hướng dẫn javascript video player timeline - dòng thời gian của trình phát video javascript

Thanh 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ó. 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ó.

Mã:

0

Tất nhiên, hiện tại thì nó chỉ hoạt động được trên trình duyệt chrome và safari. Mình 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.

#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ỉ? Mình 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ỉ? Mình 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 sau đây.
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ỉ? Mình 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ỉ? Mình 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 sau đây.

jwplayer

Thằ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

Thằ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

Thằ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

Thằ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.