介紹
基于video、swiper和slider組件,實(shí)現(xiàn)簡單的視頻播放器,可支持海報輪播、視頻播放等功能。
相關(guān)概念
- [video組件]:視頻播放組件。
- [swiper組件]:滑動容器,提供切換子組件顯示的能力。
- [slider組件]:滑動z條組件,用來快速調(diào)節(jié)設(shè)置值,如音量、亮度等。
環(huán)境搭建
軟件要求
- [DevEco Studio]版本:DevEco Studio 3.1 Release及以上版本。
- OpenHarmony SDK版本:API version 9及以上版本。
硬件要求
- 開發(fā)板類型:[潤和RK3568開發(fā)板]。
- OpenHarmony系統(tǒng):3.2 Release及以上版本。
環(huán)境搭建
完成本篇Codelab我們首先要完成開發(fā)環(huán)境的搭建,本示例以RK3568開發(fā)板為例,參照以下步驟進(jìn)行:
- [獲取OpenHarmony系統(tǒng)版本]:標(biāo)準(zhǔn)系統(tǒng)解決方案(二進(jìn)制)。以3.2 Release版本為例:
- 搭建燒錄環(huán)境。
- [完成DevEco Device Tool的安裝]
- [完成RK3568開發(fā)板的燒錄]
- 搭建開發(fā)環(huán)境。
代碼結(jié)構(gòu)解讀
本篇Codelab只對核心代碼進(jìn)行講解,對于完整代碼,我們會在gitee中提供。、
HarmonyOS與OpenHarmony鴻蒙文檔籽料:mau123789是v直接拿
├──entry/src/main/js // 代碼區(qū)
│ └──MainAbility
│ ├──common
│ │ ├──constant
│ │ │ └──commonConstants.js // 公共常量類
│ │ ├──images // 圖片文件
│ │ └──video
│ │ └──video.mp4 // 視頻文件
│ ├──i18n
│ │ ├──en-US.json // 英文國際化
│ │ └──zh-CN.json // 中文國際化
│ ├──pages
│ │ ├──homePage
│ │ │ ├──homePage.css // 主頁面樣式
│ │ │ ├──homePage.hml // 主頁面
│ │ │ └──homePage.js // 主頁面邏輯
│ │ └──videoPage
│ │ ├──videoPage.css // 播放頁面樣式
│ │ ├──videoPage.hml // 播放頁面
│ │ └──videoPage.js // 播放頁面邏輯
│ └──app.js // 程序入口
└──entry/src/main/resource // 應(yīng)用靜態(tài)資源目錄
主頁面
主頁面分為輪播圖區(qū)域和滑動圖區(qū)域兩部分,效果如圖所示:
輪播圖使用swiper組件自動播放輪播圖片,點(diǎn)擊圖片跳轉(zhuǎn)到視頻播放頁面。
< !-- homePage.hml -- >
< div class="container" >
< swiper class="swiper" id="swiper" index="0" autoplay='true' indicator="true"
loop="true" digital="false" >
< image class="swiper-img" src="{{ swiperVideos[0] }}" onclick="playVideo" >< /image >
< image class="swiper-img" src="{{ swiperVideos[1] }}" onclick="playVideo" >< /image >
< image class="swiper-img" src="{{ swiperVideos[2] }}" onclick="playVideo" >< /image >
< /swiper >
...
< /div >
// homePage.js
export default {
data: {
swiperVideos: [],
...
},
// 初始化數(shù)據(jù)
onInit() {
...
},
// 跳轉(zhuǎn)到視頻播放頁面
playVideo() {
router.push({
url: CommonConstants.PLAY_PAGE
});
},
};
滑動圖區(qū)域分為最近播放和為你推薦兩部分,使用List組件進(jìn)行縱向排列;最近播放和為你推薦中的圖片使用List組件進(jìn)行橫向排列,可滑動圖片,點(diǎn)擊圖片跳轉(zhuǎn)到播放頁面。
< !-- homePage.hml -- >
< div class="container" >
...
< div class="horizontal-area" >
< list class="todo-wrapper" >
< list-item for="{{ horizontal_description }}" class="todo-item" clickeffect="false" >
< div class="horizontal-area-div" >
< text class="horizontal-area-description" >{{ $item }}< /text >
< list class="todo-wrapper" >
< list-item for="{{ horizontal_videos }}" clickeffect="false" class="todo-item" >
< div class="image-area" onclick="playVideo" >
< image src="{{ $item.image }}" >< /image >
< text >{{ $item.name }}< /text >
< /div >
< /list-item >
< /list >
< /div >
< /list-item >
< /list >
< /div >
< /div >
// homePage.js
export default {
data: {
...
horizontal_description: [],
horizontal_videos: []
},
// 初始化數(shù)據(jù)
onInit() {
...
},
// 跳轉(zhuǎn)到視頻播放頁面
playVideo() {
router.push({
url: CommonConstants.PLAY_PAGE
});
},
};
視頻播放頁面
視頻播放頁面主要分為標(biāo)題欄、視頻播放區(qū)域和進(jìn)度條三個部分,效果如圖所示:
標(biāo)題欄包括返回圖標(biāo)和“視頻”字樣。
< !-- videoPage.hml -- >
< div class="container" >
< div class="title" >
< image src="{{ playIcons.backSrc }}" onclick="back" >< /image >
< text >{{ $t('strings.play') }}< /text >
< /div >
...
< /div >
// videoPage.js
export default {
data: {
playIcons: {},
...
},
// 初始化數(shù)據(jù)
onInit() {
this.playIcons = CommonConstants.PLAY_ICONS;
...
},
...
};
當(dāng)視頻暫停時,視頻區(qū)域展示暫停圖標(biāo);當(dāng)視頻播放時,視頻區(qū)域暫停圖標(biāo)隱藏,效果如圖所示:
< !-- videoPage.hml -- >
< div class="container" >
...
< video id="video" ... >< /video >
< image class="play-image" show="{{ !isPlay }}" src="{{ playIcons.publicPlayIcon }}" >< /image >
...
< /div >
// videoPage.js
export default {
data: {
playIcons: {},
...
src: '',
...
isPlay: false,
...
},
// 初始化數(shù)據(jù)
onInit() {
this.playIcons = CommonConstants.PLAY_ICONS;
this.src = CommonConstants.VIDEO_SRC;
},
...
};
進(jìn)度條分為播放/暫停圖標(biāo)和進(jìn)度條(進(jìn)度條左邊為當(dāng)前視頻播放時間,進(jìn)度條右邊為視頻總時長)兩部分。
< div class="container" >
...
< div class="progress" >
< div class="image-div" >
< image src="{{ isPlay ? playIcons.pauseIcon : playIcons.playIcon }}" onclick="startOrPause" >< /image >
< /div >
< div class="slider-div" >
< text class="now-time" >
{{ nowTime }}
< /text >
< slider min="{{ sliderMin }}" max="{{ sliderMax }}" value="{{ sliderValue }}"
mode="outset" onchange="change" >< /slider >
< text class="duration-time" >
{{ durationTime }}
< /text >
< /div >
< /div >
< /div >
// videoPage.js
export default {
data: {
playIcons: {},
...
sliderMin: 0,
sliderMax: 100,
sliderValue: 0,
nowTime: '00:00',
duration: 0,
durationTime: '00:00',
isPlay: false,
secondUnit: 60,
zero: '0',
initTime: '00:00',
paddingLen: 2,
milliSeconds: 1000,
...
},
// 初始化數(shù)據(jù)
onInit() {
this.playIcons = CommonConstants.PLAY_ICONS;
...
},
...
};
視頻播放邏輯
視頻播放器可設(shè)置是否靜音播放、視頻路徑、是否自動播放、是否顯示控制欄、是否循環(huán)播放等屬性。
< !-- index.hml -- >
< video id="video"
muted="{{ muted }}"
src="{{ src }}"
autoplay="{{ autoplay }}"
controls="{{ controlShow }}"
loop="{{ loop }}"
...
>
< /video >
// index.js
data: {
...
videoId: 'video', // 播放器id
muted: false, // 是否靜音播放
src: '', // 視頻地址
autoplay: true, // 是否自動播放
controlShow: false, // 是否顯示控制欄
loop: false, // 是否循環(huán)播放
...
},
視頻加載完成后獲取視頻總時長,當(dāng)視頻開始播放后獲取視頻當(dāng)前播放時間(單位:秒)并更新進(jìn)度條的值;拖動進(jìn)度條可設(shè)置視頻播放位置,點(diǎn)擊播放/暫停圖標(biāo)可對視頻進(jìn)行控制。
< !-- index.hml -- >
< video id="video"
...
onprepared="prepared"
onstart="start"
onpause="pause"
onfinish="finish"
ontimeupdate="timeUpdate" >
< /video >
...
< div class="progress" >
< div class="imageDiv" >
< image src="{{ isPlay ? playIcons.pauseIcon : playIcons.playIcon }}" onclick="startOrPause" >< /image >
< /div >
< div class="sliderDiv" >
...
< slider min="{{ sliderMin }}" max="{{ sliderMax }}" value="{{ sliderValue }}"
mode="outset" onchange="change" >< /slider >
...
< /div >
< /div >
// index.js
...
// 視頻準(zhǔn)備完成
prepared(event) {
this.duration = event.duration;
this.durationTime = this.secondToTime(event.duration);
},
// 視頻開始播放
start() {
this.isPlay = true;
},
// 視頻暫停播放
pause() {
this.isPlay = false;
},
// 視頻播放完成
finish() {
setTimeout(() = > {
this.nowTime = this.initTime;
this.sliderValue = this.sliderMin;
}, this.milliSeconds);
},
// 播放進(jìn)度變化
timeUpdate(event) {
if ((this.currentTime != -1) && (this.currentTime !== event.currenttime)) {
return;
}
this.currentTime = -1;
let currSliderValue = event.currenttime / this.duration * this.sliderMax;
this.sliderValue = ((this.sliderValue > currSliderValue) ? this.sliderValue : currSliderValue);
let currTime = this.sliderValue * this.duration / this.sliderMax;
this.nowTime = this.secondToTime(Math.round(currTime));
},
// 暫?;虿シ?/span>
startOrPause() {
if (this.isPlay) {
this.$element(this.videoId).pause();
} else {
this.$element(this.videoId).start();
}
},
// 拖動進(jìn)度條
change(event) {
this.sliderValue = event.progress;
this.currentTime = Math.round(this.duration * event.progress / this.sliderMax);
this.$element(this.videoId).setCurrentTime({
currenttime: this.currentTime
});
},
...
審核編輯 黃宇
-
鴻蒙
+關(guān)注
關(guān)注
57文章
2302瀏覽量
42689 -
HarmonyOS
+關(guān)注
關(guān)注
79文章
1966瀏覽量
29962 -
OpenHarmony
+關(guān)注
關(guān)注
25文章
3635瀏覽量
16061
發(fā)布評論請先 登錄
相關(guān)推薦
評論