最終效果:

1、demo結構

fontawesome字體下載:http://fontawesome.dashgame.com/
loading.gif:百度loading.gif選擇一張下載
2、index.html
功能包括:播放/暫停,全屏,跳播
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>自定義視頻播放器</title>
<link rel="stylesheet" href="./css/font-awesome.min.css">
<link rel="stylesheet" href="./css/index.css">
</head>
<body>
<h3 class="player-title">視頻播放器</h3>
<div class="player-container">
<video src="./mp4/test.mp4"></video>
<div class="controls-container">
<!-- 播放/暫停 -->
<a href="javascript:;" class="switch fa fa-play"></a>
<!-- 全屏 -->
<a href="javascript:;" class="expand fa fa-expand"></a>
<!-- 進度條 -->
<div class="progress"><!-- 進度條底色 -->
<div class="bar"></div><!-- 進度條最外層,用於事件控制 -->
<div class="loaded"></div><!-- 已加載 -->
<div class="current-progress"></div><!-- 已播放 -->
</div>
<!-- 當前播放時間, 視頻總長 -->
<div class="time">
<span class="current-time">00:00:00</span>
\
<span class="total-time">00:00:00</span>
</div>
</div>
</div>
<script type="text/javascript">
// 播放器
const video = document.querySelector('video');
// "播放/暫停"切換按鈕
const switchBtn = document.querySelector('.switch');
// 當前播放時間span
const currentTimeSpan = document.querySelector('.current-time')
// 視頻總時長
const totalTimeSpan = document.querySelector('.total-time')
// 當前播放進度條
const currentProgress = document.querySelector('.current-progress')
// 獲取進度條最外層,用於事件控制
const bar = document.querySelector('.bar');
// 實現"播放/暫停"
switchBtn.onclick = function() {
// 播放與暫停的切換
if (video.paused) {
video.play();
} else {
video.pause();
}
// 播放與暫停圖標的切換
this.classList.toggle('fa-pause');
this.classList.toggle('fa-play');
}
// 實現"全屏"
const playerContainer = document.querySelector('.player-container');
document.querySelector('.expand').onclick = function() {
if(playerContainer.requestFullScreen){
playerContainer.requestFullScreen();
} else if(playerContainer.webkitRequestFullScreen){
playerContainer.webkitRequestFullScreen();
} else if(playerContainer.mozRequestFullScreen){
playerContainer.mozRequestFullScreen();
} else if(playerContainer.msRequestFullScreen){
playerContainer.msRequestFullScreen();
}
}
// 當視頻文件可以播放時觸發
// 當跳播時,修改了video.currentTime,也會觸發該事件
video.oncanplay = function() {
console.log('觸發oncanplay事件, video.currentTime=', video.currentTime)
if (video.currentTime === 0) {
setTimeout(function() {
console.log('視頻緩存完成,可以播放了。。。')
// 顯示視頻第一幀畫面
video.style.display = 'block'
// 獲取當前視頻文件總時長
const totalTime = video.duration;
console.log(`當前視頻文件總時長: ${totalTime}秒`); // 單位為秒, 292.975736
// 頁面顯示視頻總時長
totalTimeSpan.innerHTML = getTime(totalTime);
}, 2000)
}
}
// 當視頻播放的時候會觸發ontimeupdate事件,進度條同步,當前時間同步
// 當跳播時,修改了video.currentTime,也會觸發該事件
video.ontimeupdate = function() {
console.log('觸發ontimeupdate事件。。。')
// 獲取當前時間
const currentTime = video.currentTime;
// 計算出視頻的總時長
const totalTime = video.duration;
// 顯示當前播放時間
currentTimeSpan.innerHTML = getTime(currentTime);
//進度條同步: 當前時間/總時間
const value = currentTime / totalTime;
currentProgress.style.width = value * 100 + "%";
//當播放完畢之后,播放暫停按鈕要轉換成暫停按鈕
if (currentTime === totalTime) {
switchBtn.classList.remove('fa-pause');
switchBtn.classList.add('fa-pause');
}
}
// 實現視頻跳播
bar.onclick = function(e) {
// 獲取鼠標點擊位置相對bar最左側的距離
const offset = getOffsetX(e);
// 獲取bar的寬度
const barWidth = this.style.width || this.clientWidth || this.offsetWidth || this.scrollWidth;
console.log(`offset=${offset}, barWidth=${barWidth}`)
const percent = offset / barWidth;
const currentTime = percent * video.duration;
video.currentTime = currentTime;
}
function getTime(time) {
//轉換時長
let h = Math.floor(time / 3600);
let m = Math.floor(time % 3600 / 60);
let s = Math.floor(time % 60);
//轉換格式
h = h > 10 ? h : "0" + h;
m = m > 10 ? m : "0" + m;
s = s > 10 ? s : "0" + s;
return h + ":" + m + ":" + s;
}
// 火狐瀏覽器不支持e.offsetX,解決方法
function getOffsetX(e){
var e = e || window.event;
var srcObj = e.target || e.srcElement;
if (e.offsetX) {
return e.offsetX;
} else {
var rect = srcObj.getBoundingClientRect();
var clientx = e.clientX;
return clientx - rect.left;
}
}
</script>
</body>
</html>
3、index.css
body { padding: 0; margin: 0; font-family: 'microsofy yahei'; background-color: #F7F7F7; } a { text-decoration: none; } .player-title { width: 100%; margin: 0 auto; line-height: 100px; font-size: 40px; text-align: center; } .player-container { width: 720px; height: 360px; margin: 0 auto; background: url('../images/loading.gif') center no-repeat; background-size: cover; position: relative; } video { height: 100%; margin: 0 auto; display: none; } /* ================ 播放器控制面板樣式 start ================ */ .controls-container { width: 720px; height: 40px; position: absolute; left: 0px; bottom: -40px; background-color: #000; } /* 播放/暫停 */ .controls-container .switch { width: 20px; height: 20px; display: block; font-size: 20px; color: #fff; position: absolute; left: 10px; top: 10px; } /* 全屏 */ .controls-container .expand { width: 20px; height: 20px; display: block; font-size: 20px; color: #fff; position: absolute; right: 10px; top: 10px; } /* 進度條 */ .controls-container .progress { width: 430px; height: 10px; position: absolute; left: 40px; bottom: 15px; background-color: #555; } .controls-container .progress .bar { /*width: 100%;*/ width: 430px; height: 100%; border-radius: 3px; cursor: pointer; position: absolute; left: 0; top: 0; opacity: 0; z-index: 999; } .controls-container .progress .loaded { width: 60%; /* 視頻緩存的進度, 后期可動態變化 */ height: 100%; background-color: #999; border-radius: 3px; position: absolute; left: 0; top: 0; z-index: 2; } .controls-container .progress .current-progress { width: 0%; /* 初始播放進度為0 */ height: 100%; background-color: #fff; border-radius: 3px; position: absolute; left: 0; top: 0; z-index: 3; } .controls-container .time { height: 20px; position: absolute; left: 490px; top: 10px; color: #fff; font-size: 14px; } /* ================ 播放器控制面板樣式 end ================ */
4、測試
1)打開index.html頁面,視頻加載完成打印"視頻緩存完成,可以播放了。。。";
2)點擊進度條某個位置,首先觸發了bar.onclick事件,計算並更新video.currentTime;然后觸發了ontimeupdate事件和oncanplay事件。

3)點擊播放按鈕;
4)播放完畢后,發現一個小bug

解決:
刪除代碼:
//當播放完畢之后,播放暫停按鈕要轉換成暫停按鈕 // if (currentTime === totalTime) { // switchBtn.classList.remove('fa-pause'); // switchBtn.classList.add('fa-pause'); // }
添加代碼:
// 視頻播放完畢,重置播放狀態為初始狀態 video.onended = function() { video.currentTime = 0; switchBtn.classList.remove('fa-pause'); switchBtn.classList.add('fa-pause'); }
---
