OpenMontage 实战:基于 ElevenLabs Scribe 的浏览器端实时语音转写(Client-Side Real-Time Streaming)完整指南
OpenMontage 实战基于 ElevenLabs Scribe 的浏览器端实时语音转写Client-Side Real-Time Streaming完整指南【免费下载链接】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导读本文聚焦 OpenMontage 仓库中 speech-to-text 技能 的客户端实时流式转写能力如何从浏览器直接采集麦克风音频以约 150ms 级别的低延迟流式送往 ElevenLabs Scribe v2 Realtime 模型进行实时转写并处理部分转写partial与提交转写committed两类结果。读完本文你将掌握单次令牌single-use token签发、ReactuseScribeHook 与原生 JavaScriptScribe.connect两条接入路径、scribe.status状态机、VAD 自动提交策略以及手动 PCM 分块推送的完整实战方案并了解该能力在 OpenMontage 视频生产流水线中的落点。本文以仓库内 realtime-client-side.md 为主体骨架同时结合 SKILL.md、realtime-events.md、realtime-commit-strategies.md 等姊妹文档与仓库源码进行纵深展开确保配置、代码、参数均可直接复制运行。一、能力定位在 OpenMontage 中用于什么OpenMontage 是一个开源的 Agent 化视频生产系统其.agents/skills/与skills/目录沉淀了大量可供 AI 编码助手调用的技能文件。speech-to-text技能的整体定位是使用 ElevenLabs Scribe v2 将音频/视频转换为文本用于生成字幕、转写会议、处理口播内容等场景。该技能包含两类模型详见 SKILL.md模型 ID特点适用场景scribe_v2高精度、支持 90 语言批量转写、字幕生成、长音频scribe_v2_realtime低延迟约 150ms实时转写、语音 Agent本文讨论的scribe_v2_realtime即属于第二条路线。在仓库中该技能与具体的转写工具形成配套tools/analysis/transcriber.py中的Transcriber工具声明了agent_skills [speech-to-text]这意味着 Agent 在触发转写任务时可以查阅本文档对应的技能知识。该工具默认基于 faster-whisper / WhisperX 提供本地离线转写支持词级时间戳、说话人分离、语言检测见 transcriber.py而 ElevenLabs Scribe 则提供了云端低延迟实时的另一条路径——两者互补离线批处理交给 Whisper浏览器实时对话场景则交给 Scribe Realtime。仓库中同为 ElevenLabs 生态的 elevenlabs 技能 还展示了语音生成侧TTS、声音克隆、音效、音乐与 Remotion 的集成工作流语音旁白脚本 → MP3 → RemotionAudio组件逐场景同步。本文的实时转写能力与该工作流配合即可构建实时聆听 → 生成逐词时间戳 → 驱动字幕/歌词/口型同步的完整闭环。二、安装必须使用 elevenlabs/* 命名空间根据 installation.md 与本文档客户端实时转写需要安装对应的官方包# React npm install elevenlabs/react elevenlabs/elevenlabs-js # JavaScript npm install elevenlabs/client elevenlabs/elevenlabs-jsWarning:客户端包必须使用elevenlabs/*命名空间。旧版elevenlabsv1.xnpm 包已废弃不应再使用如果项目里残留旧包先执行npm uninstall elevenlabs再安装新包。各包的分工如下对应 installation.md 的迁移说明import { ElevenLabsClient } from elevenlabs/elevenlabs-js; // 服务端/Node客户端实例与令牌签发 import { Scribe } from elevenlabs/client; // 浏览器端底层流式连接 import { useScribe } from elevenlabs/react; // ReactHook 封装背景补充OpenMontage 的语音生成侧同样遵循直连与托管路由并存的原则。elevenlabs 技能 指出TTS 场景优先路由到fal_elevenlabs_tts通过 fal.ai 集中管理凭证仅当注册表中直接 Provider 可用时才使用elevenlabs_tts。实时转写侧的密钥管理ELEVENLABS_API_KEY与之一致API Key 只应存在于服务端环境变量中绝不下发浏览器。三、Token 生成用单次令牌保护 API Key浏览器端流式转写必须使用单次使用令牌single-use token来保护你的 API Key——绝不能让浏览器直接持有或拼接 API Key。令牌在你的后端服务中生成并暴露为一个受鉴权保护的安全接口import { ElevenLabsClient } from elevenlabs/elevenlabs-js; const elevenlabs new ElevenLabsClient({ apiKey: process.env.ELEVENLABS_API_KEY, }); app.get(/scribe-token, yourAuthMiddleware, async (req, res) { const token await elevenlabs.tokens.singleUse.create(realtime_scribe); res.json(token); });Note:单次使用令牌的有效期只有 15 分钟过期后必须重新签发。这要求前端在每次建立连接前实时获取令牌而不是缓存复用。四、React 实现useScribe Hook 全流程React 应用通过elevenlabs/react提供的useScribeHook 接入实时转写。核心思路Hook 负责管理连接生命周期与事件回调你只需要在点击开始时获取令牌并connect()import { useScribe, CommitStrategy } from elevenlabs/react; function TranscriptionComponent() { const [transcript, setTranscript] useState(); const scribe useScribe({ modelId: scribe_v2_realtime, commitStrategy: CommitStrategy.VAD, // Auto-commit on silence for mic input onPartialTranscript: (data) { // Show live feedback as user speaks console.log(Partial:, data.text); }, onCommittedTranscript: (data) { // Final transcript for this segment setTranscript((prev) prev data.text); }, }); const startRecording async () { const tokenResponse await fetch(/scribe-token); const { token } await tokenResponse.json(); await scribe.connect({ token, microphone: { echoCancellation: true, noiseSuppression: true, autoGainControl: true, }, }); }; const stopRecording () { scribe.disconnect(); }; return ( div divStatus: {scribe.status}/div button onClick{startRecording}Start/button button onClick{stopRecording}Stop/button p{transcript}/p /div ); }4.1 Commit 策略麦克风输入必须用 VADImportant:useScribe的默认提交策略是CommitStrategy.MANUAL即必须显式调用scribe.commit()才会产出最终转写。对麦克风实时输入务必设置CommitStrategy.VAD让服务端在检测到静音时自动提交。如果不设置committed转写永远不会触发连接甚至可能因长期无提交而断开。两种策略的取舍在 realtime-commit-strategies.md 中有完整说明策略行为适用场景Manual由你调用commit()完成段提交文件处理、由你控制音频分段VAD检测到静音自动提交实时麦克风输入、对话式应用VAD 还有一组可调参数React 侧以 Hook 选项传入const scribe useScribe({ modelId: scribe_v2_realtime, commitStrategy: CommitStrategy.VAD, // Optional VAD tuning: vadSilenceThresholdSecs: 1.5, // Silence duration before commit默认 1.5s vadThreshold: 0.4, // Speech detection sensitivity 0-1默认 0.4越小越灵敏 minSpeechDurationMs: 100, // Minimum speech length required默认 100ms minSilenceDurationMs: 100, // Minimum silence length required默认 100ms });4.2 两类转写结果partial 与 committed理解实时转写首先要分清两类输出详见 SKILL.md 与 realtime-commit-strategies.md类型说明用途Partial部分转写随音频处理高频更新的当前最佳猜测边说边显示的字幕反馈不要落库随时可能被修正Committed提交转写提交后稳定不变的最终结果应用的事实来源source of truth可安全拼接与保存Committed Timestamps带词级时间戳的最终结果字幕、卡拉 OK、口型同步4.3 scribe.status 状态机StatusMeaningdisconnected无活动连接connecting正在建立连接connected已连接可接收音频transcribing正在处理语音检测到音频或 VAD 提交时由connected转入error发生错误Important:判断会话是否处于活动状态时必须同时检查connected与transcribing。因为在语音处理期间状态会切到transcribing只检查connected会导致按钮、波形、指示灯等 UI 元素在 VAD 提交时被错误重置。// Correct - handles both active states const isListening scribe.status connected || scribe.status transcribing; // Wrong - will flicker/reset when VAD commits const isListening scribe.status connected;4.4 VAD 的底层原理VADVoice Activity Detection监听静音并在说话人停顿时自动提交从而产出贴合人类自然说话节奏句间、思想间停顿的转写分段。其推荐使用场景是实时麦克风输入与对话式应用而 Manual 提交则适合文件处理、已知分段边界、需要最大时间控制的场景对应 realtime-commit-strategies.md。若采用 Manual 策略官方还给出最佳实践每 20–30 秒提交一次、在静音或逻辑断点句末、说话人切换提交、若 90 秒无手动提交则自动提交。五、JavaScript 实现Scribe.connect 事件驱动不依赖 React 的场景原生 JS、Vue、小程序等使用elevenlabs/client的Scribe.connect。与 React Hook 的回调注册方式不同底层客户端采用事件监听模型事件名与 WebSocket 消息类型一一对应import { Scribe, RealtimeEvents } from elevenlabs/client; async function startTranscription() { const tokenResponse await fetch(/scribe-token); const { token } await tokenResponse.json(); const connection Scribe.connect({ token, modelId: scribe_v2_realtime, includeTimestamps: true, microphone: { echoCancellation: true, noiseSuppression: true, autoGainControl: true, }, }); connection.on(RealtimeEvents.OPEN, () { console.log(Connected); }); connection.on(RealtimeEvents.PARTIAL_TRANSCRIPT, (data) { console.log(Partial:, data.text); }); connection.on(RealtimeEvents.COMMITTED_TRANSCRIPT, (data) { console.log(Committed:, data.text); }); connection.on(RealtimeEvents.COMMITTED_TRANSCRIPT_WITH_TIMESTAMPS, (data) { for (const word of data.words) { console.log(${word.text}: ${word.start}s - ${word.end}s); } }); connection.on(RealtimeEvents.ERROR, (error) { console.error(Error:, error); }); connection.on(RealtimeEvents.CLOSE, () { console.log(Disconnected); }); return connection; }5.1 事件协议底层消息格式理解事件驱动模型推荐通读 realtime-events.md。该文档完整定义了实时转写的 wire protocol客户端 → 服务端Sent Eventsinput_audio_chunk发送音频数据。关键字段包括message_type恒为input_audio_chunk、audio_base_64Base64 编码的 PCM 音频、commit此块后是否提交、sample_rate采样率8000–48000、previous_text仅首块可携带最长 50 字符用于断线重连后的上下文续接{ message_type: input_audio_chunk, audio_base_64: base64-encoded-pcm-audio, commit: false, sample_rate: 16000 }commit终结当前转写段{ message_type: commit }服务端 → 客户端Received Events均以message_type作为判别字段事件含义session_started连接建立成功返回session_id与回显的会话配置采样率、音频格式、模型 ID、提交策略、是否含时间戳partial_transcript部分转写随音频处理频繁更新committed_transcript提交后的最终转写committed_transcript_with_timestamps含词级时间戳的最终转写include_timestampstrue时在 committed 之后发送每个词包含text、start、end、typeword/spacing/audio_event与可选speaker_id错误事件与错误码服务端通过error事件上报失败原因常见错误码包括auth_errorKey 或令牌无效、quota_exceeded用量超限、input_error不支持的音频格式或非法输入、rate_limited请求过频、commit_throttled提交过于频繁、session_time_limit_exceeded会话超时、chunk_size_exceeded音频块过大、insufficient_audio_activity未检测到足够语音、transcriber_error内部处理错误等。六、手动音频分块处理文件与自定义音频源对于文件上传或自定义音频源例如不是麦克风而是从本地文件解码出的 PCM 流需要将音频编码为 PCM-16 并按块推送给服务端const chunkSize 4096; for (let offset 0; offset pcmData.length; offset chunkSize) { const chunk pcmData.slice(offset, offset chunkSize); const bytes new Uint8Array(chunk.buffer); const base64 btoa(String.fromCharCode(...bytes)); scribe.sendAudio(base64); // Simulate real-time streaming await new Promise((resolve) setTimeout(resolve, 50)); } // Finalize transcription scribe.commit();6.1 音频格式要求服务端对音频有明确要求详见 realtime-server-side.md 的 Audio Requirements参数推荐值格式PCM 16-bit采样率16000 Hz推荐支持 8kHz–48kHz声道单声道Mono分块大小32,000 字节 ≈ 16kHz 下的 1 秒音频服务端侧示例客户端手动分块示例使用 4096 字节提示处理多声道或非 16kHz 音频时应先做预处理。服务端示例给出了 Python 侧用 pydub 的转换思路多声道set_channels(1)、重采样set_frame_rate(16000)、位深set_sample_width(2)再按块 Base64 编码发送。JavaScript 侧可用fs.readFileSync读取.pcm文件按chunkSize切分后toString(base64)发送最后connection.commit()收尾。6.2 提供上下文previous_text如果需要在断线重连后续接对话或在转写开头为模型提供语境可在首个音频块中携带previous_text不超过 50 字符。这有助于续接重连后的对话、提升上下文准确性、处理句子碎片对应 realtime-commit-strategies.md。七、麦克风选项浏览器采集参数connect时传入的microphone配置直接映射到浏览器getUserMedia约束用于改善采集质量OptionDescriptionechoCancellation消除扬声器回声noiseSuppression过滤背景噪声autoGainControl归一化音量水平在说话人 A 对着扬声器讲话、扬声器同时播放对方声音这类视频会议场景中echoCancellation尤其重要——否则转写会把回放的对方语音也当作输入。八、安全底线浏览器端实时转写存在天然的密钥泄露风险必须遵守以下三条红线对应原文档 Security 章节绝不在客户端暴露你的 API KeyAPI Key 只存在于服务端环境变量如ELEVENLABS_API_KEY任何前端代码、构建产物、网络请求中都不应出现。始终在后端生成单次使用令牌通过elevenlabs.tokens.singleUse.create(realtime_scribe)签发前端只持有一次性、15 分钟有效的令牌。用鉴权中间件保护令牌接口/scribe-token这类端点必须挂在yourAuthMiddleware之后防止匿名用户刷取令牌造成额度消耗。九、在 OpenMontage 中的落地与延伸9.1 与仓库转写工具链的配合OpenMontage 的转写能力呈现本地离线 云端实时双轨结构本地离线Transcriber 工具 基于 faster-whisper 提供确定性的批量转写词级时间戳、VAD 过滤、GPU 探测与 CPU 回退、WhisperX 说话人分离输出{文件名}_transcript.json适合音视频文件的后期字幕生成。云端实时本文的 Scribe v2 Realtime 客户端流式方案适合交互式、低延迟场景直播字幕、会议实时记录、语音助手。两种路径产出相同的文本 词级时间戳数据结构可统一喂给下游的 字幕同步技能 或 subtitle-sync 技能 完成 SRT/ASS 字幕生成再交给 Remotion 合成器 渲染为带字幕的视频成品。9.2 延伸WebSocket 直连在不便使用 SDK 的场景例如非 JS 语言、嵌入式环境可以绕过 SDK 直连 WebSocket 端点详见 realtime-server-side.mdwss://api.elevenlabs.io/v1/speech-to-text/realtime?model_idscribe_v2_realtime直连时的消息格式与上文事件协议完全一致上行input_audio_chunk/commit下行以message_type区分的各类转写事件。这意味着本文描述的令牌签发、音频格式、事件语义在直连场景下同样适用——你完全可以用同一套后端令牌体系驱动任意语言的实时转写客户端。十、快速自检清单落地前对照检查以下要点可避免绝大多数连接建了但没结果的坑✅ 包名是否为elevenlabs/react/elevenlabs/client/elevenlabs/elevenlabs-js拒绝旧版elevenlabs。✅ API Key 是否仅存在于服务端令牌接口是否挂了鉴权中间件。✅ 麦克风输入是否设置了CommitStrategy.VAD默认 Manual 会导致 committed 永不触发。✅ UI 活动态判断是否同时覆盖connected与transcribing。✅ 手动推流时音频是否为 PCM-16 / 单声道 / 16kHz块大小是否在服务端接受范围内。✅ 是否处理了error事件并映射错误码auth_error、rate_limited、chunk_size_exceeded等。【免费下载链接】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),仅供参考
上一篇/下一篇内容由系统自动关联
返回资讯列表 →