基于vue-video-player自定义播放器的方法
先看一下效果。
图1--显示侧边栏
图2-收起侧边栏;
图三:全屏。
写在前面
本次项目中需要用到vue,vue-video-player,我用的是iview的ui框架,但是ui框架无妨,这里关注的是基于video.js开发的vue-video-player的使用,以及如何操作video.js中的api。
vue-video-player 项目地址:。
video.js文档地址:。
项目目录:
一、外层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文档地址:
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实现换肤