iT邦幫忙

2022 iThome 鐵人賽

DAY 11
0
自我挑戰組

JavaScript 30天挑戰 自學筆記系列 第 11

JS30 自學筆記 Day11_Custom HTML5 Video Player

  • 分享至 

  • xImage
  •  

今日任務:做一個播放器

HTML

<div class="player">
	<video class="player__video viewer" src="video.mp4"></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="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 data-skip="25" class="player__button">25s »</button>
        </div>
</div>

取得元素

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 buttons = player.querySelectorAll('.player__button');

播放/暫停影片

video預設只有暫停屬性沒有play屬性
true is paused,所以要play播放

function togglePlay() {
    if (viedeo.paused) {
        viedeo.play();
    } else {
        viedeo.pause();
    }
}

在播放鍵和整個影片掛上我們的function,順便簡寫

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

function togglePlay() {
    viedeo.paused ? viedeo.play() : viedeo.pause();
}

處理播放暫停鍵

//偵測影片狀態
viedeo.addEventListener('play', updateBtn); 
viedeo.addEventListener('pause', updateBtn);

function updateBtn() {
    this.paused ? (toggle.textContent = '►') : (toggle.textContent = '❚ ❚');
}

加速skip按鈕

viedeo.currentTime
設置動畫的當前時間值(以毫秒為單位),無論是運行還是暫停。
因為獲取的是字串,所以要轉為數字
使用parseFloat(字串),可以轉為數字(浮點數)

buttons.forEach((button) => {
    button.addEventListener('click', skip);
});

function skip() {
    viedeo.currentTime += parseFloat(this.dataset.skip);
}

聲音與速度控制

HTMLMediaElement.volume 可以設定影片的音量,0~1。
HTMLMediaElement.playbackRate 可以設定影片的速度,1.0是正常播放速度。

ranges.forEach((range) => {
    range.addEventListener('change', handleRange);
});
function handleRange() {
    video[this.name] = this.value;
}

處理進度條

timeupdate event
當currentTime更新時會觸發timeupdate事件。

將(目前時間 / 影片總時長)*100,來得到目前時間所占總時長的百分比
然後將得到的百分比設定給progressBar的寬度

video.addEventListener('timeupdate', handleProgress);

function handleProgress() {
    const percent = (video.currentTime / video.duration) * 100;
    progressBar.style.width = `${percent}%`;
}

處理拖拉進度條

e.offsetX / 整條進度條的長度 = 知道滑鼠按下的地方相對於進度條的占比
video.duration 影片的長度,以秒為單位

progress.addEventListener('click', scrub);
progress.addEventListener('mousemove', scrub);

function scrub(e) {
    const scrubTime = (e.offsetX / progress.offsetWidth) * video.duration;
    video.currentTime = scrubTime;
}

mousemove一碰上去就會執行拖拉進度條
但是想要滑鼠點下去之後再跳
使用我們前一天學到的mousedown, mouseup
mousedown && scrub(e)
意思是:當mousedown==true,才執行scrub(e),否則不執行

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

今日學習到的:

  • video預設只有暫停屬性沒有play屬性
  • viedeo.addEventListener('play', updateBtn);
  • viedeo.addEventListener('pause', updateBtn);
  • viedeo.currentTime: 設置動畫的當前時間值
  • parseFloat(字串),可以轉為數字(浮點數)
  • HTMLMediaElement.volume 可以設定影片的音量,0~1。
  • HTMLMediaElement.playbackRate 可以設定影片的速度,1.0是正常播放速度。
  • 當currentTime更新時會觸發timeupdate事件。
  • video.duration 影片的長度,以秒為單位
  • mousedown && scrub(e)意思是:當mousedown==true,才執行scrub(e),否則不執行

效果連結:連結

參考連結:
MDN: video.paused
MDN: video.currentTime
MDN: timeupdate event


上一篇
JS30 自學筆記 Day10_Hold Shift to Check Multiple Checkboxes
下一篇
JS30 自學筆記 Day12_Key Sequence Detection (KONAMI CODE)
系列文
JavaScript 30天挑戰 自學筆記30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言