【HarmonyOS】鸿蒙应用实现音效播放

[复制链接]
发表于 2026-1-22 17:38:21 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
一、标题配景:
应用在强提示场景下,一样平常会有播放音效的效果,提示用户注意力的关注。
在鸿蒙应用怎样实现音效播放呢???
二、办理方案:
利用AVPlayer实现当地音效资源的播放。
该播放器功能很丰富,如今只针对于音效播放举行睁开。
播放的全流程包罗:创建AVPlayer,设置播放资源,设置播放参数(音量/倍速/焦点模式),播放控制(播放/停息/跳转/克制),重置,烧毁资源。

开辟详细步调分析:

  • 起首创建实例createAVPlayer(),AVPlayer初始化idle状态。
  • 注册状态厘革回调和错误回调
  • 加载当地音效文件资源
  • 设置厘革状态,提供播放接口
  • 音效文件比力短,默认播放完不做任那边理。若播放长时间音乐文件,可在状态回调里处置惩罚
必要注意的是,当音效文件设置完成后,只有调用play才会正常播放。

ps: 着实关于音效和振动同时处置惩罚,官方有音振协同的API举行实现,但是该API如今调用资源,比方音效文件和自界说振动设置文件的方式不太友好,不能从应用沙箱raw下读取,以是保举分开实现的方式。

三、DEMO示例:
DEMO解说通过表明的方式表明。如有不清楚的点,可关注私信我沟通。
音效播放管理类
  1. import { media } from '@kit.MediaKit';
  2. import { BusinessError } from '@kit.BasicServicesKit';
  3. /**
  4. * 音效播放管理类
  5. */
  6. export class AudioMgr {
  7.   private TAG: string = 'AudioMgr';
  8.   // 单例对象
  9.   private static mAudioMgr: AudioMgr | null = null;
  10.   // 播放器实例
  11.   private mAVPlayer: media.AVPlayer | undefined = undefined;
  12.   // 是否初始化
  13.   private isInit: boolean = false;
  14.   // 创建单例
  15.   public static Ins(): AudioMgr{
  16.     if(!AudioMgr.mAudioMgr){
  17.       AudioMgr.mAudioMgr = new AudioMgr();
  18.     }
  19.     return AudioMgr.mAudioMgr;
  20.   }
  21.   /**
  22.    * 初始化接口(可以提前初始化,也可以直接调用play接口,使用时初始化)
  23.    */
  24.   public async init() {
  25.     console.log(this.TAG, "play init start");
  26.     // 创建avPlayer实例对象
  27.     this.mAVPlayer = await media.createAVPlayer();
  28.     // 创建状态机变化回调函数
  29.     this.registerStateChange(this.mAVPlayer);
  30.     // error回调监听函数,当avPlayer在操作过程中出现错误时调用 reset接口触发重置流程
  31.     this.registerErrorCall(this.mAVPlayer);
  32.     // 获取raw音效资源
  33.     let fileDescriptor = await getContext(this).resourceManager.getRawFd("test.mp3");
  34.     this.mAVPlayer.fdSrc = {
  35.         fd: fileDescriptor.fd,
  36.         offset: fileDescriptor.offset,
  37.         length: fileDescriptor.length
  38.     };
  39.     this.isInit = true;
  40.     console.log(this.TAG, "play init end");
  41.     return this.mAVPlayer;
  42.   }
  43.   /**
  44.    * 注册异常回调
  45.    * @param avPlayer
  46.    */
  47.   private registerErrorCall(avPlayer: media.AVPlayer){
  48.     avPlayer.on('error', (err: BusinessError) => {
  49.       console.log(this.TAG, " err:" + JSON.stringify(err));
  50.       // 调用reset重置资源,触发idle状态
  51.       avPlayer.reset();
  52.     })
  53.   }
  54.   /**
  55.    * 注册状态变化回调
  56.    * @param avPlayer
  57.    */
  58.   private registerStateChange(avPlayer: media.AVPlayer){
  59.     avPlayer.on('stateChange', async (state: string, reason: media.StateChangeReason) => {
  60.       switch (state) {
  61.         // 成功调用reset接口后触发该状态机上报
  62.         case 'idle':
  63.           console.info(this.TAG, 'stateChange idle-release');
  64.           avPlayer.release(); // 调用release接口销毁实例对象
  65.           break;
  66.         // avplayer 设置播放源后触发该状态上报
  67.         case 'initialized':
  68.           console.info(this.TAG, 'stateChange initialized-prepare');
  69.           avPlayer.prepare();
  70.           break;
  71.         // prepare调用成功后上报该状态机
  72.         case 'prepared':
  73.           console.info(this.TAG, 'stateChange prepared-setVolume');
  74.           avPlayer.setVolume(1); // The value ranges from 0.00 to 1.00.
  75.           break;
  76.         // play成功调用后触发该状态机上报
  77.         case 'playing':
  78.           console.info(this.TAG, 'stateChange playing');
  79.           break;
  80.         // pause成功调用后触发该状态机上报
  81.         case 'paused':
  82.           console.info(this.TAG, 'stateChange paused');
  83.           break;
  84.         // 播放结束后触发该状态机上报
  85.         case 'completed':
  86.           console.info(this.TAG, 'stateChange completed');
  87.           break;
  88.         // stop接口成功调用后触发该状态机上报
  89.         case 'stopped':
  90.           console.info(this.TAG, 'stateChange stopped');
  91.           // avPlayer.reset(); // 调用reset接口初始化avplayer状态
  92.           break;
  93.         case 'released':
  94.           console.info(this.TAG, 'stateChange released');
  95.           break;
  96.         default:
  97.           console.info(this.TAG, 'stateChange default');
  98.           break;
  99.       }
  100.     });
  101.   }
  102.   /**
  103.    * 播放音效
  104.    */
  105.   public async play(){
  106.     console.log(this.TAG, "play isInit " + this.isInit);
  107.     if(this.isInit){
  108.       await this.mAVPlayer?.play();
  109.     }else{
  110.       console.log(this.TAG, "play play-init start");
  111.       this.mAVPlayer = await this.init();
  112.       console.log(this.TAG, "play play start");
  113.       await this.mAVPlayer?.play();
  114.       console.log(this.TAG, "play play end");
  115.     }
  116.   }
  117.   /**
  118.    * 销毁音效管理工具
  119.    */
  120.   public async destroy(){
  121.     console.log(this.TAG, "play destroy start");
  122.     await this.mAVPlayer?.release();
  123.     this.mAVPlayer = undefined;
  124.     this.isInit = false;
  125.     AudioMgr.mAudioMgr = null;
  126.     console.log(this.TAG, "play destroy end");
  127.   }
  128. }
