ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

OpenMontage 实时语音转写事件协议完全参考:ElevenLabs Scribe v2 Realtime 的 WebSocket 事件流深度解析

OpenMontage 实时语音转写事件协议完全参考:ElevenLabs Scribe v2 Realtime 的 WebSocket 事件流深度解析 OpenMontage 实时语音转写事件协议完全参考ElevenLabs Scribe v2 Realtime 的 WebSocket 事件流深度解析【免费下载链接】OpenMontageWorlds first open-source, agentic video production system. 12 production pipelines, 100 tools, 700 agent skill and production-knowledge files. Turn your AI coding assistant into a full video production studio.项目地址: https://gitcode.com/GitHub_Trending/op/OpenMontage实时语音转写Realtime Speech-to-Text Streaming以毫秒级延迟将音频流转换为文本其底层是一个双向 WebSocket 事件协议。本文以 OpenMontage 仓库中 speech-to-text 技能 的实时事件参考文档realtime-events.md为核心骨架完整梳理客户端发送与服务端接收的全部事件类型、字段定义、错误码语义并结合仓库内 服务端流式参考、提交策略参考 等姊妹文档给出可落地的 Python / JavaScript 事件处理代码与实战建议。读完本文你将能够独立解析实时转写 WebSocket 上每一类消息正确驱动input_audio_chunk、commit与四种接收事件并妥善处理十二类错误场景。一、事件协议概览双向 WebSocket 上的消息流ElevenLabs Scribe v2 Realtime模型 IDscribe_v2_realtime的实时转写建立在 WebSocket 长连接之上往返延迟约 150ms专为直播字幕、语音代理等低延迟场景设计见 SKILL.md。协议两侧的流量方向如下方向角色主要消息客户端 → 服务端Sent Events上行input_audio_chunk音频数据块、commit提交当前片段服务端 → 客户端Received Events下行session_started、partial_transcript、committed_transcript、committed_transcript_with_timestamps、error传输层标准 WebSocket双向open、close协议的关键设计是所有 JSON 消息统一以message_type字段作为判别器discriminator接收方只需检查message_type即可分发到对应的处理逻辑。直接连接 WebSocket 的端点形如wss://api.elevenlabs.io/v1/speech-to-text/realtime?model_idscribe_v2_realtime见 realtime-server-side.md该文档同时强调SDK 可用时优先使用 SDK直连仅用于 SDK 无法覆盖的场景。消息分发示意上行消息{message_type: input_audio_chunk, ...}与{message_type: commit}下行消息服务端所有 JSON 事件均携带message_type前缀字段便于统一switch/if分发传输层事件open与close是标准 WebSocket 事件close携带标准关闭帧的 code 与 reason不是 JSON 消息。二、客户端 → 服务端事件Sent Events2.1input_audio_chunk发送音频数据块这是实时转写最主要的指令把音频数据以 Base64 编码后分块发给服务端进行转写。{ message_type: input_audio_chunk, audio_base_64: base64-encoded-pcm-audio, commit: false, sample_rate: 16000 }完整字段说明字段类型必填说明message_typestring是固定为input_audio_chunkaudio_base_64string是Base64 编码的 PCM 音频数据commitboolean是是否在本块之后执行提交true等价于发完本块立即 commitsample_ratenumber否采样率Hz支持 8000–48000previous_textstring否前序转写文本上下文仅首个 chunk 可带最长 50 字符几个容易踩坑的细节sample_rate的取值范围是 8000–48000Hz。服务端推荐的输入规格为 PCM 16-bit、单声道、16kHzchunk 尺寸通常取 32,000 字节即 16kHz 下 1 秒音频μ-law 8-bit 8kHz 用于电话场景见 realtime-commit-strategies.md 的音频格式表。previous_text只允许出现在第一个 chunk用于断线重连后接续对话、消除句首碎片歧义。它会被计入上下文帮助模型理解“刚才说到哪了”但上限 50 字符超长会被拒绝或截断。commit: true是“边发边提交”的快捷方式。如果你希望“发送完这块就锁定结果”可以直接置true省去单独再发一条commit消息。2.2commit固化当前转写片段{ message_type: commit }commit告诉模型把当前音频段落的转写结果“锁定”为最终稿。这是实时转写中最关键的语义节点收到 commit 之前服务端输出的是不断修正的partial_transcript临时结果收到 commit 之后服务端输出不可变的committed_transcript。提交可以由你手动触发如检测到停顿、句末也可以交给 VAD语音活动检测在静音时自动触发。关于提交时机的完整策略见 realtime-commit-strategies.md。三、服务端 → 客户端事件Received Events所有接收事件均使用message_type作为判别器字段。3.1session_started连接建立成功WebSocket 握手完成、会话参数协商完毕后服务端返回的第一条事件{ message_type: session_started, session_id: 0b0a72b57fd743ebbed6555d44836cf2, config: { sample_rate: 16000, audio_format: pcm_16000, language_code: en, model_id: scribe_v2_realtime, commit_strategy: manual, include_timestamps: true } }session_id本次会话的唯一标识可用于后续问题排查与用量对账config服务端最终生效的会话配置镜像包含采样率、音频格式如pcm_16000、语言代码、模型 ID、提交策略manual/vad以及是否输出时间戳include_timestamps。实战建议把session_started当作“可以开始发音频”的信号。在 SDK 场景下Python 端通常在这里启动音频发送任务见 realtime-server-side.md 的on_session_started回调中asyncio.create_task(send_audio())的写法JavaScript 端则在RealtimeEvents.SESSION_STARTED回调里调用sendAudio()。3.2partial_transcript临时转写结果模型持续处理音频时高频更新的“当前最佳猜测”用于实时反馈例如说话时文字实时上屏{ message_type: partial_transcript, text: Hello, how are }字段类型说明message_typestringpartial_transcripttextstring当前临时转写文本重要partial 结果是易变的——随着更多上下文到达their可能被修正为there。不要持久化 partial 文本它只适合做即时预览。3.3committed_transcript最终转写结果commit 之后由服务端返回的不可变结果是应用层的“事实来源”source of truth{ message_type: committed_transcript, text: Hello, how are you today? }字段类型说明message_typestringcommitted_transcripttextstring已固化的转写文本3.4committed_transcript_with_timestamps带词级时间戳的最终结果当连接参数include_timestampstrue时服务端在committed_transcript之后额外发送一条带词级时间戳的最终结果直接服务于字幕、卡拉OK 歌词、口型同步等场景{ message_type: committed_transcript_with_timestamps, text: Hello, how are you today?, language_code: en, words: [ {text: Hello, start: 0.0, end: 0.32, type: word}, {text: , start: 0.32, end: 0.35, type: spacing}, {text: how, start: 0.40, end: 0.55, type: word} ] }字段说明字段类型说明message_typestringcommitted_transcript_with_timestampstextstring完整转写文本language_codestring检测到的语言代码wordsarray词级时间数据words[].textstring词或 token含空格 tokenwords[].startnumber开始时间秒words[].endnumber结束时间秒words[].typestringword、spacing或audio_eventwords[].speaker_idstring说话人标识开启 diarization 时出现三个type的语义需要特别留意与批式转写中的定义一致word真实说出的词spacing词与词之间的空白提供精确到毫秒的时间边界做字幕对齐时非常有价值audio_event模型检测到的非语音声音笑声、掌声、音乐等。四、错误事件与错误码全集4.1error事件发生错误时服务端发送{ message_type: error, error: input_error }4.2 十二个错误码及其处理建议错误码说明处理建议auth_errorAPI Key 或 Token 无效校验ELEVENLABS_API_KEY环境变量或单次令牌是否过期客户端令牌有效期 15 分钟quota_exceeded用量已达上限检查账户配额等待重置或升级input_error音频格式不支持或输入非法核对 PCM 16-bit 规格与采样率范围8000–48000Hzrate_limited请求过于频繁退避重试控制发送节奏commit_throttledcommit 发送过于频繁拉长提交间隔参考“每 20–30 秒提交一次”的实践session_time_limit_exceeded会话超过最大时长主动断开并重新建立会话unaccepted_terms控制台中未接受服务条款到 ElevenLabs 控制台完成条款确认resource_exhausted服务端容量达到上限稍后重试或更换区域queue_overflow服务端队列已满降低发送速率稍后重试chunk_size_exceeded音频块过大减小 chunk 尺寸推荐 32,000 字节/秒insufficient_audio_activity未检测到足够语音检查麦克风/输入源是否正常采集transcriber_error服务端内部处理错误保留session_id与时间戳以便排障重试提示auth_error场景在客户端直连时尤其常见——浏览器端绝不能暴露 API Key应通过后端生成 15 分钟有效的单次令牌single-use token再交给useScribe/Scribe.connect详见 realtime-client-side.md。五、连接事件open与close协议层的两个标准 WebSocket 事件事件类型说明open标准 WebSocket 事件连接建立成功不是 JSON 消息此后可开始发送input_audio_chunkclose标准 WebSocket close frame连接关闭携带标准关闭码code与原因reason在 SDK 层两个事件均有对应枚举常量如 Python 的RealtimeEvents.CLOSE、JavaScript 的RealtimeEvents.CLOSE常被用作清理资源与重连触发的锚点。六、音频前置条件直连协议之前的硬性约束理解了事件格式后还需要满足音频输入规格否则input_error/chunk_size_exceeded会频繁出现。服务端侧文档realtime-server-side.md给出的要求如下参数取值格式PCM 16-bit采样率16000 Hz推荐声道单声道Mono块大小32,000 字节 ≈ 1 秒音频支持采样率8000 – 48000 Hz在上行消息里显式带上sample_rate可以帮助服务端正确解析手动分块发送时Python 端常用pydub完成“多声道→单声道、48kHz→16kHz、16-bit”的转换再按 32,000 字节切块、Base64 编码后逐块connection.send(...)全部发完后await connection.commit()完整实现见 realtime-server-side.md 的 Manual Audio Chunking 示例。七、事件处理实战Python 与 JavaScriptSDK 已经屏蔽了线协议细节Python SDK 的事件对象使用event.type而不是message_typeJavaScript SDK 的事件名与message_type取值一一对应。以下两段示例完整覆盖五种核心事件。7.1 PythonSDK 抽象使用event.typeasync for event in connection: if event.type session_started: print(fSession: {event.session_id}) elif event.type partial_transcript: print(fPartial: {event.text}) elif event.type committed_transcript: print(fFinal: {event.text}) elif event.type committed_transcript_with_timestamps: for word in event.words: print(f {word.text}: {word.start}s - {word.end}s) elif event.type error: print(fError: {event.error})除异步迭代外Python SDK 同样支持事件回调注册方式connection.on(RealtimeEvents.PARTIAL_TRANSCRIPT, handler)其中RealtimeEvents枚举覆盖SESSION_STARTED、PARTIAL_TRANSCRIPT、COMMITTED_TRANSCRIPT、COMMITTED_TRANSCRIPT_WITH_TIMESTAMPS、ERROR、CLOSE等见 realtime-server-side.md。7.2 JavaScript事件名与message_type对齐connection.on(session_started, (data) { console.log(Session:, data.sessionId); }); connection.on(partial_transcript, (data) { console.log(Partial:, data.text); }); connection.on(committed_transcript, (data) { console.log(Final:, data.text); }); connection.on(committed_transcript_with_timestamps, (data) { for (const word of data.words) { console.log( ${word.text}: ${word.start}s - ${word.end}s); } }); connection.on(error, (error) { console.error(Error:, error); });JS 端还可用枚举RealtimeEvents.OPEN/RealtimeEvents.CLOSE监听传输层状态注意字段名是驼峰风格如data.sessionId与线协议 JSON 的session_id不同。八、事件驱动的提交策略何时 commit、如何接上下文事件协议的价值最终体现在“提交时机”的控制上。综合 realtime-commit-strategies.md 与 SKILL 文档推荐实践如下Partial vs Committedpartial 只用于实时反馈不要持久化committed 才是应用可信的最终结果。手动提交Manual默认适合文件处理、已知段落边界、服务端批处理。最佳实践是每 20–30 秒提交一次、在静音或逻辑断点句末、说话人切换处提交若长时间未手动提交服务端约在 90 秒自动提交。VAD 自动提交适合实时麦克风输入与对话场景。React 的useScribe通过commitStrategy: CommitStrategy.VAD启用并可用vadSilenceThresholdSecs: 1.5、vadThreshold: 0.4、minSpeechDurationMs、minSilenceDurationMs微调灵敏度JS 客户端则在connect({ vad: {...} })中配置。上下文续接断线重连或处理句子碎片时在第一个 chunk携带previous_text≤50 字符例如So as I was saying,可显著提升接续准确率。一个需要特别警惕的陷阱麦克风输入场景若使用默认的 Manual 策略却从不调用commit()committed_transcript将永远不会触发连接甚至可能被服务端断开。因此在 realtime-client-side.md 中明确要求麦克风输入必须显式设置CommitStrategy.VAD。九、与 OpenMontage 项目的结合在 OpenMontage 中该事件协议文档是 speech-to-text 技能 的参考层组成部分与 安装指南、转写选项参考、服务端流式参考、客户端流式参考、提交策略参考 一起构成完整的实时转写知识体系低延迟场景直播字幕、语音代理、实时会议转写优先走scribe_v2_realtime 本文事件协议毫秒级延迟配合partial_transcript提供即时反馈批式场景字幕生成、长音频转写使用scribe_v2的批式convert接口参数体系见 transcription-options.md项目内本地转写仓库同时内置了基于本地模型的 transcriber.py 工具Transcriber类支持设备与计算精度选择可作为无外部 API 依赖时的离线替代方案与云端实时转写互为补充下游消费带时间戳的committed_transcript_with_timestamps输出可直接对接字幕生成srt等导出格式与视频合成链路。从源码结构看本文档所处的.agents/skills/speech-to-text/references/目录是 Agent 技能体系的参考层SKILL.md 负责总览与快速上手references 下的独立文档提供协议级细节这种“技能 参考”的分层组织让 Agent 在需要处理实时事件时能够精准检索到本文这样的事件字典。十、速查表一次会话中的典型事件时序一个完整的实时转写会话通常按以下顺序流转建立 WebSocket 连接 → 收到open收到session_started含session_id与生效的config持续发送input_audio_chunkBase64 PCM建议 32,000 字节/块附sample_rate服务端随音频到达持续返回partial_transcript高频、易变仅作预览发送commit或依赖 VAD 自动触发→ 收到committed_transcript若开启include_timestamps随后收到committed_transcript_with_timestamps词级时间与说话人标签任意时刻出错 → 收到error 具体错误码会话结束 → 收到close。掌握这份事件字典你就掌握了实时语音转写协议的核心上行只有两把钥匙音频块与提交下行是五种 JSON 事件加两个传输层事件而message_type就是分发这一切的指南针。后续接入直播字幕、实时会议纪要或语音代理时可直接回到本参考逐字段核对消息结构。【免费下载链接】OpenMontageWorlds first open-source, agentic video production system. 12 production pipelines, 100 tools, 700 agent skill and production-knowledge files. Turn your AI coding assistant into a full video production studio.项目地址: https://gitcode.com/GitHub_Trending/op/OpenMontage创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表