实现H5视频播放器的部分播放控件

  • 时间:2020-04-24 15:52 作者:SYSU_CYJ 来源: 阅读:23
  • 扫一扫,手机访问
摘要:GitHub链接: https://github.com/cyjsysu/H5_video_player1.为什么写播放器上学期(2019年末)数据库大作业本来是想做一个简易的视频网站的。但上网看了少量相关内容后,当时觉得自己还不会JS无法自己设置样式。于是放弃原计划,改做音乐网站。现在有了少量JS基

GitHub链接: cyjsysu/H5_video_player

1.为什么写播放器

上学期(2019年末)数据库大作业本来是想做一个简易的视频网站的。但上网看了少量相关内容后,当时觉得自己还不会JS无法自己设置样式。于是放弃原计划,改做音乐网站。现在有了少量JS基础,所以又把以前的想法拿了出来。这篇文章相当于一份简陋的试验报告。
(小项目中用到的图标全来自百度图片)

2.效果图

非全屏.PNG非全屏显示音量.PNG全屏显示控件.PNG全屏隐藏控件.PNG

3.自己设置控件

假如在HTML中设置video的controls属性,浏览器会显示自带的相应控件。

<video controls="controls" />

一开始我以为自己设置控件是通过设置controls属性来实现的。但后来我看了B站播放页面的HTML,发现B站的控件都是DIV标签。而后我才知道这些控件在HTML里是独立于video标签的,只是通过JS控制视频而已。

4.视频播放和暂停

4.1要求

  • 点击播放窗口和播放键都能控制视频的播放或者暂停
  • 暂停状态下播放按键图标为三角形,否则是两条竖杆

4.2实现

每次点击时根据当前视频的播放状态(Video.paused)切换到相反状态,并更改图标就可。
Video对象属性可参考https://www.runoob.com/jsref/dom-obj-video.html。这些属性在这个小项目里会用得比较多。

function playOrPause(){    var oPlayer = document.getElementById("player");  //video    let oPlayerBtn = document.getElementById("playerBtn");  //播放按钮    if(oPlayer.paused==true){        oPlayer.play();        oPlayerBtn.src="./img/pause1.png";    }else{        oPlayer.pause();        oPlayerBtn.src="./img/on1.png";    }}

5.进度条

5.1要求

  • 通过进度条实时显示当前视频的播放进度和缓冲进度
  • 播放进度为蓝色,在上;缓冲进度为浅灰色,在下(模仿B站)。
  • 能通过拖动进度条调整播放位置
  • 进度条旁边显示播放时间

5.2实现

5.2.1进度条的显示

我早期看了一篇相似的博客(基本只做出了播放器控件的样子)。文章里的进度条是一个<meter>标签,导致我被误导了一段时间。后来我又是看了B站的HTML才重新找到方向。
这里自己设置的进度条实际上是一个div,呈现条状是由于属性height设得很小,设置背景色即进度条。
我分别写了三个这样的div。一个为深灰色,作为进度条的背景,并在其中分别全套其余两个div。另外两个其中一个是浅灰,作为缓冲条;另一个是蓝色,作为播放进度条。另外再设一个div作为播放进度条末端的拖动按钮。

<div id="controlBar">  <div id="allBar">    <div id="bufferBar"></div>    <div id="playerBar"></div>    <div id="barButton"></div>  </div></div>

5.2.2拖动进度条

用JS实现,在进度条上按下鼠标触发。在鼠标按下的情况下移动鼠标会使播放进度条末端和鼠标水平坐标相同(不能超出整个进度条),并通过计算升级video的currentTime属性。
由于代码中有好几处用到document.onmousemove,所以不直接绑定函数,而是使用事件监听。

function dragProgress(){    var oControlBar = document.getElementById("controlBar");    oControlBar.onmousedown = function(evt){        var e = evt || window.event;        if(e.button == 0){            leftX = getOffsetX(oControlBar);            rightX = leftX + parseInt(getComputedStyle(oControlBar)["width"]);            document.addEventListener("mousemove", toDragProgress);        }    };    document.addEventListener("mouseup", function(){        document.removeEventListener("mousemove", toDragProgress);    })}function toDragProgress(evt){    var e = evt || window.event;    var buttonX = e.pageX;    if(buttonX < leftX)        buttonX = leftX;    if(buttonX > rightX)        buttonX = rightX;    var prog = (buttonX - leftX) / (rightX - leftX);    // console.log(prog);    setProgress(prog);}

5.2.3实时显示进度和时间

用定时器实现,每秒执行一次。

function updateProgressBar() {    var oPlayer = document.getElementById("player");    var oPlayerBar = document.getElementById("playerBar");    var oBufferBar = document.getElementById("bufferBar");    var oBarButton = document.getElementById("barButton");    var oShowTime = document.getElementById("showTime");    var cTime = oPlayer.currentTime;    var dTime = oPlayer.duration;    var playerProgress = cTime / dTime * 100;    oPlayerBar.style.width = playerProgress + "%";    oBarButton.style.left = playerProgress + "%";    if (player.buffered.length){        var bTime = oPlayer.buffered.end(0);        var bufferProgress = bTime / dTime * 100;        oBufferBar.style.width = bufferProgress + "%";    }    // duration是一个全局变量    if(duration == 0)        duration = getTime(oPlayer.duration);    var currentTime = getTime(oPlayer.currentTime);    oShowTime.innerText = currentTime + "/" + duration;}setInterval("updateProgressBar()", 1000);  //每秒

6.音量

6.1要求

音量控制的外观也是参考着B站的效果来做的(我的没音量百分比)。

  • 平常播放器只有下方那个音量图标,把鼠标移到上面时显示出音量控制条(display:block;)。当鼠标移出一段时间后,音量控制条消失(display:none;)。
  • 点击音量键变为静音,并且图标变成带"X"的喇叭。再点击静音后的音量键,音量回复静音前的值。


    B站音量

6.2实现

6.2.1显示和隐藏用来控制条

对图标设置mouseover事件。当鼠标在这个div以及子节点的div内时移除用来隐藏控制条的延时器,并显示音量条。这里要计算音量条的位置,使音量条在音量图标正上方,且不紧贴。
当鼠标移出,设置延时器,一段时间后隐藏音量条。

var hideVol = null;  // 隐藏音量条事件 // 显示音量条oControlVol.onmouseover = function(){  clearTimeout(hideVol);  // 只需鼠标在音量框内就不会隐藏音量框  // 设置的音量图标和音量条是分离的,计算音量条框位置  var tarX = oControlVol.offsetLeft + (parseInt(getComputedStyle(oControlVol)["width"]) - parseInt(getComputedStyle(oVolFrame)["width"])) / 2;  var tarY = oControlVol.offsetTop - parseInt(getComputedStyle(oVolFrame)["height"]) - 20;  oVolFrame.style.left = tarX + "px";  oVolFrame.style.top = tarY + "px";  oVolFrame.style.display = "block";}; // 隐藏音量条oControlVol.onmouseout = function(){  hideVol = setTimeout(function () {  var oVolFrame = document.getElementById("volumeFrame");            oVolFrame.style.display = "none";  }, 600);};

6.2.2拖动音量条

实现过程和视频进度条差不多。

7.全屏

7.1要求

  • 点击全屏图标进入全屏,再次点击退出全屏
  • 进入全屏后不显示浏览器自带的播放控件,而是显示自己的控件
  • 进入全屏后当鼠标移动或者者鼠标在播放控件上时,控件能一直显示;否则隐藏控件。
  • 进入全屏前控件是在视频下方的,除了音量条外两者不重叠。但进入全屏后要求控件和视频重叠并且以肯定的透明度显示在视频最下方。

7.2实现

7.2.1进入和退出全屏

可参考https://www.jianshu.com/p/54729c73686a
讲得挺全的。

7.2.2全屏下控件显示

对<video>结点全屏,浏览器会显示显示自带的播放控件。这涉及到shadow DOM。在CSS文件中禁用。

video::-webkit-media-controls{    display:none !important;}

但这不是重点。由于即便禁用了自带控件也不会显示自己的控件。
正确的做法是整个div(包括video和控件)执行全屏,上面那段css也不需要。

7.2.3显示和隐藏控件

其实到这里很多问题实际上都是和上面重复的了。
隐藏和显示是通过控制栏的display属性实现的。鼠标移动时(document.onmousemove)显示控制栏,同时设置一个延时器来隐藏控制栏。每次触发document.onmousemove时要先移除现有的延时器。
在写这一部分时我碰到一个小坑。我设置鼠标进入控制栏时移除隐藏控制栏的延时器。但实际上仍会有延时器来隐藏控制栏。也就是说,即便鼠标在控制栏上,假如鼠标不动了,控制栏仍会被隐藏。后来发现这是由于,尽管鼠标在控制栏上时去除延时器,但当鼠标移动又会触发document.onmousemove重新设定定时器。处理方法时当鼠标进入控制栏时对document.onmousemove移除显示控制栏的函数showControl,移出时在用事件监听加回来。

    document.addEventListener("mousemove", showControl);    oController.onmouseover = function(){        document.removeEventListener("mousemove", showControl);        ///console.log("H");        clearTimeout(hide_control);    };    oController.onmouseout = function () {        document.addEventListener("mousemove", showControl);    }

8.不足

“下一集”的功能没实现,由于项目里没考虑复杂的应用场景。但要用的时候实现也不难。

  • 全部评论(0)
最新发布的资讯信息
【系统环境|服务器应用】树莓派安装TensorFlow(2020-04-24 21:11)
【系统环境|服务器应用】防面试-SD_WebImage(2020-04-24 21:11)
【系统环境|服务器应用】推荐一款视频控件xgplayer(2020-04-24 21:11)
【系统环境|服务器应用】PostgreSQL 源码解读(27)- 查询语句#12(查询优化-上拉子链接#2)(2020-04-24 21:11)
【系统环境|服务器应用】如何轻松学习JavaScript?(2020-04-24 21:10)
【系统环境|服务器应用】【源码剖析】Launcher 8.0 源码 (12) --- Launcher 启动流程 第五步之计算桌面各布局细节参数(2020-04-24 21:10)
【系统环境|服务器应用】前台碰撞室之console.log与文本字符(2020-04-24 21:10)
【系统环境|服务器应用】好用的Middleware实现(2020-04-24 21:10)
【系统环境|服务器应用】前台面试每日 3+1 —— 第373天(2020-04-24 21:10)
【系统环境|服务器应用】绍圣--kafka之生产者(五)(2020-04-24 21:10)
手机二维码手机访问领取大礼包
返回顶部