复制代码
音效播放测试页
  1. import { promptAction } from '@kit.ArkUI'
  2. import { BusinessError } from '@kit.BasicServicesKit';
  3. import { AudioMgr } from '../../mgr/AudioMgr';
  4. /**
  5. * 音效播放
  6. */
  7. @Entry
  8. @Component
  9. struct AudioPage {
  10.   private TAG: string = "AudioPage";
  11.   onClickDestroy= ()=>{
  12.     AudioMgr.Ins().destroy();
  13.     this.showToast("销毁音效工具!");
  14.   }
  15.   onClickInit = ()=>{
  16.     AudioMgr.Ins().init();
  17.     this.showToast("初始化音效工具!");
  18.   }
  19.   onClickPlay = ()=>{
  20.     AudioMgr.Ins().play();
  21.     this.showToast("播放音效!");
  22.   }
  23.   private showToast(content: string){
  24.     try {
  25.       promptAction.showToast({
  26.         message: content,
  27.         duration: 2000
  28.       });
  29.     } catch (error) {
  30.       let message = (error as BusinessError).message
  31.       let code = (error as BusinessError).code
  32.       console.error(this.TAG, `showToast args error code is ${code}, message is ${message}`);
  33.     };
  34.   }
  35.   /**
  36.    * 统一样式封装
  37.    */
  38.   @Styles ButtonStyle(){
  39.     .width(px2vp(350))
  40.     .height(px2vp(200))
  41.     .margin({ top: px2vp(66) })
  42.   }
  43.   build() {
  44.     Column(){
  45.       Button("初始化音效工具")
  46.         .ButtonStyle()
  47.         .onClick(this.onClickInit)
  48.       Button("播放音效")
  49.         .ButtonStyle()
  50.         .onClick(this.onClickPlay)
  51.       Button("销毁音效工具")
  52.         .ButtonStyle()
  53.         .onClick(this.onClickDestroy)
  54.     }.size({
  55.       width: "100%",
  56.       height: "100%"
  57.     })
  58.   }
  59. }
复制代码
添加音频资源文件

https://sc.chinaz.com/yinxiao/23080315806.htm  音频资源可以从这个网站下载。
回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表