iT邦幫忙

2019 iT 邦幫忙鐵人賽

0
自我挑戰組

JavaScript 30天系列 第 11

JS30 - day11: Custom HTML5 Video Player

https://ithelp.ithome.com.tw/upload/images/20181031/20111164pv3HFPCifE.png

參考文件

使用者操作需求

使用HTML5 video影片的各種操作,有播放/暫停、聲音大小、影片速度、影片播放位置、快轉與倒退

技術重點

影片屬性

  • video.paused 判斷影片是播放/暫停

  • video.currentTime 影片當前秒數

  • video.volume 返回當前音檔/影片檔的音量大小

  • video.playbackRate 返回當前音檔/影片檔的速度

  • parseFloat(str) 將參數轉為數字

流程步驟

[ 基本設置 ]

/* 抓取需要的 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 ranges = player.querySelectorAll('.player__slider'); // 聲音 速度
const skipBtns = player.querySelectorAll('[data-skip]'); // 前後快轉

[ 播放 & 暫停 ]

點選影片及播放鍵 可以控制影片播放/暫停
判斷 video.paused 影片是播放/暫停
這裡比較特別的寫法是 video[method]() 將參數帶進去後執行

function togglePlay() {

    // 按鍵樣式更新
    const playicon = '<i class="fas fa-play"></i>';
    const pauseicon = '<i class="fas fa-pause"></i>';
    const icon = video.paused ? pauseicon : playicon;
    toggle.innerHTML = icon;
    
    // 影片播放/暫停
    const method = video.paused ? 'play' : 'pause';
    video[method](); // = video.play() || video.pause()
}

video.addEventListener('click', togglePlay);
toggle.addEventListener('click', togglePlay);

[ 倒退 & 快轉 ]

這邊是先在HTML 的 data-skip 設定好倒退&快轉的參數

<button data-skip="-10" class="player__button">« 10s</button>
<button data-skip="25" class="player__button">25s »</button>

this.dataset.skip 取出HTML中的 data-skip=
轉為數字後對影片秒數做加減的動作

function skipUpdate() {
    // currentTime 影片當前秒數
    // parseFloat(str) 將參數轉為數字
    video.currentTime += parseFloat(this.dataset.skip);
}

skipBtns.forEach((btn) => {btn.addEventListener('click', skipUpdate)});

[ 聲音 & 速度 ]

這邊也是先在HTML設定好, name 的命名 volume & playbackRate 就是video的屬性 可以直接使用

<!-- 聲音 -->
<input type="range" name="volume" class="player__slider" min="0" max="1" step="0.05" value="1">
<!-- 速度 -->
<input type="range" name="playbackRate" class="player__slider" min="0.5" max="2" step="0.1" value="1">

拖曳條range的監聽需要有 changemousemove
然後取得名字 this.name 使用

function rangeUpdate() {
    // volume 返回當前音檔/影片檔的音量大小
    // playbackRate 返回當前音檔/影片檔的速度
    video[this.name] = this.value;
}

ranges.forEach((range) => {range.addEventListener('change', rangeUpdate)});
ranges.forEach((range) => {range.addEventListener('mousemove', rangeUpdate)});

[ 進度條 ]

進度條在一開始影片播放時就會隨著影片播放來改變顯示長度
並且操作 點擊&點擊拖曳 也可以改變進度條的長度以及影片的播放位置

** 顯示長度 **
作者影片中的監聽是使用timeupdate 但是一開始顯示會在50%的位置
找了一下別人寫的方式 改用progress 會在載入時就將進度顯示在正確位置

function progressUpdate() {
    // duration 當前音檔/影片檔的長度(以秒計)
    const precent = (video.currentTime / video.duration) * 100;
    progressBar.style.flexBasis = `${precent}%`;
}

video.addEventListener('progress', progressUpdate);

** 操作位置 **
操作進度條的動作可以分為兩種 點擊click 以及 點擊並拖曳
在點擊並拖曳的動作中可以先設定一個變數let mousedown = false 來判斷滑鼠是否點擊
mousedownmouseup 來改變 let mousedown 變數的boolean
傳入function scrub(), e.offsetX滑鼠點選位置除以整條progress長度乘上影片長度(痾..數學..
之後改變影片秒數位置

function scrub(e) {
    const scrubTime = (e.offsetX / progress.offsetWidth) * video.duration;
    video.currentTime = scrubTime; // 改變影片當前秒數
}

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

上一篇
JS30 - day10: Hold Shift to Check Multiple Checkboxes
系列文
JavaScript 30天11

尚未有邦友留言

立即登入留言