鸿蒙学习实战之路-AVPlayer音频播放完全指南
AVPlayer的概念:就像音乐播放机,能播放各种音频格式播放流程:从创建实例到释放资源的完整流程监听事件:监听播放状态、错误、时长等信息播控操作:实现播放、暂停、跳转、停止功能资源管理:本地资源、网络资源、HAP资源的使用完整示例:实现了一个简单的音乐播放器是不是超简单?AVPlayer的使用其实就像操作家里的音乐播放机,跟着步骤来就能搞定~
鸿蒙学习实战之路-AVPlayer音频播放完全指南
最近好多朋友问我:“西兰花啊,我想在鸿蒙应用里加个音频播放功能,可看了官方文档有点懵,咋弄啊?” 害,这问题可问对人了!今天我就手把手带你用AVPlayer实现音频播放功能,从买"播放机"到"放音乐",全程不超过20分钟~
🥦 先唠唠AVPlayer是啥
AVPlayer就像咱们家里的音乐播放机,能播放各种音频(和视频)资源。用它你可以:
- 播放本地音乐文件
- 播放网络音乐
- 控制播放(播放/暂停/跳转/停止)
- 调整音量、倍速
- 监听播放状态变化
播放的全流程就像放CD:
- 买播放机(创建AVPlayer实例)
- 接好电源和音箱(设置监听事件)
- 放CD(设置播放资源)
- 调整音效(设置音频渲染)
- 预热(准备播放)
- 开始播放(播控操作)
- 换CD(更换资源)
- 关机(释放资源)
看看官方给的状态变化图,是不是超清晰?

