ASR 语音识别

ASR(语音识别)能力对接说明 #

中控 WebSocket 全双工接口 ASR 调用方式的说明,链接方式为 WebSocket 协议,控制报文为使用 UTF-8 编码的 JSON 文本。

调用流程 #

  1. 建立 WebSocket 连接(无需鉴权),如果在本地启动中控,地址通常为 ws://localhost:8070/v1
  2. 发送 Starter 包,内容为后续请求的通用配置信息,如果格式错误或超过 10 秒未发送会被断开 WebSocket 连接;
  3. 收到响应,表示鉴权成功或失败;
  4. 发送 Data 二进制数据包,内容为 PCM 音频;
  5. 音频发送完成后,发送 EOF 包;(可选,不发送则需额外发送 500 毫秒以上的环境静音,帮助 VAD 结束)
  6. 收到对应ASR结果,格式为 JSON 文本;
  7. 发送 EOF 请求包的情况下,收到 EOF 结果包,表示所有识别结果发送完毕;
  8. 如果当前没有更多语音识别任务,可以直接断开(没有链接断开报文的设计);
sequenceDiagram
    participant Client
    participant CS as Control System
    Client-->>CS: 1. Establish Connection
    activate CS
    Client->>CS: 2. Request: Starter
    CS-->>Client: 3. Response: Authentication
    loop
        Note right of Client: 重复4-7步至全部请求发送完毕
        loop
          Note right of Client: 按规定频率发送多个音频包
          Client->>CS: 4. Request: Data
        end
        Client->>CS: 5. Request: EOF (optional)
        CS-->>Client: 6. Response
        CS-->>Client: 7. Response: EOF (optional)
    end
    Client-->>CS: 8. Close Connection
    deactivate CS

请求报文格式 #

Starter #

每次建立连接后发送的第一个包,表示此连接的目的和后续数据包的解析方式。格式为 JSON 文本,包含以下字段:

字段名称类型默认值说明
authAuthN Tokenstring空字符串设备鉴权 Token,如服务端开启鉴权则必填
typeWorkflow Typestring必填填写能力对应的服务引擎编号,例如:“ASR5”,完整列表参见快速参考服务引擎列表部分
deviceDevice IDstring空字符串设备 ID,建议填写,以便追溯和定位问题
sessionSession IDstring随机 UUIDv4建议调用者自行生成 Session ID 并填写,以便追溯和定位问题
asrASR Configobject必填ASR 专属配置,具体信息见下

ASR Config 配置见下:

字段名称类型默认值说明
languageLanguage Codestringzh-CN可选字段,待识别的语言
mic_volumeMicrophone Volumefloat1.0可选字段,麦克风音量用于 ASR 进行自增益,支持范围为 0 到 1
subtitleSubtitle Formatstring空字符串可选字段,返回字幕的格式,空表示不返回,支持:srt
subtitle_max_lengthSubtitle Max Lengthint0可选字段,返回每行字幕/句级别时间戳的最大字数,0表示不限制字数,仅在返回字幕或返回句级别时间戳时有效
subtitle_cut_by_puncSubtitle Cut by Punctuationboolfalse可选字段,是否根据标点符号对字幕/句级别时间戳进行换行并去掉标点,仅在返回字幕或返回句级别时间戳时有效。标点符号范围见 字幕换行标点符号
subtitle_custom_puncCustom Subtitle Punctuationstring list字幕换行标点符号可选字段,使用自定义用于换行的标点符号,而不使用默认的标点符号,仅在返回字幕或句级别时间戳且 subtitle_cut_by_punc 为 true 时有效。
subtitle_punc_keepKeep Subtitle Punctuationboolfalse可选字段,是否保留换行的标点符号,仅在返回字幕或句级别时间戳且 subtitle_cut_by_punc 为 true 时有效。
intermediateReturn Intermediate Resultboolfalse可选字段,是否返回中间结果
sentence_timeReturn Sentence-Level Timestampboolfalse可选字段,是否返回句级别时间戳
word_timeReturn Word-Level Timestampboolfalse可选字段,是否返回字级别时间戳
cache_urlReturn Cache URL for Databoolfalse可选字段,是否将字幕文件上传 Object Store 存储并返回缓存 URL
pause_time_msecSpeech Pause Time (msec)int500可选字段,语音暂停时间,用于判断语音的边界和分段,默认为500毫秒

