媒體子系統是 OpenHarmony 中重要的子系統,可以提供音視頻播放能力。
媒體子系統為開發者提供一套簡單且易于理解的接口,使得開發者能夠方便接入系統并使用系統的媒體資源。
媒體子系統提供以下常用功能如下:
①音視頻播放(AVPlayer9+),AudioPlayer6+ 和 VideoPlayer8+ 整合,升級了狀態機和錯誤碼,推薦使用。
②音視頻錄制(AVRecorder9+),AudioRecorder6+ 和 VideoRecorder9+ 整合,推薦使用。
③音頻播放(AudioPlayer6+),AVPlayer9+ 發布后停止維護,請使用 AVPlayer9+。
④視頻播放(VideoPlayer8+),AVPlayer9+ 發布后停止維護,請使用 AVPlayer9+。
⑤音頻錄制(AudioRecorder6+),AVRecorder9+ 發布后停止維護,請使用 AVRecorder9+。
⑥視頻錄制(VideoRecorder9+),AVRecorder9+ 發布后停止維護,請使用 AVRecorder9+。
從 3.2 開始 OpenHarmony 推出了 AVPlayer 和 AVRecorder 接口,之前的 VideoPlayer、AudioPlayer 這些接口會停止維護,所以我們今天學習下怎么使用 AVPlayer 接口。
導入模塊
importmediafrom'@ohos.multimedia.media';
創建 avplayer:
this.avPlayer=awaitmedia.createAVPlayer()
如上,我們使用的是 promise 接口,對應的接口定義為:
/** *CreatesanAVPlayerinstance. *@since9 *@syscapSystemCapability.Multimedia.Media.AVPlayer *@paramcallbackCallbackusedtoreturnAVPlayerinstanceiftheoperationissuccessful;returnsnullotherwise. *@throws{BusinessError}5400101-Nomemory.Returnbycallback. */ functioncreateAVPlayer(callback:AsyncCallback):void; /** *CreatesanAVPlayerinstance. *@since9 *@syscapSystemCapability.Multimedia.Media.AVPlayer *@returnsAPromiseinstanceusedtoreturnAVPlayerinstanceiftheoperationissuccessful;returnsnullotherwise. *@throws{BusinessError}5400101-Nomemory.Returnbypromise. */ functioncreateAVPlayer():Promise;注冊 avplayer 回調:
//注冊狀態變化回調,不同狀態時做不同動作
avPlayer.on('stateChange',async(state,reason)=>{
……
})
//注冊時間變化回調,方便更新進度條時間
avPlayer.on('timeUpdate',(time:number)=>{
……
})
avplayer 播放流程:
graphLR 賦值avPlayer.url開始播放-->回調進入initialized-->賦值avPlayer.surfaceId-->avPlayer.prepare-->回調進入prepared-->avPlayer.play
//視頻播放偽代碼
asyncavPlayerDemo(){
this.avPlayer.on('stateChange',async(state,reason)=>{
switch(state){
case'idle'://成功調用reset接口后觸發該狀態機上報
console.info(TAG+'stateidlecalled')
this.avPlayer.release()//釋放avplayer對象
break;
case'initialized'://avplayer設置播放源后觸發該狀態上報
console.info(TAG+'stateinitializedcalled')
this.avPlayer.surfaceId=this.surfaceID//設置顯示畫面,當播放的資源為純音頻時無需設置
this.avPlayer.prepare().then(()=>{
console.info(TAG+'preparesuccess');
},(err)=>{
console.error(TAG+'preparefiled,errormessageis:'+err.message)
})
break;
case'prepared'://prepare調用成功后上報該狀態機
console.info(TAG+'statepreparedcalled')
this.avPlayer.play()//調用播放接口開始播放
break;
case'playing'://play成功調用后觸發該狀態機上報
console.info(TAG+'stateplayingcalled')
if(this.count==0){
this.avPlayer.pause()//調用暫停播放接口
}else{
this.avPlayer.seek(10000,media.SeekMode.SEEK_PREV_SYNC)//前向seek置10秒處,觸發seekDone回調函數
}
break;
case'paused'://pause成功調用后觸發該狀態機上報
console.info(TAG+'statepausedcalled')
if(this.count==0){
this.count++
this.avPlayer.play()//繼續調用播放接口開始播放
}
break;
case'completed'://播放結束后觸發該狀態機上報
console.info(TAG+'statecompletedcalled')
this.avPlayer.stop()//調用播放結束接口
break;
case'stopped'://stop接口成功調用后觸發該狀態機上報
console.info(TAG+'statestoppedcalled')
this.avPlayer.reset()//調用reset接口初始化avplayer狀態
break;
case'released':
console.info(TAG+'statereleasedcalled')
break;
case'error':
console.info(TAG+'stateerrorcalled')
break;
default:
console.info(TAG+'unkownstate:'+state)
break;
}
})
//創建avPlayer實例對象
this.avPlayer=awaitmedia.createAVPlayer()
letfdPath='fd://'
letpathDir="/data/storage/el2/base/haps/entry/files"http://pathDir在FA模型和Stage模型的獲取方式不同,請參考開發步驟首行的說明,根據實際情況自行獲取。
//path路徑的碼流可通過"hdcfilesendD:xxxH264_AAC.mp4/data/app/el2/100/base/ohos.acts.multimedia.media.avplayer/haps/entry/files"命令,將其推送到設備上
letpath=pathDir+'/H264_AAC.mp4'
letfile=awaitfs.open(path)
fdPath=fdPath+''+file.fd
//賦值url后就會進入stateChangecallback
this.avPlayer.url=fdPath
}
其他播放控制接口:
/**
*Prepareaudio/videoplayback,itwillrequestresourceforplaying.
*@since9
*@syscapSystemCapability.Multimedia.Media.AVPlayer
*@paramcallbackAcallbackinstanceusedtoreturnwhenpreparecompleted.
*@throws{BusinessError}5400102-Operationnotallowed.Returnbycallback.
*@throws{BusinessError}5400106-Unsupportformat.Returnbycallback.
*/
prepare(callback:AsyncCallback):void;
/**
*Prepareaudio/videoplayback,itwillrequestresourceforplaying.
*@since9
*@syscapSystemCapability.Multimedia.Media.AVPlayer
*@returnsAPromiseinstanceusedtoreturnwhenpreparecompleted.
*@throws{BusinessError}5400102-Operationnotallowed.Returnbypromise.
*@throws{BusinessError}5400106-Unsupportformat.Returnbypromise.
*/
prepare():Promise;
/**
*Playaudio/videoplayback.
*@since9
*@syscapSystemCapability.Multimedia.Media.AVPlayer
*@paramcallbackAcallbackinstanceusedtoreturnwhenplaycompleted.
*@throws{BusinessError}5400102-Operationnotallowed.Returnbycallback.
*/
play(callback:AsyncCallback):void;
/**
*Playaudio/videoplayback.
*@since9
*@syscapSystemCapability.Multimedia.Media.AVPlayer
*@returnsAPromiseinstanceusedtoreturnwhenplaycompleted.
*@throws{BusinessError}5400102-Operationnotallowed.Returnbypromise.
*/
play():Promise;
/**
*Pauseaudio/videoplayback.
*@since9
*@syscapSystemCapability.Multimedia.Media.AVPlayer
*@paramcallbackAcallbackinstanceusedtoreturnwhenpausecompleted.
*@throws{BusinessError}5400102-Operationnotallowed.Returnbycallback.
*/
pause(callback:AsyncCallback):void;
/**
*Pauseaudio/videoplayback.
*@since9
*@syscapSystemCapability.Multimedia.Media.AVPlayer
*@returnsAPromiseinstanceusedtoreturnwhenpausecompleted.
*@throws{BusinessError}5400102-Operationnotallowed.Returnbypromise.
*/
pause():Promise;
/**
*Stopaudio/videoplayback.
*@since9
*@syscapSystemCapability.Multimedia.Media.AVPlayer
*@paramcallbackAcallbackinstanceusedtoreturnwhenstopcompleted.
*@throws{BusinessError}5400102-Operationnotallowed.Returnbycallback.
*/
stop(callback:AsyncCallback):void;
/**
*Stopaudio/videoplayback.
*@since9
*@syscapSystemCapability.Multimedia.Media.AVPlayer
*@returnsAPromiseinstanceusedtoreturnwhenstopcompleted.
*@throws{BusinessError}5400102-Operationnotallowed.Returnbypromise.
*/
stop():Promise;
/**
*ResetAVPlayer,itwilltoidlestateandcansetsrcagain.
*@since9
*@syscapSystemCapability.Multimedia.Media.AVPlayer
*@paramcallbackAcallbackinstanceusedtoreturnwhenresetcompleted.
*@throws{BusinessError}5400102-Operationnotallowed.Returnbycallback.
*/
reset(callback:AsyncCallback):void;
/**
*ResetAVPlayer,itwilltoidlestateandcansetsrcagain.
*@since9
*@syscapSystemCapability.Multimedia.Media.AVPlayer
*@returnsAPromiseinstanceusedtoreturnwhenresetcompleted.
*@throws{BusinessError}5400102-Operationnotallowed.Returnbypromise.
*/
reset():Promise;
/**
*ReleasesresourcesusedforAVPlayer.
*@since9
*@syscapSystemCapability.Multimedia.Media.AVPlayer
*@paramcallbackAcallbackinstanceusedtoreturnwhenreleasecompleted.
*@throws{BusinessError}5400102-Operationnotallowed.Returnbycallback.
*/
release(callback:AsyncCallback):void;
/**
*ReleasesresourcesusedforAVPlayer.
*@since9
*@syscapSystemCapability.Multimedia.Media.AVPlayer
*@returnsAPromiseinstanceusedtoreturnwhenreleasecompleted.
*@throws{BusinessError}5400102-Operationnotallowed.Returnbypromise.
*/
release():Promise;
/**
*Jumpstothespecifiedplaybackposition.
*@since9
*@syscapSystemCapability.Multimedia.Media.AVPlayer
*@paramtimeMsPlaybackpositiontojump,shouldbein[0,duration].
*@parammodeSee@SeekMode.
*/
seek(timeMs:number,mode?void;
其他回調接口:
/** *Registerorunregisterlistensformediaplaybackevents. *@since9 *@syscapSystemCapability.Multimedia.Media.AVPlayer *@paramtypeTypeoftheplaybackeventtolistenfor. *@paramcallbackCallbackusedtolistenfortheplaybackstateChangeevent. */ on(type:'stateChange',callback:(state:AVPlayerState,reason:StateChangeReason)=>void):void; off(type:'stateChange'):void; /** *Registerorunregisterlistensformediaplaybackevents. *@since9 *@syscapSystemCapability.Multimedia.Media.AVPlayer *@paramtypeTypeoftheplaybackeventtolistenfor. *@paramcallbackCallbackusedtolistenfortheplaybackvolumeevent. */ on(type:'volumeChange',callback:Callback):void; off(type:'volumeChange'):void; /** *Registerorunregisterlistensformediaplaybackevents. *@since9 *@syscapSystemCapability.Multimedia.Media.AVPlayer *@paramtypeTypeoftheplaybackeventtolistenfor. *@paramcallbackCallbackusedtolistenfortheplaybackendofstream */ on(type:'endOfStream',callback:Callback):void; off(type:'endOfStream'):void; /** *Registerorunregisterlistensformediaplaybackevents. *@since9 *@syscapSystemCapability.Multimedia.Media.AVPlayer *@paramtypeTypeoftheplaybackeventtolistenfor. *@paramcallbackCallbackusedtolistenfortheplaybackseekDoneevent. */ on(type:'seekDone',callback:Callback):void; off(type:'seekDone'):void; /** *Registerorunregisterlistensformediaplaybackevents. *@since9 *@syscapSystemCapability.Multimedia.Media.AVPlayer *@paramtypeTypeoftheplaybackeventtolistenfor. *@paramcallbackCallbackusedtolistenfortheplaybackspeedDoneevent. */ on(type:'speedDone',callback:Callback):void; off(type:'speedDone'):void; /** *Registerorunregisterlistensformediaplaybackevents. *@since9 *@syscapSystemCapability.Multimedia.Media.AVPlayer *@paramtypeTypeoftheplaybackeventtolistenfor. *@paramcallbackCallbackusedtolistenfortheplaybacksetBitrateDoneevent. */ on(type:'bitrateDone',callback:Callback):void; off(type:'bitrateDone'):void; /** *LRegisterorunregisterlistensformediaplaybackevents. *@since9 *@syscapSystemCapability.Multimedia.Media.AVPlayer *@paramtypeTypeoftheplaybackeventtolistenfor. *@paramcallbackCallbackusedtolistenfortheplaybacktimeUpdateevent. */ on(type:'timeUpdate',callback:Callback):void; off(type:'timeUpdate'):void; /** *Registerorunregisterlistensformediaplaybackevents. *@since9 *@syscapSystemCapability.Multimedia.Media.AVPlayer *@paramtypeTypeoftheplaybackeventtolistenfor. *@paramcallbackCallbackusedtolistenfortheplaybackdurationUpdateevent. */ on(type:'durationUpdate',callback:Callback):void; off(type:'durationUpdate'):void; /** *Registerorunregisterlistensforvideoplaybackbufferingevents. *@since9 *@syscapSystemCapability.Multimedia.Media.AVPlayer *@paramtypeTypeoftheplaybackbufferingupdateeventtolistenfor. *@paramcallbackCallbackusedtolistenforthebufferingupdateevent,returnBufferingInfoTypeandthevalue. */ on(type:'bufferingUpdate',callback:(infoType:BufferingInfoType,value:number)=>void):void; off(type:'bufferingUpdate'):void; /** *Registerorunregisterlistensforstartrendervideoframeevents. *@since9 *@syscapSystemCapability.Multimedia.Media.AVPlayer *@paramtypeTypeoftheplaybackeventtolistenfor. *@paramcallbackCallbackusedtolistenfortheplaybackeventreturn. */ on(type:'startRenderFrame',callback:Callback):void; off(type:'startRenderFrame'):void; /** *Registerorunregisterlistensforvideosizechangeevent. *@since9 *@syscapSystemCapability.Multimedia.Media.AVPlayer *@paramtypeTypeoftheplaybackeventtolistenfor. *@paramcallbackCallbackusedtolistenfortheplaybackeventreturnvideosize. */ on(type:'videoSizeChange',callback:(width:number,height:number)=>void):void; off(type:'videoSizeChange'):void; /** *Registerorunregisterlistensforaudiointerruptevent,referto{@link#audio.InterruptEvent} *@since9 *@syscapSystemCapability.Multimedia.Media.AVPlayer *@paramtypeTypeoftheplaybackeventtolistenfor. *@paramcallbackCallbackusedtolistenfortheplaybackeventreturnaudiointerruptinfo. */ on(type:'audioInterrupt',callback:(info:audio.InterruptEvent)=>void):void; off(type:'audioInterrupt'):void; /** *RegisterorunregisterlistensforavailablebitratelistcollectcompletedeventsforHLSprotocolstreamplayback. *Thiseventwillbereportedafterthe{@link#prepare}called. *@since9 *@syscapSystemCapability.Multimedia.Media.AVPlayer *@paramtypeTypeoftheplaybackeventtolistenfor. *@paramcallbackCallbackusedtolistenfortheplaybackeventreturnavailablebitratelist. */ on(type:'availableBitrates',callback:(bitrates:Array)=>void):void; off(type:'availableBitrates'):void;
簡單樣例
界面:
build(){
Stack({alignContent:Alignment.Center}){
if(this.isShowMenu){
Column(){
//視頻名稱
PlayTitle({title:this.displayName,handleBack:this.handleBack})
Row(){
//播放控件
PreVideo({handleClick:this.handlePrevClick})
PlayButton({isPlaying:$isPlaying})
NextVideo({handleClick:this.handleNextClick})
}
.margin({top:'40%'})
Blank()
//時間刻度
Row(){
Text(getTimeString(this.currentTime))
.fontSize(25)
.fontColor(Color.White)
Blank()
Text(this.fileAsset?getTimeString(this.fileAsset.duration):'00:00')
.fontSize(25)
.fontColor(Color.White)
}
.width('95%')
//進度條
Slider({value:this.fileAsset?this.currentTime/this.fileAsset.duration*100:0})
.width('92%')
.selectedColor(Color.White)
.onChange((value:number)=>{
Logger.info(TAG,'seektimechange')
this.currentTime=this.fileAsset.duration*value/100
this.videoPlayer.seek(this.currentTime)
})
}
.height('100%')
.zIndex(2)
}
Row(){
XComponent({
id:'componentId',
type:'surface',
controller:this.mxcomponentController
})
.onLoad(()=>{
Logger.info(TAG,'onLoadiscalled')
this.playVideo()
})
.width('100%')
.aspectRatio(this.ratio)
}
.height('100%')
.width('100%')
.justifyContent(FlexAlign.Center)
}
.width('100%')
.height('100%')
.backgroundColor(Color.Black)
.onClick(()=>{
this.isShowMenu=!this.isShowMenu
})
}
播放:
//根據視頻文件獲取視頻源尺寸并生成surface
//視頻文件的路徑在/storage/media/100/local/files/Videos
asyncprepareVideo(){
this.ratio=this.fileAsset.width/this.fileAsset.height
this.mxcomponentController.setXComponentsurfaceSize({
surfaceWidth:this.fileAsset.width,
surfaceHeight:this.fileAsset.height
})
this.surfaceId=this.mxcomponentController.getXComponentsurfaceId()
this.fd=awaitthis.fileAsset.open('Rw')
Logger.info(TAG,`fd://'${this.fd}`)
return'fd://'+this.fd
}
//初始化視頻文件并初始化avplayer
asyncplayVideo(){
Logger.info(TAG,'playVideo')
try{
awaitthis.getMediaList()
letfdPath=awaitthis.prepareVideo()
this.videoPlayer.on('timeUpdate',(time:number)=>{
console.info('timeUpdatesuccess,andnewtimeis:'+time)
this.currentTime=time;
})
awaitthis.videoPlayer.initVideoPlayer(fdPath,this.surfaceId)
this.isPlaying=true
}catch(error){
Logger.info(TAG,`playVideoerror${JSON.stringify(error)}`)
}
}
小結
參考鏈接:
https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis/js-apis-media.md#play9
審核編輯:湯梓紅
-
接口
+關注
關注
33文章
9521瀏覽量
157044 -
音視頻
+關注
關注
4文章
594瀏覽量
31385 -
視頻播放器
+關注
關注
0文章
33瀏覽量
12191 -
鴻蒙
+關注
關注
60文章
2963瀏覽量
45905 -
OpenHarmony
+關注
關注
33文章
3952瀏覽量
21104
原文標題:鴻蒙上制作一個視頻播放器
文章出處:【微信號:gh_834c4b3d87fe,微信公眾號:OpenHarmony技術社區】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
鴻蒙上制作一個視頻播放器
評論