基于vue-video-player自定义播放器的方法


Posted in Javascript onMarch 21, 2018

先看一下效果。

图1--显示侧边栏

基于vue-video-player自定义播放器的方法

图2-收起侧边栏;

基于vue-video-player自定义播放器的方法

图三:全屏。

基于vue-video-player自定义播放器的方法

写在前面

本次项目中需要用到vue,vue-video-player,我用的是iview的ui框架,但是ui框架无妨,这里关注的是基于video.js开发的vue-video-player的使用,以及如何操作video.js中的api。

vue-video-player 项目地址:https://github.com/surmon-china/vue-video-player。

video.js文档地址:http://docs.videojs.com/docs/api/player.html。

项目目录:

基于vue-video-player自定义播放器的方法

一、外层ui布局

图一中可以看到,本次项目使用的是两栏自适应布局,其中,右侧为播放列表,固定宽度500px,左边是播放器box,播放列表box可根据手柄点击展开或收起,而播放器box也跟随播放列表的展开/收缩进行宽度自适应。

(因录制动画太大传不上,可clone我的程序下来运行可见)。

html代码结构如此:

基于vue-video-player自定义播放器的方法

收缩展开的时候加上一个过度动画,这里选择使用css手写动画:

[css] view plain copy
.transition{ 
       transition: all 1s ease; 
       -moz-transition: all 1s ease; 
       -webkit-transition: all 1s ease;  
       -o-transition: all 1s ease;  
   } 
[css] view plain copy
.toLeft{ 
        .transition; 
        margin-right: 540px !important; 
    } 
    .toRight{ 
        .transition; 
        margin-right: 40px !important; 
    } 
    .toHide{ 
        .transition; 
        right: -500px !important; 
    } 
    .toShow{ 
        .transition; 
        right: 0px !important; 
    } 
[css] view plain copy
// 播放区 
    .player-box{ 
        margin-right: 540px; 
        height: 100%; 
        position: relative; 
        
    } 
     
[css] view plain copy
//侧边信息区 
    .info-box{ 
        width: 520px; 
        height: 100%; 
        background: transparent;     
        position: relative; 
        overflow: hidden; 
    } 

