文档管理中心

使用AVPlayer播放音频(ArkTS)

使用AVPlayer可以实现端到端播放原始媒体资源,本开发指导将以完整播放一首音乐作为示例,向开发者讲解AVPlayer音频播放相关功能。如需播放PCM音频数据,请使用AudioRenderer

播放的全流程包含:创建AVPlayer,设置播放资源,设置播放参数(音量/倍速/焦点模式),播放控制(播放/暂停/跳转/停止),重置,销毁资源。

在应用开发的过程中,开发者可以通过AVPlayer的state属性主动获取当前状态,或使用on('stateChange')方法监听状态变化。如果应用在音频播放器处于错误状态时执行操作,系统可能会抛出异常或产生其他未定义的行为。

图1 播放状态变化示意图

状态的详细说明请参考AVPlayerState。当播放处于prepared / playing / paused / completed状态时,播放引擎处于工作状态,这需要占用系统大量的运行内存。当客户端暂时不使用播放器时,调用reset()或release()回收内存资源,做好资源利用。

开发建议

当前指导仅介绍如何实现媒体资源播放,在应用开发过程中,涉及后台播放、播放冲突等情况时,请根据实际需要参考以下说明。

  • 若要实现后台播放或熄屏播放,需要接入AVSession(媒体会话)申请长时任务,避免播放被系统强制中断。
  • 应用在播放过程中,若播放的媒体数据涉及音频,根据系统音频管理策略(参考处理音频焦点事件),可能会被其他应用打断,建议应用主动监听音频打断事件,根据内容提示做出相应处理,避免出现应用状态与预期效果不一致的问题。
  • 面对设备同时连接多个音频输出设备的情况,应用可以通过on('audioOutputDeviceChangeWithInfo')监听音频输出设备的变化,做出相应处理。
  • 若要访问在线媒体资源,需要申请 ohos.permission.INTERNET 权限。
  • 若要切换听筒/扬声器,应用可以参考音频输出设备路由切换

开发步骤及注意事项

