基于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 相关文章推荐
Extjs 继承Ext.data.Store不起作用原因分析及解决
Apr 15 Javascript
jQuery动态地获取系统时间实现代码
May 24 Javascript
AngularJS入门教程(零):引导程序
Dec 06 Javascript
jQuery中end()方法用法实例
Jan 08 Javascript
JS实现网页Div层Clone拖拽效果
Sep 26 Javascript
Node.js中使用socket创建私聊和公聊聊天室
Nov 19 Javascript
jQuery validate插件实现ajax验证重复的2种方法
Jan 22 Javascript
jQuery通过改变input的type属性实现密码显示隐藏切换功能
Feb 08 Javascript
angularjs实现table增加tr的方法
Feb 27 Javascript
在vue里面设置全局变量或数据的方法
Mar 09 Javascript
js实现开关灯效果
Mar 30 Javascript
jquery html添加元素/删除元素操作实例详解
May 20 jQuery
基于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扩展编写点滴 技巧收集
2010/03/09 PHP
php导出CSV抽象类实例
2014/09/24 PHP
PHP框架Laravel的小技巧两则
2015/02/10 PHP
js代码实现微博导航栏
2015/07/30 PHP
Yii数据读取与跳转参数传递用法实例分析
2016/07/12 PHP
PHP goto语句用法实例
2019/08/06 PHP
jquery自定义属性(类型/属性值)
2013/05/21 Javascript
jQuery简单实现QQ空间点赞已经取消点赞
2015/04/02 Javascript
js实现仿Windows风格选项卡和按钮效果实例
2015/05/13 Javascript
JS使用cookie实现DIV提示框只显示一次的方法
2015/11/05 Javascript
jQuery右下角悬浮广告实例
2016/10/17 Javascript
AngularJS入门教程之过滤器用法示例
2016/11/02 Javascript
浅谈Node.js:Buffer模块
2016/12/05 Javascript
js 博客内容进度插件详解
2017/02/19 Javascript
利用js查找数组中指定元素并返回该元素的所有索引示例
2017/03/29 Javascript
bootstrap select插件封装成Vue2.0组件
2017/04/17 Javascript
Nodejs中Express 常用中间件 body-parser 实现解析
2017/05/22 NodeJs
基于ionic实现下拉刷新功能
2018/05/10 Javascript
JavaScript对象的特性与实践应用深入详解
2018/12/30 Javascript
小程序扫描普通链接二维码跳转小程序指定界面方法
2019/05/07 Javascript
Emberjs 通过 axios 下载文件的方法
2019/09/03 Javascript
详解js中的原型,原型对象,原型链
2020/07/16 Javascript
vue addRoutes路由动态加载操作
2020/08/04 Javascript
ant design 日期格式化的实现
2020/10/27 Javascript
python入门基础之用户输入与模块初认识
2016/11/14 Python
python编程实现随机生成多个椭圆实例代码
2018/01/03 Python
python字典的setdefault的巧妙用法
2019/08/07 Python
django admin 自定义替换change页面模板的方法
2019/08/23 Python
基于python判断目录或者文件代码实例
2019/11/29 Python
详解canvas在圆弧周围绘制文本的两种写法
2018/05/22 HTML / CSS
购买正版游戏和游戏激活码:Green Man Gaming
2019/11/06 全球购物
英国网上电器商店:Electricshop
2020/03/15 全球购物
《风筝》教学反思
2014/04/10 职场文书
python爬虫之爬取笔趣阁小说
2021/04/22 Python
Python趣味挑战之给幼儿园弟弟生成1000道算术题
2021/05/28 Python
【2·13】一图读懂中国无线电发展
2022/02/18 无线电