🥦 西兰花警告
在开始之前,先说说开发建议和注意事项:
必看的开发建议
- ✅ 要实现后台/熄屏播放,需要接入AVSession(媒体会话)和申请长时任务,避免被系统打断
- ✅ 要处理音频冲突,建议监听音频打断事件,别让用户听着听着突然没声音了
- ✅ 要播放网络音乐,必须申请
ohos.permission.INTERNET权限(就像听网络电台要连Wi-Fi) - ✅ 要切换听筒/扬声器,参考音频输出设备路由切换
- ✅ 要监听设备变化,用
on('audioOutputDeviceChangeWithInfo')监听音频输出设备变化
状态管理要注意
当播放处于prepared/playing/paused/completed状态时,播放引擎处于工作状态,会占用大量内存。不用的时候一定要调用reset()或release()释放资源,就像不用播放机时要关机一样!
第一步:买播放机(创建AVPlayer实例)
要播放音乐得先有播放机,要实现音频播放得先创建AVPlayer实例:
import { media } from '@kit.MediaKit';
// 创建AVPlayer实例(买了个音乐播放机)
let 音乐播放机 = await media.createAVPlayer();
就这么简单!现在音乐播放机处于idle状态,还没开始工作~
第二步:接好电源和音箱(设置监听事件)
播放机买回来了,得接好电源和音箱才能用。AVPlayer的监听事件就是"电源"和"音箱",帮咱们监听播放状态变化:
import { BusinessError } from '@kit.BasicServicesKit';
import { audio } from '@kit.AudioKit';
// 监听播放状态变化(电源指示灯)
音乐播放机.on('stateChange', async (state: string, reason: media.StateChangeReason) => {
// 状态变化时的业务逻辑
console.info(`播放状态变了:${state},原因:${reason}`);
});
// 监听错误信息(故障提示灯)
音乐播放机.on('error', (error: BusinessError) => {
console.error(`播放出错了:${error.code},${error.message}`);
});
// 监听时长更新(唱片总时长)
音乐播放机.on('durationUpdate', (duration: number) => {
console.info(`音乐总时长:${duration}秒`);
});
// 监听当前播放时间(进度条)
音乐播放机.on('timeUpdate', (time: number) => {
console.info(`当前播放到:${time}秒`);
});
// 监听跳转完成(快进/快退完成)
音乐播放机.on('seekDone', (seekDoneTime: number) => {
console.info(`跳转完成,现在播放到:${seekDoneTime}秒`);
});
// 监听倍速设置完成(调速完成)
音乐播放机.on('speedDone', (speed: number) => {
console.info(`倍速设置完成:${speed}x`);
});
// 监听音量变化(音量调节完成)
音乐播放机.on('volumeChange', (vol: number) => {
console.info(`音量调节完成:${vol}`);
});
// 监听缓冲进度(网络播放缓冲)
音乐播放机.on('bufferingUpdate', (infoType: media.BufferingInfoType, value: number) => {
console.info(`缓冲信息:${infoType},进度:${value}%`);
});
// 监听音频焦点变化(防止被其他应用打断)
音乐播放机.on('audioInterrupt', (info: audio.InterruptEvent) => {
console.info(`音频焦点变化:${JSON.stringify(info)}`);
});
🥦 西兰花小贴士:
stateChange和error是必须监听的事件,就像播放机必须接电源一样!- 这些监听必须在
idle状态下、设置资源前完成,否则可能收不到状态变化~
第三步:放唱片(设置播放资源)
播放机接好线了,现在该放唱片了!设置AVPlayer的url属性就能指定要播放的音频资源:
// 设置播放资源(放唱片)
let 音乐地址 = 'https://example.com/music.mp3'; // 替换成你的音频地址
if (音乐播放机 == null) {
return;
}
音乐播放机.url = 音乐地址;
设置完资源后,音乐播放机就进入了initialized状态,准备就绪!
🥦 关于资源路径的小知识
| 资源类型 | 注意事项 |
|---|---|
| 本地资源 | 必须用应用沙箱路径,参考获取应用文件路径 |
| 网络资源 | 必须申请ohos.permission.INTERNET权限 |
| HAP资源 | 用ResourceManager.getRawFd打开文件描述符 |
| 格式要求 | 必须是AVPlayer支持的播放格式 |
第四步:调整音效(设置音频渲染)
想让音乐更好听?可以调整音频渲染参数,就像调节播放机的音效:
import { audio } from '@kit.AudioKit';
// 设置音频渲染信息(调节音效)
音乐播放机.audioRendererInfo = {
usage: audio.StreamUsage.STREAM_USAGE_MUSIC, // 流类型:音乐
rendererFlags: 0 // 渲染标志
};
🥦 西兰花小贴士:
- 流类型很重要!不同类型的音频要用不同的
usage:- 音乐:
STREAM_USAGE_MUSIC - 电影:
STREAM_USAGE_MOVIE - 通话:
STREAM_USAGE_VOICE_COMMUNICATION - 参考选择合适的流类型了解更多
- 音乐:
第五步:预热(准备播放)
唱片放好了,音效也调了,现在该预热播放机了!调用prepare()方法准备播放:
// 准备播放(预热播放机)
音乐播放机.prepare((err: BusinessError) => {
if (err) {
console.error('准备失败:' + err.message);
} else {
console.info('准备成功!可以开始播放了~');
// 准备成功后可以获取时长、调整音量
}
});
准备成功后,音乐播放机进入prepared状态,可以获取音乐时长并调整音量了!
第六步:开始播放(播控操作)
预热完成,终于可以开始播放音乐了!咱们来实现播放、暂停、跳转、停止等操作:
import { BusinessError } from '@kit.BasicServicesKit';
// 播放音乐
音乐播放机.play().then(() => {
console.info('开始播放!');
}, (err: BusinessError) => {
console.error('播放失败:' + err.message);
});
// 暂停播放
音乐播放机.pause((err: BusinessError) => {
if (err) {
console.error('暂停失败:' + err.message);
} else {
console.info('暂停播放');
}
});
// 跳转播放(快进/快退)
let 目标时间: number = 10; // 跳转到10秒处
音乐播放机.seek(目标时间, media.SeekMode.SEEK_PREV_SYNC);
// 停止播放
音乐播放机.stop((err: BusinessError) => {
if (err) {
console.error('停止失败:' + err.message);
} else {
console.info('停止播放');
}
});
就像操作家里的播放机一样简单!
第七步:换唱片(更换资源)
想听另一首歌?可以调用reset()方法重置播放机,然后更换资源:
// 重置播放机(取出唱片)
音乐播放机.reset((err: BusinessError) => {
if (err) {
console.error('重置失败:' + err.message);
} else {
console.info('重置成功!可以换唱片了~');
}
});
// 更换资源(放新唱片)
let 新音乐地址 = 'https://example.com/new_music.mp3';
if (音乐播放机 == null) {
return;
}
音乐播放机.url = 新音乐地址;
重置后,音乐播放机回到idle状态,可以重新设置资源并播放~
第八步:关机(释放资源)
听完音乐了,别忘了关机节约电量!调用release()方法释放AVPlayer资源:
// 释放资源(关机)
音乐播放机.release((err: BusinessError) => {
if (err) {
console.error('释放资源失败:' + err.message);
} else {
console.info('资源释放成功!');
}
});
释放后,音乐播放机进入released状态,彻底退出播放流程~
🥦 完整示例:实现一个简单的音乐播放器
光说不练假把式,咱们来整个完整的示例!
1. 准备资源
先新建工程,下载示例工程,把以下资源复制到对应目录:
AVPlayerArkTSAudio
├── entry/src/main/ets/
│ └── pages/
│ └── Index.ets (播放界面)
└── entry/src/main/resources/
├── base/
│ ├── element/
│ │ ├── color.json
│ │ ├── float.json
│ │ └── string.json
│ └── media/
│ ├── ic_video_play.svg (播放键)
│ └── ic_video_pause.svg (暂停键)
└── rawfile/
└── test_01.mp3 (音频资源)
2. 实现播放界面
在Index.ets中实现播放界面:
import { media } from '@kit.MediaKit';
import { BusinessError } from '@kit.BasicServicesKit';
import { audio } from '@kit.AudioKit';
import { promptAction } from '@kit.ArkUI';
@Entry
@Component
struct Index {
private 音乐播放机: media.AVPlayer | null = null;
private isPlaying: boolean = false;
private currentTime: number = 0;
private duration: number = 0;
private progress: number = 0;
// 页面加载时初始化
aboutToAppear() {
this.initPlayer();
}
// 初始化播放器
async initPlayer() {
try {
// 创建播放器实例
this.音乐播放机 = await media.createAVPlayer();
// 设置监听
this.setPlayerListeners();
// 设置本地资源
let context = getContext(this) as common.UIAbilityContext;
let resourceManager = context.resourceManager;
let fd = await resourceManager.getRawFd('test_01.mp3');
if (this.音乐播放机) {
this.音乐播放机.fdSrc = {
fd: fd.fd,
offset: 0,
length: fd.length
};
// 准备播放
await this.preparePlayer();
}
} catch (error) {
console.error('初始化播放器失败:' + JSON.stringify(error));
}
}
// 设置播放器监听
setPlayerListeners() {
if (!this.音乐播放机) return;
// 监听状态变化
this.音乐播放机.on('stateChange', async (state: string) => {
console.info(`状态变化:${state}`);
if (state === 'playing') {
this.isPlaying = true;
} else if (state === 'paused' || state === 'completed') {
this.isPlaying = false;
}
});
// 监听错误
this.音乐播放机.on('error', (error: BusinessError) => {
console.error(`播放错误:${error.code},${error.message}`);
promptAction.showToast({ message: '播放失败' });
});
// 监听时长更新
this.音乐播放机.on('durationUpdate', (duration: number) => {
this.duration = duration;
});
// 监听当前时间
this.音乐播放机.on('timeUpdate', (time: number) => {
this.currentTime = time;
this.progress = this.duration > 0 ? (time / this.duration) * 100 : 0;
});
}
// 准备播放器
async preparePlayer() {
if (!this.音乐播放机) return;
return new Promise<void>((resolve, reject) => {
this.音乐播放机?.prepare((err: BusinessError) => {
if (err) {
console.error('准备失败:' + err.message);
reject(err);
} else {
console.info('准备成功');
resolve();
}
});
});
}
// 播放/暂停切换
async togglePlay() {
if (!this.音乐播放机) return;
try {
if (this.isPlaying) {
await this.音乐播放机.pause();
} else {
await this.音乐播放机.play();
}
} catch (error) {
console.error('播放/暂停失败:' + JSON.stringify(error));
}
}
// 页面卸载时释放资源
aboutToDisappear() {
if (this.音乐播放机) {
this.音乐播放机.release();
this.音乐播放机 = null;
}
}
build() {
Column({ space: 20 }) {
Text('简单音乐播放器')
.fontSize(24)
.fontWeight(FontWeight.Bold)
.margin(20);
// 进度条
Slider({
value: this.progress,
min: 0,
max: 100,
style: SliderStyle.InSet
})
.width('80%')
.onChange((value: number) => {
// 拖动进度条跳转
if (this.音乐播放机 && this.duration > 0) {
let seekTime = (value / 100) * this.duration;
this.音乐播放机.seek(seekTime, media.SeekMode.SEEK_PREV_SYNC);
}
});
// 时间显示
Row() {
Text(this.formatTime(this.currentTime))
.fontSize(14);
Text('/')
.fontSize(14);
Text(this.formatTime(this.duration))
.fontSize(14);
}
// 播放按钮
Button({
type: ButtonType.Circle,
stateEffect: true
}) {
Image(this.isPlaying ? $r('app.media.ic_video_pause') : $r('app.media.ic_video_play'))
.width(30)
.height(30)
.objectFit(ImageFit.Contain);
}
.width(80)
.height(80)
.backgroundColor('#1890ff')
.onClick(() => {
this.togglePlay();
});
}
.width('100%')
.height('100%')
.justifyContent(FlexAlign.Center);
}
// 格式化时间
formatTime(seconds: number): string {
let min = Math.floor(seconds / 60);
let sec = Math.floor(seconds % 60);
return `${min.toString().padStart(2, '0')}:${sec.toString().padStart(2, '0')}`;
}
}
3. 编译运行
编译工程并运行,就能看到一个简单的音乐播放器了!点击播放按钮就能播放rawfile里的音频~
总结一下
今天咱们学会了:
- AVPlayer的概念:就像音乐播放机,能播放各种音频格式
- 播放流程:从创建实例到释放资源的完整流程
- 监听事件:监听播放状态、错误、时长等信息
- 播控操作:实现播放、暂停、跳转、停止功能
- 资源管理:本地资源、网络资源、HAP资源的使用
- 完整示例:实现了一个简单的音乐播放器
是不是超简单?AVPlayer的使用其实就像操作家里的音乐播放机,跟着步骤来就能搞定~
📚 推荐资料
我是盐焗西兰花,
不教理论,只给你能跑的代码和避坑指南。
下期见!🥦
更多推荐


所有评论(0)