Data #

Starter 包发送并成功建立连接后,后续可重复发送多个二进制 Data 包流式提交音频。

输入的音频流格式为 PCM,使用 16KHz 采样率,16bit 数据位宽,单通道,小端。即 sox -t raw -r 16000 -e signed -b 16 -c 1 可转格式,或 ffmpeg -acodec pcm_s16le -ac 1 -ar 16000 -f s16le 可转格式。

流式与非流式 ASR 对于音频的发送速率要求不同:

  • 流式 ASR:音频按照从麦克风读取的速率发送,建议为每 40 毫秒发送 1280 字节,或每 160 毫秒发送 5120 字节。
  • 非流式 ASR:音频数据可以一次性发送,每个 Data 包的大小限制在 1920KB(1 分钟) 以内。

EOF #

音频包发送完成后,发送 EOF 包,表示结束识别

流式与非流式 ASR 对于 EOF 包的用法要求不同:

  • 流式 ASR:音频 Data 包发送完成后,发送 EOF 包。可选,不发送则需额外发送 500 毫秒以上的环境静音,帮助 VAD 结束。
  • 非流式 ASR:音频 Data 包发送完成后,必须发送 EOF 包。

如果需要获取字幕,无论是否为流式,都必须发送 EOF 包,以通知 ASR 服务端进行字幕生成。

格式为 JSON 文本,包含以下字段:

字段名称类型默认值说明
signal结束标记string必填固定为 eof
traceTrace IDstring随机 UUIDv4可选字段,建议调用者自行生成 Trace ID 并填写,以便追溯和定位问题

返回报文格式 #

鉴权结果 #

发送 Starter 请求后会返回包含鉴权结果的报文。格式为 JSON 文本,包含以下字段:

字段名称类型是否必现说明
serviceService NamestringYes当前请求对应的服务模块,即auth
sessionSession IDstringYes当前连接的 Session ID
statusStatus NameenumYes当前会话的状态,正常为 ok,失败为 fail
errorError MessagestringNo如果失败,返回的错误信息

ASR 结果数据 #

ASR会持续返回多个文字识别结果数据包,并在收到 EOF 请求后返回字幕、字幕文件地址数据包。如果在 Starter 请求中未要求返回字幕和字幕地址,则仅返回文字识别结果。

返回报文的格式为 JSON 文本,包含以下字段:

字段名称类型是否必现说明
serviceService NamestringYes当前请求对应的服务模块,即asr
sessionSession IDstringYes当前连接的 Session ID
traceTrace IDstringYes当前句子对应的 Trace ID
statusStatus NameenumYes当前会话的状态,正常为 ok,失败为 fail
errorError MessagestringNo如果失败,返回的错误信息
asrASR ContentobjectNo如果成功,返回的识别结果,具体字段含义见下

具体识别结果位于 ASR Content 中:

字段名称类型是否必现说明
indexIndex No.intYes返回包序列号
typePackage TypeenumYes文字结果包为 text,中间结果包为 intermediate,字幕包为 subtitle,字幕地址包为 subtitle_url,表示全部发送完毕为 eof
textTextstringYes文字识别结果,在字幕包中亦会出现,但内容为空
subtitleSubtitlestringNo字幕内容,仅在字幕包中有
subtitle_urlSubtitle URLstringNo字幕内容下载地址,仅在字幕包中有
sentence_timeSentence-Level TimestampobjectNo句子级别时间戳
word_timesWord-Level TimestampobjectNo字级别时间戳

文字结果 #