详细的API说明请参考AVPlayer

  1. 创建实例createAVPlayer(),AVPlayer初始化idle状态。

    收起
    自动换行
    深色代码主题
    复制
    1. import { media } from '@kit.MediaKit';
    2. // 创建avPlayer实例对象。
    3. let avPlayer = await media.createAVPlayer();
  2. 设置业务需要的监听事件,搭配全流程场景使用。支持的监听事件包括:

    展开
    事件类型 说明
    stateChange

    必要事件,监听播放器的state属性改变。

    需要播放器在idle状态下、未调用设置资源接口前完成设置监听,若在调用设置资源接口后再设置监听,可能导致无法收到资源设置过程中上报的stateChange事件。

    error

    必要事件,监听播放器的错误信息。

    需要播放器在idle状态下、未调用设置资源接口前完成设置监听,若在调用设置资源接口后再设置监听,可能导致无法收到资源设置过程中上报的error事件。

    durationUpdate 用于进度条,监听进度条长度,刷新资源时长。
    timeUpdate 用于进度条,监听进度条当前位置,刷新当前时间。
    seekDone

    响应API调用,监听seek()请求完成情况。

    当使用seek()跳转到指定播放位置后,如果seek操作成功,将上报该事件。

    speedDone

    响应API调用,监听setSpeed()请求完成情况。

    当使用setSpeed()设置播放倍速后,如果setSpeed操作成功,将上报该事件。

    volumeChange

    响应API调用,监听setVolume()请求完成情况。

    当使用setVolume()调节播放音量后,如果setVolume操作成功,将上报该事件。

    bufferingUpdate 用于网络播放,监听网络播放缓冲信息,用于上报缓冲百分比以及缓存播放进度。
    audioInterrupt

    监听音频焦点切换信息,搭配属性audioInterruptMode使用。

    如果当前设备存在多个音频正在播放,音频焦点被切换(即播放其他媒体如通话等)时将上报该事件,应用可以及时处理。

    收起
    自动换行
    深色代码主题
    复制
    1. // 此处仅为示例,开发者根据需要设置合适的监听事件。
    2. import { BusinessError } from '@kit.BasicServicesKit';
    3. import { audio } from '@kit.AudioKit';
    4. avPlayer.on('stateChange', async (state: string, reason: media.StateChangeReason) => {
    5. // 开发者根据需要写入业务逻辑。
    6. });
    7. avPlayer.on('error', (error: BusinessError) => {
    8. // 开发者根据需要写入业务逻辑。
    9. });
    10. avPlayer.on('durationUpdate', (duration: number) => {
    11. // 开发者根据需要写入业务逻辑。
    12. });
    13. avPlayer.on('timeUpdate', (time:number) => {
    14. // 开发者根据需要写入业务逻辑。
    15. });
    16. avPlayer.on('seekDone', (seekDoneTime:number) => {
    17. // 开发者根据需要写入业务逻辑。
    18. });
    19. avPlayer.on('speedDone', (speed:number) => {
    20. // 开发者根据需要写入业务逻辑。
    21. });
    22. avPlayer.on('volumeChange', (vol: number) => {
    23. // 开发者根据需要写入业务逻辑。
    24. });
    25. avPlayer.on('bufferingUpdate', (infoType: media.BufferingInfoType, value: number) => {
    26. // 开发者根据需要写入业务逻辑。
    27. });
    28. avPlayer.on('audioInterrupt', (info: audio.InterruptEvent) => {
    29. // 开发者根据需要写入业务逻辑。
    30. });
  3. 设置资源:设置属性url,AVPlayer进入initialized状态。

    说明

    下面代码示例中的url仅作示意使用,开发者需根据实际情况,确认资源有效性并设置:

    示例一:播放网络媒体资源

    收起
    自动换行
    深色代码主题
    复制
    1. let url = 'https://abc.bcd.example.mp3'; // 此处仅为示意,请替换为真实资源文件URL。
    2. if (avPlayer == null) {
    3. return;
    4. }
    5. avPlayer.url = url;

    示例二:应用沙箱文件播放

    收起
    自动换行
    深色代码主题
    复制
    1. let fdPath = 'fd://'; // 此处仅为示意,请替换为真实资源文件URL。
    2. let path : string = `${this.context.filesDir}/${this.fileName}`; // 此处仅为示意,请替换为真实资源文件URL。
    3. let file = await fs.open(path);
    4. fdPath = fdPath + file.fd;
    5. this.avPlayer = await media.createAVPlayer();
    6. this.avPlayer.url = url;
  4. (可选)设置音频渲染:只允许在initialized状态下,第一次调用prepare()之前设置,以便音频渲染器信息在之后生效。若媒体源包含视频,则usage默认值为STREAM_USAGE_MOVIE,否则usage默认值为STREAM_USAGE_MUSIC。rendererFlags默认值为0。

    为了确保音频行为符合使用预期,建议根据具体业务场景和实际需求,主动配置audio.AudioRendererInfo,为音频选择恰当的流类型usage

    收起
    自动换行
    深色代码主题
    复制
    1. import { audio } from '@kit.AudioKit';
    2. avPlayer.audioRendererInfo = {
    3. usage: audio.StreamUsage.STREAM_USAGE_MOVIE,
    4. rendererFlags: 0
    5. }
  5. 准备播放:调用 prepare()方法进入准备播放阶段,AVPlayer 将切换至 prepared 状态,此时可获取视频时长(duration)并调整音量参数。

    收起
    自动换行
    深色代码主题
    复制
    1. import { BusinessError } from '@kit.BasicServicesKit';
    2. avPlayer.prepare((err: BusinessError) => {
    3. if (err) {
    4. console.error('Failed to prepare,error message is :' + err.message);
    5. } else {
    6. console.info('Succeeded in preparing');
    7. }
    8. });
  6. 音频播控:播放play()、暂停pause()、跳转seek()、停止stop() 等操作。

    说明

    在API version 23及之后版本中,播放音频时会跳过静音帧。

    收起
    自动换行
    深色代码主题
    复制
    1. import { BusinessError } from '@kit.BasicServicesKit';
    2. // 播放操作。
    3. avPlayer.play().then(() => {
    4. console.info('Succeeded in playing');
    5. }, (err: BusinessError) => {
    6. console.error('Failed to play,error message is :' + err.message);
    7. });
    8. // 暂停操作。
    9. avPlayer.pause((err: BusinessError) => {
    10. if (err) {
    11. console.error('Failed to pause,error message is :' + err.message);
    12. } else {
    13. console.info('Succeeded in pausing');
    14. }
    15. });
    16. // 跳转操作。
    17. let seekTime: number = 1000;
    18. avPlayer.seek(seekTime, media.SeekMode.SEEK_PREV_SYNC);
    19. // 停止操作。
    20. avPlayer.stop((err: BusinessError) => {
    21. if (err) {
    22. console.error('Failed to stop,error message is :' + err.message);
    23. } else {
    24. console.info('Succeeded in stopping');
    25. }
    26. });
  7. (可选)更换资源:调用reset()方法重置播放资源,AVPlayer重新进入idle状态,此时可重新设置资源url。

    收起
    自动换行
    深色代码主题
    复制
    1. import { BusinessError } from '@kit.BasicServicesKit';
    2. await avPlayer.reset((err: BusinessError) => {
    3. avPlayer.url = url;
    4. if (err) {
    5. console.error('Failed to reset,error message is :' + err.message);
    6. } else {
    7. console.info('Succeeded in resetting');
    8. }
    9. });
    10. // 更换URL。
    11. let url = 'https://example.com/audio.mp3'; // 此处仅为示意,请替换为真实资源文件URL。
    12. if (avPlayer == null) {
    13. return;
    14. }
    15. avPlayer.url = url;
  8. 退出播放:调用release()销毁实例,AVPlayer进入released状态,退出播放。

    收起
    自动换行
    深色代码主题
    复制
    1. import { BusinessError } from '@kit.BasicServicesKit';
    2. avPlayer.release((err: BusinessError) => {
    3. if (err) {
    4. console.error('Failed to release,error message is :' + err.message);
    5. } else {
    6. console.info('Succeeded in releasing');
    7. }
    8. });

运行完整示例

参考以下示例,完整地播放一首音乐,实现起播后3s暂停,暂停3s重新播放的效果。

  1. 新建工程,下载示例工程,并将示例工程的以下资源复制到对应目录。
    收起
    自动换行
    深色代码主题
    复制
    1. AVPlayerArkTSAudio
    2. entry/src/main/ets/
    3. └── pages
    4. └── Index.ets (播放界面)
    5. entry/src/main/resources/
    6. ├── base
    7. │ ├── element
    8. │ │ ├── color.json
    9. │ │ ├── float.json
    10. │ │ └── string.json
    11. │ └── media
    12. │ ├── ic_video_play.svg (播放键图片资源)
    13. │ └── ic_video_pause.svg (暂停键图片资源)
    14. └── rawfile
    15. └── test_01.mp3 (音频资源)
  2. 编译新建工程并运行。
在 指南 中进行搜索
请输入您想要搜索的关键词