基于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 相关文章推荐
超清晰的document对象详解
Feb 27 Javascript
jQuery Dialog 弹出层对话框插件
Aug 09 Javascript
javascript中的注释使用与注意事项小结
Sep 20 Javascript
jQuery Validation Plugin验证插件手动验证
Jan 26 Javascript
JavaScript性能优化总结之加载与执行
Aug 11 Javascript
JavaScript两个变量交换值的实现方法
Mar 01 Javascript
基于vue配置axios的方法步骤
Nov 09 Javascript
解决vue接口数据赋值给data没有反应的问题
Aug 27 Javascript
详解vue开发中调用微信jssdk的问题
Apr 16 Javascript
JAVA面试题 static关键字详解
Jul 16 Javascript
详解ES6新增字符串扩张方法includes()、startsWith()、endsWith()
May 12 Javascript
使用 Opentype.js 生成字体子集的实例代码详解
May 25 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读写文件的方法(生成HTML)
2006/11/27 PHP
PHP中使用php://input处理相同name值的表单数据
2015/02/03 PHP
用PHP代码给图片加水印
2015/07/01 PHP
php+ajax 实现输入读取数据库显示匹配信息
2015/10/08 PHP
PHP检查URL包含特定字符串实例方法
2019/02/11 PHP
javascript 类型判断代码分析
2010/03/28 Javascript
Document对象内容集合(比较全)
2010/09/06 Javascript
BootStrap中关于Select下拉框选择触发事件及扩展
2016/11/22 Javascript
jQuery实现页面顶部下拉广告
2016/12/30 Javascript
详解webpack-dev-server 设置反向代理解决跨域问题
2018/04/18 Javascript
PostgreSQL Node.js实现函数计算方法示例
2019/02/12 Javascript
微信小程序绘制图片发送朋友圈
2019/07/25 Javascript
vuex根据不同的用户权限展示不同的路由列表功能
2019/09/20 Javascript
通过高德地图API获得某条道路上的所有坐标用于描绘道路的方法
2020/08/24 Javascript
js实现筛选功能
2020/11/24 Javascript
matplotlib简介,安装和简单实例代码
2017/12/26 Python
python实现聊天小程序
2018/03/13 Python
python3中获取文件当前绝对路径的两种方法
2018/04/26 Python
基于python log取对数详解
2018/06/08 Python
Python单元测试工具doctest和unittest使用解析
2019/09/02 Python
mac在matplotlib中显示中文的操作方法
2020/03/06 Python
在Python IDLE 下调用anaconda中的库教程
2020/03/09 Python
TensorFlow Autodiff自动微分详解
2020/07/06 Python
Python jieba结巴分词原理及用法解析
2020/11/05 Python
使用HTML5的Canvas绘制曲线的简单方法
2015/09/08 HTML / CSS
Anthropologie英国:美国家喻户晓的休闲服装和家居产品品牌
2018/12/05 全球购物
TCP协议通讯的过程和步骤是什么
2015/10/18 面试题
软件测试工程师笔试题带答案
2015/03/27 面试题
母亲节演讲稿范文
2014/01/02 职场文书
承诺书格式范文
2014/06/03 职场文书
2014年社区党建工作总结
2014/11/11 职场文书
销售业务员岗位职责
2015/02/13 职场文书
团支部书记竞选稿
2015/11/21 职场文书
2016大学生求职自荐信范文
2016/01/28 职场文书
《圆的面积》教学反思
2016/02/19 职场文书
什么是css原子化,有什么用?
2022/04/24 HTML / CSS