[css] view plain copy
// 内容区 
.content{ 
    background: #292929; 
    position: relative; 
    padding: 20px 0 20px 20px; 
 

二、播放器ui

整个自定义的播放器ui封装成了一个组件--CostomVedio.vue,播放区使用的是vue-video-player的播放器,但是底部控制栏是自定义的,不使用播放器自带的controlBar,通常通用的这些都不符合设计哥哥的要求,所以我们需要自定义播放器UI。

html结构代码如下:

[html] view plain copy
<template> 
    <div class="custom-video-outer-box" @mouseover="videoMouseOver"> 
      <video-player  class="video-player-box" 
                 ref="videoPlayer" 
                 :options="playerOptions" 
                 :playsinline="true" 
                 customEventName="customstatechangedeventname" 
                 @play="onPlayerPlay($event)" 
                 @pause="onPlayerPause($event)" 
                 @ended="onPlayerEnded($event)" 
                 @waiting="onPlayerWaiting($event)" 
                 @playing="onPlayerPlaying($event)" 
                 @loadeddata="onPlayerLoadeddata($event)"    
                 @timeupdate="onPlayerTimeupdate($event)" 
                 @statechanged="playerStateChanged($event)" 
                 @ready="playerReadied" 
                 > 
                  
                  <!-- @canplay="onPlayerCanplay($event)" --> 
                   <!-- @canplaythrough="onPlayerCanplaythrough($event)" --> 
                 
       </video-player> 
       <!-- 底部进度条 start --> 
         <transition name="fade"> 
                <div class="bottomCtrl" v-show="isBottomCtrlShow" id="bottomCtrl"> 
                    <!--  --> 
                    <!-- <div class="bottomCtrl" v-show="false"> --> 
                <!-- <div class="bottomCtrl"  > --> 
                     
                    <Slider v-model="playerCtrl.currentTimeInt" class="progress-slider" :max="playerCtrl.durationInt" :tip-format="progressTipFormat" @on-change="progressChange"></Slider> 
                    <div class="clearfix" > 
                        <div class="left"> 
                                <!-- 暂停 --> 
                                <span v-on:click="play" v-if="!playerCtrl.isPlay" class="icon"> 
                                    <Icon type="play"></Icon> 
                                </span> 
                                <!-- 播放 --> 
                                <span v-else v-on:click="pause" class="icon"> 
                                     <Icon type="stop"></Icon> 
                                </span> 
                                
                                <!-- 下一曲 --> 
                                <span class="icon" v-on:click="nextClick"> 
                                    <Icon type="skip-forward"></Icon> 
                                </span> 
                           
                            <span class="time"> 
                                {{playerCtrl.currentTime}}/{{playerCtrl.duration}} 
                            </span> 
                        </div> 
                        <div class="right clearfix"> 
                                <div class="voice-box clearfix left">  
                                    <!-- 音量 --> 
                                    <Icon type="volume-medium" class="left icon"></Icon> 
                                    <Slider v-model="playerCtrl.voiceSlider" class="voice-slider left " max=100 @on-change="volumeChange"></Slider> 
                                </div> 
                                 <!-- 全屏 --> 
                                 <span class="icon left" @click="fullScreenHandle"> 
                                    <Icon type="crop" class="full-screen" ></Icon> 
                                 </span> 
                        </div> 
                    </div> 
                </div> 
         </transition> 
       </div> 
  </template> 

具体思路就是,使用播放器铺满播放区,使用position定位将自定义的controlBar固定在播放区的底部,这里注意controlBar的z-index一定要足够大,否则在全屏的时候不在最上层看不到。
css样式:

[css] view plain copy
<style lang="less"> 
    .video-player-box{ 
        height: 100% !important; 
        width: 100% !important; 
    } 
    //底部进度条 
    .bottomCtrl{ 
        line-height: 60px; 
        height: 60px; 
        overflow: visible; 
        position: absolute; 
        bottom: 0; 
        left: 0; 
        background-color: rgba(45, 45, 45, .92); 
        width: 100%; 
        padding: 0 50px; 
        color: #fff; 
        z-index: 999999999999999; 
 
        .icon{ 
            font-size: 16px; 
            line-height: 60px; 
            cursor: pointer; 
        } 
 
        .icon+.icon{ 
            margin-left: 20px; 
        } 
    } 
    .custom-video-outer-box{ 
        position: relative; 
        height: 100%; 
        width: 100%; 
    } 
    .progress-slider{ 
        position: absolute; 
        width: 100%; 
        top: 0; 
        left: 0; 
        height: 18px; 
        line-height: 18px; 
        .ivu-slider-wrap{ 
            margin: 0 !important; 
            border-radius: 0 !important; 
        } 
        .ivu-slider-button-wrap{ 
             line-height: normal !important; 
        } 
        .ivu-slider-button{ 
            height: 8px !important; 
            width: 8px !important; 
            
        } 
    } 
    .voice-box{ 
        .voice-slider{ 
            width: 100px; 
            margin-left: 20px; 
        } 
        .ivu-slider-wrap{ 
            margin: 27px 0 !important; 
        } 
 
    } 
    .time{ 
        margin-left: 25px; 
    } 
    .full-screen{ 
       margin-left: 25px; 
        line-height: 60px; 
    } 
   
    .ivu-progress-outer{ 
        padding: 0 10px !important; 
    } 
     
    .vjs-big-play-button{ 
        height: 80px !important; 
        width: 80px !important; 
        line-height: 80px !important; 
        text-align: center; 
        background:rgba(0, 0, 0, 0.8) !important; 
        border-radius: 50% !important; 
        top: 50% !important; 
        left: 50% !important; 
        margin-left: -40px !important; 
        margin-top: -40px !important; 
    } 
    #vjs_video_3{ 
        max-height: 100% !important; 
        width: 100% !important; 
        height: 100% !important; 
    } 
    .video-player-box>div{ 
        height: 100% !important; 
        width: 100% !important; 
    } 
    .video-js .vjs-big-play-button{ 
        font-size: 5em !important; 
    } 
    video{ 
        max-height: 100% !important; 
 
    } 
    
</style> 

三、实现自定义controlBar功能

