HarmonyOS鸿蒙Next中AVPlayer的状态机具体该怎么处理
HarmonyOS鸿蒙Next中AVPlayer的状态机具体该怎么处理 AVPlayer的状态机具体该怎么处理?有没有一个简单的demo能参考一下?
3 回复
//avplayerManager.ets:
import { media } from '@kit.MediaKit';
import { BusinessError } from '@kit.BasicServicesKit';
const TAG = '[AvPlayer] '
@ObservedV2
export class AudioPlayManager {
private avPlayer: media.AVPlayer | null = null
@Trace audioDuration: number = 0
@Trace currAudioTime: number = 0
@Trace isPlaying: boolean = false
@Trace audioPlayState: media.AVPlayerState = 'idle';
// 注册avplayer回调函数。
setAVPlayerCallback(avPlayer: media.AVPlayer) {
// seek操作结果回调函数。
avPlayer.on('seekDone', (seekDoneTime: number) => {
console.info(`${TAG} on seekDone, seek time is ${seekDoneTime}`);
});
// error回调监听函数,当avPlayer在操作过程中出现错误时调用 reset接口触发重置流程。
avPlayer.on('error', (err: BusinessError) => {
console.error(`${TAG} on error, code is ${err.code}, message is ${err.message}`);
avPlayer.reset(); // 调用reset重置资源,触发idle状态。
});
avPlayer.on('timeUpdate', (time: number) => {
console.info(`${TAG} on timeUpdate : ${time}`);
this.currAudioTime = time
});
avPlayer.on('durationUpdate', (time: number) => {
console.info(TAG + `on durationUpdate: ${time}`)
this.audioDuration = time;
})
// 状态机变化回调函数。
avPlayer.on('stateChange', async (state: string, reason: media.StateChangeReason) => {
switch (state) {
case 'idle': // 成功调用reset接口后触发该状态机上报。
console.info(`${TAG} 状态机 audioPlayState: ${avPlayer.state}`);
this.setAudioPlayState(avPlayer.state)
// avPlayer.release(); // 调用release接口销毁实例对象。
break;
case 'initialized': // avplayer 设置播放源后触发该状态上报。
console.info(`${TAG} 状态机 audioPlayState: ${avPlayer.state}`);
this.setAudioPlayState(avPlayer.state)
// avPlayer.audioRendererInfo = {
// usage: audio.StreamUsage.STREAM_USAGE_MUSIC, // 音频流使用类型:音乐。根据业务场景配置,参考StreamUsage。
// rendererFlags: 0 // 音频渲染器标志。
// };
avPlayer.prepare();
break;
case 'prepared': // prepare调用成功后上报该状态机。
console.info(`${TAG} 状态机 audioPlayState: ${avPlayer.state}`);
this.setAudioPlayState(avPlayer.state)
// this.audioDuration = avPlayer.duration
break;
case 'playing': // play成功调用后触发该状态机上报。
console.info(`${TAG} 状态机 audioPlayState: ${avPlayer.state}`);
this.setAudioPlayState(avPlayer.state)
break;
case 'paused': // pause成功调用后触发该状态机上报。
console.info(`${TAG} 状态机 audioPlayState: ${avPlayer.state}`);
this.setAudioPlayState(avPlayer.state)
avPlayer.pause()
break;
case 'completed': // 播放结束后触发该状态机上报。
console.info(`${TAG} 状态机 audioPlayState: ${avPlayer.state}`);
this.setAudioPlayState(avPlayer.state)
this.resetCurrAudioPlayStatusInfo();
break;
case 'stopped': // stop接口成功调用后触发该状态机上报。
console.info(`${TAG} 状态机 audioPlayState: ${avPlayer.state}`);
this.setAudioPlayState(avPlayer.state)
break;
case 'released':
console.info(`${TAG} 状态机 audioPlayState: ${avPlayer.state}`);
this.setAudioPlayState(avPlayer.state)
break;
default:
console.info(`${TAG} 状态机 audioPlayState: ${avPlayer.state}`);
break;
}
});
}
//设置当前音频播放状态
setAudioPlayState(state: media.AVPlayerState) {
this.audioPlayState = state;
console.info(TAG + `setAudioPlayState audioPlayState: ${this.audioPlayState}`)
}
//音频播放
async setAudioSrcToPrepared(audioSrc: string) {
// 创建avPlayer实例对象。
this.avPlayer = await media.createAVPlayer();
//设置状态机
this.setAVPlayerCallback(this.avPlayer!);
//设置 音频url,状态自动跳至 initialized
this.avPlayer!.url = audioSrc;
}
async startPlay() {
this.isPlaying = true
try {
this.avPlayer?.play()
}catch (err){
let error:BusinessError = err as BusinessError
}
}
async stopPlay() {
this.avPlayer?.prepare()
this.isPlaying = false
}
async release() {
this.avPlayer?.release()
this.isPlaying = false
}
async reset() {
this.isPlaying = false
this.currAudioTime = 0
this.avPlayer?.prepare();
// this.avPlayer?.release()
this.avPlayer = null;
}
//重置当前音频播放状态信息
resetCurrAudioPlayStatusInfo() {
this.isPlaying = false
this.currAudioTime = 0
this.setAudioPlayState('stopped');
}
async seek(value: number) {
this.avPlayer?.seek(value)
}
}
//Index
import { AudioPlayManager } from './avplayerManager';
@Entry
@Component
struct Index {
avplayerManager:AudioPlayManager = new AudioPlayManager()
build() {
Column({space:20}){
Button('AVPlayer实例化')
.onClick(()=>{
this.avplayerManager.setAudioSrcToPrepared('')
// 在该函数中传入音频文件url
})
Button('开始播放(确保实例化完成之后再点击播放)')
.onClick(()=>{
this.avplayerManager.startPlay()
})
Button('暂停播放')
.onClick(()=>{
this.avplayerManager.stopPlay()
})
Button('重置播放')
.onClick(()=>{
this.avplayerManager.reset()
})
Button('销毁资源')
.onClick(()=>{
this.avplayerManager.release()
})
}
.width('100%')
.justifyContent(FlexAlign.Center)
.alignItems(HorizontalAlign.Center)
}
}
更多关于HarmonyOS鸿蒙Next中AVPlayer的状态机具体该怎么处理的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
AVPlayer状态机处理基于状态监听和回调机制。通过on('stateChange')监听状态变化,事件包括idle、initialized、prepared、playing、paused、completed、stopped、error等。开发者需在回调中根据state参数执行相应操作,如播放器准备完成后自动播放。错误状态需通过on('error')单独处理。状态转换由系统管理,应用只需响应状态变更。
在HarmonyOS Next中,AVPlayer的状态机是其核心控制逻辑,主要通过监听状态回调进行有序处理。其生命周期主要包含以下关键状态:Idle、Initialized、Prepared、Playing、Paused、Completed、Stopped 以及 Error。
核心处理流程如下:
- 状态监听:通过
on('stateChange')方法注册监听器,在回调中根据state参数进行分支处理。 - 关键状态与操作:
- Idle -> Initialized:调用
avPlayer.prepare()后进入。 - Initialized -> Prepared:准备就绪,可获取媒体信息(如时长)。此时可调用
avPlayer.play()开始播放。 - Prepared -> Playing / Paused:进行播放控制。
- Completed / Stopped / Error:需进行资源释放或错误处理。
- Idle -> Initialized:调用
一个简单的状态处理代码结构示例:
import media from '@ohos.multimedia.media';
// 1. 创建AVPlayer实例
let avPlayer: media.AVPlayer;
avPlayer = await media.createAVPlayer();
// 2. 设置状态监听
avPlayer.on('stateChange', async (state: string) => {
switch (state) {
case 'initialized':
// 资源已设置,可进行prepare
await avPlayer.prepare();
break;
case 'prepared':
// 准备就绪,可开始播放
await avPlayer.play();
break;
case 'playing':
// 播放中,可更新UI控件(如进度条)
break;
case 'paused':
// 已暂停
break;
case 'completed':
// 播放完成,可重置或释放
await avPlayer.reset();
break;
case 'stopped':
// 已停止
break;
case 'error':
// 发生错误,需查询错误码进行处理
let errorMsg = avPlayer.getErrorMessage();
// 处理错误逻辑...
break;
default:
break;
}
});
// 3. 设置资源并触发初始化(例如设置网络URL)
avPlayer.url = 'https://example.com/sample.mp4';
// 设置url后,状态会从idle变为initialized,触发上述监听回调
重要提醒:
- 确保在合适的生命周期(如页面退出时)调用
avPlayer.release()释放资源。 - 进行
play()、pause()、seek()等操作前,建议检查当前状态是否允许该操作。 - 错误状态必须处理,可调用
getErrorMessage()获取详细信息。
以上代码框架清晰地展示了状态机的流转与处理要点,你可以基于此结构扩展具体的UI控制与业务逻辑。

