语音转文字识别库
| Files | Last commit | Last update |
|---|---|---|
| 18 days ago | ||
| 18 days ago | ||
| 19 days ago | ||
| 1 month ago | ||
| 1 month ago | ||
| 1 month ago | ||
| 1 month ago | ||
| 1 month ago | ||
| 28 days ago | ||
| 19 days ago | ||
| 18 days ago | ||
| 18 days ago | ||
| 1 month ago | ||
| 18 days ago | ||
| 1 month ago |
react-native-voice
react-native-voice 基于上游 @react-native-voice/voice 开发。如果在使用过程中有任何问题,欢迎在GitCode提交Issue,会及时跟进。
项目介绍
react-native-voice 为 React Native 提供实时语音识别能力:开始 / 停止 / 取消 / 销毁识别会话,查询识别可用性与当前是否正在识别,并通过 7 个 device 事件把识别开始、结束、识别中、部分结果、最终结果、音量变化、错误逐一回抛给 JS。
react-native-voice 是 OpenHarmony(RNOH)适配版,落成一个 ArkTS TurboModule(Voice),不含 Fabric 组件:
- 上游基线
v3.2.4(MIT),旧架构NativeModules直接取模块,无 codegen 输入;鸿蒙侧Platform.OS === 'harmony'使上游 JS 走与 iOS 相同的调用分支(2 参、无options),故本端以 iOS 原生导出面为基准实现。 - 底层能力 = CoreSpeechKit
speechRecognizer(识别,本地引擎)+@ohos.multimedia.audioAudioCapturer(麦克风采集,定长 640/1280 字节分帧)。 - 迁移面合计:1 个 TurboModule / 8 个方法 / 7 个 device 事件 / 0 Fabric 组件。
集成指南
本节用于接入已有 RN 鸿蒙应用;运行本仓库示例请参见「快速验证(运行 Example)」。
1. 安装适配包
当前 npm 适配包为 @hxa-rn/react-native-voice-voice@3.2.5(与上游基线同号),业务代码仍从上游包名 @react-native-voice/voice 导入。在 RN 应用根目录执行:
npm install @hxa-rn/react-native-voice-voice@3.2.5 --save-exact --legacy-peer-deps
peerDependencies:{"react":">=18","react-native":">=0.72"}。还需已有可运行的 RNOH 宿主工程。
2. 配置 Metro 并导入
适配包已声明 harmony.alias。宿主 metro.config.js 合并以下配置,并保留原有的自定义设置:
const {getDefaultConfig, mergeConfig} = require('@react-native/metro-config');
const {createHarmonyMetroConfig} = require('@react-native-oh/react-native-harmony/metro.config');
module.exports = mergeConfig(
getDefaultConfig(__dirname),
createHarmonyMetroConfig({
reactNativeHarmonyPackageName: '@react-native-oh/react-native-harmony',
}),
);
业务代码:
import Voice from '@react-native-voice/voice';
3. 注册鸿蒙原生模块
本包声明了 Autolinking 元数据:CMake 目标 voice,ohpm 包 @oh-rn/voice,C++ / ETS 类 VoicePackage。宿主启用 RNOH Autolinking 后,应检查生成的 HAR 依赖、CMake 链接及 C++ / ETS Package 注册是否齐全;已自动注册时不要重复手动注册。
Autolinking 不可用时,保留宿主已有配置,补齐以下四处:
- 在
harmony/entry/oh-package.json5的dependencies追加下项,然后在harmony/entry执行ohpm install并同步工程:
"@oh-rn/voice": "file:../../node_modules/@hxa-rn/react-native-voice-voice/harmony/voice.har"
- 在
harmony/entry/src/main/cpp/CMakeLists.txt添加子目录,并在已有add_library(rnoh_app ...)之后链接:
set(OH_MODULE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../oh_modules")
add_subdirectory("${OH_MODULE_DIR}/@oh-rn/voice/src/main/cpp" ./voice)
# 放在 rnoh_app 目标创建之后:
target_link_libraries(rnoh_app PUBLIC voice)
- 在
harmony/entry/src/main/cpp/PackageProvider.cpp添加头文件,并把实例加入已有getPackages返回集合(本仓库模板可加入ManualLinkingPackage列表):
#include "VoicePackage.h"
// 加入已有 Package 集合:
std::make_shared<rnoh::VoicePackage>(ctx)
- 在
harmony/entry/src/main/ets/RNPackagesFactory.ets添加默认导入,并把实例加入已有createRNPackages返回数组:
import VoicePackage from '@oh-rn/voice';
// 加入 createRNPackages(ctx) 返回数组:
new VoicePackage(ctx)
确保宿主 RNApp 使用上述 createRNPackages,并启用 enableCAPIArchitecture: true。完成后重新生成宿主 Bundle、构建并安装 HAP;只刷新 JS 不会加载新增的原生模块。若 HAR 内 RNOH 相对依赖无法解析,在宿主鸿蒙根 oh-package.json5 的 overrides 中将 @rnoh/react-native-openharmony 指向宿主正在使用的同一 RNOH HAR,勿混用 debug/release 或不同版本。
4. 麦克风与识别环境
在宿主 harmony/entry/src/main/module.json5 的 module.requestPermissions 中声明麦克风权限(与本仓示例相同):
"requestPermissions": [
{
"name": "ohos.permission.MICROPHONE",
"reason": "$string:microphone_permission_reason",
"usedScene": {
"abilities": ["EntryAbility"],
"when": "inuse"
}
}
]
$string:microphone_permission_reason 需在 harmony/entry/src/main/resources/base/element/string.json 中定义(例如「用于录制麦克风音频以进行语音识别」);abilities 填宿主实际承载 RN 页面的 Ability。运行时授权弹窗由本库在 Voice.start() 时自动发起,宿主无需另行申请;用户拒绝时回抛 onSpeechError(code: permission_denied),不会开麦。设备需支持 CoreSpeechKit 识别引擎。
使用说明
import Voice from '@react-native-voice/voice';
import { useEffect } from 'react';
useEffect(() => {
Voice.onSpeechStart = () => console.log('start');
Voice.onSpeechEnd = () => console.log('end');
Voice.onSpeechPartialResults = (e) => console.log('partial:', e.value);
Voice.onSpeechResults = (e) => console.log('final:', e.value);
Voice.onSpeechVolumeChanged = (e) => console.log('volume:', e.value);
Voice.onSpeechError = (e) => console.log(e.error.code, e.error.message);
return () => {
Voice.destroy();
};
}, []);
await Voice.start('zh-CN'); // 空串回落 zh-CN
await Voice.stop(); // 结束识别,必定收到 onSpeechEnd
await Voice.cancel(); // 取消识别,必定收到 onSpeechEnd
await Voice.destroy(); // 销毁会话并清空全部事件监听
const available = await Voice.isAvailable();
const busy = await Voice.isRecognizing();
接口文档
方法(8 个):
| 方法 | 签名 | 说明 |
|---|---|---|
start |
(locale: string) => Promise<void> |
开始识别;空串回落 zh-CN;识别中再次调用会先收束前一会话(补发一次 onSpeechEnd)再启动新会话 |
stop |
() => Promise<void> |
结束识别;必定收到 onSpeechEnd |
cancel |
() => Promise<void> |
取消识别;由本适配主动补发 onSpeechEnd,非引擎自然发出 |
destroy |
() => Promise<void> |
销毁会话并释放资源,连带执行 removeAllListeners() |
isAvailable |
() => Promise<0 | 1> |
查询识别能力是否可用 |
isRecognizing |
() => Promise<0 | 1> |
查询当前是否正在识别 |
getSpeechRecognitionServices |
() => Promise<undefined> |
鸿蒙侧既定空结果(对齐上游 iOS 分支行为),非 [] / null |
removeAllListeners |
() => void |
清除全部事件监听;可重复调用不抛异常;清除后可重新 start 并重建订阅 |
事件(7 个,字面事件名,无 top 前缀):
| 事件 | 触发时机 | payload |
|---|---|---|
onSpeechStart |
start() 生效 |
{} |
onSpeechEnd |
stop() / cancel() / 识别自然结束 |
{} |
onSpeechRecognized |
识别到语音片段 | { isFinal: boolean } |
onSpeechResults |
最终结果 | { value: string[] } |
onSpeechPartialResults |
中间结果 | { value: string[] } |
onSpeechVolumeChanged |
每帧音频自算 | { value: number }(0~10 区间) |
onSpeechError |
引擎错误 / 权限拒绝 | { error: { message, code } }(嵌套) |
⚠️ onSpeechStart / onSpeechEnd 的 payload 恰为空对象 {};结果类事件的载荷键是 value(不是 values)。
快速验证(运行 Example)
前置条件
| 依赖 | 版本要求 |
|---|---|
| Node.js | >= 20(示例工程 engines 要求) |
| DevEco Studio | 6.1.1 及以上(示例 targetSdkVersion 为 6.1.1(24)) |
| HarmonyOS SDK | API 18+(example/harmony 的 compatibleSdkVersion 为 5.1.0(18)) |
| 路径 | Windows 下仓库根目录的完整路径不超过 40 个字符,否则原生构建的中间文件路径会超过系统上限 |
运行步骤
1. 克隆仓库
git clone -b br_rnoh0.72 https://gitcode.com/hxa-rn/react-native-voice.git
cd react-native-voice
Windows 下可在克隆时指定短目录名,例如 git clone -b br_rnoh0.72 https://gitcode.com/hxa-rn/react-native-voice.git C:\rv。
2. 进入 example 目录,安装依赖
cd example
npm install --legacy-peer-deps
Example 从 npm 公仓安装 @hxa-rn/react-native-voice-voice@3.2.5,不需要在仓根执行 npm pack。
3. 生成 JS Bundle
npm run dev
产物:harmony/entry/src/main/resources/rawfile/bundle.harmony.js
4. 用 DevEco Studio 打开鸿蒙工程
- 打开 DevEco Studio,选择
example/harmony目录 - 首次构建请在 File → Project Structure → Signing Configs 勾选 Automatically generate signature,Apply 后 Sync
- 等待 Sync 完成
5. 编译并运行 HAP
在 DevEco Studio 中点击运行按钮,将 HAP 安装到设备。
example_auto(自动化用例工程)步骤相同,把 example 换成 example_auto 即可,两者的依赖与构建输出相互独立。
注意:Example 已预置 Package 注册、Metro alias 与 HAR 依赖,无需手动 Link。编 HAP 前必须先执行
npm run dev;改过 JS 后重新执行再运行。
常见问题
- 找不到 JS 模块:检查适配包安装、Metro 别名及对应入口,修改 Metro 后重启打包进程。
- 找不到 npm 包或 HAR:核对
example/node_modules/@hxa-rn/react-native-voice-voice/harmony/voice.har是否存在;不要将example_auto的 node_modules 当成example的依赖。 - 原生模块或组件未注册:检查 HAR、CMake、C++ 和 ETS 注册,排除重复注册并重建 HAP。
- SDK / 签名报错:按当前工程配置安装对应 SDK,并重新配置本机签名。
- Ninja
.rsp创建失败:查看完整日志;确认是路径长度问题后,缩短工程目录、清理旧路径构建缓存再构建。
约束与限制
兼容性:
| 项 | 值 |
|---|---|
| 鸿蒙最低兼容 API | API 18(compatibleSdkVersion 5.1.0(18)) |
| 目标 API | API 24(targetSdkVersion 6.1.1(24)) |
| 已验证通过的设备与档位 | API22 / API23 / API24 / API26 真机,共四档 |
| 上游 SDK 版本 | @react-native-voice/voice@3.2.4 |
| RN / RNOH | RN 0.72.5 + @react-native-oh/react-native-harmony@0.72.143 |
权限:
ohos.permission.MICROPHONE(麦克风)—— 由宿主module.json5声明,用于语音识别采集音频。库本身不声明任何权限。- 未授予权限时不开麦,回抛
onSpeechError(code: permission_denied)。
使用约束:
getSpeechRecognitionServices恒返回undefined:该方法不落原生实现,与上游 iOS 分支行为一致,不是缺陷。- 音量值范围为
[0, 10]的非负数:与上游 Android 的 dBFS 语义不同,鸿蒙侧由 CoreSpeechKit 归一化给出。 - 识别语言/文案质量由系统引擎决定,非
react-native-voice判定范围。
开源license
react-native-voice 基于 The MIT License (MIT),请自由地享受和参与开源。
问题反馈渠道
使用过程中发现任何问题,欢迎在GitCode 提交 Issue,也欢迎提交 PR 参与共建。