接下来就是实现自定义controlBar的功能,如播放,暂停,下一曲,播放进度,剩余时间,全屏,音量调节等。

这里我们肯定要先看video.js的相应api了,虽然是英文的但是上边写的很清楚,很容易看明白。

video.js api文档地址:http://docs.videojs.com/docs/api/player.html

1. 播放,暂停,下一曲,全屏主要就是监听我们添加的自定义按钮click事件,然后调用播放器API执行相应操作,并改变状态。

[javascript] view plain copy
// 播放 
 play(){ 
     this.player.play(); 
 }, 
 // 暂停 
 pause(){ 
      this.player.pause(); 
 }, 
 //下一曲 
 nextClick(){ 
     console.log("自定义","下一曲点击"); 
     
 }, 
 //全屏 
 fullScreenHandle(){ 
     console.log("全屏"); 
     if(!this.player.isFullscreen()){ 
         this.player.requestFullscreen(); 
         this.player.isFullscreen(true); 
     }else{ 
          this.player.exitFullscreen(); 
          this.player.isFullscreen(false); 
     } 
 }, 

当然,在vue-video-player中的播放器会在回调方法中监听状态的变化:
[html] view plain copy
<video-player  class="video-player-box" 
                ref="videoPlayer" 
                :options="playerOptions" 
                :playsinline="true" 
                customEventName="customstatechangedeventname" 
                @play="onPlayerPlay($event)" 
                @pause="onPlayerPause($event)" 
                @ended="onPlayerEnded($event)" 
                @waiting="onPlayerWaiting($event)" 
                @playing="onPlayerPlaying($event)" 
                @loadeddata="onPlayerLoadeddata($event)"    
                @timeupdate="onPlayerTimeupdate($event)" 
                @statechanged="playerStateChanged($event)" 
                @ready="playerReadied" 
                > 
                 
                 <!-- @canplay="onPlayerCanplay($event)" --> 
                  <!-- @canplaythrough="onPlayerCanplaythrough($event)" --> 
                
      </video-player> 
我们可以根据这些状态变化,相应的改变我们的UI,比如播放时显示“暂停”按钮,暂停时显示“播放”等功能。

2.播放进度,剩余时间,音量调节

播放进度的话是根据在播放器onPlayerTimeupdate()回调方法中,通过currentTime这个方法来获取当前播放的进度时间,单位S,因为这里我使用的是slider,进度都是整数计算,所以这里我需要两个变量存放,一个是整数形式,另一个是格式化好时分秒之后的string形式,用以显示。

[javascript] view plain copy
//时间更新   
           onPlayerTimeupdate(player){ 
               this.playerCtrl.currentTime=timeUtil.secondToDate(player.currentTime()); 
               this.playerCtrl.currentTimeInt=Math.floor(player.currentTime()); 
               console.log("当前音量",player.volume()); 
           }, 

定点播放,即用户点击进度条某个地方,即可在这个点进度播放,使用的是slider的
[html] view plain copy
@on-change="progressChange" 

这个方法监听slider定点,

[javascript] view plain copy
//进度条被拉动 
           progressChange(val){ 
               this.player.currentTime(val); 
               this.playerCtrl.currentTimeInt=val; 
               this.playerCtrl.currentTime=timeUtil.secondToDate(val); 
           }, 

拿到定点的值,然后通过player的currentTime设置跳到定点播放。
音量调节的做法跟播放进度相似:

一开始初始化的时候记得配置

[javascript] view plain copy
muted:false,//开始声音 

来开启声音,否则静音状态下调节声音无效。

使用player.volume(val)这个api设置音量,其中val=0,表示声音off,val=1表示声音最大,0.5表示声音设置在half。

四:总

最后在app.vue/需要用到这个播放器的地方 引入自定义播放器组件即可。vue-video-player是大神基于video.js开发的适用于vue.js框架的组件,具有良好兼容性,所以我们在vue中使用这个播放器组件本质还是使用video.js,我们要更多的去了解video.js中的api并使用他。

