1.less页面包装,引用混合
//导入播放器基础css
@import "reset.less";
//定义进度条混合
.progress-bar-position() {
position: relative;
}
.progress-bar-line() {
//定位:位置不变
position: absolute;
//进度条:height:3px BG:#737373
width: 100%;
height: 3px;
//总高25,这里是3,剩余22
margin-top: 11px;
background: #737373;
}
.progress-bar-btn() {
//定位:拖拽
position: absolute;
//w/h:w9*h7 BG:white border-radius+2px solid
width: 15px;
height: 12px;
background: white;
border-radius: 5px;
//总高7,这里是3,剩余4
margin-top: -5px;
background: steelblue;
}
.progress-bar-current() {
//实时进度条
position: absolute;
left: 0;
top: 0;
width: 0;
background: skyblue;
//高度和line相同
margin-top: 11px;
height: 3px;
}
* {
margin: 0;
padding: 0;
}
#wrap {
//全屏效果
height: 100%;
//overflow: hidden;
//overflow: auto;
//滚动条,x轴有,y轴hidden
overflow-x: auto;
overflow-y: hidden;
// position: absolute;
// width: 800px;
// height: 800px;
background: #383838;
// border: 1xp solid steelblue;
// border-radius: 8%;
// box-shadow: 2px 5px 5px #000000;
// top: 50%;
// left: 50%;
// transform: translate3d(-50%,-50%,0);
text-align: center;
//避免div之间存在缝隙空间padding
font-size: 0;
h1 {
color: white;
font-weight: bold;
font: 20px "微软雅黑";
margin: 2% auto;
}
#video-control {
//行定位
position: relative;
height: 25px;
background: #2A2A2A;
//这里设置最小宽度,需要在wrap中放开overflow:auto,否则不生效
min-width: 600px;
.video-btn {
position: absolute;
width: 55px;
height: 25px;
//background: skyblue;
//修改默认的left top=auto
left: 0;
top: 0;
//span居中
text-align: center;
//总高25,span=11,余14空间,上下各7
margin-top: 7px;
span {
display: inline-block;
width: 9px;
height: 11px;
background: url(../img/icon.png) no-repeat;
&:nth-child(1) {
background-position: 0px -23px;
margin-right: 10px;
//如果具备active属性,则位置移动到stop后面
&.active{
background-position: 0px -11px;
}
}
&:nth-child(2) {
background-position: 0px 0px;
}
}
}
.video-progress {
//相对定位(基于control,需要将min-width给video-control),根据line和btn
//position: relative;
//上右下左,宽度自适应,不需要定位
margin: 0 230px 0 55px;
height: 25px;
font-size: 20px;
.progress-bar-position();
.progress-line {
.progress-bar-line();
.progress-btn {
.progress-bar-btn();
}
}
.progress-current {
.progress-bar-current();
}
}
//3.视频尾部模块
.video-other-operation {
//定位,基于video-control
position: absolute;
width: 230px;
height: 25px;
//不写right,默认auto,下一行,需要指定0
right: 0;
bottom: 0;
//高度统一
&>div {
height: 25px;
float: left;
}
//视频时间
.video-time {
font: 14px "微软雅黑";
color: skyblue;
line-height: 25px;
text-align: center;
width: 120px;
}
.video-audio {
width: 80px;
div {
height: 25px;
float: left;
}
.audio-switch {
width: 20px;
text-align: center;
span {
display: inline-block;
width: 12px;
height: 12px;
margin: 7px auto;
background: url(../img/icon.png) no-repeat;
background-position: 0 -34px;
&.active{
background-position: 0 -46px;
}
}
}
.audio-volume {
width: 60px;
.progress-bar-position();
.volume-line {
.progress-bar-line();
.volume-btn {
.progress-bar-btn();
}
}
.volume-current {
.progress-bar-current();
}
}
}
.video-full-screen {
width: 30px;
text-align: center;
span {
display: inline-block;
width: 12px;
height: 12px;
margin: 7px auto;
background: url(../img/icon.png) no-repeat;
background-position: 0 -58px;
&.active{
background-position: 0 -70px;
}
}
}
}
}
}
2.css生成样式
html,
body {
height: 100%;
overflow: hidden;
}
html,
body,
div,
span,
applet,
object,
iframe,
h1,
h2,
h3,
h4,
h5,
h6,
p,
blockquote,
pre,
a,
abbr,
acronym,
address,
big,
cite,
code,
del,
dfn,
em,
img,
ins,
kbd,
q,
s,
samp,
small,
strike,
strong,
sub,
sup,
tt,
var,
b,
u,
i,
center,
dl,
dt,
dd,
ol,
ul,
li,
fieldset,
form,
label,
legend,
table,
caption,
tbody,
tfoot,
thead,
tr,
th,
td,
article,
aside,
canvas,
details,
embed,
figure,
figcaption,
footer,
header,
menu,
nav,
output,
ruby,
section,
summary,
time,
mark,
audio,
video,
input {
margin: 0;
padding: 0;
border: 0;
font-size: 100%;
font-weight: normal;
vertical-align: baseline;
}
article,
aside,
details,
figcaption,
figure,
footer,
header,
menu,
nav,
section {
display: block;
}
body {
line-height: 1;
}
blockquote,
q {
quotes: none;
}
blockquote:before,
blockquote:after,
q:before,
q:after {
content: none;
}
table {
border-collapse: collapse;
border-spacing: 0;
}
a {
color: #7e8c8d;
text-decoration: none;
-webkit-backface-visibility: hidden;
}
li {
list-style: none;
}
::-webkit-scrollbar {
width: 5px;
height: 5px;
}
::-webkit-scrollbar-track-piece {
background-color: rgba(0, 0, 0, 0.2);
-webkit-border-radius: 6px;
}
::-webkit-scrollbar-thumb:vertical {
height: 5px;
background-color: rgba(125, 125, 125, 0.7);
-webkit-border-radius: 6px;
}
::-webkit-scrollbar-thumb:horizontal {
width: 5px;
background-color: rgba(125, 125, 125, 0.7);
-webkit-border-radius: 6px;
}
html,
body {
width: 100%;
}
body {
-webkit-text-size-adjust: none;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}
* {
margin: 0;
padding: 0;
}
#wrap {
height: 100%;
overflow-x: auto;
overflow-y: hidden;
background: #383838;
text-align: center;
font-size: 0;
}
#wrap h1 {
color: white;
font-weight: bold;
font: 20px "微软雅黑";
margin: 2% auto;
}
#wrap #video-control {
position: relative;
height: 25px;
background: #2A2A2A;
min-width: 600px;
}
#wrap #video-control .video-btn {
position: absolute;
width: 55px;
height: 25px;
left: 0;
top: 0;
text-align: center;
margin-top: 7px;
}
#wrap #video-control .video-btn span {
display: inline-block;
width: 9px;
height: 11px;
background: url(../img/icon.png) no-repeat;
}
#wrap #video-control .video-btn span:nth-child(1) {
background-position: 0px -23px;
margin-right: 10px;
}
#wrap #video-control .video-btn span:nth-child(1).active {
background-position: 0px -11px;
}
#wrap #video-control .video-btn span:nth-child(2) {
background-position: 0px 0px;
}
#wrap #video-control .video-progress {
margin: 0 230px 0 55px;
height: 25px;
font-size: 20px;
position: relative;
}
#wrap #video-control .video-progress .progress-line {
position: absolute;
width: 100%;
height: 3px;
margin-top: 11px;
background: #737373;
}
#wrap #video-control .video-progress .progress-line .progress-btn {
position: absolute;
width: 15px;
height: 12px;
background: white;
border-radius: 5px;
margin-top: -5px;
background: steelblue;
}
#wrap #video-control .video-progress .progress-current {
position: absolute;
left: 0;
top: 0;
width: 0;
background: skyblue;
margin-top: 11px;
height: 3px;
}
#wrap #video-control .video-other-operation {
position: absolute;
width: 230px;
height: 25px;
right: 0;
bottom: 0;
}
#wrap #video-control .video-other-operation > div {
height: 25px;
float: left;
}
#wrap #video-control .video-other-operation .video-time {
font: 14px "微软雅黑";
color: skyblue;
line-height: 25px;
text-align: center;
width: 120px;
}
#wrap #video-control .video-other-operation .video-audio {
width: 80px;
}
#wrap #video-control .video-other-operation .video-audio div {
height: 25px;
float: left;
}
#wrap #video-control .video-other-operation .video-audio .audio-switch {
width: 20px;
text-align: center;
}
#wrap #video-control .video-other-operation .video-audio .audio-switch span {
display: inline-block;
width: 12px;
height: 12px;
margin: 7px auto;
background: url(../img/icon.png) no-repeat;
background-position: 0 -34px;
}
#wrap #video-control .video-other-operation .video-audio .audio-switch span.active {
background-position: 0 -46px;
}
#wrap #video-control .video-other-operation .video-audio .audio-volume {
width: 60px;
position: relative;
}
#wrap #video-control .video-other-operation .video-audio .audio-volume .volume-line {
position: absolute;
width: 100%;
height: 3px;
margin-top: 11px;
background: #737373;
}
#wrap #video-control .video-other-operation .video-audio .audio-volume .volume-line .volume-btn {
position: absolute;
width: 15px;
height: 12px;
background: white;
border-radius: 5px;
margin-top: -5px;
background: steelblue;
}
#wrap #video-control .video-other-operation .video-audio .audio-volume .volume-current {
position: absolute;
left: 0;
top: 0;
width: 0;
background: skyblue;
margin-top: 11px;
height: 3px;
}
#wrap #video-control .video-other-operation .video-full-screen {
width: 30px;
text-align: center;
}
#wrap #video-control .video-other-operation .video-full-screen span {
display: inline-block;
width: 12px;
height: 12px;
margin: 7px auto;
background: url(../img/icon.png) no-repeat;
background-position: 0 -58px;
}
#wrap #video-control .video-other-operation .video-full-screen span.active {
background-position: 0 -70px;
}
3.Reset.css引用样式
html,
body {
height: 100%;
overflow: hidden;
}
html,
body,
div,
span,
applet,
object,
iframe,
h1,
h2,
h3,
h4,
h5,
h6,
p,
blockquote,
pre,
a,
abbr,
acronym,
address,
big,
cite,
code,
del,
dfn,
em,
img,
ins,
kbd,
q,
s,
samp,
small,
strike,
strong,
sub,
sup,
tt,
var,
b,
u,
i,
center,
dl,
dt,
dd,
ol,
ul,
li,
fieldset,
form,
label,
legend,
table,
caption,
tbody,
tfoot,
thead,
tr,
th,
td,
article,
aside,
canvas,
details,
embed,
figure,
figcaption,
footer,
header,
menu,
nav,
output,
ruby,
section,
summary,
time,
mark,
audio,
video,
input {
margin: 0;
padding: 0;
border: 0;
font-size: 100%;
font-weight: normal;
vertical-align: baseline;
}
article,
aside,
details,
figcaption,
figure,
footer,
header,
menu,
nav,
section {
display: block;
}
body {
line-height: 1;
}
blockquote,
q {
quotes: none;
}
blockquote:before,
blockquote:after,
q:before,
q:after {
content: none;
}
table {
border-collapse: collapse;
border-spacing: 0;
}
a {
color: #7e8c8d;
text-decoration: none;
-webkit-backface-visibility: hidden;
}
li {
list-style: none;
}
::-webkit-scrollbar {
width: 5px;
height: 5px;
}
::-webkit-scrollbar-track-piece {
background-color: rgba(0, 0, 0, 0.2);
-webkit-border-radius: 6px;
}
::-webkit-scrollbar-thumb:vertical {
height: 5px;
background-color: rgba(125, 125, 125, 0.7);
-webkit-border-radius: 6px;
}
::-webkit-scrollbar-thumb:horizontal {
width: 5px;
background-color: rgba(125, 125, 125, 0.7);
-webkit-border-radius: 6px;
}
html,
body {
width: 100%;
}
body {
-webkit-text-size-adjust: none;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}
4.Video-btn-drag拖拽组件Js,函数自调用
(function(wind) {
wind.dragFunc = {};
wind.dragFunc.dragger = function(dragNode, callBack) {
var initialPoint = {
x: 0,
y: 0
};
var mousePoint = {
x: 0,
y: 0
};
dragNode.onmousedown = function(e) {
e = e || event;
if(dragNode.setCapture) {
dragNode.setCapture();
}
initialPoint.x = dragNode.offsetLeft;
initialPoint.y = dragNode.offsetTop;
mousePoint.x = e.clientX;
mousePoint.y = e.clientY;
document.onmousemove = function(e) {
e = e || event;
var movePoint = {
x: 0,
y: 0
};
movePoint.x = e.clientX;
movePoint.y = e.clientY;
var dragLeft = initialPoint.x + (movePoint.x - mousePoint.x);
if(dragLeft < 0) {
dragLeft = 0;
} else if(dragLeft > dragNode.parentNode.clientWidth - dragNode.offsetWidth) {
dragLeft = dragNode.parentNode.clientWidth - dragNode.offsetWidth
}
dragNode.style.left = dragLeft + "px";
if(callBack && callBack["move"] && typeof callBack["move"] === "function") {
callBack["move"].call(dragNode);
}
}
document.onmouseup = function() {
document.onmouseup = document.onmousemove = null;
if(document.releaseCapture) {
document.releaseCapture();
}
}
return false;
}
}
})(window)
5.Video-player组件js
$(function() {
var wrapNode = document.querySelector("#wrap");
var videoNode = document.querySelector("#wrap > video");
videoNode.poster = "./img/cubic-3D-camera-web全栈片头_Moment.jpg";
var videoControlNode = document.querySelector("#wrap > #video-control");
var videoProgressNode = document.querySelector("#wrap > #video-control > .video-progress");
var progressBtnNode = document.querySelector("#wrap > #video-control > .video-progress > .progress-line > .progress-btn");
var progressCurrentNode = document.querySelector("#wrap > #video-control > .video-progress > .progress-current");
var progressLineNode = document.querySelector("#wrap > #video-control > .video-progress > .progress-line");
var videoDurationTimeNode = document.querySelector("#wrap > #video-control > .video-other-operation > .video-time > .duration-time");
var videoCurrentTimeNode = document.querySelector("#wrap > #video-control > .video-other-operation > .video-time > .current-time");
var videoStartBtn = document.querySelector("#wrap > #video-control > .video-btn > .video-start");
var videoStopBtn = document.querySelector("#wrap > #video-control > .video-btn > .video-stop");
var audioSwitchBtn = document.querySelector("#wrap > #video-control > .video-other-operation > .video-audio > .audio-switch");
var volumnBtnNode = document.querySelector("#wrap > #video-control > .video-other-operation > .video-audio > .audio-volume > .volume-line > .volume-btn");
var volumnCurrentNode = document.querySelector("#wrap > #video-control > .video-other-operation > .video-audio > .audio-volume > .volume-current");
var volumeLineNode = document.querySelector("#wrap > #video-control > .video-other-operation > .video-audio > .audio-volume > .volume-line");
var volumeSwitch = document.querySelector("#wrap > #video-control > .video-other-operation > .video-audio > .audio-switch >span");
var volumeSyncFlag = 0;
var fullScreenNode = document.querySelector("#wrap > #video-control > .video-other-operation > .video-full-screen");
var fullScreen = document.querySelector("#wrap > #video-control > .video-other-operation > .video-full-screen > span");
videoNode.width = 800;
videoNode.height = document.documentElement.clientHeight - videoControlNode.offsetHeight;
window.onresize = function() {
if(document.documentElement.clientWidth >= 600) {
videoNode.width = document.documentElement.clientWidth;
videoNode.height = document.documentElement.clientHeight - videoControlNode.offsetHeight;
}
}
var callBack = {
move: function() {
console.log("progress-current开始移动=drag-->progressBtnNode.offsetLeft");
progressCurrentNode.style.width = this.offsetLeft + "px";
var dragRate = this.offsetLeft / (videoProgressNode.clientWidth - progressBtnNode.offsetWidth);
videoNode.currentTime = videoNode.duration * dragRate;
}
}
dragFunc.dragger(progressBtnNode, callBack);
var runTime = 0;
videoPlay();
function videoPlay() {
videoStartBtn.onclick = function() {
if(videoNode.paused) {
addClass(this, "active");
videoNode.play();
runTime = setInterval(progressRun, 100);
} else {
removeClass(this, "active");
videoNode.pause();
clearInterval(runTime);
}
}
videoStopBtn.onclick = function() {
removeClass(videoStartBtn, "active");
videoNode.pause();
clearInterval(runTime);
progressBtnNode.style.left = progressCurrentNode.style.width = 0 + "px";
videoNode.currentTime = 0;
}
videoProgressNode.onclick = function(e) {
e = e || event;
addClass(videoStartBtn, "active");
videoNode.play();
runTime = setInterval(progressRun, 100);
console.log("拖拽到这里video-currentTime:", videoNode.currentTime);
videoNode.currentTime = videoNode.duration * ((e.clientX - this.offsetLeft) / (videoProgressNode.clientWidth - progressBtnNode.offsetWidth));
videoCurrentTimeNode.innerHTML = timeFormat(videoNode.currentTime);
}
function progressRun() {
progressBtnNode.style.left = progressCurrentNode.style.width = (videoNode.currentTime / videoNode.duration) * (videoProgressNode.clientWidth - progressBtnNode.offsetWidth) + "px";
videoCurrentTimeNode.innerHTML = timeFormat(videoNode.currentTime);
}
}
videoNode.addEventListener("loadeddata", function() {
videoDurationTimeNode.innerHTML = timeFormat(videoNode.duration);
})
volumnBtnNode.style.left = volumnCurrentNode.style.width = volumeLineNode.clientWidth - volumnBtnNode.offsetWidth + "px";
audioSwitchBtn.onclick = function() {
if(videoNode.muted) {
videoNode.muted = false;
videoNode.volume = 1;
removeClass(volumeSwitch, "active");
volumeSyncFlag = volumeSyncFlag == 0 ? 1 : volumeSyncFlag;
volumnBtnNode.style.left = volumnCurrentNode.style.width = (volumeLineNode.clientWidth - volumnBtnNode.offsetWidth) * volumeSyncFlag + "px";
} else {
videoNode.muted = true;
videoNode.volume = 0;
addClass(volumeSwitch, "active");
volumnBtnNode.style.left = volumnCurrentNode.style.width = 0 + "px";
}
}
var callBacks = {
move: function() {
volumnCurrentNode.style.width = this.offsetLeft + "px";
var volumeRate = this.offsetLeft / (volumeLineNode.clientWidth - volumnBtnNode.offsetWidth);
volumeSyncFlag = volumeRate;
videoNode.volume = volumeRate;
if(videoNode.volume == 0) {
videoNode.muted = true;
videoNode.volume = 0;
addClass(volumeSwitch, "active");
} else {
removeClass(volumeSwitch, "active");
videoNode.muted = false;
}
}
}
dragFunc.dragger(volumnBtnNode, callBacks);
var isFullScreen = false;
fullScreenNode.onclick = function() {
if(isFullScreen) {
removeClass(fullScreen, "active");
isFullScreen = false;
if(document.exitFullscreen) {
document.exitFullscreen();
} else if(document.mozCancelFullScreen) {
document.mozCancelFullScreen();
} else if(document.webkitCancelFullScreen) {
document.webkitCancelFullScreen();
} else if(document.msExitFullscreen) {
document.msExitFullscreen();
}
} else {
addClass(fullScreen, "active");
isFullScreen = true;
var docElm = document.documentElement;
if(docElm.requestFullscreen) {
docElm.requestFullscreen();
}
else if(docElm.mozRequestFullScreen) {
docElm.mozRequestFullScreen();
}
else if(docElm.webkitRequestFullScreen) {
docElm.webkitRequestFullScreen();
}
else if(docElm.msRequestFullscreen) {
docElm.msRequestFullscreen();
}
}
}
function addClass(node, className) {
var reg = new RegExp("\\b" + className + "\\b");
if(!reg.test(node.className)) {
node.className += (" " + className);
}
}
function removeClass(node, className) {
if(node.className) {
var reg = new RegExp("\\b" + className + "\\b");
var classes = node.className;
node.className = classes.replace(reg, "");
if(/^\s*$/g.test(node.className)) {
node.removeAttribute("class");
}
} else {
node.removeAttribute("class");
}
}
function timeFormat(time) {
time = parseInt(time);
var hour = addZero(Math.floor(time / 3600));
var minute = addZero(Math.floor(time % 3600 / 60));
var second = addZero(Math.round(time % 60));
return hour + ":" + minute + ":" + second;
}
function addZero(num) {
var value = "";
if(num < 10) {
value = "0" + num;
} else {
value = value + num;
}
return value;
}
})
6.html页面
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0,user-scalable=no" />
<title>一刀coder-视频播放器</title>
</head>
<link rel="stylesheet" href="css/22-video-player.css" />
<body>
<div id="wrap">
<video src="video/cubic-3D-camera-web全栈片头_Trim2.mp4"></video>
<div id="video-control">
<div class="video-btn">
<span class="video-start"></span>
<span class="video-stop"></span>
</div>
<div class="video-progress">
<div class="progress-line">
<div class="progress-btn"></div>
</div>
<div class="progress-current"></div>
</div>
<div class="video-other-operation">
<div class="video-time">
<span class="current-time"></span>/<span class="duration-time"></span>
</div>
<div class="video-audio">
<div class="audio-switch">
<span></span>
</div>
<div class="audio-volume">
<div class="volume-line">
<div class="volume-btn"></div>
</div>
<div class="volume-current"></div>
</div>
</div>
<div class="video-full-screen">
<span></span>
</div>
</div>
</div>
</div>
</body>
<script type="text/javascript" src="../6-bootstrap/js/jquery.min.js"></script>
<script type="text/javascript" src="js/22-video-btn-drag.js"></script>
<script type="text/javascript" src="js/22-video-player.js"></script>
</html>
7.效果图