跳到主要内容

流式语音识别WebSocket API

目录

使用要求

项目说明
发送格式音频数据采用二进制格式,其余采用文本格式发送json数据
响应格式以文本格式返回json数据
音频数据属性采样率16k、单声道;使用PCM格式时,位长16bit
音频格式PCM(无压缩的PCM或WAV音频流)、OPUS、AMR、MP3、AAC格式
采用PCM格式时,音频需满足采样率16k、位长16bit、单声道;其他格式需满足采样率16k、单声道
数据发送建议音频流每160ms发送一次,每次发送160ms的数据
建立请求后,数据发送间隔不能超过10s。若长时间未发送数据(超过10s),服务会返回错误消息并结束识别
如果用户发送数据过快,可能导致引擎出现过载错误

服务地址与鉴权方式

外网访问地址:

wss://aibook-api.mthreads.com:62220/api/v1/asr

鉴权方式:

在URL中使用鉴权token:

wss://aibook-api.mthreads.com:62220/api/v1/asr?token=${your_token}

注意: 访问令牌(Access Token)请联系我们获取。联系方式: meng.cai@mthreads.com, ye.wang@mthreads.com

WebSocket交互流程

在流式识别中,随着用户传输数据,服务端不断返回结果,直到用户发送StopTranscription后,服务端返回TranscriptionCompleted。

ASR流式识别时序图

注意:

  • 用户发送StopTranscription之前,发送数据包的间隔需小于10s。若超过10s未发送数据,会被服务器断开连接。
  • 用户发送StopTranscription后,需等待服务端返回所有剩余结果。服务端会继续处理所有已接收数据,待所有数据处理完成并将结果返回给用户后,再断开与用户的连接。
  • 若用户在StopTranscription后发送任何信息,服务端都会返回错误信息。

交互流程说明

阶段1: 建立连接并设置参数

  1. 客户端向服务端发送开始转录(StartTranscription)的请求,在该请求中,客户端需要指定识别过程中使用的相关参数
  2. 服务端收到开始转录的请求后,会进行鉴权并初始化资源,完成后向客户端发送识别开始(TranscriptionStarted)的信息
  3. 以上步骤完成后,客户端可以开始向服务端发送待识别音频

阶段2: 实时识别

  1. 客户端将音频数据以二进制的形式向服务端发送
  2. 服务端收到二进制音频数据后,开始进行流式识别:
    • 当收到新一句话开始的音频数据后,会向客户端返回一句话开始(SentenceBegin)的信息
    • 当收到更多音频数据,直到识别的内容发生改变时,服务端会向客户端发送识别结果变化(SentenceChanged)的信息。在该结果中,服务端仅发送当前句子已被识别出的内容。注意:每次识别结果发生变化时,并不一定是多识别出了一个字,有可能是多了几个字或者是句子中之前的识别结果发生改变
    • 在识别一句话的过程中,识别结果变化的信息会发送多次
    • 服务端自动检测到一句话说完后,会向客户端发送一句话识别结束(SentenceEnd)的信息。至此,一句话的内容识别完成
    • 当客户端继续发送数据时,服务端会持续进行上述步骤,即循环返回一句话开始、识别结果变化、一句话识别结束

阶段3: 停止识别

  1. 当客户端需要停止识别过程时,向服务端发送结束识别(StopTranscription)的请求
  2. 服务端停止识别并释放资源,并向客户端发送识别完成(TranscriptionCompleted)。至此整个交互过程完成。

发送请求

发送的请求主体分为文本和二进制两种格式。除发送音频数据采用二进制格式外,其余采用JSON编码的文本格式,并分为主体头(header)和主体内容(payload)两部分。

请求Header格式

参数类型必需说明
appidString用于说明当前的应用ID
typeString消息类型,用于区分当前请求的类型。可选: "StartTranscription", "StopTranscription"

开始转录(StartTranscription)

开始识别,用于传输相关配置。其header部分如上所述,payload部分说明如下:

