> 此自定义播放器基于JS ,内部只用了少量JQ 此播放器可以拖动进度条, 也可以点击进度条的任一位置进行播放,同理声音也是如此, 有全屏功能,以及调节播放速度。
用法超级简单
当然如果要修改样式以及其他需求, 核心代码都是不需要改变的
html:
video
css
.media-controller {
position: absolute;
bottom: 0;
left: 0;
right: 0;
height: 50px;
box-sizing: border-box;
background: rgba(0, 0, 0, 0.3);
}
.media-progress {
position: absolute;
top: 0;
height: 8px;
width: 100%;
background: rgba(0, 0, 0, 0.6);
box-sizing: border-box;
cursor: pointer;
}
.media-bar {
position: absolute;
top: 0px;
height: 8px;
width: 0;
background: #aaa;
}
.media-circular {
width: 12px;
height: 12px;
border-radius: 100%;
background: #fff;
position: absolute;
top: -2px;
left: -6px;
}
.media-center {
position: absolute;
width: 100%;
box-sizing: border-box;
bottom: 12px;
line-height: 20px;
}
.media-play-stop {
float: left;
margin-left: 20px;
cursor: pointer;
width: 15px;
height: 20px;
overflow: hidden;
}
.media-play {
height: 0;
width: 0;
display: inline-block;
border: 12px solid #fff;
border-color: transparent transparent transparent #fff;
border-right-width: 0;
border-top-width: 10px;
border-bottom-width: 10px;
}
.media-stop {
height: 20px;
width: 4px;
background: #fff;
float: left;
position: relative;
}
.media-stop::after {
content: " ";
position: absolute;
height: 20px;
width: 4px;
left: 10px;
background: #fff;
}
.media-time {
display: inline-block;
color: #fff;
margin-left: 26px;
float: left;
}
.media-volume-control {
cursor: pointer;
float: right;
margin-right: 20px;
border-radius: 50px;
height: 20px;
width: 100px;
background: rgba(0, 0, 0, 0.6);
}
.media-volume-progress {
float: right;
height: 5px;
width: 80px;
background: #aaa;
border-radius: 50px;
margin-right: 10px;
margin-top: 7.5px;
}
.media-volume-horizontal {
height: 5px;
width: 0;
background: #fff;
border-radius: 50px;
}
.media-full {
cursor: pointer;
float: right;
border: 1px solid #fff;
width: 20px;
height: 20px;
display: inline-block;
box-sizing: border-box;
margin-right: 30px;
}
.media-ico {
position: absolute;
z-index: 10;
width: 60px;
height: 60px;
background: rgba(0, 0, 0, 0.4);
border-radius: 100%;
top: 50%;
left: 50%;
margin-left: -30px;
margin-top: -30px;
cursor: pointer;
}
.media-ico::after {
content: " ";
width: 0;
height: 0;
display: inline-block;
border: 15px solid #fff;
border-color: transparent transparent transparent #fff;
border-right-width: 0;
border-top-width: 12px;
border-bottom-width: 12px;
margin-left: 26.25px;
margin-top: 18px;
}
.media-ico:hover {
background: rgba(0, 0, 0, 0.6);
box-shadow: 0 0 6px #f3f3f3;
}
.media-speed {
float: right;
color: #fff;
margin-right: 15px;
cursor: pointer;
position: relative;
}
.media-speed-item {
display: none;
position: absolute;
top: -50px;
border-radius: 6px;
background: rgba(0, 0, 0, 0.5);
width: 200px;
left: -80px;
overflow: hidden;
height: 30px;
padding: 0;
}
.media-speed .media-speed-item li {
float: left;
margin-right: 0 !important;
cursor: pointer;
width: 30px !important;
line-height: 30px;
padding: 0px 5px;
box-sizing: content-box;
text-align: center;
list-style: none;
font-size: 12px;
}
.media-speed .media-speed-item li.active {
background: rgba(0, 0, 0, 0.7);
border-radius: 6px;
}
js
function comm_medias(id, data) {
if (data.src.length > 0) {
var panlParent = $("#" + id);//传入一个div 的ID
var videoNode = document.createElement("VIDEO");//new 一個VOID的實例
~function orgHtml() {
// 这个是正确的配置方式
// videoNode.style.objectFit = "fill";
// videoNode.style.width = '100%';
// videoNode.style.height = '100%';
// panlParent.css("width", 500);
// panlParent.css("height", 500);
videoNode.style.objectFit = "fill";
videoNode.style.width = '100%';
videoNode.style.height = '100%';
panlParent.css("width", 600);
panlParent.css("height", 310);
videoNode.setAttribute("src", data.src);
panlParent.css("position", "relative");
panlParent.css("overflow", "hidden");
panlParent.addClass("clear");
var setOption = '';
setOption += '';
setOption += '';
setOption += ' ';
setOption += ' ';
setOption += ' ';
setOption += ' ';
setOption += ' ';
setOption += ' ';
setOption += ' ';
setOption += ' ';
setOption += ' ';
setOption += ' 00 : 00 : 00/00 : 00 : 00';
setOption += ' ';
setOption += ' ';
if (panlParent.width() >= 415) {
setOption += ' ';
setOption += ' ';
setOption += ' ';
setOption += ' ';
setOption += ' ';
setOption += ' 倍速';
setOption += ' ';
setOption += ' - 0.5x
';
setOption += ' - 1.0x
';
setOption += ' - 1.25x
';
setOption += ' - 1.5x
';
setOption += ' - 2.0x
';
setOption += '
';
setOption += ' ';
}
setOption += ' ';
setOption += '';
panlParent.append(videoNode);
panlParent.append(setOption);
}()
var media_current, media_total, media_bar, media_play_stop, media_progress, media_volume_progress,
media_full, media_ico, media_controller, media_speed_item, media_speed, media_circular;
~function DocElements() {
media_current = panlParent.find(".media-current");//看过的时间
media_total = panlParent.find(".media-total");//总时长
media_bar = panlParent.find(".media-bar")//正在播放的进度条
media_play_stop = panlParent.find(".media-play-stop")//播放暂停按钮
media_progress = panlParent.find(".media-progress")//播放的进度条总长
media_volume_progress = panlParent.find(".media-volume-progress")//固定的音量
media_volume_horizontal = panlParent.find(".media-volume-horizontal")//拖动的条音量
media_full = panlParent.find(".media-full");//全屏
media_ico = panlParent.find(".media-ico")//屏幕中间的播放
media_controller = panlParent.find(".media-controller")//显示隐藏
media_speed_item = panlParent.find(".media-speed-item")//控制播放速率
media_speed = panlParent.find(".media-speed");//显示播放速率
media_circular = panlParent.find(".media-circular")//拖动球
}()
~function EventTag() {
/**
* 当前可播放状态
*/
videoNode.addEventListener('canplay', function () {//低版本不识别 videoNode.oncanplay
try {
var type = videoNode.error;
panlParent.hide();
if (type == null) {
//显示视频
panlParent.show();
} else if (type.code == 1) {
//隐藏视频频
console.log("用户终止视频文件加载");
} else if (type.code == 2) {
console.log("视频文件网络错误");
} else if (type.code == 3) {
console.log("视频文件解码错误");
} else if (type.code == 4) {
console.log("视频文件URL无效");
}
//显示视频总时长
media_total.html(getFormatTime(videoNode.duration))
videoNode.volume = 0.5;
media_volume_horizontal.width(media_volume_progress.width() / 2);
videoNode.controls = false;
} catch (ex) {
console.log(ex);
}
});
/**
* 播放停止
*/
function plays() {
if (videoNode) {
if (videoNode.paused) {
videoNode.play();
media_play_stop.find("span")[0].className = "media-stop";
media_ico.hide();
} else {
videoNode.pause();
media_play_stop.find("span")[0].className = "media-play";
media_ico.show();
}
return false;
} else {
alert("浏览器不支持video标签,或者资源没有正确加载");
}
}
/**
* 给播放按钮赋上点击事件
*/
media_play_stop.off('click').click(plays);
media_ico.off('click').click(plays);
/**
* 进度条
* videoNode.ontimeupdate = function (){}在Chrome上无效,可以使用addEventListener来代替它:
*/
videoNode.addEventListener('timeupdate', function () {
setTimeout(function () {
var type = videoNode.networkState;
if (type == 0 || type == 3) {
panlParent.hide(); //网络问题就隐藏掉
} else {
panlParent.show();
}
}, 10);
//要实现的功能,首先是进度条根据视频播放的进度,不断的增加。意思就是不断的获取视频的当前进度,然后去除以视频的总长度,拿这个比值乘以进度条的总长度,就得到经度条当前的长度,赋值
var currTime = this.currentTime, //当前播放时间
duration = this.duration; // 视频总时长
//百分比
// var scales = currTime / duration * 100 + "%"; //百分比的获取方式
var scales = currTime / duration * panlParent.width();
//显示进度条
media_bar.css("width", scales);
//显示进度球
media_circular.css("left", scales - 6);
//显示当前播放进度时间
media_current.html(getFormatTime(currTime));
})
/**
* 跳跃播放
*/
media_progress.off('click').click(function (e) {
var event = e || window.event;
var w = this.offsetWidth;//本身的宽度
var v = event.offsetX;//点击的距离
if (v < 0) {
v = 0;
} else if (v > w) {
v = w;
}
var scale = v / w;
//得到所点击的距离占比, 乘以总长时间,0.8*time
videoNode.currentTime = scale * videoNode.duration;
return false;
});
/**
* 进度条控制拖拽
* 拖动经度条,视频在相应的位置播放。反过来,先获取进度条的当前位置,除以进度条的总长度,拿这个比值乘以视频的总长度,就得到视频当前应该播放的进度,赋值。
*/
var moveFlag = false;
media_circular.off('mousedown').mousedown(function (e) {
// console.log('left :', media_circular.offset().left);//不能用这个 相对于文档窗口
moveFlag = true;
var event = e || window.event;
var x = event.clientX;
console.log('offsetLeft :');//相对与父元素
var nowLocation = media_circular[0].offsetLeft; //进度条的当前位置
var width = media_progress.width(); //进度条的总长度
// videoNode.currentTime = nowLocation / width * videoNode.duration; //视频当前进度 = 进度条的当前位置 /进度条的总长度 * 视频的总长度
document.onmousemove = function (e) {
if (moveFlag) {
var event = e || window.event;
var moveX = event.clientX - x; //移动后的距离 - 去移动前的距离
var allLeft = moveX + nowLocation; //等于总共的偏移量(正负都包含了)
if (allLeft < 0) {
allLeft = 0;
}
if (allLeft > width) {
allLeft = width;
}
media_circular.css("left", allLeft);//球移动了这么多的距离
media_bar.css("width", allLeft);
//视频当前进度 = 进度条的当前位置 /进度条的总长度 * 视频的总长度
videoNode.currentTime = allLeft / width * videoNode.duration;
}
}
document.onmouseup = function () {
document.onmousedown = null;
document.onmousemove = null;
moveFlag = false;
}
})
/**
* 跳跃音量条
*/
media_volume_progress.off('click').click(function (e) {
var event = e || window.event;
var w = this.offsetWidth;//本身的宽度
var v = event.offsetX;//点击的距离
if (v < 0) {
v = 0;
} else if (v > w) {
v = w;
}
var scale = v / w;
//得到所点击的距离占比, 乘以总音量,0.8*volume
videoNode.volume = scale;
media_volume_horizontal.width(v);
return false;
});
/**
* 进入全屏
*/
function requestFullScreen() {
if (videoNode.requestFullscreen) {
videoNode.requestFullscreen();
} else if (videoNode.mozRequestFullScreen) {
videoNode.mozRequestFullScreen();
} else if (videoNode.webkitRequestFullScreen) {
videoNode.webkitRequestFullScreen();
} else if (videoNode.msRequestFullscreen) {
videoNode.msRequestFullscreen()
}
}
media_full[0].addEventListener("click", requestFullScreen, false);
/**
* 退出全屏
*/
function cancelFullScrren(elem) {
elem = elem || document;
if (elem.cancelFullScrren) {
elem.cancelFullScrren();
} else if (elem.mozCancelFullScreen) {
elem.mozCancelFullScreen();
} else if (elem.webkitCancelFullScreen) {
elem.webkitCancelFullScreen();
} else if (elem.msExitFullscreen) {
elem.msExitFullscreen();
}
}
videoNode.addEventListener('ended', cancelFullScrren, false);
/**
* 播放完毕还原设置
* videoNode.onended = function () {};在低版本上无效
*/
videoNode.addEventListener("ended", function () {
videoNode.pause();
videoNode.currentTime = 0;
media_bar[0].style.width = 0;
media_play_stop.find("span")[0].className = "media-play";
media_ico.show();
/**
* 浏览器的用法
* 1.
* 进度条为0 :
* media_bar[0].style.width = 0;
* 还原当前播放时间 :
* media_current[0].innerHTML = getFormatTime();
* 视频恢复到播放开始状态:
* videoNode.currentTime = 0;
* 切换播放按钮状态:
* media_play[0].className = "media-play";
* 2.
* 或者:videoNode.load(); 但是视频会跳一下,安卓下不适用
* 3.
* 所有通用用法
*videoNode.src = '';
*videoNode.src = data.src;
* media_bar[0].style.width = 0;
* media_current[0].innerHTML = getFormatTime();
* videoNode.currentTime = 0;
*/
});
/**
* 淡入淡出显示隐藏播放栏
*/
var fadeOut;
~function toggleSwitch() {
//显示
panlParent.off("mouseenter").on("mouseenter", function () {
clearInterval(fadeOut);
media_controller.fadeIn(300);
});
//隐藏
panlParent.off("mouseleave").on("mouseleave", function () {
fadeOut = setTimeout(function () {
media_controller.fadeOut(300);
media_speed_item.fadeOut(300);
}, 3000)
});
}()
/**
* 显示播放速率
*/
media_speed.off('click').click(function () {
media_speed_item.toggle();
})
/**
* 控制播放速率
*/
var speedArry = [0.5, 1, 1.25, 1.5, 2.0];
media_speed_item.off("click", 'li').on("click", 'li', function () {
var index = $(this).index();
videoNode.playbackRate = speedArry[index];
media_speed_item.find("li").removeClass("active");
$(this).addClass('active');
media_speed_item.hide();
return false;
});
}()
} else {
var panlParent = $("#" + id);
panlParent.hide();
alert("视频路径错误,播放失败!");
}
return videoNode;
}
//时间
function getFormatTime(time) {
var time = time || 0;
var h = parseInt(time / 3600),
m = parseInt(time % 3600 / 60),
s = parseInt(time % 60);
h = h < 10 ? "0" + h : h;
m = m < 10 ? "0" + m : m;
s = s < 10 ? "0" + s : s;
return h + " : " + m + " : " + s;
}
/**
* 调用方法
*
* html += ' ';
* comm_medias('details-video', { src: 'https://d-image.i4.cn/pubImg/mall/2019/04/19/11/1555643566349_616931.mp4' });
*
*/
最后 你再引入jq 或者 你想用js 就修改一下里面的获取的方式 ,其他逻辑不变