疑難雜癥攻克--自定義JS視頻播放器控制欄全屏問題解決
??想了解更多關(guān)于開源的內(nèi)容,請(qǐng)?jiān)L問:??
前言
在做一個(gè)HarmonyOS應(yīng)用項(xiàng)目的時(shí)候,需要自定義播放器(這里選用的js組件),發(fā)現(xiàn)沒法在自定義播放器控制欄上做全屏播放的功能,翻遍官網(wǎng)和百度都沒法找到答案,并且發(fā)現(xiàn)之前有博主寫到了自定義播放器時(shí),這個(gè)全屏問題作為遺留問題一直沒解決,那么我只好想辦法攻克了,足足花了五六個(gè)小時(shí)才搞定。
核心疑難雜癥
在自定義視頻播放器控制欄的時(shí)候,播放、暫停、進(jìn)度條、時(shí)長顯示、倍速等功能都好實(shí)現(xiàn),但是在全屏的時(shí)候,我們發(fā)現(xiàn)問題就來了。在做這些自定義功能的時(shí)候,我們肯定要優(yōu)先看官方文檔提供的API支持,下表是官方的API支持。
從中可以看出只需要調(diào)用requestFullScreen這個(gè)api即可請(qǐng)求全屏播放,但是調(diào)用之后會(huì)發(fā)現(xiàn)自己定義的控制欄就沒有辦法顯示出來了。
解決思路:
曾經(jīng)想過的解決方案:
(1)修改requestFullScreen方法的底層源碼,重新編譯一個(gè)sdk出來。
HarmonyOS上這塊沒有開源,不用想了。
(2)自定義的控制欄沒有顯示出來會(huì)不會(huì)是因?yàn)槿敛シ诺臅r(shí)候控制欄和視頻的圖層層級(jí)關(guān)系導(dǎo)致控制欄被遮擋了?結(jié)果通過各種設(shè)置z-index,發(fā)現(xiàn)也無法解決,放棄了,更換其它思路。
前面兩種一直都是陷入到了依賴官方提供的requestFullScreen方法去進(jìn)行全屏,思維被限制住了,繼續(xù)圍繞這個(gè)發(fā)現(xiàn)怎么也弄不出來。于是需要切換下思路,如果不用官方的這個(gè)api該如何實(shí)現(xiàn)全屏呢?
拋棄自帶api之后,我想到的實(shí)現(xiàn)播放器全屏并且能顯示自定義控制欄和隱藏自定義控制欄需要下面幾步:
(1)video組件和自定義控制欄所在的div組件包裹在stack組件進(jìn)行布局。
(2)在data中設(shè)定stack組件寬度和高度需要的變量,半屏或全屏的時(shí)候會(huì)修改該值。
(3)全屏的時(shí)候需要先切換屏幕為橫屏方向,然后講stack組件的寬度和高度都設(shè)置為100%,同時(shí)還需要隱藏頁面中其它所有的組件。切換半屏的時(shí)候需要將屏幕切回豎屏,然后將寬度和高度都設(shè)置為全屏之前的值,并且顯示頁面中的所有其他組件。這里還可以在做下延伸,針對(duì)視頻源的寬高比進(jìn)行判斷,如果寬度大于高度則切成橫屏狀態(tài)的全屏模式,如果寬度小于高度,則是采用豎屏下的全屏模式。
(4)切換全屏還需要將系統(tǒng)自帶的狀態(tài)欄設(shè)置為隱藏,切換成半屏的時(shí)候在將狀態(tài)欄顯示出來。
后面我就沿著這個(gè)思路去想辦法解決了,第(1)和第(2)步很簡單,不過多介紹。第(3)步中要求一個(gè)核心技術(shù)點(diǎn)就是需要找到切換橫豎屏的api,然后去查看官方api文檔發(fā)現(xiàn)js沒有切換橫豎屏的api,那么咋辦呢?難道又要放棄嗎。No,這個(gè)時(shí)候可以想想java是否具備橫豎屏切換的api,結(jié)果發(fā)現(xiàn)java中是具備的,如下:
//切換橫屏
abilityContext.setDisplayOrientation(AbilityInfo.DisplayOrientation.LANDSCAPE);
//切換豎屏
abilityContext.setDisplayOrientation(AbilityInfo.DisplayOrientation.PORTRAIT);
說到這里,大家就應(yīng)該知道如何做了吧,利用js和java混合開發(fā)即可,關(guān)于混合開發(fā)的細(xì)節(jié)我就不在本文中詳細(xì)講解了。
第(4)步中,顯示和隱藏系統(tǒng)狀態(tài)欄目前js直接有api可以實(shí)現(xiàn),如下:
windowClass.setFullScreen(!this.isFullScreen, (err, data) => {
if (err) {
console.error('Failed to enable the full-screen mode. Cause: ' + JSON.stringify(err));
return;
}
console.info('Succeeded in enabling the full-screen mode. Data: ' + JSON.stringify(data));
});
同時(shí),我們應(yīng)該需要關(guān)閉app自帶的標(biāo)題欄,這個(gè)只需要在config.json中加入如下配置即可。
"module": {
//...
"metaData" : {
"customizeData" : [
{
"name": "hwc-theme",
"value": "androidhwext:style/Theme.Emui.NoTitleBar"
}
]
},
//...
}
復(fù)制這里還有個(gè)重點(diǎn)需要強(qiáng)調(diào),就是我們會(huì)在data中設(shè)置各種變量用來記錄播放狀態(tài)、進(jìn)度、全屏狀態(tài)等,而在橫豎屏進(jìn)行切換時(shí),默認(rèn)是會(huì)導(dǎo)致FA的生命周期重繪的,那么就會(huì)導(dǎo)致data中的所有變量會(huì)被重新初始化,于是為了防止生命周期重繪,請(qǐng)務(wù)必在config.json中給需要的FA添加如下配置:
"abilities": [
{
"configChanges": ["orientation"],
//....
}
//....
]
最后附上半屏和全屏的效果圖: