语音识别概述
语音识别功能提供面向移动终端的语音识别能力。它基于华为智慧引擎(HUAWEI HiAI Engine)中的语音识别引擎,向开发者提供人工智能应用层API。该技术可以将语音文件、实时语音数据流转换为汉字序列,准确率达到90%以上(本地识别95%)。
基本概念
语音识别技术,也称为自动语音识别(Automatic Speech Recognition, ASR),可以基于机器识别和理解,将语音信号转变为文本或命令。
约束与限制
- 支持的输入文件格式有wav或pcm。
- 当前仅支持对普通话的识别。
- 输入时长不能超过20s。
- 采样要求:采样率16000Hz,单声道。
- 引擎的使用必须初始化和释放处理,且调用必须在UI的主线程中进行。
- 多线程调用:HUAWEI HiAI Engine不支持同一应用使用多线程调用同一接口,这样会使某一线程调用release方法后,卸载模型,导致正在运行的另一些线程出错。故多线程执行同一功能达不到并行的效果。但是引擎支持使用多线程调用不同接口,如开启两个线程同时使用文档矫正和ASR接口。
语音识别开发
场景介绍
支持开发具有语音识别需求的第三方应用,如语音输入法、语音搜索、实时字幕、游戏娱乐、社交聊天、人机交互(如驾驶模式)等场景。
- 语音输入法
将需要输入的文字,直接用语音的方式输入。即用户说话的时候语音识别引擎返回识别的汉字序列,让输入更加便捷,解放双手。
- 语音搜索
搜索内容直接以语音的方式输入,可以用于客服系统的关键词搜索,同时转录成文本,让搜索更加高效。
- 实时字幕
将直播、视频、现场演讲等音频进行实时的字幕转换、降低理解成本,提升用户体验。
- 驾驶模式
在开车过程中,手握方向盘,无法分神去操作手机来选择音乐、拨打电话。使用语音识别,只要向手机说出命令,例如:听音乐的时候说上一首/下一首进行切歌或调节音量等,即可被手机识别并执行相应操作。
接口说明
主要接口
接口功能 | 接口原型 | 接口描述 |
---|---|---|
实例化ASR客户端对象 | Optional<AsrClient> createAsrClient(Context context) | 实例化一个ASR客户端对象,该对象用于调用ASR引擎能力。 |
初始化ASR服务 | void init(AsrIntent intent, AsrListener asrListener) | 初始化ASR服务。传入回调,用于等待ASR功能接口的调用过程和结果;以及传入初始化参数,初始化ASR引擎。 |
开始听取和识别语音 | void startListening(AsrIntent asrIntent) | 开始听取和识别语音。如果识别的是音频文件,则读取文件识别。 如果识别PCM语音数据流,则结合writePcm(byte[], int)来识别。在调用此方法前,需要先调用init(AsrIntent, AsrListener)来初始化ASR引擎服务。 |
停止识别语音 | void stopListening() | 调用此方法,已经获取到的语音会完成识别,未获取到的语音将不再识别。 一般在默认场景下,无需调用此方法去停止识别,因为语音识别会自动地决策语音是否已经完成,然后自动地停止识别。然而,也可以调用此方法来直接在某刻手动地停止识别。 调用此方法前,需要先调用init(AsrIntent, AsrListener)来初始化ASR引擎服务。 |
写入PCM数据流,进行语音识别 | void writePcm(byte[] bytes, int length) | 调用此方法,写入PCM语音数据流,并对PCM进行语音识别。 调用此方法前,需要先调用init(AsrIntent, AsrListener)来初始化ASR引擎服务。 在调用startListening(AsrIntent)}之后,将获取的PCM数据通过此方法来下发给ASR引擎处理。 PCM数据流长度存在限制:PCM数据流大小不能超过800KB,另外PCM数据流对应的音频长度不能超过20s。length代表有效长度,当前只支持1280或者640字节。 |
取消语音识别 | void cancel() | 取消语音识别,已经获取到的语音也不再识别。调用此方法前,需要先调用init(AsrIntent, AsrListener)来初始化ASR引擎服务。 |
销毁ASR服务 | void destroy() | 取消所有ASR任务,销毁ASR引擎服务。调用此方法后,无法再使用ASR服务。如果需要重新使用ASR服务,需要重新调用createAsrClient(Context)来创建 AsrClient实例。 |
包名 | 类名 | 接口原型 | 功能描述 |
---|---|---|---|
ohos.ai.asr | AsrListener | void onInit(PacMap params) | ASR引擎初始化结束后,ASR的服务端会调用此回调接口处理初始化结果数据。 |
void onBeginningOfSpeech() | ASR引擎检测到用户开始说话时,ASR服务端调用此回调接口。 | ||
void onRmsChanged (float rms) | ASR引擎检测到音频输入的语音能量变化时,ASR服务端调用此回调接口处理语音能量。 | ||
void onEndOfSpeech() | ASR引擎检测到用户说话停止时,调用此回调接口。 | ||
void onIntermediateResults(PacMap intermediateResults) | ASR引擎语音识别过程中,当部分识别结果可以获取到时,调用此回调处理中间过程的识别结果。 | ||
void onError(int error) | ASR语音识别过程中出现错误时,调用此回调接口。 | ||
void onResults(PacMap results) | ASR引擎完成语音识别,调用此回调返回和处理完整的识别结果。 | ||
void onBufferReceived(byte[] buffer) | ASR引擎每次接收到新输入的音频流时,会调用此回调接口处理接收到的语音流数据。 | ||
void onEvent(int eventType, PacMap params) | ASR引擎检测到某些事件时,调用此接口上报事件给调用者。 | ||
void onEnd() | ASR引擎识别结束时,调用此回调接口。但如果识别音频过程中被AsrClient类中的stopListening()或者cancel()方法打断,则不会调用此回调接口。 | ||
void onAudioStart() | 在音频开始时,ASR引擎服务端调用此回调接口。 | ||
void onAudioEnd() | 在音频结束时,ASR引擎服务端调用此回调接口。 |
接口返回值说明
AsrListener中的onResults(PacMap results)方法返回结果。结果封装在JSON格式中,需要解析得到。结果说明:
返回结果 | 结果类型 | 结果说明 |
---|---|---|
{"result":[{"confidence":0,"ori_word":"你 好 ","pinyin":"NI3 HAO3 ","word":"你好。"}]} | Json | 识别结果 |
{"confidence":xxx} | Double | 识别结果的置信度 |
{ "word":"xxx"} | String | 识别结果的文本内容 |
示例结果(JSON):
{
"engine_type":"local_engine",
"result":[{"confidence":0,"ori_word":"你 好 ","pinyin":"NI3 HAO3 ","word":"你好。"}],
"result_type":"lvcsr",
"scenario_type":5
}
语音识别结果码说明
表2 AsrError说明
常量名 | 取值 | 错误码含义 |
---|---|---|
SUCCESS | 0 | 表示在某个接口被调用成功时,在回调中会返回这个结果码。 |
ERROR_AUDIO | 3 | 表示接口调用时,发生因音频读取导致的错误时,在回调中会返回的结果码。 |
ERROR_SERVER | 4 | 表示接口调用时,ASR引擎服务端发生错误时,在回调中会返回的结果码。 |
ERROR_CLIENT | 5 | 表示接口调用时,调用ASR的客户端发生错误时,在回调中会返回的结果码。 |
ERROR_SPEECH_TIMEOUT | 6 | 表示ASR接口调用时,在设定的时间内没有语音输入时,在回调中会返回的结果码。 |
ERROR_NO_MATCH | 7 | 表示ASR接口调用时,发生ASR的识别结果不匹配定义的json格式时,在回调中会返回的结果码。 |
ERROR_RECOGNIZER_BUSY | 8 | 表示ASR接口调用时,ASR引擎正忙时,在回调中会返回的结果码。 |
ERROR_INVALID_PARAMS | 10 | 表示ASR接口调用时,发生参数输入错误时,在回调中会返回的结果码。 |
ERROR_UNKNOWN | 11 | 表示ASR接口调用时,发生未知错误时,在回调中会返回的结果码。 |
ERROR_GET_MODEL_PATH | 13 | 表示ASR接口调用时,ASR模型路径获取失败时,在回调中会返回的结果码。 |
ERROR_RESULT_UNSUPPORTED | 15 | 表示ASR接口调用时,设备上当前版本的ASR引擎不支持正在被调用的接口时,在回调中会返回的结果码。 |
ERROR_MODEL_NOT_MATCH | 16 | 表示ASR接口调用时,当前设备中预置的ASR引擎应用和ASR模型不匹配时,在回调中会返回的结果码。 |
ERROR_INIT_FAIL | 23 | 表示ASR接口调用时,发生ASR引擎初始化失败的错误时,在回调中会返回的结果码。 |
ERROR_NO_ASR | 30 | 表示当前设备上没有ASR引擎,不支持ASR能力的调用时,在回调中会返回的结果码。 |
开发步骤
在使用语音识别API时,将实现ASR的相关的类添加至工程。
// 提供ASR引擎执行时所需要传入的参数类
import ohos.ai.asr.AsrIntent;
// 错误码的定义类
import ohos.ai.asr.util.AsrError;
// 加载语音识别Listener
import ohos.ai.asr.AsrListener;
// 提供调用ASR引擎服务接口的类
import ohos.ai.asr.AsrClient;
// ASR回调结果中的关键字封装类
import ohos.ai.asr.util.AsrResultKey;
调用API接口。
- 创建一个AsrClient对象。context为应用上下文信息,应为ohos.aafwk.ability.Ability或ohos.aafwk.ability.AbilitySlice的实例或子类实例。
AsrClient asrClient = AsrClient.createAsrClient(context).orElse(null);
- 设置引擎参数。如果希望识别文件,音频文件需满足约束与限制,并设置音频类型为“ASR_SRC_TYPE_FILE”;如果希望识别音频流,则设置音频类型为“ASR_SRC_TYPE_PCM”。
AsrIntent initIntent = new AsrIntent(); initIntent.setAudioSourceType(AsrIntent.AsrAudioSrcType.ASR_SRC_TYPE_PCM);
- 初始化ASR服务。其中,mMyAsrListener为实现了AsrListener接口的实例对象。
asrClient.init(initIntent, mMyAsrListener);
- 开始识别。用户可以不设置参数,使用默认参数。
AsrIntent asrIntent = new AsrIntent(); // 设置后置的端点检测(VAD)时间 asrIntent.setVadEndWaitMs(2000); // 设置前置的端点检测(VAD)时间 asrIntent.setVadFrontWaitMs(4800); // 设置语音识别的超时时间 asrIntent.setTimeoutThresholdMs(20000); asrClient.startListening(asrIntent); // buffer需要替换为真实的音频数据 byte[] buffer = new byte[]{0, 1, 0, 10, 1}; // 对于长度大于1280的音频,需要多次调用writePcm分段传输 asrClient.writePcm(buffer, 1280);
需要注意的是,startListening或writePcm方法建议放在mMyAsrListener中onInit()方法内调用,保证初始化引擎成功之后再调用识别接口。如果希望识别音频文件,则不需要调用writePcm接口。
AsrIntent asrIntent = new AsrIntent(); // 将FilePath修改为正确的地址,且文件路径需要给com.huawei.hiai进程授予可访问权限。 asrIntent.setFilePath("FilePath"); asrClient.startListening(asrIntent);
- 取消或停止识别。
asrClient.stopListening(); // 停止识别 asrClient.cancel(); // 取消识别
- 释放引擎。
asrClient.destroy();