HarmonyOS鸿蒙Next中播放MP3怎么获取振幅?

HarmonyOS鸿蒙Next中播放MP3怎么获取振幅? 录制的时候可以使用。recorder.getAudioCapturerMaxAmplitude() 。那我播放的时候怎么获取?

5 回复

播放(Playback)时获取音频最大振幅(电平值)需要使用 AVPlayeron('amplitudeUpdate') 事件订阅机制,而不是像录制时那样调用 getAudioCapturerMaxAmplitude() 方法。

场景 组件 方法/事件 说明
录制 (Recording) AVRecorder getAudioCapturerMaxAmplitude() 主动调用获取,返回的是上一次调用到当前时间区间内的音频最大振幅
播放 (Playback) AVPlayer on('amplitudeUpdate') 订阅事件,音频播放时系统定时自动上报当前音频的最大电平值

播放时获取音频最大振幅的详细步骤

步骤1:创建AVPlayer并准备资源

import { media } from '@kit.MediaKit';

// 创建AVPlayer实例
let avPlayer: media.AVPlayer = await media.createAVPlayer();

// 设置资源并准备
avPlayer.url = '您的音频/视频文件路径或URL';
await avPlayer.prepare();

步骤2:订阅 amplitudeUpdate 事件

// 订阅音频最大电平值更新事件
avPlayer.on('amplitudeUpdate', (value: Array<number>) => {
  // value是一个数字数组,包含左右声道的最大电平值
  console.info(`音频最大电平值: ${value}`);
  // 例如: [0.75, 0.68] 表示左声道0.75,右声道0.68
  // 取值范围通常在[0, 1]之间
});

步骤3:开始播放

// 开始播放
avPlayer.play();
// 事件会在音频资源播放时定时触发

步骤4:取消订阅(不需要时)

// 取消订阅特定回调
avPlayer.off('amplitudeUpdate', callbackFunction);

// 或取消所有amplitudeUpdate事件的订阅
avPlayer.off('amplitudeUpdate');

关键参数说明

  • 事件类型: 'amplitudeUpdate'(API version 13+ 支持)
  • 回调参数: Array<number>
    • 数组包含左右声道的最大电平值
    • 例如 [左声道值, 右声道值]
    • 取值范围通常为 [0, 1],其中0表示无声,1表示最大电平
  • 触发时机: 音频资源播放时系统定时自动上报

注意事项!

  1. API版本要求: on('amplitudeUpdate') 需要 API version 13+
  2. 系统能力: 需要 SystemCapability.Multimedia.Media.AVPlayer 能力
  3. 播放状态: 只有在音频实际播放时才会触发该事件
  4. 与录制的区别:
    • 录制: 主动拉取 (getAudioCapturerMaxAmplitude())
    • 播放: 被动接收 (on('amplitudeUpdate'))
  5. 数据类型: 播放返回的是电平值数组,而录制返回的是单个振幅数值

相关文档:【interface_on(‘amplitudeUpdate’)】

更多关于HarmonyOS鸿蒙Next中播放MP3怎么获取振幅?的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


import { BusinessError } from '@kit.BasicServicesKit';

let rendererInfo: audio.AudioRendererInfo = {
  usage: audio.StreamUsage.STREAM_USAGE_MUSIC, // 音频流使用类型:音乐。根据业务场景配置,参考StreamUsage。
  rendererFlags: 0 // 音频渲染器标志。
};

audio.getAudioManager().getRoutingManager().getPreferOutputDeviceForRendererInfo(rendererInfo).then((data) => {
  audioVolumeGroupManager.getMaxAmplitudeForOutputDevice(data[0]).then((value) => {
    console.info(`max amplitude is: ${value}`);
  }).catch((err: BusinessError) => {
    console.error(`getMaxAmplitudeForOutputDevice error. Code: ${err.code}, message: ${err.message}`);
  })
}).catch((err: BusinessError) => {
  console.error(`getPreferOutputDeviceForRendererInfo error. Code: ${err.code}, message: ${err.message}`);
})

参考地址

https://developer.huawei.com/consumer/cn/doc/harmonyos-references/arkts-apis-audio-audiovolumegroupmanager#getmaxamplitudeforoutputdevice12

如果你使用 AVPlayer 进行播放的话,可以试试,监听 ‘amplitudeUpdate’

on(type: ‘amplitudeUpdate’, callback: Callback<Array<number>>): void

订阅音频最大电平值,音频资源播放时定时上报。

async function test(){
  let avPlayer = await media.createAVPlayer();
  avPlayer.on('amplitudeUpdate', (value: Array<number>) => {
    console.info(`amplitudeUpdate called,and amplitudeUpdate = ${value}`);
  });
}

在HarmonyOS Next中,获取MP3振幅可通过AudioRenderer实现。使用getAudioTime获取时间戳,结合on('audioInterrupt')监听音频中断事件,通过AudioRenderergetBufferSizeon('dataReceived')回调获取原始音频数据。计算振幅需处理PCM数据,取绝对值并计算均方根。示例代码涉及AudioRenderer的创建、配置及数据回调处理。

在HarmonyOS Next中,播放音频时获取实时振幅数据,需要使用AudioRenderergetAudioTimegetBufferSize等接口结合音频数据处理来实现,因为系统没有直接提供类似getAudioCapturerMaxAmplitude的播放振幅查询方法。

核心思路是:在播放音频前,先解码或读取音频文件(如MP3)的PCM数据,然后对这些原始音频数据进行分析计算,得到振幅信息。播放时,可以将计算好的振幅数据与播放进度进行同步。

简要步骤如下:

  1. 准备音频数据:使用AudioDecoder等组件将MP3文件解码为PCM格式的原始音频数据(通常为16位有符号整数)。你需要读取这些数据到内存中(例如ArrayBuffer)。

  2. 计算振幅:对解码后的PCM数据块(例如每1024个采样点为一个窗口)进行计算。振幅通常指该窗口内采样点绝对值的最大值,或计算均方根值(RMS)来反映平均能量。

    // 示例:计算一个数据块(Int16Array)的最大振幅(绝对值)
    function calculateMaxAmplitude(pcmData, startIndex, windowSize) {
      let max = 0;
      for (let i = 0; i < windowSize && startIndex + i < pcmData.length; i++) {
        const sample = Math.abs(pcmData[startIndex + i]);
        if (sample > max) {
          max = sample;
        }
      }
      return max; // 值范围通常为0~32767(对于16位有符号PCM)
    }
    
  3. 播放与同步:使用AudioRenderer播放原始PCM数据。同时,你需要根据AudioRenderer的播放进度(可通过getAudioTime获取已渲染的帧数或时间),映射到对应的音频数据块,并取出或实时计算该数据块的振幅值。

注意:这个过程需要你在应用层管理音频数据和播放状态,实现数据解析、振幅计算和播放进度同步。如果音频文件较大,需注意内存和性能管理。对于简单的波形显示,可以预先计算并存储关键点的振幅值,播放时根据进度进行插值查询。

回到顶部