圖2-收起側(cè)邊欄;
圖三:全屏。
本次項(xiàng)目中需要用到vue,vue-video-player,我用的是iview的ui框架,但是ui框架無妨,這里關(guān)注的是基于video.js開發(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)目目錄:
圖一中可以看到,本次項(xiàng)目使用的是兩欄自適應(yīng)布局,其中,右側(cè)為播放列表,固定寬度500px,左邊是播放器box,播放列表box可根據(jù)手柄點(diǎn)擊展開或收起,而播放器box也跟隨播放列表的展開/收縮進(jìn)行寬度自適應(yīng)。
(因錄制動(dòng)畫太大傳不上,可clone我的程序下來運(yùn)行可見)。
html代碼結(jié)構(gòu)如此:
收縮展開的時(shí)候加上一個(gè)過度動(dòng)畫,這里選擇使用css手寫動(dòng)畫:
view plain copy .transition{ transition: all 1s ease; -moz-transition: all 1s ease; -webkit-transition: all 1s ease; -o-transition: all 1s ease; } 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; } view plain copy // 播放區(qū) .player-box{ margin-right: 540px; height: 100%; position: relative; } 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; }
整個(gè)自定義的播放器ui封裝成了一個(gè)組件--CostomVedio.vue,播放區(qū)使用的是vue-video-player的播放器,但是底部控制欄是自定義的,不使用播放器自帶的controlBar,通常通用的這些都不符合設(shè)計(jì)哥哥的要求,所以我們需要自定義播放器UI。
html結(jié)構(gòu)代碼如下:
view plain copy <template> <p 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"> <p class="bottomCtrl" v-show="isBottomCtrlShow" id="bottomCtrl"> <!-- --> <!-- <p class="bottomCtrl" v-show="false"> --> <!-- <p class="bottomCtrl" > --> <Slider v-model="playerCtrl.currentTimeInt" class="progress-slider" :max="playerCtrl.durationInt" :tip-format="progressTipFormat" @on-change="progressChange"></Slider> <p class="clearfix" > <p 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> </p> <p class="right clearfix"> <p 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> </p> <!-- 全屏 --> <span class="icon left" @click="fullScreenHandle"> <Icon type="crop" class="full-screen" ></Icon> </span> </p> </p> </p> </transition> </p> </template>
具體思路就是,使用播放器鋪滿播放區(qū),使用position定位將自定義的controlBar固定在播放區(qū)的底部,這里注意controlBar的z-index一定要足夠大,否則在全屏的時(shí)候不在最上層看不到。
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>p{ 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的功能,如播放,暫停,下一曲,播放進(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)聽我們添加的自定義按鈕click事件,然后調(diào)用播放器API執(zhí)行相應(yīng)操作,并改變狀態(tài)。
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ài)的變化:
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í)顯示“暫停”按鈕,暫停時(shí)顯示“播放”等功能。
2.播放進(jìn)度,剩余時(shí)間,音量調(diào)節(jié)
播放進(jìn)度的話是根據(jù)在播放器onPlayerTimeupdate()回調(diào)方法中,通過currentTime這個(gè)方法來獲取當(dāng)前播放的進(jìn)度時(shí)間,單位S,因?yàn)檫@里我使用的是slider,進(jìn)度都是整數(shù)計(jì)算,所以這里我需要兩個(gè)變量存放,一個(gè)是整數(shù)形式,另一個(gè)是格式化好時(shí)分秒之后的string形式,用以顯示。
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的
view plain copy @on-change="progressChange"
這個(gè)方法監(jiān)聽slider定點(diǎn),
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)的值,然后通過player的currentTime設(shè)置跳到定點(diǎn)播放。
音量調(diào)節(jié)的做法跟播放進(jìn)度相似:
一開始初始化的時(shí)候記得配置
view plain copy muted:false,//開始聲音
來開啟聲音,否則靜音狀態(tài)下調(diào)節(jié)聲音無效。
使用player.volume(val)這個(gè)api設(shè)置音量,其中val=0,表示聲音off,val=1表示聲音最大,0.5表示聲音設(shè)置在half。
最后在app.vue/需要用到這個(gè)播放器的地方 引入自定義播放器組件即可。vue-video-player是大神基于video.js開發(fā)的適用于vue.js框架的組件,具有良好兼容性,所以我們?cè)趘ue中使用這個(gè)播放器組件本質(zhì)還是使用video.js,我們要更多的去了解video.js中的api并使用他。
相信看了本文案例你已經(jīng)掌握了方法,更多精彩請(qǐng)關(guān)注Gxl網(wǎng)其它相關(guān)文章!
推薦閱讀:
如何使用Vue.js+computed
如何使用Bootstrap+WebUploader
聲明:本網(wǎng)頁內(nèi)容旨在傳播知識(shí),若有侵權(quán)等問題請(qǐng)及時(shí)與本網(wǎng)聯(lián)系,我們將在第一時(shí)間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com