参数类型必需说明
domainString识别领域。默认为general(通用场景)
languageString语种。默认为cn(中文)
可选:
- cn: 中文
- en: 英文
2024/6/24新增
formatString音频编码格式,默认是无压缩、无头PCM文件,16bit采样、单声道
可选: PCM、WAV(带头WAV文件)、OPUS、MP3、AMR、AAC
采用PCM格式时,音频需满足采样率16k、位长16bit、单声道;其他格式需满足采样率16k、单声道
vocabulary_idString自定义热词对应的ID
lm_idString自定义语言模型对应的ID
enable_punctuationBoolean是否在后处理中添加标点,默认是False
enable_itnBoolean逆文本归一化,即将识别结果中的中文数字转换阿拉伯数字。默认是False
remove_disfluencyBoolean语气词过滤,即结果顺滑,默认是False
enable_speaker_infoBoolean是否开启说话人分离功能,默认是False。该功能为True时,在一句话识别结束时,返回该句子对应的说话人ID
nbestInteger输出结果的nbest,默认为1
show_confidenceBoolean是否输出置信度,默认为False
show_wordsBoolean是否开启返回词级别信息,默认是False
show_intermediate_resultBoolean是否返回识别过程中间结果(SentenceChanged),默认是False
enable_semantic_sentence_detectionBoolean是否开启语义断句,默认是False
special_word_filterString (JSON字符串)敏感词过滤功能,可根据实际需求开启或关闭自定义词或默认词表。默认为空字符串,该参数支持:
- null 或 未定义: 不处理
- object: 敏感词替换
- array: 敏感词替换为*

示例:

{
"header": {
"appid": "76e81efb964447",
"type": "StartTranscription"
},
"payload": {
"format": "pcm",
"domain": "general",
"language": "cn",
"vocabulary_id": "hotword",
"lm_id": "lm",
"enable_punctuation": true,
"enable_itn": true,
"remove_disfluency": true,
"enable_speaker_info": false,
"nbest": 1,
"show_confidence": true,
"show_intermediate_result": true,
"enable_semantic_sentence_detection": true,
"special_word_filter": ""
}
}

发送音频数据(SendData)

直接发送二进制音频数据。

结束识别(StopTranscription)

在header中将type设置为"StopTranscription",payload为空。

示例:

{
"header": {
"appid": "76e81efb964447",
"type": "StopTranscription"
}
}

返回信息

返回信息的主体均采用JSON编码的文本,同样分为主体头(header)和主体内容(payload)两部分。

返回Header格式

参数类型说明
taskidString用于记录本次会话的任务ID
typeString消息类型,用于区分当前响应的类型。可选: "TranscriptionStarted", "SentenceBegin", "SentenceChanged", "SentenceEnd", "TranscriptionCompleted", "Warning", "Error"
statusInteger状态码,表示请求是否成功,见服务状态码
status_textString状态消息

识别开始(TranscriptionStarted)

在header中type为"TranscriptionStarted",payload为空。

示例:

{
"header": {
"taskid": "4c0d4443fcd34567b42e028a54400e40",
"type": "TranscriptionStarted",
"status": 1000,
"status_text": "Success."
}
}

一句话开始(SentenceBegin)

在header中type为"SentenceBegin",payload格式如下:

参数类型说明
indexInteger句子编号,从1开始递增

示例:

{
"header": {
"taskid": "4c0d4443fcd34567b42e028a54400e40",
"type": "SentenceBegin",
"status": 1000,
"status_text": "Success."
},
"payload": {
"index": 1
}
}

句子识别结果变化(SentenceChanged)

注意: 该部分内容仅在show_intermediate_result=true时才会输出

在header中type为"SentenceChanged",payload中的字段如下:

参数类型说明
indexInteger句子编号,与SentenceBegin中的index对应
start_timeInteger当前句子的开始时间,单位为毫秒。暂未实现
end_timeInteger当前句子已处理的时间,单位为毫秒。暂未实现
resultList当前句子的识别结果,当nbest=1时,List仅包含一个元素,当nbest>1时,包含top N结果

result元素包含:

参数类型说明
textString当前句子的识别结果
confidenceDouble当前句子识别结果的置信度,取值范围: [0.0,1.0]。值越大表示置信度越高。暂未实现
wordsList词级别信息。该部分仅在show_words=true时才会输出。暂未实现
target_textString当开启翻译功能时,输出当前句子的目标语种翻译结果

注意:

  • 在流式返回的结果中,识别结果和翻译后的结果并不完全对应,翻译结果会有一定滞后性
  • 翻译结果没有词级别信息

词级别信息包含:

参数类型说明
textString词的文本
start_timeInteger词的开始时间,单位为毫秒
end_timeInteger词的结束时间,单位为毫秒

示例:

{
"header": {
"taskid": "4c0d4443fcd34567b42e028a54400e40",
"type": "SentenceChanged",
"status": 1000,
"status_text": "Success."
},
"payload": {
"index": 1,
"start_time": 0,
"end_time": 1135,
"result": [
{
"text": "摩尔线",
"confidence": 0,
"words": [
{
"text": "摩",
"start_time": 430,
"end_time": 870
},
{
"text": "尔",
"start_time": 870,
"end_time": 990
},
{
"text": "线",
"start_time": 990,
"end_time": 1135
}
]
}
]
}
}

