发布时间:2025-06-24 19:31:50  作者:北方职教升学中心  阅读量:222


📝往期推文全新看点(文中附带最新·鸿蒙全栈学习笔记)

🚩 鸿蒙(HarmonyOS)北向开发知识点记录~

🚩 鸿蒙(OpenHarmony)南向开发保姆级知识点汇总~

🚩 鸿蒙应用开发与鸿蒙系统开发哪个更有前景?

🚩 嵌入式开发适不适合做鸿蒙南向开发?看完这篇你就了解了~

🚩 对于大前端开发来说,转鸿蒙开发究竟是福还是祸?

🚩 鸿蒙岗位需求突增!移动端、

OHAudio依赖libohaudio.so动态库,通过引入<native_audiostreambuilder.h>和<native_audiocapturer.h)>头文件,使用音频录制相关API。

AudioCapture

使用AudioCapturer录制音频涉及到AudioCapturer实例的创建、

权限申请

音频采集需要动态申请权限,现在module.json5中声明权限:

"requestPermissions": [    {      "name": "ohos.permission.MICROPHONE",      "reason": "$string:reason",      "usedScene": {        "abilities": [          "FormAbility"        ],        "when": "inuse"      }    }  ],

动态申请权限:

function reqPermissionsFromUser(permissions: Array<Permissions>, context: common.UIAbilityContext): void {    let atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager();    // requestPermissionsFromUser会判断权限的授权状态来决定是否唤起弹窗    atManager.requestPermissionsFromUser(context, permissions).then((data) => {      let grantStatus: Array<number> = data.authResults;      let length: number = grantStatus.length;      for (let i = 0; i < length; i++) {        if (grantStatus[i] === 0) {          // 用户授权,可以继续访问目标操作        } else {          // 用户拒绝授权,提示用户必须授权才能访问当前页面的功能,并引导用户到系统设置中打开相应的权限          return;        }      }    // 授权成功    }).catch((err: BusinessError) => {      console.error(`Failed to request permissions from user. Code is ${err.code}, message is ${err.message}`);    })  }

在aboutToAppera中调用申请权限方法,在授权成功后启动录音

const context: common.UIAbilityContext = getContext(this) as common.UIAbilityContext;    reqPermissionsFromUser(permissions, context);  }
配置C++项目

创建C++模块后,配置ohaudio动态库依赖:

cmake_minimum_required(VERSION 3.5.0)  project(audiorecorderdemo)    set(NATIVERENDER_ROOT_PATH ${CMAKE_CURRENT_SOURCE_DIR})    if(DEFINED PACKAGE_FIND_FILE)      include(${PACKAGE_FIND_FILE})  endif()    include_directories(${NATIVERENDER_ROOT_PATH}                      ${NATIVERENDER_ROOT_PATH}/include)    add_library(capture SHARED napi_init.cpp)  target_link_libraries(capture PUBLIC libace_napi.z.so)  target_link_libraries(capture PUBLIC libohaudio.so)

配置napi方法:

static napi_value start(napi_env env, napi_callback_info info)  {              return nullptr;    }  static napi_value stop(napi_env env, napi_callback_info info)  {              return nullptr;    }  EXTERN_C_START  static napi_value Init(napi_env env, napi_value exports)  {      napi_property_descriptor desc[] = {          { "start", nullptr, start, nullptr, nullptr, nullptr, napi_default, nullptr },          { "stop", nullptr, stop, nullptr, nullptr, nullptr, napi_default, nullptr }      };      napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);      return exports;  }
实现启动录制
// 自定义写入数据函数  int32_t MyOnReadData(      OH_AudioCapturer* capturer,      void* userData,      void* buffer,      int32_t length)  {      //TODO 从buffer中取出length长度的录音数据      return 0;  }  // 自定义音频流事件函数  int32_t MyOnStreamEvent(      OH_AudioCapturer* capturer,      void* userData,      OH_AudioStream_Event event)  {      //TODO 根据event表示的音频流事件信息,更新播放器状态和界面      return 0;  }  // 自定义音频中断事件函数  int32_t MyOnInterruptEvent(      OH_AudioCapturer* capturer,      void* userData,      OH_AudioInterrupt_ForceType type,      OH_AudioInterrupt_Hint hint)  {      //TODO 根据type和hint表示的音频中断信息,更新录制器状态和界面      return 0;  }  // 自定义异常回调函数  int32_t MyOnError(      OH_AudioCapturer* capturer,      void* userData,      OH_AudioStream_Result error)  {      //TODO 根据error表示的音频异常信息,做出相应的处理      return 0;  }  static napi_value start(napi_env env, napi_callback_info info)  {      OH_AudioStreamBuilder* builder;      OH_AudioStreamBuilder_Create(&builder, AUDIOSTREAM_TYPE_CAPTURER);      // 设置音频采样率      OH_AudioStreamBuilder_SetSamplingRate(builder, 48000);      // 设置音频声道      OH_AudioStreamBuilder_SetChannelCount(builder, 2);      // 设置音频采样格式      OH_AudioStreamBuilder_SetSampleFormat(builder, AUDIOSTREAM_SAMPLE_S16LE);      // 设置音频流的编码类型      OH_AudioStreamBuilder_SetEncodingType(builder, AUDIOSTREAM_ENCODING_TYPE_RAW);      // 设置输入音频流的工作场景      OH_AudioStreamBuilder_SetCapturerInfo(builder, AUDIOSTREAM_SOURCE_TYPE_MIC);            OH_AudioCapturer_Callbacks callbacks;      // 配置回调函数      callbacks.OH_AudioCapturer_OnReadData = MyOnReadData;      callbacks.OH_AudioCapturer_OnStreamEvent = MyOnStreamEvent;      callbacks.OH_AudioCapturer_OnInterruptEvent = MyOnInterruptEvent;      callbacks.OH_AudioCapturer_OnError = MyOnError;      // 设置音频输入流的回调      OH_AudioStreamBuilder_SetCapturerCallback(builder, callbacks, nullptr);      OH_AudioCapturer* audioCapturer;      OH_AudioStreamBuilder_GenerateCapturer(builder, &audioCapturer);      return nullptr;  }

最佳实践一:
为了避免不可预期的行为,在设置音频回调函数时,请确保OH_AudioCapturer_Callbacks的每一个回调都被自定义的回调方法空指针初始化,比如:

OH_AudioCapturer_Callbacks callbacks;// 配置回调函数,如果需要监听,则赋值callbacks.OH_AudioCapturer_OnReadData = MyOnReadData;callbacks.OH_AudioCapturer_OnInterruptEvent = MyOnInterruptEvent;// (必选)如果不需要监听,使用空指针初始化callbacks.OH_AudioCapturer_OnStreamEvent = nullptr;callbacks.OH_AudioCapturer_OnError = nullptr;

最佳实践二:
对于支持低延时模式的设备,对于延时要求比较高的场景(比如语音通话)可以使用低时延模式创建音频录制构造器,获得更高质量的音频体验:

OH_AudioStream_LatencyMode latencyMode = AUDIOSTREAM_LATENCY_MODE_FAST;OH_AudioStreamBuilder_SetLatencyMode(builder, latencyMode);
音频文件处理

在音频回调中我们对音频数据就行处理,可以交给ASR也可以直接写入文件,下一篇我们实现编码成mp3并写入文件的实践。

构造录制音频流
OH_AudioCapturer* audioCapturer;OH_AudioStreamBuilder_GenerateCapturer(builder, &audioCapturer);
使用音频流
  • OH_AudioStream_Result OH_AudioCapturer_Start(OH_AudioCapturer* capturer):开始录制
  • OH_AudioStream_Result OH_AudioCapturer_Pause(OH_AudioCapturer* capturer):暂停录制
  • OH_AudioStream_Result OH_AudioCapturer_Stop(OH_AudioCapturer* capturer):停止录制
  • OH_AudioStream_Result OH_AudioCapturer_Flush(OH_AudioCapturer* capturer):释放缓存数据
  • OH_AudioStream_Result OH_AudioCapturer_Release(OH_AudioCapturer* capturer):释放录制实例
释放构造器
OH_AudioStreamBuilder_Destroy(builder);

音频录制最佳实践

我们以录制MP3为例来实现音频采集的全流程实践。

设置音频回调函数
// 自定义写入数据函数int32_t MyOnReadData(    OH_AudioCapturer* capturer,    void* userData,    void* buffer,    int32_t length){    // 从buffer中取出length长度的录音数据    return 0;}// 自定义音频流事件函数int32_t MyOnStreamEvent(    OH_AudioCapturer* capturer,    void* userData,    OH_AudioStream_Event event){    // 根据event表示的音频流事件信息,更新播放器状态和界面    return 0;}// 自定义音频中断事件函数int32_t MyOnInterruptEvent(    OH_AudioCapturer* capturer,    void* userData,    OH_AudioInterrupt_ForceType type,    OH_AudioInterrupt_Hint hint){    // 根据type和hint表示的音频中断信息,更新录制器状态和界面    return 0;}// 自定义异常回调函数int32_t MyOnError(    OH_AudioCapturer* capturer,    void* userData,    OH_AudioStream_Result error){    // 根据error表示的音频异常信息,做出相应的处理    return 0;}OH_AudioCapturer_Callbacks callbacks;// 配置回调函数callbacks.OH_AudioCapturer_OnReadData = MyOnReadData;callbacks.OH_AudioCapturer_OnStreamEvent = MyOnStreamEvent;callbacks.OH_AudioCapturer_OnInterruptEvent = MyOnInterruptEvent;callbacks.OH_AudioCapturer_OnError = MyOnError;// 设置音频输入流的回调OH_AudioStreamBuilder_SetCapturerCallback(builder, callbacks, nullptr);

通过OH_AudioStreamBuilder_SetCapturerCallback函数配置回调函数。

创建构造器
OH_AudioStreamBuilder* builder;OH_AudioStreamBuilder_Create(&builder, AUDIOSTREAM_TYPE_CAPTURER);
配置音频流参数

可参考如下示例:

