先看一下效果。图1--显示侧边栏图2-收起侧边栏;图三:全屏。写在前面本次项目中需要用
先看一下效果。
图1--显示侧边栏
图2-收起侧边栏;
图三:全屏。
写在前面
本次项目中需要用到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。
项目目录:
一、外层ui布局
图一中可以看到,本次项目使用的是两栏自适应布局,其中,右侧为播放列表,固定宽度500px,左边是播放器box,播放列表box可根据手柄点击展开或收起,而播放器box也跟随播放列表的展开/收缩进行宽度自适应。
(因录制动画太大传不上,可clone我的程序下来运行可见)。
html代码结构如此:
收缩展开的时候加上一个过度动画,这里选择使用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并使用他。
vue video player