video自定义播放器

video自定义播放器_第1张图片
video自定义播放器_第2张图片
video自定义播放器_第3张图片

> 此自定义播放器基于JS ,内部只用了少量JQ 此播放器可以拖动进度条, 也可以点击进度条的任一位置进行播放,同理声音也是如此, 有全屏功能,以及调节播放速度。

用法超级简单
video自定义播放器_第4张图片
当然如果要修改样式以及其他需求, 核心代码都是不需要改变的

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 就修改一下里面的获取的方式 ,其他逻辑不变

你可能感兴趣的:(前端js技术,问题集合,video,video自定义,video进度条,js播放器)