介紹
OhosVideoCache是一個支持邊播放邊緩存的庫,只需要將音視頻的url傳遞給OhosVideoCache處理之后再設置給播放器,
OhosVideoCache就可以一邊下載音視頻數據并保存在本地,一邊讀取本地緩存返回給播放器,使用者無需進行其他操作。
效果圖預覽
使用說明:
- 進入頁面,自動播放視頻,點擊暫停,視頻停止播放,點擊播放,視頻繼續播放。
- 視頻播放完成之后,點擊播放按鈕,視頻重新播放。
實現思路
邊緩存播放功能主要是通過Xcomponent組件、@ohos.multimedia.media以及OhosVideoCache三方庫實現,XComponent組件主要用于繪制
視頻播放的窗口,頁面進來初始化服務器然后利用XComponent組件的onLoad函數來調用VideoPlayerManager
中的initPlayer方法創建一個音視頻管理實例,并通過setAVPlayerCallback函數和cacheAndPlayVideo函數來實現視頻狀態的監聽以及邊緩存邊播放功能。
- XComponent組件繪制視頻播放窗口。源碼參考VideoCacheView.ets。
XComponent({id: 'xcomponent',type: 'surface',controller: this.componentController
}).height(`${this.xComponentHeight}px`).width(`${this.xComponentWidth}px`).onLoad(() => {// 設置XComponent持有Surface的寬度和高度this.componentController.setXComponentSurfaceSize({surfaceWidth: SURFACE_WIDTH,surfaceHeight: SURFACE_HEIGHT});this.surfaceId = this.componentController.getXComponentSurfaceId();// 創建音視頻播放實例AvPlayManager.getInstance().initPlayer(getContext(this) as common.UIAbilityContext, this.surfaceId, (avPlayer: media.AVPlayer) => {avPlayer.on('timeUpdate', (time: number) => {this.currentTime = time;});this.videoDuration = handleTime(avPlayer.duration);this.total = avPlayer.duration;})})
- 初始化代理服務器,頁面一進來需要使用setServer方法來初始化代理服務器,以便后續調用此服務器處理url。源碼參考GlobalProxyServer.ets
import common from '@ohos.app.ability.common';
import { HttpProxyCacheServer } from '@ohos/video-cache';const CONTEXT_STR: string = 'context';
const SERVER_STR: string = 'server';export default class GlobalProxyServer {private static instance: GlobalProxyServer | null = null;private objects: Map<string, Object | null> = new Map<string, Object | null>();public static getInstance(): GlobalProxyServer {if (!GlobalProxyServer.instance) {GlobalProxyServer.instance = new GlobalProxyServer();}return GlobalProxyServer.instance;}/*** 獲取上下文信息* @returns*/getContext(): common.UIAbilityContext {return this.objects.get(CONTEXT_STR) as common.UIAbilityContext;}/*** 設置上下文信息* @param context*/setContext(context: common.UIAbilityContext): void {this.objects.set(CONTEXT_STR, context);}/*** 獲取服務器* @returns*/getServer(): HttpProxyCacheServer {return this.objects.get(SERVER_STR) as HttpProxyCacheServer;}/*** 設置服務器* @param objectClass*/setServer(objectClass: HttpProxyCacheServer): void {try {const currentServer: HttpProxyCacheServer = this.getServer();currentServer.shutdown();} catch (err) {}this.objects.set(SERVER_STR, objectClass);}
}
- media.createAVPlayer()創建播放管理類,用于管理和播放媒體資源。源碼參考VideoPlayerManager.ets
async initPlayer(context: common.UIAbilityContext, surfaceId: string,callback: (avPlayer: media.AVPlayer) => void): Promise<void> {logger.info(TAG, `initPlayer==initCamera surfaceId== ${surfaceId}`);this.surfaceID = surfaceId;try {// 創建avPlayer實例對象this.avPlayer = await media.createAVPlayer();// 創建狀態機變化回調函數await this.setAVPlayerCallback(callback);// 邊緩存邊播放this.cacheAndPlayVideo(context);} catch (err) {logger.error(TAG, `initPlayer initPlayer err:${JSON.stringify(err)}`);}}
- 邊播放邊緩存,MyCacheListener監聽緩存進度,getProxyUrl(ORIGIN_URL)獲取視頻播放地址并設置給播放器。源碼參考VideoPlayerManager.ets
/*** 邊緩存邊監聽函數* @param context 上下文信息* @returns*/async cacheAndPlayVideo(context: common.UIAbilityContext): Promise<void> {logger.info(TAG, `cacheAndPlayVideo start`);// TODO:知識點:監聽緩存進度class MyCacheListener implements CacheListener {onCacheAvailable(cacheFilePath: string, url: string, percentsAvailable: number): void {AppStorage.setOrCreate('currentCachePercent', percentsAvailable);}}GlobalProxyServer?.getInstance()?.getServer()?.registerCacheListener(new MyCacheListener(), ORIGIN_URL);// TODO:知識點:將原始的音視頻url交給OhosVideoCachelet proxyUrl: string | undefined = await GlobalProxyServer?.getInstance()?.getServer()?.getProxyUrl(ORIGIN_URL);// 由于avplayer不支持直接加載本地文件路徑 這里需要轉化為fd的路徑if (proxyUrl.startsWith(context.cacheDir)) {const file = fs.openSync(proxyUrl, fs.OpenMode.READ_ONLY);proxyUrl = `fd://${file.fd}`;}logger.info(TAG, `proxyUrl ${proxyUrl}`);// 將處理之后的url設置給播放器this.avPlayer.url = proxyUrl;}
高性能知識點
不涉及。
工程結構&模塊類型
videocache // har類型
|---model
| |---GlobalProxyServer.ets // 模型層-服務器管理
| |---VideoPlayerManager.ets // 模型層-音視頻管理
|---utils
| |---utils.ets // 工具
|---view
| |---VideoCacheView.ets // 視圖層-應用主頁面
模塊依賴
本實例依賴common模塊來實現日志的打印、資源
的調用、動態路由模塊來實現頁面的動態加載以及video-cache,版本為1.0.0。
參考資料
音視頻管理
鴻蒙全棧開發全新學習指南
為了讓大家都能學習到鴻蒙開發最新的技術,針對一些在職人員、0基礎小白、應屆生/計算機專業、鴻蒙愛好者等人群,整理了一套純血版鴻蒙(HarmonyOS Next)全棧開發技術的學習路線【包含了大廠APP實戰項目開發】。
本路線共分為四個階段:
第一階段:鴻蒙初中級開發必備技能
第二階段:鴻蒙南北雙向高工技能基礎:gitee.com/MNxiaona/733GH
第三階段:應用開發中高級就業技術
第四階段:全網首發-工業級南向設備開發就業技術:gitee.com/MNxiaona/733GH
《鴻蒙 (Harmony OS)開發學習手冊》(共計892頁)
如何快速入門?
1.基本概念
2.構建第一個ArkTS應用
3.……
開發基礎知識:gitee.com/MNxiaona/733GH
1.應用基礎知識
2.配置文件
3.應用數據管理
4.應用安全管理
5.應用隱私保護
6.三方應用調用管控機制
7.資源分類與訪問
8.學習ArkTS語言
9.……
基于ArkTS 開發
1.Ability開發
2.UI開發
3.公共事件與通知
4.窗口管理
5.媒體
6.安全
7.網絡與鏈接
8.電話服務
9.數據管理
10.后臺任務(Background Task)管理
11.設備管理
12.設備使用信息統計
13.DFX
14.國際化開發
15.折疊屏系列
16.……
鴻蒙開發面試真題(含參考答案):gitee.com/MNxiaona/733GH
鴻蒙入門教學視頻:
美團APP實戰開發教學:gitee.com/MNxiaona/733GH
寫在最后
- 如果你覺得這篇內容對你還蠻有幫助,我想邀請你幫我三個小忙:
- 點贊,轉發,有你們的 『點贊和評論』,才是我創造的動力。
- 關注小編,同時可以期待后續文章ing🚀,不定期分享原創知識。
- 想要獲取更多完整鴻蒙最新學習資源,請移步前往小編:
gitee.com/MNxiaona/733GH