// 设置音频采样率OH_AudioStreamBuilder_SetSamplingRate(builder, 48000);// 设置音频声道OH_AudioStreamBuilder_SetChannelCount(builder, 2);// 设置音频采样格式OH_AudioStreamBuilder_SetSampleFormat(builder, AUDIOSTREAM_SAMPLE_S16LE);// 设置音频流的编码类型OH_AudioStreamBuilder_SetEncodingType(builder, AUDIOSTREAM_ENCODING_TYPE_RAW);// 设置输入音频流的工作场景OH_AudioStreamBuilder_SetCapturerInfo(builder, AUDIOSTREAM_SOURCE_TYPE_MIC);

参数作用于AudioCapture类似。很多音频编码库都是C/C++实现的,在迁移到 鸿蒙 平台后,采集侧也使用OHAudio C++接口,可以减少数据在TS层与C++层传递的消耗,提高效率。在Android和iOS端,系统提供了两种形式:

  • 实时音频流采集
  • 音频文件录制

系统还提供了不同形式的API,比如Android:

  • AudioRecorder Java接口
  • MediaRecorder Java接口
  • OpenSLES C++接口
  • AAudio C++接口

在 鸿蒙 化适配的过程中也有音频采集的需求,本文我们一步一步实现音频采集功能。资源的释放等,下面官方给出的状态示意图将方法和状态切换标记的很清晰:

createAudioCapture

创建capture主要涉及到参数配置:

import { audio } from '@kit.AudioKit';  let audioStreamInfo: audio.AudioStreamInfo = {   samplingRate: audio.AudioSamplingRate.SAMPLE_RATE_48000, // 采样率   channels: audio.AudioChannel.CHANNEL_2, // 通道   sampleFormat: audio.AudioSampleFormat.SAMPLE_FORMAT_S16LE, // 采样格式   encodingType: audio.AudioEncodingType.ENCODING_TYPE_RAW // 编码格式 };  let audioCapturerInfo: audio.AudioCapturerInfo = {   source: audio.SourceType.SOURCE_TYPE_MIC,   capturerFlags: 0 };  let audioCapturerOptions: audio.AudioCapturerOptions = {   streamInfo: audioStreamInfo,   capturerInfo: audioCapturerInfo };  audio.createAudioCapturer(audioCapturerOptions, (err, data) => {   if (err) {   } else {     let audioCapturer = data;   } });

参数包含两大块:

  • AudioStreamInfo:音频格式配置信息
    • samplingRate:采样率
    • channels:声道数
    • sampleFormat:采样格式
    • encodingType:音频编码类型,目前只支持PCM的ENCODING_TYPE_RAW配置
  • AudioCapturerInfo:采集配置信息
    • source:音源类型,包含:
      • SOURCE_TYPE_INVALID:无效的音频源
      • SOURCE_TYPE_MIC:Mic音频源
      • SOURCE_TYPE_VOICE_RECOGNITION:语音识别源
      • SOURCE_TYPE_PLAYBACK_CAPTURE:播放音频流(内录)录制音频源
      • SOURCE_TYPE_VOICE_COMMUNICATION:语音通话场景的音频源
      • SOURCE_TYPE_VOICE_MESSAGE:短语音消息的音频源
    • capturerFlags:音频采集器标志,0代表音频采集器
on(‘readData’)

on(‘readData’)方法用来订阅监听音频数据读入回调:

let readDataCallback = (buffer: ArrayBuffer) => {//处理音频流}audioCapturer.on('readData', readDataCallback);
start

start方法用来开始录制:

import { BusinessError } from '@kit.BasicServicesKit'; audioCapturer.start((err: BusinessError) => {   if (err) {   } else {        } });
stop

stop用来停止录制:

import { BusinessError } from '@kit.BasicServicesKit'; audioCapturer.stop((err: BusinessError) => {   if (err) {   } else {   } });
release

release销毁实例,释放资源

import { BusinessError } from '@kit.BasicServicesKit'; audioCapturer.release((err: BusinessError) => {   if (err) {   } else {   } });

OHAudio

OHAudio是系统在API version 10中引入的一套C API,此API在设计上实现归一,同时支持普通音频通路和低时延通路。PC端、IoT到底该怎么选?

🚩 记录一场鸿蒙开发岗位面试经历~

📃 持续更新中……


背景

应用开发过程中很多场景都有音频采集需求,比如聊天功能的发送语音功能,实时语音转文本功能,实时语音通话,实时视频通话等。

音频录制接口介绍

HarmonyOS 提供了TS与C++两种音频采集接口:

  • AudioCapture
  • OHAudio

分别介绍这两种语言的API。采集的开始与停止、

停止播放销毁实例
OH_AudioCapturer_Stop(builder, &audioCapturer);OH_AudioStreamBuilder_Destroy(builder);

总结

本文介绍了HarmonyOS 提供的两种音频采集方式:TS层的AudioCapture和C++层的OHAudio,并以OHAudio接口实现了实时音频采集功能。音频采集参数的配置、仅支持PCM格式,适用于依赖Native层实现音频输入功能的场景。