语音识别Android SDK文档
文档修订记录
| 文档版本号 | 修订日期 | 修订原因 |
|---|---|---|
| V1.0 | 2022.8.30 | 创建文档 |
| V1.1 | 2023.10.18 | 优化文档 |
| V1.2 | 2024.05.06 | 优化文档 |
概述
ASR模块主要是语音转文字的过程,支持的交互场景包括单句识别和连续识别,支持的开启方式开启录音器和输入音频数据流。
集成步骤
1. 添加依赖库
//必须依赖库
implementation 'com.google.code.gson:gson:2.6.2'
implementation 'com.squareup.okhttp3:okhttp:3.9.0'
implementation "org.java-websocket:Java-WebSocket:1.4.0"
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'com.aliyun.dpa:oss-android-sdk:2.9.11'//SDKV2.4.1.25 以后需加入
//vad所需
implementation 'com.microsoft.onnxruntime:onnxruntime-android:1.15.1'
2. 权限声明
网络权限 - 使用过程中,会有https与wss请求、网络状态检测
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
存储权限 - 使用过程中,会写入日志文件、保存临时音频文件(debug),请在清单中指定以下内容。
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<!-- android10 以上需要额外添加-->
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
在android10及以上需要在application标签下添加如下配置
android:requestLegacyExternalStorage="true"
音频录制权限 - 在使用过程中录制音频,您的应用必须请求音频捕获权限。
<uses-permission android:name="android.permission.RECORD_AUDIO" />
3. 配置文件
将turing_config.json配置文件放在main/assets文件夹下
{
"authorization": {
"apikey": "您的apikey",
"secret": "您的secret"
},
"ability": {
"asr": {
"asrSrcFormatEnum": 0,
"asrFormatEnum": 0,
"asrLanguageEnum": 0,
"asrRateEnum": 16000,
"channel": 1,
"enableITN": true,
"enablePunctuation": false,
"enableVoiceDetection": true,
"intermediateResult": true,
"maxEndSilence": 1000,
"maxStartSilence": 5000,
"vadThreshold": 0.5,
"vadReviseTime": 1200,
"vadState": true,
"interactionTime": 20,
"enableCloudVad": false,
"enableVolume": false,
"audioSource": 1,
"saveAudioPath": ""
}
}
}
参数说明见文档末端《参数说明》#输入参数
4. 代码混淆
代码混淆文件proguard-project.txt,添加如下内容
-keep class com.turing.**{ *;}
-dontwarn com.turing.**
-keep class com.tuling.**{ *;}
-dontwarn com.tuling.**
-keep class org.java_websocket.**{*;}
-dontwarn org.java_websocket.**
-keep class org.slf4j.**{*;}
-dontwarn org.slf4j.**
-keep class org.eclipse.** { *; }
-dontwarn org.eclipse.**
5. SDK 初始化
使用任何能力前调用,请先调用SDK初始化代码。(SDK初始化详情见《接入指南说明文档》)
TuringInitializer.getInstance().initV3XXX()
6. 实例化
var turingAsr = TuringAsr.getInstance(this)
接口说明
public interface TuringAsrInterface {
/**
* 录音并识别ASR,使用全局配置文件Turing_config.json中的参数,需配置asr参数
* @param isLoop 是否循环录音识别
* @param isAssignAsr 是否使用配置文件中的asr参数
* @param listener 回调接口
*/
void startAsrWithRecorder(boolean isLoop, boolean isAssignAsr,TuringOSClientAsrListener listener);
/**
* 录音并识别ASR
* @param isLoop 是否循环录音识别
* @param asrRequestConfig asr请求参数,如设置为空,则使用Turing_config.json中的asr配置,如没有asr配置,则使用默认值
* @param listener 回调接口
*/
void startAsrWithRecorder(boolean isLoop, AsrRequestConfig asrRequestConfig, TuringOSClientAsrListener listener);
/**
* 初始化音频流识别,使用全局配置文件Turing_config.json中的参数,需配置asr参数
* @param isAssignAsr 是否使用配置文件中的asr参数
* @param listener 回调接口
*/
public void initAsrStream(boolean isAssignAsr, final TuringOSClientAsrListener listener);
/**
* 初始化音频流识别
* @param asrRequestConfig asr请求参数,如设置null,则使用Turing_config.json中的asr配置,如没有asr配置,则使用默认值
* @param listener 回调接口
*/
public void initAsrStream(AsrRequestConfig asrRequestConfig, final TuringOSClientAsrListener listener);
/**
* 初始化音频流识别
* @param isAutoStop 是否自动停止,为false时,和上面没有isAutoStop一样,当为true时,输入的音频数据在识别到完整的结果后会自动丢弃剩余数据
* @param isAssignAsr 是否使用配置文件中的asr参数
* @param listener 回调接口
*/
public void initAsrStream(boolean isAutoStop, boolean isAssignAsr, final TuringOSClientAsrListener listener);
/**
* 初始化音频流识别
* @param isAutoStop 是否自动停止,为false时,和上面没有isAutoStop一样,当为true时,输入的音频数据在识别到完整的结果后会自动丢弃剩余数据
* @param asrRequestConfig asr请求参数,如设置null,则使用Turing_config.json中的asr配置,如没有asr配置,则使用默认值
* @param listener 回调接口
*/
public void initAsrStream(boolean isAutoStop,AsrRequestConfig asrRequestConfig, final TuringOSClientAsrListener listener);
/**
* 发送音频流
* @param dataBuffer 音频数据,建议单包长度为1280个byte,小于6400个byte
* @param length 音频数据长度
*/
public void sendAudio(byte[] dataBuffer, int length);
/**
* 停止录音
* 该方法会将音频数据池中的数据发送完毕后正常结束Asr引擎
*/
public void stop();
/**
* 重置vad
* 如需修改vad参数,可先设置asr参数后,再调用此接口
*/
void resetVad();
/**
* 释放ASR
* 该方法会强制停止释放Asr引擎
*/
void release();
}
接口类型:
- 类型一:全局使用turing_config中的配置参数,需要在 turing_config.json 中添加 asr 节点,节点字段见《接入指南说明文档》配置文件参数说明。可使用TuringConfig.setConfigData设置全局配置参数,此参数在使用到配置文件的接口全局生效,适用于不频繁修改参数场景
- 类型二:不使用 turing_config.json 中的配置,使用入参带AsrRequestConfig 的接口,此参数仅调用时生效,适用于频繁修改参数场景。
使用说明
功能描述
- ASR模块支持SDK内部录音器或者输入音频字节流数据
- ASR模块支持单句识别与多句识别
支持的所有方式:
使用内置录音:打开SDK录音器识别,返回ASR结果
使用外置录音:初始化ASR后,应用端实现录音功能,给图灵SDK输入音频字节流数据,返回ASR结果
ASR功能使用
接口类型
- 类型一:全局使用turing_config中的配置参数,需要在 turing_config.json 中添加asr 节点,节点字段见《接入指南说明文档》配置文件参数说明。可使用TuringConfig.setConfigData设置全局配置参数,此参数在使用到配置文件的接口全局生效,适用于不频繁修改参数场景
- 类型二:不使用 turing_config.json 中的配置,使用入参带AsrRequestConfig 的接口,此参数仅调用时生效,适用于频繁修改参数场景。
对象实例化
val turingAsr:TuringAsrInterface = TuringAsr.getInstance(this)
一、使用内置录音
方法一:使用全局配置文件Turing_config.json中的参数,需配置asr参数
//动态配置参数
TuringConfig.getInstance(this).configData.ability.asr.asrFormatEnum = type
TuringConfig.getInstance(this).configData.ability.asr.asrSrcFormatEnum = type
turingAsr.startAsrWithRecorder(
true,
true,
object : TuringOSClientAsrListener {
override fun onRecorderStart() {
Log.i(TAG, " =========onRecorderStart=====")
mUIHandler.postRunnable(Runnable { updateUI(MODE_RECORD) })
}
override fun onStop() {
Log.i(TAG, " =========onStop=====")
mUIHandler.postRunnable(Runnable { updateUI(MODE_NONE) })
}
override fun onStreamOpen() {
//打开内部录音的方式,该方法不会回调
}
override fun onResult(
code: Int,
result: String?,
isLast: Boolean,
responBean: BaseResp?
) {
Log.i(TAG, " =========onResult=====")
if (TextUtils.isEmpty(result))
return
mUIHandler.postRunnable(Runnable { updateResult(code, result!!, responBean) })
}
override fun onTimer(second: Int) {}
override fun onError(code: Int, msg: String) {
Log.e(TAG, "onError code: $code msg:$msg")
mUIHandler.postRunnable(Runnable {
updateResult(code, msg, null)
updateUI(MODE_NONE)
})
}
override fun onVoiceVolume(i: Int) {
Log.i(TAG, "onVoiceVolume volume: $i")
}
})
方法二:使用局部生效参数,可以指定AsrRequestConfig
//设置单声道,16k采样率
val asrConfig = AsrRequestConfig.Builder().channel(AsrRequestConfig.CHANNEL_IN_MONO)
.asrRateEnum(AsrRequestConfig.RATE_16000).build()
turingAsr.startAsrWithRecorder(false,asrConfig,object : TuringOSClientAsrListener {
override fun onRecorderStart() {
Log.i(TAG, " =========onRecorderStart=====")
mUIHandler.postRunnable(Runnable { updateUI(MODE_RECORD) })
}
override fun onStop() {
Log.i(TAG, " =========onStop=====")
mUIHandler.postRunnable(Runnable { updateUI(MODE_NONE) })
}
override fun onStreamOpen() {
//打开内部录音的方式,该方法不会回调
}
override fun onResult(
code: Int,
result: String?,
isLast: Boolean,
responBean: BaseResp?
) {
Log.i(TAG, " =========onResult=====")
if (TextUtils.isEmpty(result))
return
mUIHandler.postRunnable(Runnable { updateResult(code, result!!, responBean) })
}
override fun onTimer(second: Int) {}
override fun onError(code: Int, msg: String) {
Log.e(TAG, "onError code: $code msg:$msg")
mUIHandler.postRunnable(Runnable {
updateResult(code, msg, null)
updateUI(MODE_NONE)
})
}
override fun onVoiceVolume(i: Int) {
Log.i(TAG, "onVoiceVolume volume: $i")
}
})
二、使用外置录音
第一步:先调用初始化方法
初始化方法一:使用全局配置文件Turing_config.json中的参数,需配置asr参数
turingAsr.initAsrStream(false, true, object : TuringOSClientAsrListener {
override fun onRecorderStart() {
//流式输入该方法不会回调
}
override fun onStop() {
Log.i(TAG, "===========onStop========")
mUIHandler.postRunnable(Runnable { updateUI(MODE_NONE) })
}
override fun onStreamOpen() {
//todo 开始输入音频数据流
Log.i(TAG, "===========onStreamOpen========")
startStreamEncodeInput()
}
override fun onResult(
code: Int,
result: String?,
isLast: Boolean,
baseResp: BaseResp?
) {
Log.i(TAG, "===========onResult========")
if (TextUtils.isEmpty(result))
return
mUIHandler.postRunnable(Runnable { updateResult(code, result!!, baseResp) })
}
override fun onTimer(second: Int) {}
override fun onError(code: Int, msg: String) {
Log.e(TAG, "onError code: $code msg:$msg")
mUIHandler.postRunnable(Runnable {
updateResult(code, msg, null)
updateUI(MODE_NONE)
})
}
override fun onVoiceVolume(i: Int) {}
})
初始化方法二:使用局部生效参数,可以指定AsrRequestConfig。
//设置单声道,16k采样率
val asrConfig = AsrRequestConfig.Builder().channel(AsrRequestConfig.CHANNEL_IN_MONO)
.asrRateEnum(AsrRequestConfig.RATE_16000).build()
turingAsr.initAsrStream(false,asrConfig,object : TuringOSClientAsrListener {
override fun onRecorderStart() {
//流式输入该方法不会回调
}
override fun onStop() {
Log.i(TAG, "===========onStop========")
mUIHandler.postRunnable(Runnable { updateUI(MODE_NONE) })
}
override fun onStreamOpen() {
//todo 开始输入音频数据流
Log.i(TAG, "===========onStreamOpen========")
startStreamEncodeInput()
}
override fun onResult(
code: Int,
result: String?,
isLast: Boolean,
baseResp: BaseResp?
) {
Log.i(TAG, "===========onResult========")
if (TextUtils.isEmpty(result))
return
mUIHandler.postRunnable(Runnable { updateResult(code, result!!, baseResp) })
}
override fun onTimer(second: Int) {}
override fun onError(code: Int, msg: String) {
Log.e(TAG, "onError code: $code msg:$msg")
mUIHandler.postRunnable(Runnable {
updateResult(code, msg, null)
updateUI(MODE_NONE)
})
}
override fun onVoiceVolume(i: Int) {}
})
第二步:调用发送音频的方法
//伪代码,自行实现录音,并传入音频数据
private fun startStreamEncodeInput() {
turingAsr.sendAudio(buffer, length)
}
第三步:结束录音,返回ASR结果
正常返回此次结果。如果没有使用vad,或者需要提前结束录音,可以调用此方法结束录音;如果使用了vad,则可不调此方法
turingAsr.stop()
VAD说明
概述:语音活性检测 (Voice activity detection,VAD),是一项用于语音处理的技术,目的是检测语音信号是否存在。
VAD可用于主动结束录音,支持离线VAD和云端VAD,离线VAD支持设置前端静音超时、后端静音超时,推荐使用离线VAD
使用离线vad:
设置enableVoiceDetection=true,enableCloudVad=false
使用云端vad:
设置enableVoiceDetection=false,enableCloudVad=false
修改VAD参数:
若在不同场景下,想要修改vad的参数,可先调用resetVad()方法,再重新设置vad参数,如下:
turingAsr.resetVad()
val asrConfig = AsrRequestConfig.Builder().maxStartSilence(4000).maxEndSilence(1000).vadThreshold(0.6f)
.asrRateEnum(AsrRequestConfig.RATE_16000).build()
turingAsr.startAsrWithRecorder(false,asrConfig,turingOSClientPlayListener)
VAD相关参数,在asr模块中设置,详细说明见AsrRequestConfig
备注:此功能需要开通权限才能使用,如需要使用VAD功能,请联系图灵技术支持
参数说明
输入参数
AsrRequestConfig
对应turing_config.json中的asr参数
| 参数 | 类型 | 是否必须 | 说明 |
|---|---|---|---|
| asrSrcFormatEnum | int | N | 当不使用内部录音器的时候该值为必填,音频格式: asrFormatEnum=0:PCM asrFormatEnum=1:OPUS asrFormatEnum=2:SPEEX,默认-1,不使用外部录音 |
| asrFormatEnum | int | Y | 音频格式: asrFormatEnum=0:PCM asrFormatEnum=1:OPUS asrFormatEnum=2:SPEEX |
| asrLanguageEnum | int | Y | 语言: asrLanguageEnum=0:中文(开启后支持中英文混合识别) asrLanguageEnum=1:英文 |
| asrRateEnum | int | Y | 音频采样率: asrRateEnum=0:8k(PCM) asrRateEnum=1:16k(PCM, OPUS, SPEEX) |
| intermediateResult | boolean | N | 是否返回中间ASR结果(默认false) |
| enableITN | boolean | N | 返回结果的数字格式规则为阿拉伯数字格式(默认true) |
| enablePunctuation | boolean | N | 是否开启标点符号添加(默认true) |
| enableVoiceDetection | boolean | N | 是否开启离线VAD(默认false): 启动后需要同时设置maxStartSilence和maxEndSilence的值 |
| maxStartSilence | Integer | N | 允许的最大开始静音(单位是毫秒),即为说话前的超时时间,超时后结束录音,asr回调接口会回调onResult,code=5002,需要先设置enableVoiceDetection为true |
| maxEndSilence | Integer | N | 允许的最大结束静音(单位是毫秒),即为说话后的超时时间, 超时后结束录音,返回识别结果,需要先设置enableVoiceDetection为true |
| vadThreshold | float | N | 声音检测灵敏度,范围0-1,越小则越容易检测到声音,默认0.8 |
| vadReviseTime | Integer | N | 设置VAD修正时间,针对VAD提前异常结束问题,在这个时间内,如果VAD出现 了FINISH状态则会跳过此事件,这个值不建议设置太大,否则可能会忽略正常的VAD 事件 |
| vadState | boolean | N | 是否返回VAD状态,默认false,设置true时,在turingOSClientAsrListener.onResult()中会返回code=TuringCode.VAD_STATE_BEGIN或TuringCode.VAD_STATE_FINISH |
| interactionTime | int | N | ASR最大录音时间 |
| enableCloudVad | boolean | N | 是否开启云端VAD(默认false) |
| enableVolume | boolean | N | 使用内部录音时,是否返回声音音量变化,true则回调void onVoiceVolume(int i) |
| saveAudioPath | String | N | 保存本地音频路径,设置后会保存录音到本地,不设置则不保存 |
opus格式要求:
- pcm转为opus裸包之后在头部增加8个字节,其中第3,4字节代表音频片段数据长度{head(8byte 3,4位存数据长度)+data} + {head(8byte 3,4位存数据长度)+data} + ...
- 每次调用opensocket上传音频片段必须完整
- 大端模式
回调接口
TuringOSClientAsrListener
录音或者音频流输入时,ASR通道状态、ASR识别结果以及对话结果都使用该接口回调,具体参考下面对应方法的示例说明;
public interface TuringOSClientAsrListener {
/**
* 当使用SDK录音器开启的识别,此方法会在录音开始后回调
* 一般用于UI显示开始录音,更新UI需要放到主线程,不能再此回调方法中更新
*/
void onRecorderStart();
/**
* asr识别停止,包括请求Error或者外部调用client.stopAsr都会回调
*/
void onStop();
/**
* 允许输入音频数据流,在该方法回调之后开始调用sendAudio
*/
void onStreamOpen();
/**
*
* 请求结果返回
*
* @param code 具体参考code说明
* @param result 返回的json字符串
* @param isLast Asr识别结果;last : 是否是最终结果
* @param baseResp 返回的json字符串转换的Java对象
*/
void onResult(int code, String result, boolean isLast, BaseResp baseResp);
/**
* Asr识别单论交互倒计时 最大值20s
* 单句语音识别场景下的倒计时限制,连续识别不受影响
*
* @param second
*/
void onTimer(int second);
/**
* 请求发生错误的信息
*
* @param code
* @param msg
*/
void onError(int code, String msg);
/**
* 使用内部录音时,返回声音音量变化,该方法的回调需要先设置参数enableVolume为true
*
*/
void onVoiceVolume(int i);
}
输出参数
ASR识别结果
返回的结果在TuringOSClientAsrListener的onResult方法中,其中String result为json字符串,BaseResp baseResp为result转换为json后的java对象。
json示例如下:
{
"asrResponse":{
"binarysId":"0a2071a8-2bb6-4fae-b109-32bee00c1726",
"state":200,
"value":"深圳明天的天气"
},
"code":200,
"globalId":"98412368730000000",
"message":"success"
}
BaseResp说明
| 参数 | 类型 | 说明 |
|---|---|---|
| code | int | 请求响应Code,具体可参考Code说明 |
| message | String | 请求响应的消息描述 |
| localAudioFile | String | 本地音频文件路径 |
| asrResponse | AsrResponse(Object) | ASR识别结果 |
- 当code=200表示识别成功;
- 当code=5002时表示没有任何有效人声输入;
- 其他code表示识别异常,参考Code说明。
AsrResponse参数说明
| 参数 | 类型 | 是否必须 | 取值范围 | 说明 |
|---|---|---|---|---|
| binarysId | String | Y | - | asr二进制参数Id |
| value | String | Y | - | asr识别内容 |
| state | int | Y | 200,210 | 210:asr识别中间结果返回,200:asr识别完成结果 |
- AsrRequestConfig的参数intermediateResult设置为true之后,语音识别会实时返回识别结果;
- state=210表示此次返回的识别结果为中间结果,此时onResult方法中的isLast为fasle;
- state=200表示此次返回的识别结果为最终结果,此时onResult方法中的isLast为true。