一句话识别结束(SentenceEnd)

在header中type为"SentenceEnd",payload字段如下:

参数类型说明
indexInteger句子编号,与SentenceBegin中的index对应
start_timeInteger当前句子的开始时间,单位为毫秒。当静音过长时,返回的句子内容为空,此时结果中不包含开始时间
end_timeInteger当前句子的结束时间,单位为毫秒。当静音过长时,返回的句子内容为空,此时结果中不包含结束时间
speakerInteger当前句子对应的说话人ID。仅当enable_speaker_info=True时有效。暂未实现
resultList当前句子的识别结果,当nbest=1时,List仅包含一个元素,当nbest>1时,包含top N结果

result元素包含:

参数类型说明
textString当前句子的识别结果。当静音过长时,返回的句子内容为空字符串
confidenceDouble当前句子识别结果的置信度,取值范围: [0.0,1.0]。值越大表示置信度越高。暂未实现
wordsList词级别信息。该部分仅在show_words=true时才会输出。当静音过长时,返回的词信息为空列表
target_textString当开启翻译功能时,输出当前句子的目标语种翻译结果。注意:翻译结果没有词级别信息

词级别信息包含:

参数类型说明
textString词的文本
start_timeInteger词的开始时间,单位为毫秒
end_timeInteger词的结束时间,单位为毫秒

示例:

{
"header": {
"taskid": "4c0d4443fcd34567b42e028a54400e40",
"type": "SentenceEnd",
"status": 1000,
"status_text": "Success."
},
"payload": {
"index": 1,
"start_time": 0,
"end_time": 1430,
"speaker": 0,
"result": [
{
"text": "摩尔线程",
"confidence": 0,
"words": [
{
"text": "摩",
"start_time": 430,
"end_time": 870
},
{
"text": "尔",
"start_time": 870,
"end_time": 990
},
{
"text": "线",
"start_time": 990,
"end_time": 1140
},
{
"text": "程",
"start_time": 1140,
"end_time": 1430
}
]
}
]
}
}

识别完成(TranscriptionCompleted)

在header中的type为"TranscriptionCompleted",payload为空。

示例:

{
"header": {
"taskid": "4c0d4443fcd34567b42e028a54400e40",
"type": "TranscriptionCompleted",
"status": 1000,
"status_text": "Success."
}
}

识别错误(Warning/Error)

在header中type为"Warning"或"Error",payload为空。

  • 若错误类型为"Warning",用户可以继续交互流程,连接被保持
  • 若错误类型为"Error",本次交互流程直接结束,连接断开

示例:

{
"header": {
"taskid": "4c0d4443fcd34567b42e028a54400e40",
"type": "Error",
"status": 3002,
"status_text": "service timeout"
}
}

状态码

状态码状态消息说明
1000success!成功
1001waiting排队中
1002running识别中
2001appid doesn't exist!appid不存在
2002authorization failed.鉴权失败
2003too many requests并发数量过多
2004service overload数据发送过快,服务超负荷
3001service is busy服务器忙
3002service timeout服务处理超时
3003client is disconnected未完成前客户端主动断开
3004errors occured during processing识别过程中发生错误
3005cannot find the taskid任务过期,或taskid不存在
3006invalid audio typeaudio type非法
3007language is not supported输入的语种不支持
3008target language is not supported翻译目标语种不支持
3009errors occured during translation翻译过程中发生错误
4001unknown parameter is given.输入了未知/不支持的参数
4002given value is invalid参数值非法
4003request invalid请求消息格式错误
4004fail to read the audio音频解码失败
4005unsupported audio format音频格式不支持
4006audio too large音频文件过大
4007audio too long音频时长过长
4008fail to download the audio file文件下载失败
4009data timeout发送数据超时,等待下一包太久,导致识别结束
4010url is invalidURL非法
4011callback url is invalidcallback URL非法
4012fail to check content-lengthcontent-length 检查失败
4013fail to check md5音频md5校验失败
4014fail to upload audio data文件上传失败或超时
4015duplicated upload done detected重复发送UploadDone
4016duplicated start detected未按照规定的交互流程发送请求

示例代码

请参考: https://github.com/yiliu-mt/mtasr_examples/blob/main/realtime_streaming_asr/python/realtime_asr_demo.py