播放器自定义控制条
这是我目前做的,但并不完善,后期有时间还会修改过,但大致上已经可以了。
我写进度条样式的方法不是很好,我觉得把进度条最后的原点额外用一个div来控制比较好。我这里写的是用 :before 来控制的。
效果图:
引入的文件
<link rel="stylesheet" href="css/bootstrap.min.css">
<link rel="stylesheet" href="css/video-play.css">//自己写的
<script src="../jQuery版本/jquery-1.12.4.min.js"></script>
<script src="js/bootstrap.js"></script>
<script src="js/videoPlay.js"></script>//自己写的
主代码结构
<div id="player" class="player">
<div id="videoBox" class="video-box text-center">
<video id="film" width="100%" ondblclick="fullScreen()">
<source src="video/遇见你之前Me.Before.You.2016.hd720p.x264.AAC.英语中文字幕.mp4" type="video/mp4"/>
</video>
<!--屏幕中显示的这暂停/播放图标-->
<img id="playImg" class="none" src="img/play.svg" alt="">
<img id="pauseImg" class="none" src="img/pause.svg" alt="">
<div id="controller" style="display: none;">
<div class="custom-progress">
<div class="progress-bar">
<div class="now"></div>
</div>
</div>
<div class="controller-btns">
<div class="controller-left">
<!--播放/暂停-->
<span class="glyphicon glyphicon-play pointer" onclick="playPause()"></span>
<span class="glyphicon glyphicon-pause pointer none" style="padding-right: 19px;"
onclick="playPause()"></span>
<!--停止-->
<span class="glyphicon glyphicon-stop pointer" onclick="stop()"></span>
<!--音量-->
<div class="sound-group">
<span class="glyphicon glyphicon-volume-up pointer" style="font-size: 19px;top:3px; padding-left:13px;"
onclick="soundMuted()"></span>
<span class="glyphicon glyphicon-volume-down pointer none" style="font-size: 19px;top:3px; padding-left:15px;"
onclick="soundMuted()"></span>
<span class="glyphicon glyphicon-volume-off pointer none"
style="font-size: 19px;padding-left: 11px;padding-right: 10px; top:3px;"
onclick="soundMuted()"></span>
<div class="sound-progress" style="display: none;">
<div class="sound-now"></div>
<div class="show-sound-now none"></div>
</div>
</div>
<!--当前/总时间-->
<span class="start"></span>/<span class="end"></span>
</div>
<div class="controller-right">
<div class="rate-group">
<span class="rate">倍速</span>
<ul class="rate-dashboard none">
<li onclick="getRate(this)">2.0x</li>
<li onclick="getRate(this)">1.5x</li>
<li onclick="getRate(this)">1.25x</li>
<li style="color:#007ffe;" onclick="getRate(this)">1x</li>
<li onclick="getRate(this)">0.5x</li>
</ul>
</div>
<span class="glyphicon glyphicon-resize-full pointer" style="top:3px;"
onclick="fullScreen()"></span>
<span class="glyphicon glyphicon-resize-small pointer none" onclick="exitFullscreen()"></span>
</div>
</div>
</div>
</div>
</div>
css:
.none {
display: none;
}
.player {
position: relative;
overflow: hidden;
line-height: 1;
height: 100%;
}
.video-box {
width: 50%;
height: auto;
background-color: #000;
position: relative;
}
video{
width: 100%;
position: relative;
}
.pointer {
cursor: pointer;
color: #ddd;
font-size: 16px;
}
.pointer:hover {
color: #fff;
}
/*自定义控制条*/
#controller {
color: #eee;
width: 100%;
opacity: 1;
-webkit-transform: translateY(100%);
transform: translateY(100%);
position: absolute;
bottom: -5px;
height: 41px;
padding: 0 20px;
}
.controller-btns {
position: relative;
top: -40px;
left: 0;
}
.controller-btns span {
padding: 0 5px;
width: 40px;
}
.controller-left {
display: inline-block;
position: absolute;
top: 0;
left: 0;
}
.controller-right {
display: inline-block;
position: absolute;
top: 0;
right: 0;
}
.custom-progress {
width: 100%;
position: relative;
top: -50px;
left: 0;
}
/*总进度条*/
.progress-bar {
position: relative;
width: 100%;
height: 4px;
background-color: #333333;
vertical-align: 2px;
border-radius: 4px;
cursor: pointer;
}
.now {
position: absolute;
left: 2px;
display: inline-block;
height: 4px;
background: #007ffe;
}
.now::after {
content: '';
position: absolute;
top: -2px;
left: 97%;
width: 8px;
height: 8px;
border-radius: 50%;
background-color: #007ffe;
}
.sound-group{
display: inline-block;
}
/*音量进度条*/
.sound-progress {
width: 60px;
height: 5px;
background-color: #fff;
border-radius: 3px;
cursor: pointer;
display: inline-block;
position: relative;
top: -4px;
left: -5px;
}
.sound-now {
display: inline-block;
width: 100%;
border-radius: 3px;
height: 5px;
background: #007ffe;
position: absolute;
left: 0;
}
.sound-now::after {
content: '';
position: absolute;
left: 95%;
top: -2px;
width: 8px;
height: 8px;
border-radius: 50%;
background-color: #007ffe;
}
.show-sound-now{
display: inline-block;
padding: 3px 5px;
background-color: rgba(1,1,1,0.7);
color: #eee;
border-radius: 3px;
position: absolute;
top: -30px;
}
.rate-group{
display: inline-block;
width: 55px;
border-radius: 14px;
padding: 0 5px;
}
.rate{
display: inline-block;
height: 22px;
text-align: center;
line-height: 22px;
color: #fff;
cursor: pointer;
}
.rate-group:hover{
background-color: #007ffe;
}
.rate-dashboard{
list-style: none;
position: absolute;
top: -170px;
left: -40px;
}
.rate-dashboard >li{
display: block;
cursor: pointer;
background-color: rgba(0, 0, 0, 0.8);
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
box-shadow: 0 0 16px 0 rgba(0, 0, 0, 0.2);
border-radius: 1px;
color: #fff;
text-align: center;
line-height: 30px;
font-size: 12px;
padding: 0 15px;
}
.rate-dashboard >li:hover{
background-color: rgba(0,0,0,0.5);
}
/*屏幕中播放/暂停图标*/
#videoBox img{
padding: 15px;
border-radius: 50%;
background-color: rgba(255,255,255,0.2);
position: absolute;
top: 40%;
right: 42.5%;
width: 100px;
cursor: pointer;
}
js:
var videoBox = document.getElementById("videoBox");
var myVideo = document.getElementById("film");
var soundNow = document.getElementsByClassName("sound-now")[0];
var playImg = document.getElementById("playImg");
var pauseImg = document.getElementById("pauseImg");
var last="100%",timeId;
/*停止-跳回开头*/
function stop() {
myVideo.pause();
myVideo.currentTime = 0;
}
/*全屏*/
function fullScreen() {
if (videoBox.requestFullscreen) {
videoBox.requestFullscreen();
myVideo.style.width = "100%";
myVideo.style.height = "auto";
} else if (videoBox.mozRequestFullScreen) {
videoBox.mozRequestFullScreen();
myVideo.style.width = "100%";
myVideo.style.height = "auto";
} else if (videoBox.webkitRequestFullScreen) {
videoBox.webkitRequestFullScreen();
myVideo.style.width = "100%";
myVideo.style.height = "auto";
}
$(".glyphicon-resize-full").hide();
$(".glyphicon-resize-small").show();
}
/*退出全屏*/
function exitFullscreen() {
var de = document;
if (de.exitFullscreen) {
de.exitFullscreen();
myVideo.style.width = "100%";
myVideo.style.height = "auto";
} else if (de.mozCancelFullScreen) {
de.mozCancelFullScreen();
myVideo.style.width = "100%";
myVideo.style.height = "auto";
} else if (de.webkitCancelFullScreen) {
de.webkitCancelFullScreen();
myVideo.style.width = "100%";
myVideo.style.height = "auto";
}
}
/*音量*/
function soundMuted() {
if (myVideo.muted) {//未静音
myVideo.muted = false;
} else {//静音
myVideo.muted = true;
soundNow.style.width = "0";
}
}
/*倍速播放*/
function getRate(element){
console.log();
myVideo.playbackRate = parseFloat(element.innerHTML);
}
/*播放/暂停*/
function playPause() {
if (myVideo.paused){
myVideo.play();
pauseImg.style.display="none";
playImg.style.display="block";
$("#playImg").fadeIn(400);
timeId=setInterval("hideScreenPlay()",300)
}else{
myVideo.pause();
pauseImg.style.display="block";
}
}
function hideScreenPlay(){
$("#playImg").fadeOut(300);
clearInterval(timeId);
}
/******************* jQuery ***********************/
$(function () {
var play = $(".glyphicon-play");
var pause = $(".glyphicon-pause");
var full = $(".glyphicon-resize-full");
var exitFull = $(".glyphicon-resize-small");
var soundUp = $(".glyphicon-volume-up");
var soundDown = $(".glyphicon-volume-down");
var muted = $(".glyphicon-volume-off");
var soundProgress=$(".sound-progress");
$(".video-box").mousemove(function () {
$("#controller").fadeIn(400);
}).mouseleave(function () {
$("#controller").fadeOut(400);
});
/*点击视频暂停/播放*/
/*此处右问题,点击视频处仅一次有效*/
// $("#film,#pauseImg,#playImg").click(function () {
// if(pause.show()){ //播放状态
// $("#pauseImg").fadeIn(500);
// playPause();
// pause.hide();
// play.show();
// }else{ //暂停状态
// pause.show();
// play.hide();
// }
// });
/*切换显示图标*/
play.click(function () {//播放状态
$(this).hide();
pause.show();
// flag=true;
});
pause.click(function () {//暂停状态
$(this).hide();
play.show();
// flag=false;
});
full.click(function () {
$(this).hide();
exitFull.show();
});
exitFull.click(function () {
$(this).hide();
full.show();
});
soundUp.click(function () {
$(this).hide();
muted.show();
});
soundDown.click(function () {
$(this).hide();
muted.show();
});
muted.click(function () {
$(this).hide();
soundNow.style.width = last;
last === "100%" ? soundUp.show() : soundDown.show();
});
/*显示音乐进度条*/
$(".sound-group").mouseover(function () {
soundProgress.stop().show(400);
}).mouseout(function () {
soundProgress.stop().hide(400);
});
/*点击音量进度条*/
soundProgress.click(function (event) {
muted.hide();
last === "100%" ? soundUp.show() : soundDown.show();
myVideo.muted = false;
let soundWidth = event.pageX - this.getBoundingClientRect().left;
soundWidth = soundWidth < 0 ? 0 : soundWidth;
soundWidth = soundWidth > this.offsetWidth ? this.offsetWidth : soundWidth;
let p = soundWidth / this.offsetWidth;
soundNow.style.width = p.toFixed(2) * 100 + '%';
last = p.toFixed(2) * 100 + '%';
myVideo.volume = p;
$(".show-sound-now").stop().show().text(soundNow.style.width).delay(1000).hide(0);
if (soundNow.style.width === "0%") {
soundUp.hide();
soundDown.hide();
muted.show();
} else if (soundNow.style.width === "100%") {
muted.hide();
soundDown.hide();
soundUp.show();
} else {
soundUp.hide();
muted.hide();
soundDown.show();
}
});
/*点击倍速*/
$(".rate").click(function () {
$(".rate-dashboard").show().children("li").click(function(){
$(this).css("color","#007ffe").siblings().css("color","#eee");
var t=$(this).text();
$(".rate").text(t);
$(this).parent().hide();
});
});
});
/******* 视频进度条 ********/
// const 定义的变量不可以修改,而且必须初始化
const video = document.getElementById('film');
const start = document.querySelector('.start');
const end = document.querySelector('.end');
const progressBar = document.querySelector('.progress-bar');
const now = document.querySelector('.now');
// let 声明的变量只在该花括号内有效(块级作用域),要声明才可用
function conversion(value) {
let minute = Math.floor(value / 60);
minute = minute.toString().length === 1 ? ('0' + minute) : minute;
let second = Math.round(value % 60);
second = second.toString().length === 1 ? ('0' + second) : second;
return `${minute}:${second}`
}
video.onloadedmetadata = function () {
end.innerHTML = conversion(video.duration);
start.innerHTML = conversion(video.currentTime);
};
progressBar.addEventListener('click', function (event) {
//getBoundingClientRect();
// 这个方法返回一个矩形对象,包含四个属性:left、top、right和bottom。分别表示元素各边与页面上边和左边的距离。
let coordStart = this.getBoundingClientRect().left;
let coordEnd = event.pageX;
let p = (coordEnd - coordStart) / this.offsetWidth;
now.style.width = p.toFixed(3) * 100 + '%';
video.currentTime = p * video.duration;
video.play()
});
setInterval(() => {
start.innerHTML = conversion(video.currentTime);
now.style.width = video.currentTime / video.duration.toFixed(3) * 100 + '%'
}, 1000)