OpenHarmony3.1新特性-surface+videoplayer實現(xiàn)視頻播放
??51CTO OpenHarmony技術(shù)社區(qū)??
千呼萬喚始出來,在OpenHarmony最新發(fā)布的3.1版本中終于支持了surface+videoplayer實現(xiàn)視頻播放的功能。
1、 surface+videoplayer視頻播放與傳統(tǒng)的video組件對比
大家可能覺得不是很早就支持一個video組件就可以實現(xiàn)視頻播放嗎?是的,video組件也就簡簡單單能做個視頻播放,而你仔細(xì)去查閱下,video組件支持的api功能太少了,很多定制化功能都無法實現(xiàn)。下面是3.1版本上video組件所具備的api:
而在3.1中添加了一個關(guān)鍵組件就是xcomponent,它可以設(shè)置一個type為surface,而我更關(guān)心的就是這個surface,在講surface之前我先講講videoplayer。
3.1版本中同時還新增了視頻播放的媒體服務(wù)videoplayer,它為我們提供了視頻播放服務(wù)相關(guān)的各種api,video組件所具備的功能它全部具備,同時還具備視頻首幀送顯上報事件、監(jiān)聽視頻播放寬高變化事件、監(jiān)聽視頻緩存更新事件等等高級功能,這樣就可以幫助我們自定義出非常高級的視頻播放器出來了。
而videoplayer它只是個做視頻播放的媒體服務(wù),它并不能直接項video組件那樣輸出視頻顯示在顯示器上,這個時候就需要借助surface了。Surface可以簡單的理解為繪制時用的畫布,在hml布局文件中添加一個xcomponent組件并設(shè)置type為surface,就相當(dāng)于放置了一塊畫布。而surface在程序中可以抽象為一塊內(nèi)存,在js代碼中xcomponent組件通過調(diào)用getXComponentSurfaceId()方法可以申請這塊內(nèi)存,然后就可以隨意的繪制,videoplayer在完成視頻的編解碼服務(wù)之后,可以通過調(diào)用setDisplaySurface這個方法將視頻內(nèi)容輸出到之前的surface內(nèi)存中,從而達(dá)到最終視頻在窗口上顯示的功能。下圖是基本架構(gòu)圖
2、 surface+videoplayer視頻播放代碼實現(xiàn)
下面只實現(xiàn)一個最基礎(chǔ)的視頻播放功能。
首先是編寫hml布局文件,代碼如下:
<div class="container">
<xcomponent id="Xcomponent" type='surface' onload='LoadXcomponent'
style="width : 400px; height : 200px; border-color : red; border-width : 5px;"></xcomponent>
</div>
然后編寫js文件,代碼如下:
import media from '@ohos.multimedia.media'
import fileIO from '@ohos.fileio'
let videoPlayer = undefined;
let surfaceID = undefined; // 用于保存Xcomponent接口返回的surfaceID
export default {
data: {
title: ""
},
onInit() {
},
// 調(diào)用Xcomponent的接口用于獲取surfaceID,并保存在surfaceID變量中,該接口由XComponent組件默認(rèn)加載,非主動調(diào)用
async LoadXcomponent() {
surfaceID = this.$element('Xcomponent').getXComponentSurfaceId();
console.info('LoadXcomponent surfaceID is' + surfaceID);
// 用戶選擇視頻設(shè)置fd(本地播放)
let fdPath = 'fd://';
// path路徑的碼流可通過"hdc file send D:\xxx\01.mp3 /data/accounts/account_0/appdata" 命令,將其推送到設(shè)備上
let path = '/data/accounts/account_0/appdata/1.mp4';
await fileIO.open(path).then(fdNumber => {
fdPath = fdPath + '' + fdNumber;
console.info('open fd sucess fd is' + fdPath);
}, err => {
console.info('open fd failed err is' + err);
});
await media.createVideoPlayer().then((video) => {
if (typeof (video) != 'undefined') {
videoPlayer = video;
console.info('video createVideoPlayer success');
} else {
console.info('video createVideoPlayer fail');
}
}).catch((error) => {
console.info(`video catchCallback, error:${error.message}`);
});
videoPlayer.url = fdPath;
console.info('video url success');
// 設(shè)置surfaceID用于顯示視頻畫面
await videoPlayer.setDisplaySurface(surfaceID).then(() => {
console.info('setDisplaySurface success');
}).catch((error) => {
console.info(`video catchCallback, error:${error.message}`);
});
// 調(diào)用prepare完成播放前準(zhǔn)備工作
await videoPlayer.prepare().then(() => {
console.info('prepare success');
}).catch((error) => {
console.info(`video catchCallback, error:${error.message}`);
});
// 調(diào)用play開始播放
await videoPlayer.play().then(() => {
console.info('play success');
}).catch((error) => {
console.info(`video catchCallback, error:${error.message}`);
});
},
}
??51CTO OpenHarmony技術(shù)社區(qū)??