基于vue-video-player自定義播放器的方法
先看一下效果。
圖1--顯示側(cè)邊欄
圖2-收起側(cè)邊欄;
圖三:全屏。
寫在前面
本次項(xiàng)目中需要用到vue,vue-video-player,我用的是iview的ui框架,但是ui框架無(wú)妨,這里關(guān)注的是基于video.js開(kāi)發(fā)的vue-video-player的使用,以及如何操作video.js中的api。
vue-video-player 項(xiàng)目地址:https://github.com/surmon-china/vue-video-player。
video.js文檔地址:http://docs.videojs.com/docs/api/player.html。
項(xiàng)目目錄:
一、外層ui布局
圖一中可以看到,本次項(xiàng)目使用的是兩欄自適應(yīng)布局,其中,右側(cè)為播放列表,固定寬度500px,左邊是播放器box,播放列表box可根據(jù)手柄點(diǎn)擊展開(kāi)或收起,而播放器box也跟隨播放列表的展開(kāi)/收縮進(jìn)行寬度自適應(yīng)。
(因錄制動(dòng)畫太大傳不上,可clone我的程序下來(lái)運(yùn)行可見(jiàn))。
html代碼結(jié)構(gòu)如此:
收縮展開(kāi)的時(shí)候加上一個(gè)過(guò)度動(dòng)畫,這里選擇使用css手寫動(dòng)畫:
[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
// 播放區(qū)
.player-box{
margin-right: 540px;
height: 100%;
position: relative;
}
[css] view plain copy
//側(cè)邊信息區(qū)
.info-box{
width: 520px;
height: 100%;
background: transparent;
position: relative;
overflow: hidden;
}
[css] view plain copy
// 內(nèi)容區(qū)
.content{
background: #292929;
position: relative;
padding: 20px 0 20px 20px;
}
二、播放器ui
整個(gè)自定義的播放器ui封裝成了一個(gè)組件--CostomVedio.vue,播放區(qū)使用的是vue-video-player的播放器,但是底部控制欄是自定義的,不使用播放器自帶的controlBar,通常通用的這些都不符合設(shè)計(jì)哥哥的要求,所以我們需要自定義播放器UI。
html結(jié)構(gòu)代碼如下:
[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>
<!-- 底部進(jìn)度條 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>
具體思路就是,使用播放器鋪滿播放區(qū),使用position定位將自定義的controlBar固定在播放區(qū)的底部,這里注意controlBar的z-index一定要足夠大,否則在全屏的時(shí)候不在最上層看不到。
css樣式:
[css] view plain copy
<style lang="less">
.video-player-box{
height: 100% !important;
width: 100% !important;
}
//底部進(jìn)度條
.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>
三、實(shí)現(xiàn)自定義controlBar功能
接下來(lái)就是實(shí)現(xiàn)自定義controlBar的功能,如播放,暫停,下一曲,播放進(jìn)度,剩余時(shí)間,全屏,音量調(diào)節(jié)等。
這里我們肯定要先看video.js的相應(yīng)api了,雖然是英文的但是上邊寫的很清楚,很容易看明白。
video.js api文檔地址:http://docs.videojs.com/docs/api/player.html
1. 播放,暫停,下一曲,全屏主要就是監(jiān)聽(tīng)我們添加的自定義按鈕click事件,然后調(diào)用播放器API執(zhí)行相應(yīng)操作,并改變狀態(tài)。
[javascript] view plain copy
// 播放
play(){
this.player.play();
},
// 暫停
pause(){
this.player.pause();
},
//下一曲
nextClick(){
console.log("自定義","下一曲點(diǎn)擊");
},
//全屏
fullScreenHandle(){
console.log("全屏");
if(!this.player.isFullscreen()){
this.player.requestFullscreen();
this.player.isFullscreen(true);
}else{
this.player.exitFullscreen();
this.player.isFullscreen(false);
}
},
當(dāng)然,在vue-video-player中的播放器會(huì)在回調(diào)方法中監(jiān)聽(tīng)狀態(tài)的變化:
[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>
我們可以根據(jù)這些狀態(tài)變化,相應(yīng)的改變我們的UI,比如播放時(shí)顯示“暫?!卑粹o,暫停時(shí)顯示“播放”等功能。
2.播放進(jìn)度,剩余時(shí)間,音量調(diào)節(jié)
播放進(jìn)度的話是根據(jù)在播放器onPlayerTimeupdate()回調(diào)方法中,通過(guò)currentTime這個(gè)方法來(lái)獲取當(dāng)前播放的進(jìn)度時(shí)間,單位S,因?yàn)檫@里我使用的是slider,進(jìn)度都是整數(shù)計(jì)算,所以這里我需要兩個(gè)變量存放,一個(gè)是整數(shù)形式,另一個(gè)是格式化好時(shí)分秒之后的string形式,用以顯示。
[javascript] view plain copy
//時(shí)間更新
onPlayerTimeupdate(player){
this.playerCtrl.currentTime=timeUtil.secondToDate(player.currentTime());
this.playerCtrl.currentTimeInt=Math.floor(player.currentTime());
console.log("當(dāng)前音量",player.volume());
},
定點(diǎn)播放,即用戶點(diǎn)擊進(jìn)度條某個(gè)地方,即可在這個(gè)點(diǎn)進(jìn)度播放,使用的是slider的
[html] view plain copy
@on-change="progressChange"
這個(gè)方法監(jiān)聽(tīng)slider定點(diǎn),
[javascript] view plain copy
//進(jìn)度條被拉動(dòng)
progressChange(val){
this.player.currentTime(val);
this.playerCtrl.currentTimeInt=val;
this.playerCtrl.currentTime=timeUtil.secondToDate(val);
},
拿到定點(diǎn)的值,然后通過(guò)player的currentTime設(shè)置跳到定點(diǎn)播放。
音量調(diào)節(jié)的做法跟播放進(jìn)度相似:
一開(kāi)始初始化的時(shí)候記得配置
[javascript] view plain copy
muted:false,//開(kāi)始聲音
來(lái)開(kāi)啟聲音,否則靜音狀態(tài)下調(diào)節(jié)聲音無(wú)效。
使用player.volume(val)這個(gè)api設(shè)置音量,其中val=0,表示聲音off,val=1表示聲音最大,0.5表示聲音設(shè)置在half。
四:總結(jié)
最后在app.vue/需要用到這個(gè)播放器的地方 引入自定義播放器組件即可。vue-video-player是大神基于video.js開(kāi)發(fā)的適用于vue.js框架的組件,具有良好兼容性,所以我們?cè)趘ue中使用這個(gè)播放器組件本質(zhì)還是使用video.js,我們要更多的去了解video.js中的api并使用他。
- vue視頻播放插件vue-video-player的具體使用方法
- vue-video-player 通過(guò)自定義按鈕組件實(shí)現(xiàn)全屏切換效果【推薦】
- vue-video-player實(shí)現(xiàn)實(shí)時(shí)視頻播放方式(監(jiān)控設(shè)備-rtmp流)
- 詳解vue2.0+vue-video-player實(shí)現(xiàn)hls播放全過(guò)程
- 詳解vue-video-player使用心得(兼容m3u8)
- vue-video-player視頻播放器使用配置詳解
- vue使用video插件vue-video-player詳解
- vue video和vue-video-player實(shí)現(xiàn)視頻鋪滿教程
- vue-video-player 解決微信自動(dòng)全屏播放問(wèn)題(橫豎屏導(dǎo)致樣式錯(cuò)亂問(wèn)題)
- vue使用vue-video-player插件播放視頻的步驟講解
相關(guān)文章
ElementUI Tag組件實(shí)現(xiàn)多標(biāo)簽生成的方法示例
這篇文章主要介紹了ElementUI Tag組件實(shí)現(xiàn)多標(biāo)簽生成的方法示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-07-07Vue3+Vue Router實(shí)現(xiàn)動(dòng)態(tài)路由導(dǎo)航的示例代碼
隨著單頁(yè)面應(yīng)用程序(SPA)的日益流行,前端開(kāi)發(fā)逐漸向復(fù)雜且交互性強(qiáng)的方向發(fā)展,在這個(gè)過(guò)程中,Vue.js及其生態(tài)圈的工具(如Vue Router)為我們提供了強(qiáng)大的支持,本文將介紹如何在Vue 3中使用Vue Router實(shí)現(xiàn)動(dòng)態(tài)路由導(dǎo)航,需要的朋友可以參考下2024-08-08npm安裝vue@cli報(bào)錯(cuò)的簡(jiǎn)單處理方式
最近工作中遇到了報(bào)錯(cuò),現(xiàn)在將解決的辦法分享給大家,下面這篇文章主要給大家介紹了關(guān)于npm安裝vue@cli報(bào)錯(cuò)的簡(jiǎn)單處理方式,文中通過(guò)圖文介紹的非常詳細(xì),需要的朋友可以參考下2022-12-12Vue?+?SpringBoot?實(shí)現(xiàn)文件的斷點(diǎn)上傳、秒傳存儲(chǔ)到Minio的操作方法
這篇文章主要介紹了Vue?+?SpringBoot?實(shí)現(xiàn)文件的斷點(diǎn)上傳、秒傳存儲(chǔ)到Minio的操作方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2024-06-06詳解vue中使用express+fetch獲取本地json文件
本篇文章主要介紹了詳解vue中使用express+fetch獲取本地json文件,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2017-10-10解決前端調(diào)用后端接口返回200但數(shù)據(jù)返回的是html標(biāo)簽
這篇文章主要給大家介紹了關(guān)于如何解決前端調(diào)用后端接口返回200但數(shù)據(jù)返回的是html標(biāo)簽的相關(guān)資料,文中通過(guò)圖文將解決的過(guò)程介紹的非常詳細(xì),對(duì)同樣遇到這個(gè)問(wèn)題的朋友具有一定的參考解決價(jià)值,需要的朋友可以參考下2024-05-05Vue3使用postcss-px-to-viewport實(shí)現(xiàn)頁(yè)面自適應(yīng)
postcss-px-to-viewport 是一個(gè) PostCSS 插件,它可以將 px 單位轉(zhuǎn)換為視口單位,下面我們就看看如何使用postcss-px-to-viewport實(shí)現(xiàn)頁(yè)面自適應(yīng)吧2024-01-01