Custom HTML5 Video Player


Posted by wayne201299 on 2023-09-28

客製一個影片播放器,功能有

  • 播放、暫停
  • 快轉、倒轉
  • 聲音及播放速度調整
  • 進度條調整

實作

因為這次的JavaScript內容較多因此將檔案獨立出去,由外部引入

<script src="scripts.js"></script>

透過querySelector querySelectorAll將所有畫面上可以操作的element選取

const player = document.querySelector(".player");
const video = player.querySelector(".viewer");
const progress = player.querySelector(".progress");
const progressBar = player.querySelector(".progress__filled");

const toggle = player.querySelector(".toggle");
const skipButtons = player.querySelectorAll("[data-skip]");
const ranges = player.querySelectorAll(".player__slider");

播放、暫停

監聽畫面及播放按鈕的點擊事件,以此決定影片是否播放

toggle.addEventListener("click", togglePlay);
video.addEventListener("click", togglePlay);
function togglePlay() {
    const method = video.paused ? "play" : "pause";
    video[method]();
}

改變按鈕樣式,監聽影片播放狀態來改變按鈕

function updateButton() {
    const icon = this.paused ? "►" : "❚ ❚";
    toggle.textContent = icon;
}
video.addEventListener("play", updateButton);
video.addEventListener("pause", updateButton);

影片快轉或倒轉

快轉或倒轉按鈕中有一個data-skip屬性,可以透過dataset取得skip的數值,可以用來決定影片要快轉或倒轉

<button data-skip="-10" class="player__button">« 10s</button>
<button data-skip="25" class="player__button">25s »</button>
function skip(){
    video.currentTime += parseFloat(this.dataset.skip);
}

關於dataset的使用詳細可以看我的這篇文章

聲音及播放速度

一樣透過監聽的方式得到點擊跟滑鼠移動事件

ranges.forEach(range => range.addEventListener("change", handleRangeUpdate));
ranges.forEach(range => range.addEventListener("mousemove", handleRangeUpdate));

動態調整video對應的屬性

function handleRangeUpdate(){
    video[this.name] = this.value;
}

進度條

  1. 讓進度條隨著影片播放進度增加或減少
    監聽video的timeupdate事件

     video.addEventListener("timeupdate", handleProgress);
    

    依照影片撥放的比例調整progress bar的style

     function handleProgress() {
         const percent = (video.currentTime / video.duration) * 100;
         progressBar.style.flexBasis = `${percent}%`;
     }
    
  2. 支援點擊調整進度條
    監聽progressBar的點擊事件

     progress.addEventListener("click", scrub);
    

    點擊event會告訴我們點擊的位置,取offsetX與整段progress的長度比例乘上影片總長度就可以知道要撥放的時間區段

     function scrub(e){
         const scrubTime = (e.offsetX / progress.offsetWidth) * video.duration;
         video.currentTime = scrubTime;
     }
    
  3. 支援滑動調整進度條
    監聽progress的滑鼠移動事件抓到對應的X軸座標,但這樣會變成當滑鼠移動進度條就會跟著跑,需要添加一個flag來判斷滑鼠是不是有按著,當滑鼠按著拖拉進度條才會調整

     let mousedown=false;
     progress.addEventListener("click", scrub);
     progress.addEventListener("mousemove", (e)=>mousedown && scrub(e));
     progress.addEventListener("mousedown", () => mousedown=true);
     progress.addEventListener("mouseup", () => mousedown=false);
    

知識點

  • HTML中的<video>標籤可以播放影片
  • flexBasis 設定flexbox的初始大小

#javascript #html







Related Posts

OOP - 6 關於抽象

OOP - 6 關於抽象

快速排序(Quick Sort)

快速排序(Quick Sort)

Leetcode 刷題 pattern - 一週年特典

Leetcode 刷題 pattern - 一週年特典


Comments