实时 ASR(WebSocket)
实时 ASR 通过 WebSocket 流式传输音频,并在您说话时返回转录结果——在音频仍在传输时返回临时的**部分(partial)结果,然后按话语返回权威的最终(final)**结果。可用于实时字幕、会议转录和语音界面。
如需一次性转录完整的音频文件,请改用批量 ASR 端点。
端点
wss://api.shisa.ai/ws/asr/realtime
在 WebSocket 握手期间,使用您的 ASR bearer 令牌进行认证:
Authorization: Bearer YOUR_API_KEY
您的 API 密钥需要对 shisa/asr-realtime 服务具有明确的访问权限。对批量 ASR、聊天、翻译或 TTS 的访问权限不会授予实时 ASR 的访问权限。如果您的密钥使用服务允许列表,请将 shisa/asr-realtime 添加到其中——否则握手将被拒绝。
实时 ASR 专为后端使用而设计。请将 API 密钥保存在服务器端:将音频从浏览器中继到您自己的服务器,再从那里连接到 Shisa。
工作原理
- 使用
Authorization标头打开到端点的 WebSocket。 - 发送一条
session.update消息以设置音频格式和语言。 - 等待
session.created。 - 将原始音频作为 base64 的
input_audio.append消息进行流式传输(每个块 50–250 ms 是不错的起点)。 - 将
asr.partial_result显示为实时临时文本;当asr.final_result到达时将其替换。 - 完成后发送
session.close。
音频要求
发送原始 PCM——不使用容器、不压缩:
| 属性 | 值 |
|---|---|
| 编码 | pcm_s16le(有符号 16 位小端) |
| 采样率 | 16000 Hz |
| 声道 | 1(单声道) |
| 块间隔 | 建议 50–250 ms(示例使用 100 ms) |
发送前请在客户端进行重采样和降混。请勿发送 WAV 头、Ogg、MP3、data URL、浮点 PCM 或立体声音频。
客户端消息
session.update
在发送任何音频之前,务必发送一条 session.update。固定语言的会话是最简单的选项:
{
"type": "session.update",
"session": {
"input_audio_format": "pcm_s16le",
"sample_rate": 16000,
"channels": 1,
"language": "ja"
}
}
| 字段 | 是否必需 | 值 | 备注 |
|---|---|---|---|
input_audio_format | 是 | pcm_s16le | 原始有符号 16 位小端 PCM。 |
sample_rate | 是 | 16000 | 发送前重采样到 16 kHz。 |
channels | 是 | 1 | 仅限单声道。请先降混立体声。 |
language | 是 | ja、en、zh、auto | 已知语言时使用固定值。自动语言识别使用 auto(见下文)。 |
default_language | 仅 auto 时 | ja、en、zh | 检测不确定时的回退值。 |
language_detection_mode | 仅 auto 时 | session、utterance | session 只检测一次;utterance 按段检测(进阶——见下文)。 |
input_audio.append
将音频块作为 base64 编码的 PCM 进行流式传输:
{
"type": "input_audio.append",
"audio": "<base64 pcm_s16le bytes>"
}
session.close
完成后正常关闭会话:
{ "type": "session.close" }
语言识别(可选)
如果您事先不知道说话的语言,请设置 language: "auto"。有两种模式。
会话检测在开始附近识别一次语言,并在整个会话中使用该语言:
{
"type": "session.update",
"session": {
"input_audio_format": "pcm_s16le",
"sample_rate": 16000,
"channels": 1,
"language": "auto",
"default_language": "en",
"language_detection_mode": "session"
}
}
会话会发出 session.language_detecting,然后发出一条包含所选 language 的 session.language_detected。
逐话语检测(language_detection_mode: "utterance")分别检测每个话语的语言,这对于多语言混合的音频很有用。它会为每个话语发出 utterance.language_detected。此模式必须在后端启用;如果未启用,会话将返回带有 code: "invalid_config" 的 error——此时请回退到固定语言或会话检测。
当检测无法确信地选择时,它会回退到 default_language,并且事件会带有 source: "default" 和 reason(例如 no_speech、short_utterance、inconclusive 或 timeout)。请始终将 asr.final_result.text 视为权威结果——不要仅凭语言事件就改写转录文本。
服务事件
所有事件都是 JSON 文本消息。会话创建后,每个事件都带有 session_id 和单调递增的 seq。
session.created
会话已被接受;您可以开始发送音频:
{
"type": "session.created",
"session_id": "asr_sess_...",
"seq": 1,
"format": { "encoding": "pcm_s16le", "sample_rate": 16000, "channels": 1 }
}
语音边界
speech_started 和 speech_stopped 标记每个话语的语音活动检测(VAD)端点:
{
"type": "speech_started",
"session_id": "asr_sess_...",
"seq": 4,
"utterance_id": "utt_0001",
"audio_start_ms": 420
}
{
"type": "speech_stopped",
"session_id": "asr_sess_...",
"seq": 9,
"utterance_id": "utt_0001",
"audio_start_ms": 420,
"audio_end_ms": 2860,
"reason": "vad_endpoint"
}
常见的停止原因有 vad_endpoint、max_buffer 和 session_close。
asr.partial_result
进行中话语的临时文本。请按 utterance_id 显示最新的部分结果,替换前一个——不要将每个部分结果都追加到历史记录中:
{
"type": "asr.partial_result",
"session_id": "asr_sess_...",
"seq": 7,
"utterance_id": "utt_0001",
"result_id": "utt_0001:p3",
"text": "今日の会議は3時から",
"is_final": false,
"audio_start_ms": 420,
"audio_end_ms": 2260
}
asr.final_result
话语的权威文本。使用 replaces 丢弃您正在显示的临时部分结果:
{
"type": "asr.final_result",
"session_id": "asr_sess_...",
"seq": 12,
"utterance_id": "utt_0001",
"result_id": "utt_0001:final",
"replaces": ["utt_0001:p1", "utt_0001:p2", "utt_0001:p3"],
"replaces_audio_range_ms": [420, 2860],
"text": "今日の会議は3時からです。",
"is_final": true,
"audio_start_ms": 420,
"audio_end_ms": 2860
}
最终结果是异步的,可能在后续语音事件之后到达。非常长的话语可能会被拆分为带有额外 continuation_of 和 overlap_mode 元数据的续接最终结果;显示时只显示逻辑上的 audio_start_ms–audio_end_ms 范围。
session.usage
用量是累积的。计费使用最新的事件。billable_duration 以整秒为单位:
{
"type": "session.usage",
"session_id": "asr_sess_...",
"seq": 20,
"final": true,
"usage": {
"input_duration": 18.3036875,
"billable_duration": 19,
"utterance_count": 3,
"final_result_count": 3,
"status": "completed",
"final": true
}
}
error
{
"type": "error",
"code": "finalization_failed",
"message": "Finalization failed",
"fatal": false,
"session_id": "asr_sess_...",
"seq": 18,
"utterance_id": "utt_0002"
}
致命(fatal)错误之后会关闭连接。非致命的话语错误则允许会话继续。
处理转录结果
- 以
utterance_id为键保存临时文本。 - 当更新的
asr.partial_result到达时,替换当前的部分结果。 - 收到
asr.final_result时,移除replaces中的 ID 并提交最终文本。 - 显示时忽略空的最终文本(但保留用于诊断)。
- 切勿将
session.usage渲染为转录文本。
后续步骤
- 使用批量 ASR 端点转录完整文件。
- 在音频与语言中查阅支持的格式和语言。
- 在定价中了解用量如何计费。