每句被完整识别的文字都会返回一条报文,中间识别结果不返回,如果无法识别或识别结果为空白字符,亦不返回。

文字结果样例:

{
    "service": "asr",
    "status": "ok",
    "session": "eab708a8-7aca-4237-a0a3-a6422ade8a23",
    "trace": "c9cb36d8-3ca9-4e2b-9034-29f2c4edc3de",
    "asr": {
        "index": 1,
        "type": "text",
        "text": "你好。"
    }
}

字幕结果 #

请求字幕且发送 EOF 后,返回生成的字幕结果。

字幕结果样例:

{
    "service": "asr",
    "status": "ok",
    "session": "eab708a8-7aca-4237-a0a3-a6422ade8a23",
    "trace": "9a971f17-f871-4b73-9084-b856b67537d5",
    "asr": {
        "index": 3,
        "type": "subtitle",
        "subtitle": "1\n00:00:00,000 --> 00:00:01,280\n你好。\n\n2\n00:00:02,960 --> 00:00:04,240\n再见。\n\n"
    }
}

字幕地址 #

请求字幕、请求 Cache URL、且发送 EOF 后,返回上传 Object Store 存储的字幕文件缓存 URL。

{
    "service": "asr",
    "status": "ok",
    "session": "eab708a8-7aca-4237-a0a3-a6422ade8a23",
    "trace": "25b30001-0b5a-4e9e-892c-4cc4d5bf134d",
    "asr": {
        "index": 4,
        "type": "subtitle_url",
        "subtitle_url": "https://aigc.blob.core.chinacloudapi.cn/audio/asr-srt/eab708a8-7aca-4237-a0a3-a6422ade8a23_25b30001-0b5a-4e9e-892c-4cc4d5bf134d.srt"
    }
}

EOF #

收到 EOF 请求的情况下,发送 EOF 结果包,表示结果全部发送完毕。

EOF 样例:

{
    "service": "asr",
    "status": "ok",
    "session": "eab708a8-7aca-4237-a0a3-a6422ade8a23",
    "trace": "16ff049a-41fb-4c7a-ac5e-b26dbc3218e5",
    "asr": {
        "index": 5,
        "type": "eof"
    }
}

实际流程样例解析 #

Case 1: 最小配置流程 #

Request: Starter

{
    "type": "ASR5",
    "asr": {}
}

Request: 二进制 Data 略

Response: 1

{
    "service": "auth",
    "status": "ok",
    "session": "4ea613f2-b1d4-47cf-8033-db59aae66721"
}

Response: 2

{
    "service": "asr",
    "session": "4ea613f2-b1d4-47cf-8033-db59aae66721",
    "trace": "e1c44bdc-4f9a-487c-806e-005679db7d0d",
    "asr": {
        "index": 1,
        "type": "text",
        "text": "早知道你喜欢十里春光"
    }
}

Response: 3

{
    "service": "asr",
    "session": "4ea613f2-b1d4-47cf-8033-db59aae66721",
    "trace": "f7551818-5025-4d83-b41b-136bb19b5b5f",
    "asr": {
        "index": 2,
        "type": "text",
        "text": "我一定会在麦田里种满玫瑰和山茶"
    }
}

Response: 4

{
    "service": "asr",
    "session": "4ea613f2-b1d4-47cf-8033-db59aae66721",
    "trace": "89d3a8b4-a291-4cdc-9b78-d3f912d06223",
    "asr": {
        "index": 3,
        "type": "text",
        "text": "你路过这片土地才算浪漫"
    }
}

Case 2: 完整配置流程 #

Request: Starter

{
    "auth": "XSMLTGKQVVCPJCQHJZ4VEDMGIY",
    "type": "ASR5",
    "session": "8f97055c-bd29-41c7-92d1-3933fed566fa",
    "asr": {
        "subtitle": "srt",
        "cache_url": true,
        "intermediate": true,
        "mic_volume": 0.67
    }
}

Response: 1

