要自製一個video player
需要做的有
play()
/pause()
以下是html
<div class="player">
<video class="player__video viewer" src="https://player.vimeo.com/external/194837908.sd.mp4?s=c350076905b78c67f74d7ee39fdb4fef01d12420&profile_id=164"></video>
<div class="player__controls">
<div class="progress">
<div class="progress__filled"></div>
</div>
<button class="player__button toggle" title="Toggle Play">►</button>
<input type="range" name="volume" class="player__slider" min="0" max="1" step="0.05" value="0.1">
<input type="range" name="playbackRate" class="player__slider" min="0.5" max="2" step="0.1" value="1">
<button data-skip="-10" class="player__button">« 10s</button>
<button class="player__button full-screen" style="font-size: 24px;">▭</button>
</div>
</div>
首先先將包裹著的video的容器選起來
let player = document.querySelector('.player'); //容器
let toggle = player.querySelector('.toggle'); //播放鈕
let video = player.querySelector('.viewer'); //影片
let skipButtons = player.querySelectorAll('[data-skip]'); //skip按鈕
let handlers = player.querySelectorAll('[type="range"]'); //handler
let progressBar = player.querySelector('.progress'); //進度條
let currentBar = player.querySelector('.progress__filled'); //當前進度
let fullScreen = player.querySelector('.full-screen'); //全螢幕按鈕
設置點擊的監聽事件
video.addEventListener('click', togglePlay); //點擊影片
toggle.addEventListener('click', togglePlay); //點擊播放按鈕
video.addEventListener('play', changeButton); //影片播放/暫停時,按鈕樣式改變
video.addEventListener('pause', changeButton);
要控制影片的播放就要偵側影片的播放狀態
並依照狀態播放或者暫停
然後還要修改播放鈕的圖示
//偵測video的播放狀態,並播放或暫停
function togglePlay() {
// const method = video.paused ? 'play' : 'pause';
// video[method]();
video.paused ? video.play() : video.pause();
}
function changeButton() {
const icon = this.paused ? '►' : '❚ ❚';
toggle.textContent = icon;
}
由於我們拿到的handler是nodeList組成
所以要使用forEach()
方法來監聽每個handler的change
和mousemove
事件change
是改變的當下才會執行handlerChange()
而mousemove
讓我們在拖曳的時候也能執行
handlers.forEach(handler => handler.addEventListener('change', handlerChange));
handlers.forEach(handler => handler.addEventListener('mousemove', handlerChange));
兩個handler的name
都已經放入控制video屬性volume
和playbackRate
了
所以我們就用video[this.name]
來帶入屬性,讓他等於this.value
即可控制音量和播放速度
function handlerChange() {
video[this.name] = this.value;
}
監聽點擊跳轉鈕和雙擊影片的事件
skipButtons.forEach(skipButton => skipButton.addEventListener('click' ,skip));
video.addEventListener('dblclick', doubleClickScreen);
由於點擊跳轉鈕的時間寫在data-skip
屬性內(string)
所以使用this.dataset.skip
將字串叫出來
並使用pardeFloat()
將字串轉成數字
如下
function skip() {
video.currentTime += parseFloat(this.dataset.skip);
}
function doubleClickScreen(e) {
const skipTime = (e.offsetX > this.offsetWidth / 2) ? '10' : '-10';
video.currentTime += parseFloat(skipTime);
}
另外我們也要偵測點擊影片的位置
由於我們取得的element都是在player
底下
因此只要e.offsetX
大於整個寬度的一半就是往後快轉10s
小於則是倒帶10s
首先我們先讓進度條可以跟著影片的播放而移動
css內使用的是flex-basis
所以可以使用百分比來顯示等前進度
我們只要
將時間還換成百分比即可
程式碼如下
function handleProgress() {
const percent = (video.currentTime / video.duration) * 100;
currentBar.style.flexBasis = `${percent}%`;
}
progressBar.addEventListener('mousemove', drag);
但是只有偵測mousemove
是不夠的
我們只要讓滑鼠在進度條上移動
就會影響其長度
因此用一個變數mousedown
來存取mouse的狀態
預設是false
並偵測滑鼠點下與放開
let mousedown = false;
progressBar.addEventListener('mousemove', drag);
progressBar.addEventListener('mousedown', clickProgressBar);
progressBar.addEventListener('mouseup', clickProgressBar);
當滑鼠被點下或拿起是
會改變mousedown
的狀態
這樣在拖曳的時候才會有反應
function drag(e) {
if (mousedown) {
const dragTime = (e.offsetX / progressBar.offsetWidth) * video.duration;
video.currentTime = dragTime;
}
}
function clickProgressBar(e) {
mousedown = !mousedown;
}
但我們會發現在點擊的時候
影片並不會到指定的時間點
因此我們再添加下列程式碼
function clickProgressBar(e) {
const dragTime = (e.offsetX / progressBar.offsetWidth) * video.duration;
video.currentTime = dragTime;
mousedown = !mousedown;
}
監聽全螢幕按鈕
fullScreen.addEventListener('click', toggleFullScreen);
由於全螢幕並未標準化
所以需要分別來設置他們全螢幕的方式
程式碼如下
function toggleFullScreen() {
if (video.requestFullscreen) {
video.requestFullscreen();
} else if (video.mozRequestFullScreen) { /* Firefox */
video.mozRequestFullScreen();
} else if (video.webkitRequestFullscreen) { /* Chrome, Safari & Opera */
video.webkitRequestFullscreen();
} else if (video.msRequestFullscreen) { /* IE/Edge */
video.msRequestFullscreen();
}
}
關於全螢幕可以參考MDN