实时语音识别通过 WebSocket 持续接收音频流并返回识别结果,适用于会议演讲、视频直播等长时间不间断识别场景。本文介绍服务地址、请求参数、识别事件和状态码。
计费和并发限制
实时语音识别提供试用版和商用版,费用说明请参见计费项。
升级商用版和计费方式,请参见计费方式;并发限制请参见并发和 QPS 说明。
使用须知
如需使用Android或iOS SDK,请参见移动端接口说明。
调用接口前,确认音频格式、采样率和项目模型符合以下要求。
支持的输入格式:单声道(mono)、16 bit采样位数,包括PCM、PCM编码的WAV、OGG封装的OPUS、OGG封装的SPEEX、AMR、MP3、AAC。
支持的音频采样率:8000 Hz、16000 Hz。
支持设置返回结果:是否返回中间识别结果,在后处理中添加标点,将中文数字转为阿拉伯数字输出。
支持情感分析:目前仅开放中文8k情感识别功能,且使用时需关闭语义断句功能(即enable_semantic_sentence_detection=False)。
不支持说话人分离,无法进行角色分析。
-
识别使用的语种和方言由项目模型决定,不能通过请求参数指定。模型配置方法,请参见管理项目。
目前支持的语种和方言模型如下:
-
就近地域智能接入
实时语音识别支持就近地域智能接入,域名为nls-gateway.aliyuncs.com。
推荐终端用户使用就近地域接入域名。根据调用接口时客户端所在的地理位置,系统会自动解析到最近的某个具体地域的服务器。例如在北京地域发起请求,系统会自动解析到北京地域的服务器,与指定域名nls-gateway-cn-beijing.aliyuncs.com的实现效果一致。
服务地址
访问类型 | 说明 | URL |
外网访问(默认上海地域) | 所有服务器均可使用外网访问URL(SDK中默认设置了外网访问URL)。 |
|
ECS内网访问 | 使用阿里云上海、北京、深圳ECS(即ECS地域为华东2(上海)、华北2(北京)、华南1(深圳)),可使用内网访问URL。 ECS的经典网络不能访问AnyTunnel,即不能在内网访问语音服务;如果希望使用AnyTunnel,需要创建专有网络在其内部访问。 说明
|
|
交互流程
服务端响应的 header.task_id 标识本次识别任务。记录该值,便于排查问题。
1. 鉴权
客户端与服务端建立 WebSocket 连接时,使用 NLS Token 进行鉴权。
获取方法,请参见获取 Token。
2. 开始识别
客户端发送 StartTranscription 指令,并设置识别参数。服务端返回 TranscriptionStarted 后,客户端开始发送音频。使用 SDK 时,通过对应的参数设置方法完成配置。参数含义如下:
参数 | 类型 | 是否必选 | 说明 |
appkey | String | 是 | 在智能语音交互控制台创建的项目 Appkey。 |
format | String | 否 | 音频格式:pcm、wav、opus、speex、amr、mp3、aac。 |
sample_rate | Integer | 否 | 音频采样率,默认是16000 Hz,根据音频采样率在控制台对应项目中配置支持该采样率及场景的模型。 |
enable_intermediate_result | Boolean | 否 | 是否返回中间识别结果,默认是false。 |
enable_punctuation_prediction | Boolean | 否 | 是否在后处理中添加标点,默认是false。 |
enable_inverse_text_normalization | Boolean | 否 | 是否开启逆文本正则化(ITN),将中文数字转为阿拉伯数字输出。默认值为 false。 |
customization_id | String | 否 | 自学习模型ID。 |
vocabulary_id | String | 否 | 定制泛热词ID。 |
max_sentence_silence | Integer | 否 | 静音断句阈值,单位为毫秒。检测到语音后的静音时长超过阈值时触发断句。取值范围:200~6000,默认值:800。 开启 enable_semantic_sentence_detection 后,不使用此阈值进行静音断句,但参数值仍需在允许范围内。 静音时长按音频数据计算,不是停止发送数据后的等待时长。需要通过静音断句时,应持续发送包含静音段的音频;PCM 音频的静音段可以用零值采样表示。 |
enable_words | Boolean | 否 | 是否开启返回词信息,默认是false。 |
disfluency | Boolean | 否 | 过滤语气词,即声音顺滑,默认值false(关闭)。 |
speech_noise_threshold | Float | 否 | 噪音参数阈值,参数范围:[-1,1]。取值说明如下:
重要 该参数属高级参数,调整需慎重并重点测试。 |
enable_semantic_sentence_detection | Boolean | 否 | 是否开启语义断句,可选,默认是False。语义断句参数需要和开启中间结果配合使用,即开启该语义断句参数需将中间结果参数同时打开:enable_intermediate_result=true。 说明 开启语义断句可提升识别准确率,但会小幅增加延迟,适合会议转写等场景。 |
special_word_filter | Object(JSON 对象) | 否 | 自定义敏感词过滤,词语总数不超过 32 个。可将指定词语替换为空字符串或星号(*)。 直接使用 WebSocket 协议时,在请求的 payload 中传入 JSON 对象,不要传入 JSON 序列化后的字符串。 SDK 配置示例见下文。 |
enable_multi_thresh_mod | Boolean | 否 | 该参数仅在enable_semantic_sentence_detection参数为False(即VAD断句)时生效。取值如下:
|
以下为 Java SDK 的自定义过滤词配置片段。transcriber 为已初始化的识别对象。
// 以实时转写为例,
JSONObject root = new JSONObject();
root.put("system_reserved_filter", true);
// 将以下词语替换成空
JSONObject root1 = new JSONObject();
JSONArray array1 = new JSONArray();
array1.add("开始");
array1.add("发生");
root1.put("word_list", array1);
// 将以下词语替换成*
JSONObject root2 = new JSONObject();
JSONArray array2 = new JSONArray();
array2.add("测试");
root2.put("word_list", array2);
// 可以全部设置,也可以部分设置
root.put("filter_with_empty", root1);
root.put("filter_with_signed", root2);
transcriber.addCustomedParam("special_word_filter", root);
3. 接收识别结果
客户端持续发送音频数据并接收识别事件。以下 JSON 示例使用中文语音,展示各事件的消息结构。
header对象参数说明:
|
参数 |
类型 |
说明 |
|
namespace |
String |
消息所属的命名空间。 |
|
name |
String |
事件名称。 |
|
status |
Integer |
状态码,表示请求是否成功,见服务状态码。 |
|
status_text |
String |
状态消息。 |
|
task_id |
String |
任务全局唯一ID,请记录该值,便于排查问题。 |
|
message_id |
String |
本次消息的ID。 |
SentenceBegin
SentenceBegin事件表示服务端检测到了一句话的开始。实时语音识别服务的智能断句功能会判断出一句话的开始与结束,举例如下:
{
"header": {
"namespace": "SpeechTranscriber",
"name": "SentenceBegin",
"status": 20000000,
"message_id": "a426f3d4618447519c9d85d1a0d1****",
"task_id": "5ec521b5aa104e3abccf3d361822****",
"status_text": "Gateway:SUCCESS:Success."
},
"payload": {
"index": 1,
"time": 0
}
}
payload对象参数说明:
|
参数 |
类型 |
说明 |
|
index |
Integer |
句子编号,从1开始递增。 |
|
time |
Integer |
当前已处理的音频时长,单位为毫秒。 |
TranscriptionResultChanged
TranscriptionResultChanged事件表示识别结果发生了变化。仅当enable_intermediate_result取值为true时会多次返回此消息,即一句话的中间识别结果,举例如下:
{
"header": {
"namespace": "SpeechTranscriber",
"name": "TranscriptionResultChanged",
"status": 20000000,
"message_id": "dc21193fada84380a3b6137875ab****",
"task_id": "5ec521b5aa104e3abccf3d361822****",
"status_text": "Gateway:SUCCESS:Success."
},
"payload": {
"index": 1,
"time": 1835,
"result": "北京的天",
"confidence": 1.0,
"words": [{
"text": "北京",
"startTime": 630,
"endTime": 930
}, {
"text": "的",
"startTime": 930,
"endTime": 1110
}, {
"text": "天",
"startTime": 1110,
"endTime": 1140
}]
}
}
此事件的 header.name 为 TranscriptionResultChanged,表示句子的中间识别结果。
payload对象参数说明:
|
参数 |
类型 |
说明 |
|
index |
Integer |
句子编号,从1开始递增。 |
|
time |
Integer |
当前已处理的音频时长,单位为毫秒。 |
|
result |
String |
当前句子的识别结果。 |
|
words |
List< Word > |
当前句子的词信息,需要将enable_words设置为true。 |
|
confidence |
Double |
当前句子识别结果的置信度,取值范围:[0.0,1.0]。值越大表示置信度越高。 |
SentenceEnd
SentenceEnd事件表示服务端检测到了一句话的结束,并附带返回该句话的识别结果,举例如下:
{
"header": {
"namespace": "SpeechTranscriber",
"name": "SentenceEnd",
"status": 20000000,
"message_id": "c3a9ae4b231649d5ae05d4af36fd****",
"task_id": "5ec521b5aa104e3abccf3d361822****",
"status_text": "Gateway:SUCCESS:Success."
},
"payload": {
"index": 1,
"time": 1820,
"begin_time": 0,
"result": "北京的天气。",
"confidence": 1.0,
"words": [{
"text": "北京",
"startTime": 630,
"endTime": 930
}, {
"text": "的",
"startTime": 930,
"endTime": 1110
}, {
"text": "天气",
"startTime": 1110,
"endTime": 1380
}],
"emo_tag": "neutral",
"emo_confidence": 0.931
}
}
此事件的 header.name 为 SentenceEnd,表示识别到句子的结束。
payload对象参数说明:
|
参数 |
类型 |
说明 |
|
index |
Integer |
句子编号,从1开始递增。 |
|
time |
Integer |
当前已处理的音频时长,单位为毫秒。 |
|
begin_time |
Integer |
当前句子对应的SentenceBegin事件的时间,单位是毫秒。 |
|
result |
String |
当前的识别结果。 |
|
words |
List< Word > |
当前句子的词信息,需要将enable_words设置为true。 |
|
confidence |
Double |
当前句子识别结果的置信度,取值范围:[0.0,1.0]。值越大表示置信度越高。 |
中文 8 kHz 情感识别还会返回以下字段。使用时需关闭语义断句。
|
参数 |
类型 |
说明 |
|
emo_tag |
String |
当前句子的情感,包含positive(正面情感,如开心、满意)、negative(负面情感,如愤怒、沉闷、失望)、neutral(无明显情感)三种类别。 |
|
emo_confidence |
Double |
当前句子识别情感的置信度,取值范围:[0.0,1.0]。值越大表示置信度越高。 |
Words对象参数说明:
|
参数 |
类型 |
说明 |
|
text |
String |
文本。 |
|
startTime |
Integer |
词开始时间,单位为毫秒。 |
|
endTime |
Integer |
词结束时间,单位为毫秒。 |
4. 结束识别
音频发送完成后,发送 StopTranscription 指令结束本次识别任务。服务端处理剩余音频,并在任务结束时返回 TranscriptionCompleted。收到该事件后再关闭连接。
StopTranscription 不是保持任务运行的强制断句指令。如果剩余音频中有有效语音,服务端可能先返回 SentenceEnd;仅包含静音的任务不一定返回 SentenceEnd。
服务状态码
通过响应中的 header.status 和 header.status_text 判断请求状态。下表列出常见错误及处理方法。
通用错误码
|
状态码 |
状态消息 |
原因 |
解决方案 |
|
40000000 |
默认的客户端错误码,对应了多个错误消息。 |
用户使用了不合理的参数或者调用逻辑。 |
请参考官网文档示例代码进行对比测试验证。 |
|
40000001 |
The token 'xxx' has expired; The token 'xxx' is invalid |
用户使用了不合理的参数或者调用逻辑。通用客户端错误码,通常是涉及Token相关的不正确使用,例如Token过期或者非法。 |
请参考官网文档示例代码进行对比测试验证。 |
|
40000002 |
Gateway:MESSAGE_INVALID:Can't process message in state'FAILED'! |
无效或者错误的报文消息。 |
请参考官网文档示例代码进行对比测试验证。 |
|
40000003 |
PARAMETER_INVALID; Failed to decode url params |
用户传递的参数有误,一般常见于RESTful接口调用。 |
请参考官网文档示例代码进行对比测试验证。 |
|
40000005 |
Gateway:TOO_MANY_REQUESTS:Too many requests! |
并发请求过多。 |
如果是试用版调用,建议升级为商用版本以增大并发。 如果已是商用版,可购买并发资源包,扩充并发额度。 |
|
40000009 |
Invalid wav header! |
错误的消息头。 |
如果发送的是WAV语音文件,且设置 |
|
40000009 |
Too large wav header! |
传输的语音WAV头不合法。 |
建议使用PCM、OPUS等格式发送音频流,如果是WAV,建议关注语音文件的WAV头信息是否为正确的数据长度大小。 |
|
40000010 |
Gateway:FREE_TRIAL_EXPIRED:The free trial has expired! |
试用期已结束,并且未开通商用版、或账号欠费。 |
检查服务开通状态和账户余额。 购买资源包不等于开通商用版。即使已购买资源包,仍需将实时语音识别服务升级为商用版后才能使用。升级方法请参见计费方式。 |
|
40010001 |
Gateway:NAMESPACE_NOT_FOUND:RESTful url path illegal |
不支持的接口或参数。 |
请检查调用时传递的参数内容是否和官网文档要求的一致,并结合错误信息对比排查,设置为正确的参数。 比如是否通过curl命令执行RESTful接口请求, 拼接的URL是否合法。 |
|
40010003 |
Gateway:DIRECTIVE_INVALID:[xxx] |
客户端侧通用错误码。 |
表示客户端传递了不正确的参数或指令,在不同的接口上有对应的详细报错信息,请参考对应文档进行正确设置。 |
|
40010004 |
Gateway:CLIENT_DISCONNECT:Client disconnected before task finished! |
在请求处理完成前客户端主动结束。 |
收到 TranscriptionCompleted 后再关闭连接。 |
|
40010005 |
Gateway:TASK_STATE_ERROR:Got stop directive while task is stopping! |
客户端发送了当前不支持的消息指令。 |
检查指令发送顺序。任务正在结束时,不要重复发送 StopTranscription。 |
|
40020105 |
Meta:APPKEY_NOT_EXIST:Appkey not exist! |
使用了不存在的Appkey。 |
请确认是否使用了不存在的Appkey,Appkey可以通过登录控制台后查看项目配置。 |
|
40020106 |
Meta:APPKEY_UID_MISMATCH:Appkey and user mismatch! |
调用时传递的Appkey和Token并非同一个账号UID所创建,导致不匹配。 |
请检查是否存在两个账号混用的情况,避免使用账号A名下的Appkey和账号B名下生成的Token搭配使用。 |
|
403 |
Forbidden |
使用的Token无效,例如Token不存在或者已过期。 |
请设置正确的Token。Token存在有效期限制,请及时在过期前获取新的Token。 |
|
41000003 |
MetaInfo doesn't have end point info |
无法获取该Appkey的路由信息。 |
请检查是否存在两个账号混用的情况,避免使用账号A名下的Appkey和账号B名下生成的Token搭配使用。 |
|
41010101 |
UNSUPPORTED_SAMPLE_RATE |
不支持的采样率格式。 |
当前实时语音识别只支持8000 Hz和16000 Hz两种采样率格式的音频。 |
|
41040201 |
Realtime:GET_CLIENT_DATA_TIMEOUT:Client data does not send continuously! |
获取客户端发送的数据超时失败。 |
按实时速率持续发送音频。发送完成后发送 StopTranscription,收到 TranscriptionCompleted 后再关闭连接。 |
|
50000000 |
GRPC_ERROR:Grpc error! |
受机器负载、网络等因素导致的异常,通常为偶发出现。 |
一般重试调用即可恢复。 |
|
50000001 |
GRPC_ERROR:Grpc error! |
受机器负载、网络等因素导致的异常,通常为偶发出现。 |
一般重试调用即可恢复。 |
|
52010001 |
GRPC_ERROR:Grpc error! |
受机器负载、网络等因素导致的异常,通常为偶发出现。 |
一般重试调用即可恢复。 |
实时语音识别错误码
|
状态码 |
状态消息 |
原因 |
解决方案 |
|
40000004 |
Gateway:IDLE_TIMEOUT:Websocket session is idle for too long time |
请求建立连接后,长时间没有发送任何数据,超过10s后,服务端会返回此错误信息。 |
建立连接后持续发送音频,可边采集边发送。音频发送完成后发送 StopTranscription,收到 TranscriptionCompleted 后再关闭连接。 |
|
40270002 |
NO_VALID_AUDIO_ERROR |
无效的音频。 |
从音频中没有识别出有效文本。 |
|
40270003 |
DECODE_ERROR |
音频解码失败。 |
请根据实际音频格式,设置对应的format参数。 |
|
41000002 |
APPKEY_KEY_IS_NULL |
没有正确设置appkey。 |
请参考官网文档及示例代码。 |