{
    "service": "auth",
    "status": "ok",
    "session": "8f97055c-bd29-41c7-92d1-3933fed566fa"
}

Request: 二进制 Data 略

Request: EOF

{
    "signal": "eof",
    "trace": "52517513-875a-47b6-bd30-f11a75e26745"
}

Response: 2

{
  "service": "asr",
  "status": "ok",
  "session": "8f97055c-bd29-41c7-92d1-3933fed566fa",
  "trace": "dcf88fbe-6cda-452d-8f51-e316cb4a0943",
  "asr": {
    "index": 1,
    "type": "intermediate",
    "text": "介"
  }
}

Response: 3

{
  "service": "asr",
  "status": "ok",
  "session": "8f97055c-bd29-41c7-92d1-3933fed566fa",
  "trace": "879d4700-746f-411b-954c-f83a2c6cd300",
  "asr": {
    "index": 2,
    "type": "intermediate",
    "text": "介绍下长"
  }
}

Response: 4

{
  "service": "asr",
  "status": "ok",
  "session": "8f97055c-bd29-41c7-92d1-3933fed566fa",
  "trace": "20e6a5e5-6d5d-4284-9013-4d410f1a5d37",
  "asr": {
    "index": 3,
    "type": "intermediate",
    "text": "介绍下长宁图书"
  }
}

Response: 5

{
  "service": "asr",
  "status": "ok",
  "session": "8f97055c-bd29-41c7-92d1-3933fed566fa",
  "trace": "cf7733e2-da28-442d-b5bb-282fc8f352f3",
  "asr": {
    "index": 4,
    "type": "text",
    "text": "介绍一下长宁图书馆。",
    "sentence_time": {
      "begin_ms": 2080,
      "end_ms": 4640
    },
    "word_times": [
      {
        "begin_ms": 2080,
        "end_ms": 2560,
        "text": "介"
      },
      {
        "begin_ms": 2560,
        "end_ms": 2800,
        "text": "绍"
      },
      {
        "begin_ms": 2800,
        "end_ms": 2920,
        "text": "一"
      },
      {
        "begin_ms": 2920,
        "end_ms": 3040,
        "text": "下"
      },
      {
        "begin_ms": 3040,
        "end_ms": 3280,
        "text": "长"
      },
      {
        "begin_ms": 3280,
        "end_ms": 3480,
        "text": "宁"
      },
      {
        "begin_ms": 3480,
        "end_ms": 3640,
        "text": "图"
      },
      {
        "begin_ms": 3640,
        "end_ms": 3880,
        "text": "书"
      },
      {
        "begin_ms": 3880,
        "end_ms": 4640,
        "text": "馆"
      }
    ]
  }
}

Response: 6

{
    "service": "asr",
    "session": "8f97055c-bd29-41c7-92d1-3933fed566fa",
    "trace": "3dcafe20-d6e0-4bce-a2ba-932b442e9e92",
    "asr": {
        "index": 5,
        "type": "subtitle",
        "subtitle": "1\n00:00:00,000 --> 00:00:02,280\n介绍一下长宁图书馆\n\n"
    }
}

Response: 7

{
    "service": "asr",
    "session": "8f97055c-bd29-41c7-92d1-3933fed566fa",
    "trace": "3dcafe20-d6e0-4bce-a2ba-932b442e9e92",
    "asr": {
        "index": 6,
        "type": "subtitle_url",
        "subtitle_url": "https://aigc.blob.core.chinacloudapi.cn/audio/asr-srt/8f97055c-bd29-41c7-92d1-3933fed566fa_3dcafe20-d6e0-4bce-a2ba-932b442e9e92.srt"
    }
}

Response: 8

{
    "service": "asr",
    "session": "8f97055c-bd29-41c7-92d1-3933fed566fa",
    "trace": "2bd4cbce-0f72-402c-8e88-0f2704a22868",
    "asr": {
        "index": 7,
        "type": "eof"
    }
}