播放器
重写video标签实现的本地自定义播放器。
播放器样式
进度条具体样式
语速具体样式
实现的功能
1.播放本地视频文件
2.拖动进度条进行播放
3.定点播放
4.切换播放语速
5.动态调整音量
没实现的功能
视频全屏,可以自行修改
体验
想体验一下?戳这里==> http://www.suanliutudousi.com/player/index.html
若需要源码 链接: https://pan.baidu.com/s/1jJqLIse 密码: y76n
新增==》解决ie10,ie9不能播放的问题。将video的src地址换成本地的即可
源码部分
html代码
<!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta http-equiv="X-UA-Compatible" content="ie=edge" /> <title>Document</title> <link rel="stylesheet" type="text/css" href="//cdn.bootcss.com/font-awesome/4.2.0/css/font-awesome.min.css" /> <link rel="stylesheet" href="//t99panzer.oss-cn-shanghai.aliyuncs.com/css/index.css" /> </head> <body> <div class="mediaplayer"> <div class="video"> <video id="player" src="//t99panzer.oss-cn-shanghai.aliyuncs.com/video/Idina%20Menzel%20-%20Let%20It%20Go.mp4" autoplay="" poster=""> 你的浏览器太low了!! <input type="file" name="" id="" /> </video> </div> <div class="wrap"> <div class="progress-list"> <div class="play-progress"> </div> <!--进度条--> </div> <!--底层--> <div class="controls"> <div class="left-box"> <span id="video-btn"><i class="fa fa-pause"></i></span><span id="curtime"> 00:00:00</span><span class="left-box-div">/</span><span id="duration"> 00:00:00</span><span><label for="inputFile" id="upload-file"><i class="fa fa-upload"></i></label><input type="file" name="" id="inputFile" style="position: absolute;clip: rect(0,0,0,0);"/></span> </div> <!--左盒子--> <div id="box"> <ul> <span id="slience"> <i class="fa fa-volume-up"></i></span><span class="volume_wrap voice-box"> <div class="voice-line"></div> <div class="voice-volume"></div> <div class="voice-btn"></div> </span><span class="speed"> 正常 <ul> <li id="btn1">X1.0<i class='fa fa-check'></i></li> <li id="btn2">X1.5</li> <li id="btn3">X2.0</li> </ul> </span> <!--<span id="fullScreen" style="outline: none;"> <i class="fa fa-arrows-alt"></i></span>--> <!--全屏功能预留 #fullScreen margin-left:50px;--> </ul> </div> <!--右盒子--> </div> </div> <!--视频控制层--> </div> <!--播放器--> <script src="//apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js" type="text/javascript" charset="utf-8"></script> <script src="//t99panzer.oss-cn-shanghai.aliyuncs.com/js/Base.min.js" type="text/javascript" charset="utf-8"></script> <script src="//t99panzer.oss-cn-shanghai.aliyuncs.com/js/main.js" type="text/javascript" charset="utf-8"></script> </body> </html>
css代码
* { margin: 0; padding: 0; } /*整个容器*/ .fa { cursor: pointer; font-size: 24px; color: white; } .mediaplayer { margin: 0 auto; width: 960px; height: 576px; border: 2px solid #333; } .video { width: 960px; height: 530px; } /*控制组件容器*/ .wrap { position: absolute; width: 960px; height: 46px; background: #333; } /*视频资源层容器*/ #player { width: 100%; height: 100%; } /*---------------进度条层开始--------*/ /*进度条资源总长度层*/ .progress-list { transition-duration: .2s; position: absolute; width: 960px; height: 3px; top: -4px; margin-left: -1px; border: 1px solid black; border-radius: 3px; background: rgb(130, 130, 130); } /*进度条当前播放层*/ .play-progress { height: 3px; transition-duration: .2s; background-image: -webkit-linear-gradient(left, #57a900, #97ff00 80%, #dee2da); background-image: -ms-linear-gradient(left, #57a900, #97ff00 80%, #dee2da); background-image: -moz-linear-gradient(left, #57a900, #97ff00 80%, #dee2da); background-color: #D3D3D3\0; /*ie10以下兼容*/ } .progress-list:hover { height: 13px; } .progress-list:hover .play-progress { height: 13px; } /*进度条层结束*/ /*组件具体盒子层 */ /*---------左盒子----------*/ /*暂停按钮*/ #curtime, #duration, .left-box-div { color: white; } #video-btn { display: inline-block; width: 22px; height: 22px; margin-right: 15px; } .left-box { width: 400px; float: left; margin-left: 40px; } .left-box span { margin-left: 5px; } #upload-file { margin-left: 15px; } /*----------------右盒子----*/ /*静音,全屏*/ #slience, #fullScreen { display: inline-block; width: 22px; height: 22px; list-style: none; margin-left: 100px; } #box { width: 400px; float: right; } #box ul { vertical-align: middle; } #box ul ul li { list-style: none; } /*音量控制层*/ .voice-box { display: inline-block; position: relative; height: 30px; width: 124px; opacity: 0.7; line-height: 30px; top: 5px; margin-left: 5px; filter: alpha(opacity=70); } .voice-line { cursor: pointer; position: absolute; top: 13px; height: 4px; width: 124px; background: #ddd; } .voice-volume { position: absolute; top: 13px; height: 4px; width: 56px; cursor: pointer; background: #57a900; } .voice-btn { position: absolute; left: 56px; top: 9px; width: 12px; height: 12px; border-radius: 50%; background: white; } /*语速层开始*/ .speed { cursor: pointer; position: relative; display: inline-block; width: 44px; height: 22px; line-height: 22px; text-align: center; border: 1px solid black; background: #DAD6D8; margin-left: 25px; top: -2px } .speed:hover ul { visibility: visible; } /*滑动语速显示*/ .speed ul { visibility: hidden; background: #292929; position: absolute; top: -91px; left: -10px; } .speed li { cursor: pointer; color: white; font-family: arial; font-size: 16px; width: 70px; height: 30px; line-height: 30px; } .speed li:hover { background: grey; } /*语速层结束*/ .controls { height: 46px; line-height: 46px; }
js核心代码
var base = new Base(); var player = document.getElementById("player"), //视频源 btn = document.getElementById("video-btn"), //播放按钮 btn1 = document.getElementById("btn1"), //倍速x1 btn2 = document.getElementById("btn2"), //倍速x1.5 btn3 = document.getElementById("btn3"), //倍速x2 box = document.getElementById("box"), //视频控制层 slience = document.getElementById("slience"), //静音 full = document.getElementById("fullScreen"), //全屏 curtime = document.getElementById("curtime"), //当前的播放长度 duration = document.getElementById("duration"), //播放源的总长度 inputFile = document.getElementById("inputFile"), //上传文件 mediaplayer = base.getClass("document", "mediaplayer")[0], //整个播放器 wrap = base.getClass("document", "wrap")[0], //控制层容器 play_progress = base.getClass("document", "play-progress")[0], //播放时的进度条 progress_width = base.getClass("document", "progress-list")[0], //进度条底层 speed = base.getClass("document", "speed")[0], //速度层 video = base.getClass("document", "video")[0], controls = base.getClass("document", "controls")[0], //组件控制层 voice_btn = base.getClass("document", "voice-btn")[0], //音量按钮 voice_box = base.getClass("document", "voice-box")[0], //音量盒子 voice_line = base.getClass("document", "voice-line")[0], //音量底线 voice_volume = base.getClass("document", "voice-volume")[0], //音量控制线 curSpeed = base.getClass("document", "fa fa-check")[0]; //视频播放源容器 player.load(); //加载 //视频的元数据加,计算总时间 base.addHandler(player, "loadedmetadata", function() { var total = Math.floor(player.duration); total = base.formatTime(total); if(!isNaN(player.duration)) { //还没有加载时会为NaN play_progress.max = player.duration base.preventDefault(play_progress); duration.innerHTML = total; } }); /*---------------- 进度条start-------------------*/ //拖动进度条 base.addHandler(progress_width, "click", function(event) { event = base.getEvent(event); var newCoor = base.getPageCoordinates(event).pageX, offLeft = mediaplayer.offsetLeft, //距左边的距离 progress_list_width = progress_width.offsetWidth; curPlay = newCoor - offLeft; //拖到的新的位置 var newLocation = curPlay / progress_list_width * player.duration; player.currentTime = newLocation; }); //进度条滑动上浮 base.addHandler(progress_width, "mouseenter", function() { $(progress_width).animate({ top: -14 }, 0); }); //进度条滑出上浮 base.addHandler(progress_width, "mouseleave", function() { $(progress_width).animate({ top: -4 }, 0); }); /*---------------- 进度条end-------------------*/ /*---------------- 播放暂停按钮控制start-------------------*/ //屏幕点击 base.addHandler(player, "click", function(event) { if(player.paused) { player.play(); btn.innerHTML = "<i class='fa fa-pause'></i>"; } else { player.pause(); btn.innerHTML = "<i class='fa fa-play'></i>"; } }); //按钮点击 base.addHandler(btn, "click", function(event) { if(player.paused) { player.play(); btn.innerHTML = "<i class='fa fa-pause'></i>"; } else { player.pause(); btn.innerHTML = "<i class='fa fa-play'></i>"; } }); /*---------------- 播放暂停按钮控制end-------------------*/ /*---------------- 上传文件start-------------------*/ base.addHandler(inputFile, "change", function() { var reader = new FileReader(), files = this.files[0]; reader.readAsDataURL(files); reader.onload = function(event) { var res = event.target.result; player.src = res; player.load(); //加载 //本地文件加载时,播放新文件 base.addHandler(player, "loadedmetadata", function() { if(player.paused) { player.play(); btn.innerHTML = "<i class='fa fa-pause'></i>"; } }); } }); /*---------------- 上传文件end-------------------*/ /*---------------- 音量静音start-------------------*/ player.volume = .5; //设置默认音量 //点击改变音量 var fn = function(event) { event = base.getEvent(event); var clientX = base.getPageCoordinates(event).pageX, ClientRect = base.getBoundingClientRect(voice_box).left, //相对于左边视口的距离 volumeWidth = clientX - ClientRect; volumeWidth > voice_box.offsetWidth ? volumeWidth = voice_box.offsetWidth : volumeWidth; volumeWidth > 0 ? volumeWidth : volumeWidth = 0; voice_volume.style.width = volumeWidth + "px"; //音量宽度设置 player.volume = (volumeWidth / voice_box.offsetWidth).toFixed(2); voice_btn.style.left = volumeWidth + "px"; //音量游标控制 switch(true) { case player.volume >= 0.5: slience.innerHTML = "<i class='fa fa-volume-up'></i>"; break; case player.volume > 0: slience.innerHTML = "<i class='fa fa-volume-down'></i>"; break; case player.volume == 0: slience.innerHTML = "<i class='fa fa-volume-off'></i>"; break; } base.preventDefault(event); }; base.addHandler(voice_box, "click", fn); base.addHandler(voice_btn, "mousedown", function(event) { var boxOffset = base.getBoundingClientRect(voice_box).left; event = base.getEvent(event); var target = base.getTarget(event); document.onmousemove = function(event) { //因为这里是在document上移动的,所以需要在document上监听 var event = base.getEvent(event); var oX = event.clientX - boxOffset; //鼠标点击的位置距离面板左边的距离 var maxW = voice_box.offsetWidth; var minW = 0; oX > minW ? oX : oX = minW; oX > maxW ? oX = maxW : oX; target.style.left = oX + "px"; voice_volume.style.width = oX + "px"; player.volume = (oX / voice_box.offsetWidth).toFixed(2); switch(true) { case player.volume >= 0.5: slience.innerHTML = "<i class='fa fa-volume-up'></i>"; break; case player.volume > 0: slience.innerHTML = "<i class='fa fa-volume-down'></i>"; break; case player.volume == 0: slience.innerHTML = "<i class='fa fa-volume-off'></i>"; break; } }; document.onmouseup = function() { document.onmousemove = null; //删除移动事件 document.onmouseup = null; //删除鼠标释放事件 } base.preventDefault(event); }); //静音及恢复 base.addHandler(slience, "click", function(event) { player.muted = !player.muted; //设置是否静音 if(player.muted) { //静音时,设置音量盒,不需要设置player.volume voice_volume.style.width = 0 + "px"; voice_btn.style.left = 0 + "px"; slience.innerHTML = "<i class='fa fa-volume-off'></i>"; } else { voice_volume.style.width = player.volume * voice_box.offsetWidth + "px"; voice_btn.style.left = player.volume * voice_box.offsetWidth + "px"; // player.volume >= .5 ? slience.innerHTML = "<i class='fa fa-volume-up'></i>" : slience.innerHTML = "<i class='fa fa-volume-down'></i>"; switch(true) { case player.volume >= 0.5: slience.innerHTML = "<i class='fa fa-volume-up'></i>"; break; case player.volume > 0: slience.innerHTML = "<i class='fa fa-volume-down'></i>"; break; case player.volume == 0: slience.innerHTML = "<i class='fa fa-volume-off'></i>"; break; } } }); base.addHandler(controls, "dragstart", function() { return false; }) /*---------------- 音量静音end-------------------*/ /*---------------- 语速调节start-------------------*/ //更改播放速度 base.addHandler(btn1, "click", function(event) { event = base.getEvent(event); player.playbackRate = 1; //倍速为1 speed.childNodes[1].style.visibility = "hidden"; base.stopPropagation(event); speed.childNodes[0].nodeValue = "\u6b63\u5e38"; if(btn1.innerHTML == "X1.0") { btn1.innerHTML = "X1.0<i class='fa fa-check'></i>"; base.siblingNodes(btn1)[0].innerHTML = "X1.5" base.siblingNodes(btn1)[1].innerHTML = "X2.0" } }); base.addHandler(btn2, "click", function(event) { event = base.getEvent(event); player.playbackRate = 1.5; speed.childNodes[1].style.visibility = "hidden"; base.stopPropagation(event); speed.childNodes[0].nodeValue = "X1.5"; if(btn2.innerHTML == "X1.5") { btn2.innerHTML = "X1.5<i class='fa fa-check'></i>"; base.siblingNodes(btn2)[0].innerHTML = "X1.0" base.siblingNodes(btn2)[1].innerHTML = "X2.0" } }); base.addHandler(btn3, "click", function(event) { event = base.getEvent(event); player.playbackRate = 2; speed.childNodes[1].style.visibility = "hidden"; base.stopPropagation(event); speed.childNodes[0].nodeValue = "X2.0"; if(btn3.innerHTML == "X2.0") { btn3.innerHTML = "X2.0<i class='fa fa-check'></i>"; base.siblingNodes(btn3)[0].innerHTML = "X1.0" base.siblingNodes(btn3)[1].innerHTML = "X1.5" } }); //得以触发下次滑动事件 base.addHandler(speed, "mouseenter", function() { speed.childNodes[1].style.cssText = ""; }); /*---------------- 语速调节end-------------------*/ /*---------------- 全屏start-------------------*/ base.addHandler(full, "click", function(event) { if(full.className == "") { //网页全屏 mediaplayer.style.width = "100%"; mediaplayer.style.height = "100%"; full.className = "flag"; progress_width.style.width = video.offsetWidth + "px"; //全屏时进度条 } else if(full.className != "") { mediaplayer.style.width = 960 + "px"; mediaplayer.style.height = 450 + "px"; full.className = ""; progress_width.style.width = video.offsetWidth + "px"; //正常情况进度条 } }); /*---------------- 全屏end-------------------*/ //定时更新当前时间 setInterval(function() { var cur = Math.floor(player.currentTime), med = mediaplayer.offsetWidth - 2, cur = base.formatTime(cur); curtime.innerHTML = cur; //播放完成 if(player.ended === true) { player.pause(); btn.innerHTML = "<i class='fa fa-play'></i>"; } play_progress.style.width = player.currentTime * med / player.duration + "px"; }, 0);