基于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加号&quot;+&quot;的二义性说明
Mar 04 Javascript
js中indexof的用法详细解析
Dec 24 Javascript
js 处理数组重复元素示例代码
Dec 27 Javascript
浅析jquery的js图表组件highcharts
Mar 06 Javascript
21个JavaScript事件(Events)属性汇总
Dec 02 Javascript
jQuery实现平滑滚动到指定锚点的方法
Mar 20 Javascript
js给selected添加options的方法
May 06 Javascript
jQuery实现的动态文字变化输出效果示例【附演示与demo源码下载】
Mar 24 jQuery
JavaScript实现的数字与字符串转换功能示例
Aug 23 Javascript
详解Vue实战指南之依赖注入(provide/inject)
Nov 13 Javascript
JS字符串补全方法padStart()和padEnd()
May 27 Javascript
Vue实现动态查询规则生成组件
May 27 Vue.js
基于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来处理多个提交任务
2006/10/09 PHP
php将mysql数据库整库导出生成sql文件的具体实现
2014/01/08 PHP
Linux下编译redis和phpredis的方法
2016/04/07 PHP
php-msf源码详解
2017/12/25 PHP
JQuery实现鼠标滑过显示导航下拉列表
2013/09/12 Javascript
Jquery的each里用return true或false代替break或continue
2014/05/21 Javascript
JavaScript实现的一个计算数字步数的算法分享
2014/12/06 Javascript
实例讲解JQuery中this和$(this)区别
2014/12/08 Javascript
jQuery中queue()方法用法实例
2014/12/29 Javascript
JavaScript实现梯形乘法表的方法
2015/04/25 Javascript
js图片跟随鼠标移动代码
2015/11/26 Javascript
简述JavaScript提交表单的方式 (Using JavaScript Submit Form)
2016/03/18 Javascript
详解闭包解决jQuery中AJAX的外部变量问题
2017/02/22 Javascript
JS中使用正则表达式g模式和非g模式的区别
2017/04/01 Javascript
详谈ES6中的迭代器(Iterator)和生成器(Generator)
2017/07/31 Javascript
微信小程序基于slider组件动态修改标签透明度的方法示例
2017/12/04 Javascript
详解Vue.js中.native修饰符
2018/04/24 Javascript
微信小程序之裁剪图片成圆形的实现代码
2018/10/11 Javascript
layui树形菜单动态遍历的例子
2019/09/23 Javascript
jquery 遍历hash操作示例【基于ajax交互】
2019/10/12 jQuery
Vue实现多标签选择器
2019/11/28 Javascript
JavaScript快速调试的两个技巧
2020/11/04 Javascript
python机器学习之神经网络(三)
2017/12/20 Python
Django+Ajax+jQuery实现网页动态更新的实例
2018/05/28 Python
Python把csv数据写入list和字典类型的变量脚本方法
2018/06/15 Python
python实现基于信息增益的决策树归纳
2018/12/18 Python
Python内置加密模块用法解析
2019/11/25 Python
PyCharm 在Windows的有用快捷键详解
2020/04/07 Python
Django集成MongoDB实现过程解析
2020/12/01 Python
Python之多进程与多线程的使用
2021/02/23 Python
玖熙女鞋美国官网:Nine West
2016/10/06 全球购物
草莓网美国官网:Strawberrynet USA
2016/12/11 全球购物
Steve Madden官网:美国鞋类品牌
2017/01/29 全球购物
阿迪达斯印度官方商城:adidas India
2017/03/26 全球购物
Desigual德国官网:在线购买原创服装
2018/03/27 全球购物
安全生产责任书
2014/03/12 职场文书