Javascript 相关文章推荐
javascript 日期常用的方法
Nov 11 Javascript
改善你的jQuery的25个步骤 千倍级效率提升
Feb 11 Javascript
JS继承 笔记
Jul 13 Javascript
页面右下角弹出提示框示例代码js版
Aug 02 Javascript
JavaScript的事件代理和委托实例分析
Mar 25 Javascript
贴近用户体验的Jquery日期、时间选择插件
Aug 19 Javascript
JS控制弹出悬浮窗口(一览画面)的实例代码
May 30 Javascript
浅谈在vue中用webpack打包之后运行文件的问题以及相关配置方法
Feb 21 Javascript
Vue CLI 3.x 自动部署项目至服务器的方法
Apr 02 Javascript
angular6开发steps步骤条组件
Jul 04 Javascript
如何在现代JavaScript中编写异步任务
Jan 31 Javascript
什么是SOLID
Mar 24 Javascript
基于iScroll实现内容滚动效果
Mar 21 #Javascript
JS中的回调函数实例浅析
Mar 21 #Javascript
使用Vue制作图片轮播组件思路详解
Mar 21 #Javascript
JS实现为动态添加的元素增加事件功能示例【基于事件委托】
Mar 21 #Javascript
JS实现遍历不规则多维数组的方法
Mar 21 #Javascript
vue项目关闭eslint校验
Mar 21 #Javascript
去掉vue 中的代码规范检测两种方法(Eslint验证)
Mar 21 #Javascript
You might like
php ci框架验证码实例分析
2013/06/26 PHP
PHP自动生成后台导航网址的最佳方法
2013/08/27 PHP
php数组中包含中文的排序方法
2014/06/03 PHP
PHP中iconv函数转码时截断字符问题的解决方法
2015/01/21 PHP
php生成图片验证码的实例讲解
2015/08/03 PHP
Zend Framework教程之资源(Resources)用法实例详解
2016/03/14 PHP
phpstorm最新激活码分享亲测phpstorm2020.2.3版可用
2020/11/22 PHP
Some tips of wmi scripting in jscript (1)
2007/04/03 Javascript
javascript针对DOM的应用实例(一)
2012/04/15 Javascript
JQuery使用index方法获取Jquery对象数组下标的方法
2015/05/18 Javascript
jquery实现九宫格大转盘抽奖
2015/11/13 Javascript
JavaScript+html5 canvas实现本地截图教程
2020/04/16 Javascript
easyui messager alert 三秒后自动关闭提示的实例
2016/11/07 Javascript
vue2 前后端分离项目ajax跨域session问题解决方法
2017/04/27 Javascript
js字符串与Unicode编码互相转换
2017/05/17 Javascript
详解基于node的前端项目编译时内存溢出问题
2017/08/01 Javascript
原生js通过一行代码实现简易轮播图
2019/06/05 Javascript
websocket4.0+typescript 实现热更新的方法
2019/08/14 Javascript
Vue父子传递实例讲解
2020/02/14 Javascript
详解Webpack4多页应用打包方案
2020/07/16 Javascript
[02:01]BBC DOTA2国际邀请赛每日综述:八强胜者组鏖战,中国队喜忧参半
2014/07/19 DOTA
[32:47]完美世界DOTA2联赛 GXR vs IO 第二场 11.07
2020/11/09 DOTA
python3+PyQt5实现拖放功能
2018/04/24 Python
利用Pycharm断点调试Python程序的方法
2018/11/29 Python
pycharm激活码快速激活及使用步骤
2020/03/12 Python
pytorch 移动端部署之helloworld的使用
2020/10/30 Python
pycharm 实现光标快速移动到括号外或行尾的操作
2021/02/05 Python
HTML5 文件上传下载的实例代码
2017/07/03 HTML / CSS
HTML5拖拽文件上传的示例代码
2021/03/04 HTML / CSS
英国百年闻名的优质健康产品连锁店:Holland & Barrett
2019/12/19 全球购物
村长贪污检举信
2014/04/04 职场文书
让生命充满爱演讲稿
2014/05/10 职场文书
2013年最新自荐信范文
2014/06/23 职场文书
民族精神月活动总结
2014/08/28 职场文书
无房产证房屋转让协议书合同样本
2014/10/18 职场文书
幼儿园亲子活动通知
2015/04/24 职场文书