W3Cschool
恭喜您成為首批注冊(cè)用戶(hù)
獲得88經(jīng)驗(yàn)值獎(jiǎng)勵(lì)
使用AVPlayer可以實(shí)現(xiàn)端到端播放原始媒體資源,本開(kāi)發(fā)指導(dǎo)將以完整地播放一首音樂(lè)作為示例,向開(kāi)發(fā)者講解AVPlayer音頻播放相關(guān)功能。
播放的全流程包含:創(chuàng)建AVPlayer,設(shè)置播放資源,設(shè)置播放參數(shù)(音量/倍速/焦點(diǎn)模式),播放控制(播放/暫停/跳轉(zhuǎn)/停止),重置,銷(xiāo)毀資源。
在進(jìn)行應(yīng)用開(kāi)發(fā)的過(guò)程中,開(kāi)發(fā)者可以通過(guò)AVPlayer的state屬性主動(dòng)獲取當(dāng)前狀態(tài)或使用on('stateChange')方法監(jiān)聽(tīng)狀態(tài)變化。如果應(yīng)用在音頻播放器處于錯(cuò)誤狀態(tài)時(shí)執(zhí)行操作,系統(tǒng)可能會(huì)拋出異常或生成其他未定義的行為。
狀態(tài)的詳細(xì)說(shuō)明請(qǐng)參考AVPlayerState。當(dāng)播放處于prepared / playing / paused / completed狀態(tài)時(shí),播放引擎處于工作狀態(tài),這需要占用系統(tǒng)較多的運(yùn)行內(nèi)存。當(dāng)客戶(hù)端暫時(shí)不使用播放器時(shí),調(diào)用reset()或release()回收內(nèi)存資源,做好資源利用。
詳細(xì)的API說(shuō)明請(qǐng)參考AVPlayer API參考。
事件類(lèi)型 | 說(shuō)明 |
---|---|
stateChange | 必要事件,監(jiān)聽(tīng)播放器的state屬性改變。 |
error | 必要事件,監(jiān)聽(tīng)播放器的錯(cuò)誤信息。 |
durationUpdate | 用于進(jìn)度條,監(jiān)聽(tīng)進(jìn)度條長(zhǎng)度,刷新資源時(shí)長(zhǎng)。 |
timeUpdate | 用于進(jìn)度條,監(jiān)聽(tīng)進(jìn)度條當(dāng)前位置,刷新當(dāng)前時(shí)間。 |
seekDone | 響應(yīng)API調(diào)用,監(jiān)聽(tīng)seek()請(qǐng)求完成情況。 當(dāng)使用seek()跳轉(zhuǎn)到指定播放位置后,如果seek操作成功,將上報(bào)該事件。 |
speedDone | 響應(yīng)API調(diào)用,監(jiān)聽(tīng)setSpeed()請(qǐng)求完成情況。 當(dāng)使用setSpeed()設(shè)置播放倍速后,如果setSpeed操作成功,將上報(bào)該事件。 |
volumeChange | 響應(yīng)API調(diào)用,監(jiān)聽(tīng)setVolume()請(qǐng)求完成情況。 當(dāng)使用setVolume()調(diào)節(jié)播放音量后,如果setVolume操作成功,將上報(bào)該事件。 |
bufferingUpdate | 用于網(wǎng)絡(luò)播放,監(jiān)聽(tīng)網(wǎng)絡(luò)播放緩沖信息,用于上報(bào)緩沖百分比以及緩存播放進(jìn)度。 |
audioInterrupt | 監(jiān)聽(tīng)音頻焦點(diǎn)切換信息,搭配屬性audioInterruptMode使用。 如果當(dāng)前設(shè)備存在多個(gè)音頻正在播放,音頻焦點(diǎn)被切換(即播放其他媒體如通話(huà)等)時(shí)將上報(bào)該事件,應(yīng)用可以及時(shí)處理。 |
下面代碼示例中的url僅作示意使用,開(kāi)發(fā)者需根據(jù)實(shí)際情況,確認(rèn)資源有效性并設(shè)置:
- import media from '@ohos.multimedia.media';
- import fs from '@ohos.file.fs';
- import common from '@ohos.app.ability.common';
- export class AVPlayerDemo {
- private avPlayer;
- private count: number = 0;
- // 注冊(cè)avplayer回調(diào)函數(shù)
- setAVPlayerCallback() {
- // seek操作結(jié)果回調(diào)函數(shù)
- this.avPlayer.on('seekDone', (seekDoneTime) => {
- console.info(`AVPlayer seek succeeded, seek time is ${seekDoneTime}`);
- })
- // error回調(diào)監(jiān)聽(tīng)函數(shù),當(dāng)avPlayer在操作過(guò)程中出現(xiàn)錯(cuò)誤時(shí)調(diào)用reset接口觸發(fā)重置流程
- this.avPlayer.on('error', (err) => {
- console.error(`Invoke avPlayer failed, code is ${err.code}, message is ${err.message}`);
- this.avPlayer.reset(); // 調(diào)用reset重置資源,觸發(fā)idle狀態(tài)
- })
- // 狀態(tài)機(jī)變化回調(diào)函數(shù)
- this.avPlayer.on('stateChange', async (state, reason) => {
- switch (state) {
- case 'idle': // 成功調(diào)用reset接口后觸發(fā)該狀態(tài)機(jī)上報(bào)
- console.info('AVPlayer state idle called.');
- this.avPlayer.release(); // 調(diào)用release接口銷(xiāo)毀實(shí)例對(duì)象
- break;
- case 'initialized': // avplayer 設(shè)置播放源后觸發(fā)該狀態(tài)上報(bào)
- console.info('AVPlayerstate initialized called.');
- this.avPlayer.prepare().then(() => {
- console.info('AVPlayer prepare succeeded.');
- }, (err) => {
- console.error(`Invoke prepare failed, code is ${err.code}, message is ${err.message}`);
- });
- break;
- case 'prepared': // prepare調(diào)用成功后上報(bào)該狀態(tài)機(jī)
- console.info('AVPlayer state prepared called.');
- this.avPlayer.play(); // 調(diào)用播放接口開(kāi)始播放
- break;
- case 'playing': // play成功調(diào)用后觸發(fā)該狀態(tài)機(jī)上報(bào)
- console.info('AVPlayer state playing called.');
- if (this.count !== 0) {
- console.info('AVPlayer start to seek.');
- this.avPlayer.seek(this.avPlayer.duration); //seek到音頻末尾
- } else {
- this.avPlayer.pause(); // 調(diào)用暫停接口暫停播放
- }
- this.count++;
- break;
- case 'paused': // pause成功調(diào)用后觸發(fā)該狀態(tài)機(jī)上報(bào)
- console.info('AVPlayer state paused called.');
- this.avPlayer.play(); // 再次播放接口開(kāi)始播放
- break;
- case 'completed': // 播放結(jié)束后觸發(fā)該狀態(tài)機(jī)上報(bào)
- console.info('AVPlayer state completed called.');
- this.avPlayer.stop(); //調(diào)用播放結(jié)束接口
- break;
- case 'stopped': // stop接口成功調(diào)用后觸發(fā)該狀態(tài)機(jī)上報(bào)
- console.info('AVPlayer state stopped called.');
- this.avPlayer.reset(); // 調(diào)用reset接口初始化avplayer狀態(tài)
- break;
- case 'released':
- console.info('AVPlayer state released called.');
- break;
- default:
- console.info('AVPlayer state unknown called.');
- break;
- }
- })
- }
- // 以下demo為使用fs文件系統(tǒng)打開(kāi)沙箱地址獲取媒體文件地址并通過(guò)url屬性進(jìn)行播放示例
- async avPlayerUrlDemo() {
- // 創(chuàng)建avPlayer實(shí)例對(duì)象
- this.avPlayer = await media.createAVPlayer();
- // 創(chuàng)建狀態(tài)機(jī)變化回調(diào)函數(shù)
- this.setAVPlayerCallback();
- let fdPath = 'fd://';
- // 通過(guò)UIAbilityContext獲取沙箱地址filesDir,以下為Stage模型獲方式,如需在FA模型上獲取請(qǐng)參考《訪問(wèn)應(yīng)用沙箱》獲取地址
- let context = getContext(this) as common.UIAbilityContext;
- let pathDir = context.filesDir;
- let path = pathDir + '/01.mp3';
- // 打開(kāi)相應(yīng)的資源文件地址獲取fd,并為url賦值觸發(fā)initialized狀態(tài)機(jī)上報(bào)
- let file = await fs.open(path);
- fdPath = fdPath + '' + file.fd;
- this.avPlayer.url = fdPath;
- }
- // 以下demo為使用資源管理接口獲取打包在HAP內(nèi)的媒體資源文件并通過(guò)fdSrc屬性進(jìn)行播放示例
- async avPlayerFdSrcDemo() {
- // 創(chuàng)建avPlayer實(shí)例對(duì)象
- this.avPlayer = await media.createAVPlayer();
- // 創(chuàng)建狀態(tài)機(jī)變化回調(diào)函數(shù)
- this.setAVPlayerCallback();
- // 通過(guò)UIAbilityContext的resourceManager成員的getRawFd接口獲取媒體資源播放地址
- // 返回類(lèi)型為{fd,offset,length},fd為HAP包fd地址,offset為媒體資源偏移量,length為播放長(zhǎng)度
- let context = getContext(this) as common.UIAbilityContext;
- let fileDescriptor = await context.resourceManager.getRawFd('01.mp3');
- // 為fdSrc賦值觸發(fā)initialized狀態(tài)機(jī)上報(bào)
- this.avPlayer.fdSrc = fileDescriptor;
- this.isSeek = false; // 不支持seek操作
- }
- }
Copyright©2021 w3cschool編程獅|閩ICP備15016281號(hào)-3|閩公網(wǎng)安備35020302033924號(hào)
違法和不良信息舉報(bào)電話(huà):173-0602-2364|舉報(bào)郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號(hào)
聯(lián)系方式:
更多建議: