rntpc_react-native-audio:基于 react-native-audio 的 OpenHarmony 适配版,用于录制音频

基于 react-native-audio 的 OpenHarmony 适配版,用于录制音频

分支4Tags12

文档模板:v0.4.2

react-native-audio

本项目基于 react-native-audio 开发。

该第三方库的仓库已迁移至 Gitcode,且支持直接从 npm 下载,新的包名为:@react-native-ohos/react-native-audio 版本所属关系如下:

三方库名称 三方库版本(npm地址) 发布信息 支持RN版本 Autolink 编译API版本 社区基线版本 源码地址
@react-native-ohos/react-native-audio ~ 4.2.4 Gitcode Releases 0.72.* 是 API12+ 4.2.2 br_rnoh0.72
@react-native-oh-tpl/react-native-audio <= 4.3.1-0.1.0@deprecated Github Releases(deprecated) 0.72.* 否 API12+ 4.3.0 sig

简介

react-native-audio 是一个 React Native 音频录制扩展库,提供麦克风权限申请、录音参数配置、开始/暂停/恢复/停止录制,以及录制进度与完成回调等能力。鸿蒙侧基于系统 AVRecorder 实现,接口与上游社区库保持一致,import 包名不变。

下载安装

进入到工程目录并输入以下命令:

npm

npm install @react-native-ohos/react-native-audio

yarn

yarn add @react-native-ohos/react-native-audio
是否支持autolink RN框架版本
~ 4.2.4 是 0.72
<= 4.3.1-0.1.0@deprecated 否 0.72

使用 AutoLink 的工程需要根据 Autolink 框架指导文档 配置。

如您使用的版本支持 Autolink,并且工程已接入 Autolink,可跳过ManualLink配置。

ManualLink: 此步骤为手动配置原生依赖项的指导

首先需要使用 DevEco Studio 打开项目里的 HarmonyOS 工程 harmony。

1. Overrides RN SDK

为了让工程依赖同一个版本的 RN SDK,需要在工程根目录的 oh-package.json5 添加 overrides 字段,指向工程需要使用的 RN SDK 版本。替换的版本既可以是一个具体的版本号,也可以是一个模糊版本,还可以是本地存在的 HAR 包或源码目录。

关于该字段的作用请阅读官方说明

{
  "overrides": {
    "@rnoh/react-native-openharmony": "~0.72.140" // ohpm 在线版本
    // "@rnoh/react-native-openharmony" : "./react_native_openharmony.har" // 指向本地 har 包的路径
    // "@rnoh/react-native-openharmony" : "./react_native_openharmony" // 指向源码路径
  }
}

2. 引入原生端代码

目前有两种方法:

  • 通过 har 包引入;
  • 直接链接源码。

方法一:通过 har 包引入(推荐)

har 包位于三方库安装路径的 `harmony` 文件夹下。

打开 entry/oh-package.json5,添加以下依赖:

"dependencies": {
    "@react-native-ohos/react-native-audio": "file:../../node_modules/@react-native-ohos/react-native-audio/harmony/audio.har"
  }

点击右上角的 sync 按钮,或在命令行终端执行:

cd entry
ohpm install

方法二:直接链接源码

如需使用直接链接源码,请参考[直接链接源码说明](https://gitcode.com/CPF-RN/usage-docs/blob/master/zh-cn/link-source-code.md)

3. 配置 CMakeLists 和引入 AudioPackage

打开 entry/src/main/cpp/CMakeLists.txt,添加:

+ set(OH_MODULES "${CMAKE_CURRENT_SOURCE_DIR}/../../../oh_modules")

# RNOH_BEGIN: manual_package_linking_1
+ add_subdirectory("${OH_MODULES}/@react-native-ohos/react-native-audio/src/main/cpp" ./audio)
# RNOH_END: manual_package_linking_1

# RNOH_BEGIN: manual_package_linking_2
+ target_link_libraries(rnoh_app PUBLIC rnoh_audio)
# RNOH_END: manual_package_linking_2

打开 entry/src/main/cpp/PackageProvider.cpp,添加:

#include "RNOH/PackageProvider.h"
#include "generated/RNOHGeneratedPackage.h"
+ #include "AudioPackage.h"

using namespace rnoh;

std::vector<std::shared_ptr<Package>> PackageProvider::getPackages(Package::Context ctx) {
    return {
        std::make_shared<RNOHGeneratedPackage>(ctx),
+       std::make_shared<AudioPackage>(ctx)
    };
}

4. 在 ArkTs 侧引入 AudioPackage

打开 entry/src/main/ets/RNPackagesFactory.ets,添加:

  ...
+ import {AudioPackage} from '@react-native-ohos/react-native-audio/ts';

export function createRNPackages(ctx: RNPackageContext): RNPackage[] {
  return [
+   new AudioPackage(ctx)
  ];
}

运行

点击右上角的 sync 按钮,或在命令行终端执行:

cd entry
ohpm install

然后编译、运行即可。

约束与限制

兼容性

本文档内容基于以下版本验证通过:

  1. RNOH: 0.72.140; SDK: HarmonyOS 6.0.0 Release SDK; IDE: DevEco Studio 6.0.0.858; ROM: 6.0.0.112;

权限要求

录音功能需要在 HarmonyOS 工程 entry/src/main/module.json5 中声明麦克风权限:

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

编译运行 API 要求

当前三方库所有版本均已实现版本隔离,支持在 `API12+` 工程编译,及 `API12+` ROM 运行。

使用示例

下面的代码展示了这个库的基本使用场景:

使用时 import 的库名不变。

import React, { useEffect } from 'react';
import { SafeAreaView, Text, Button, View } from 'react-native';
import { AudioRecorder, AudioUtils, AudioSource } from 'react-native-audio';

export default function App() {
  const initRecording = async () => {
    await AudioRecorder.requestAuthorization();
    await AudioRecorder.checkAuthorizationStatus();

    await AudioRecorder.prepareRecordingAtPath(
      `${AudioUtils.FilesDirectoryPath}/audio_demo.m4a`,
      {
        SampleRate: 44100,
        Channels: 2,
        AudioQuality: 'High',
        AudioEncoding: 'aac',
        AudioEncodingBitRate: 32000,
        AudioSource: AudioSource.MIC,
        OutputFormat: 'm4a',
        MeteringEnabled: false,
        IncludeBase64: false,
      }
    );

    AudioRecorder.onProgress = (data) => {
      console.log('currentTime:', data.currentTime);
    };

    AudioRecorder.onFinished = (data) => {
      console.log('finished:', data.audioFileURL, data.duration);
    };
  };

  useEffect(() => {
    initRecording();
  }, []);

  return (
    <SafeAreaView>
      <View style={{ flexDirection: 'row', gap: 8, padding: 16 }}>
        <Button title="start" onPress={() => AudioRecorder.startRecording()} />
        <Button title="pause" onPress={() => AudioRecorder.pauseRecording()} />
        <Button title="resume" onPress={() => AudioRecorder.resumeRecording()} />
        <Button title="stop" onPress={() => AudioRecorder.stopRecording()} />
      </View>
    </SafeAreaView>
  );
}

使用说明

录音流程

  1. 调用 requestAuthorization 申请麦克风权限;
  2. 调用 prepareRecordingAtPath(path, options) 初始化录音参数并订阅原生事件;
  3. 设置 AudioRecorder.onProgress / AudioRecorder.onFinished 回调;
  4. 调用 startRecording 开始录音,可 pauseRecording / resumeRecording;
  5. 调用 stopRecording 停止录音;约 200ms 后会自动移除事件订阅并清空回调引用;
  6. 开始新的录音会话前,需重新调用 prepareRecordingAtPath 并重新设置回调。

prepareRecordingAtPath 默认参数

JS 层默认值(与上游社区库对齐)如下,鸿蒙/Android 未显式传入 AudioEncoding 时会自动将 ima4 替换为 aac,并默认 AudioSource: 1(MIC):

参数 默认值
SampleRate 44100
Channels 2
AudioQuality High
AudioEncoding ima4(Android/HarmonyOS 默认转为 aac)
OutputFormat mpeg_4
AudioEncodingBitRate 32000
MeteringEnabled false
MeasurementMode false
IncludeBase64 false

AudioUtils 路径(HarmonyOS)

鸿蒙平台提供以下目录路径,用于拼接录音文件保存位置:

属性 说明
FilesDirectoryPath 应用文件目录
CacheDirectoryPath 应用缓存目录
TempsDirectoryPath 应用临时目录

AudioEncoding 格式支持

值 iOS Android HarmonyOS Support
aac yes yes yes
aac_eld4.2.5+ yes yes yes(API 22+)
he_aac4.2.5+ no yes yes(API 22+)
amr_nb4.2.5+ yes yes yes(API 18+)
amr_wb4.2.5+ no yes yes(API 18+)
mp34.2.5+ no no yes(API 12+)
ima4 yes no no
vorbis no yes no
lpcm yes no no
alac yes no no

OutputFormat 格式支持

值 iOS Android HarmonyOS Support
mpeg_44.2.5+ no yes yes
m4a no yes yes
aac_adts4.2.5+ no yes yes(API 20+)
amr_nb no yes no
amr_wb no yes no
three_gpp4.2.5+ no yes yes(API 18+)
mp34.2.5+ no no yes
webm no yes no

OutputFormat 为 Android 专用参数;iOS 通过文件扩展名与 AudioEncoding 决定输出格式。MP3 编码须配合 OutputFormat=mp3。

AudioSource 常量

常量 值 iOS Android HarmonyOS Support
DEFAULT 0 no yes yes
MIC 1 no yes yes
VOICE_UPLINK 2 no yes no
VOICE_DOWNLINK 3 no yes no
VOICE_CALL 4 no yes no
CAMCORDER4.2.5+ 5 no yes yes
VOICE_RECOGNITION4.2.5+ 6 no yes yes
VOICE_COMMUNICATION4.2.5+ 7 no yes yes
REMOTE_SUBMIX 8 no yes(API 19+) no
UNPROCESSED 9 no yes(API 24+) no

电平计量(MeteringEnabled4.2.5+)

当 MeteringEnabled: true 时,onProgress 回调除 currentTime 外还会包含 currentMetering 与 currentPeakMetering 字段。

接口说明

"Platform" 列表示该属性在原三方库上支持的平台。

"HarmonyOS Support" 列为 **yes** 表示 HarmonyOS 平台支持该属性;标注 **API xx+** 表示需对应 HarmonyOS SDK API 级别;**no** 则表示不支持。使用方法跨平台一致,效果对标 iOS 或 Android 的效果。

**版本角标**:名称旁标注 4.2.5+ 表示该 API / 参数 / 枚举值自 **4.2.5+** 起在 HarmonyOS 侧新增或增强支持;

事件回调

名称 类型 参数类型 返回值 必填 平台 OpenHarmony平台支持 描述
onProgress function data: { currentTime: number, currentMetering?: number, currentPeakMetering?: number } void no Android/iOS yes 录音进度回调。接收 { currentTime: number };当 MeteringEnabled: true 时还包含 currentMetering、currentPeakMetering
onFinished function data: { base64?: string, duration: number, status: string, audioFileURL: string, audioFileSize: number } void no Android/iOS yes 录音完成回调。接收 { base64, duration, status, audioFileURL, audioFileSize };base64 仅在 IncludeBase64: true 时有值

注意:stopRecording 会在约 200ms 延迟后自动移除原生事件订阅并清除 onProgress / onFinished 回调引用。开始新的录音会话前,必须重新调用 prepareRecordingAtPath 并重新设置回调。

API

名称 类型 参数类型 返回值 必填 平台 OpenHarmony平台支持 描述
requestAuthorization function / Promise no Android/iOS yes 请求麦克风权限
checkAuthorizationStatus function / Promise no Android/iOS yes 检查授权状态。返回值存在平台差异:iOS 返回 string 枚举值('granted' / 'denied' / 'undetermined'),Android/HarmonyOS 返回 boolean
prepareRecordingAtPath function path: string, options: RecordingOptions Promise no Android/iOS yes 初始化录音实例参数
startRecording function / Promise no Android/iOS yes 开始录音
pauseRecording function / Promise no Android/iOS yes 暂停录音
resumeRecording function / Promise no Android/iOS yes 恢复录音
stopRecording function / Promise no Android/iOS yes 停止录音
getAllPath function / { FilesDirectoryPath: string, CacheDirectoryPath: string, TempsDirectoryPath: string } no HarmonyOS yes 获取应用文件/缓存/临时目录路径;模块加载时用于生成鸿蒙平台 AudioUtils
removeListeners function / void no Android/iOS yes 移除录音进度和完成事件订阅;stopRecording 延迟后会自动调用,通常无需手动调用
clearCallback function / void no HarmonyOS yes 清空 onProgress / onFinished 回调引用;stopRecording 延迟后会自动调用,通常无需手动调用

prepareRecordingAtPath 参数(RecordingOptions)

名称 参数类型 默认值 必填 平台 OpenHarmony平台支持 描述
SampleRate number 44100 yes Android/iOS yes 采样率(Hz)
Channels number 2 yes Android/iOS yes 声道数
AudioQuality4.2.5+ 'Low' / 'Medium' / 'High' High no iOS/Android yes 音质档位,影响码率:Low=32000、Medium=64000、High=使用 AudioEncodingBitRate
AudioEncoding4.2.5+ string aac(Android/HarmonyOS) yes Android/iOS yes 编码格式,见上方「AudioEncoding 格式支持」(部分枚举值需 API 12+/18+/22+)
AudioEncodingBitRate number 32000 yes Android/iOS yes 编码码率(bps)
AudioSource4.2.5+ number 1(MIC) yes Android yes 音源类型,见上方「AudioSource 常量」(扩展音源需 API 12+)
OutputFormat4.2.5+ string mpeg_4 yes Android yes 封装格式,见上方「OutputFormat 格式支持」(部分枚举值需 API 12+/18+/20+)
MeteringEnabled4.2.5+ boolean false no iOS/Android yes 是否开启电平计量
MeasurementMode boolean false no iOS no iOS 专用测量模式
IncludeBase64 boolean false yes Android/iOS yes 停止录音时是否返回 base64 数据

AudioUtils 属性

库导出的目录路径常量(均为 string 类型),用于拼接录音文件保存位置;按平台取值不同:

名称 类型 必填 平台 OpenHarmony平台支持 描述
FilesDirectoryPath string no HarmonyOS yes 应用文件目录
CacheDirectoryPath string no HarmonyOS yes 应用缓存目录
TempsDirectoryPath string no HarmonyOS yes 应用临时目录
MainBundlePath string no Android/iOS no 应用安装包主目录
CachesDirectoryPath string no Android/iOS no 应用缓存目录(鸿蒙侧名称为 CacheDirectoryPath)
DocumentDirectoryPath string no Android/iOS no 应用文档目录
LibraryDirectoryPath string no Android/iOS no 应用 Library 目录
PicturesDirectoryPath string no Android no 系统图片目录
MusicDirectoryPath string no Android no 系统音乐目录
DownloadsDirectoryPath string no Android no 系统下载目录

鸿蒙平台取值来自 getAllPath() 返回的应用沙箱目录,在模块加载时生成。

遗留问题

  • MeasurementMode 为 iOS 专用参数,HarmonyOS 侧忽略
  • ima4、vorbis、webm 等格式在 HarmonyOS 侧不支持,请参见上方格式支持表
  • AudioSource 中 VOICE_UPLINK、VOICE_DOWNLINK、VOICE_CALL、REMOTE_SUBMIX、UNPROCESSED 在 HarmonyOS 侧不支持

其他

  • 完整 API 演示可参考工程内 example/src/AudioDemo.tsx
  • 英文文档见 README_EN.md

目录结构

/rntpc_react-native-audio           # 项目根目录
├── harmony                         # 鸿蒙适配代码
│   ├── audio.har                   # HAR 包(npm 发布产物)
│   └── audio                       # 鸿蒙适配核心模块
│       ├── index.ets
│       ├── oh-package.json5
│       └── src/main
│           ├── cpp                 # C++ TurboModule 与 codegen 产物
│           │   ├── AudioPackage.h
│           │   ├── CMakeLists.txt
│           │   └── generated/
│           └── ets
│               ├── AudioPackage.ets
│               ├── AudioModule.ts
│               ├── AudioRecordManager.ts
│               ├── AudioApiCompat.ts
│               ├── AudioType.ts
│               ├── StopWatch.ts
│               └── generated/      # codegen 产物
├── example                         # 示例工程
├── index.js                        # JS 入口
├── NativeAudio.ts                  # TurboModule 类型定义
├── package.json
├── README.md                       # 中文文档
├── README_EN.md                    # 英文文档
└── LICENSE

贡献代码

使用过程中发现任何问题都可以提交 Issue,也非常欢迎提交 PR。

开源协议

本项目基于 The MIT License (MIT) ,请自由地享受和参与开源。

项目介绍

基于 react-native-audio 的 OpenHarmony 适配版,用于录制音频

定制我的领域