转录文本与提交策略

本指南介绍如何通过 ElevenLabs 实时文本转语音 API 处理转录文本和提交策略。

操作指南 · 假设你已完成客户端或服务端 流式传输指南。

概览

转录音频时,你会收到部分转录和已提交转录。

  • 部分转录 - 转录的中间结果
  • 已提交转录 - 收到“提交”消息时发送的最终转录片段结果。一个会话可以有多个已提交转录。

已提交的转录可选择包含词级时间戳。仅在“包含时间戳”选项设为 true 时才会收到这些时间戳。

# Initialize the connection
connection = await elevenlabs.speech_to_text.realtime.connect(RealtimeUrlOptions(
model_id="scribe_v2_realtime",
include_timestamps=True, # Include this to receive the RealtimeEvents.COMMITTED_TRANSCRIPT_WITH_TIMESTAMPS event with word-level timestamps
))

提交策略

通过 WebSocket 发送音频块时,可以通过两种方式提交转录片段:手动提交或语音活动检测(VAD)。

手动提交

使用手动提交策略时,你可以控制何时提交转录片段。这是默认使用的策略。提交片段会清除已处理的累积转录,并开始新片段,同时不会丢失上下文。为改善延迟,建议每隔 20-30 秒提交一次。即使不手动提交,模型也会在累积约 36 秒音频后自动提交。

为获得最佳效果,请在静音期间或其他合理节点(如轮次切换)提交。

发送首个 2 秒音频后,转录处理即会开始。
await connection.send({
"audio_base_64": audio_base_64,
"sample_rate": 16000,
})
# When ready to finalize the segment
await connection.commit()

在短时间内连续多次手动提交可能会降低模型性能。

发送此前的文本上下文

发送待转录音频时,可以在首个音频块中一并发送此前的文本上下文,帮助模型理解语音上下文。这在以下几种场景中很有用:

  • 对话式 AI 使用场景中的智能体文本 - 让模型更容易理解对话上下文,并生成更好的转录结果。
  • 网络错误后重新连接 - 让模型能以前面的文本为参考继续转录。
  • 常规上下文信息 - 简要说明转录内容,有助于模型理解上下文。

仅能在通过 connection.send() 发送首个音频块时发送 previous_text 上下文。在后续音频块中发送会导致错误。此前文本最好少于 50 个字符。

await connection.send({
"audio_base_64": audio_base_64,
"previous_text": "The previous text context",
})

语音活动检测(VAD)

使用 VAD 策略时,转录引擎会自动检测语音和静音片段。达到静音阈值后,转录引擎会自动提交转录片段。

通过客户端集成转录麦克风音频时,建议使用 VAD 策略。

import { Scribe, AudioFormat, CommitStrategy } from "@elevenlabs/client";
const connection = Scribe.connect({
token: "sutkn_1234567890",
modelId: "scribe_v2_realtime",
audioFormat: AudioFormat.PCM_16000,
commitStrategy: CommitStrategy.VAD,
vadSilenceThresholdSecs: 1.5,
vadThreshold: 0.4,
minSpeechDurationMs: 100,
minSilenceDurationMs: 100,
});

在静音期间保持连接

官方 SDK 不会在没有消息到达时断开连接,因此大多数集成无需进行此设置。如果自有 WebSocket 客户端,或中间的代理或负载均衡器,会在一段时间未收到帧时关闭连接,请在连接时传入可选的 keepalive_interval_ms 查询参数。这在长时间静音时尤为重要,例如通话中有 10-15 秒的停顿。服务器大约每隔一个时间间隔发送一次保活 partial_transcript:如果当前片段没有未提交文本,则其为空(text: "");否则会重复最新的部分文本。

保活不是持续运行的 ping:你必须持续传输音频(可以传输静音帧)。 如果停止发送音频,就不会发送保活消息;客户端 15 秒未发送任何消息后,服务器会关闭连接。此服务器限制不可配置。

  • 接受介于 500 和 10000 之间的整数(毫秒)。默认禁用;省略该参数即可保持现有行为。
  • 超出范围或非整数的值会导致服务器发送 invalid_request 错误并关闭连接。
  • 保活由模型实际处理所发送的静音音频触发,而非持续运行的计时器,因此也能确认转录链路仍然正常。
  • 音频大约按 1 秒的块处理,因此保活消息大约会按该节奏每隔一个时间间隔到达(例如,1000 大约每秒触发一次,3000 大约每 3 秒触发一次)。会话的首次保活会在启动约 2 秒后到达,因为服务器会在转录前缓冲最初约 2 秒的音频。将间隔设为自定义读取超时的至多约三分之一,以留出余量。
  • 仅当当前片段尚无未提交文本时,保活消息的 text 才为空。若语音结束后、提交前发生停顿——在 filter_background_audio=true 或未提交的手动提交模式下最明显——保活消息会改为重复最新的部分文本,因此不会清空中间文本。提交后,保活消息会恢复为空,直到有新的语音到达。
  • 同时适用于 commit_strategy=manual 和 commit_strategy=vad,也适用于 filter_background_audio=true。除已传输的音频外,不会产生额外计费影响。
  • session_started 消息的 config 会回传 keepalive_interval_ms(禁用时为 null)。

空的 partial_transcript(text: "")表示“当前片段中没有语音”。停顿期间重复且相同的 partial_transcript 也是保活消息——客户端应像往常一样渲染部分转录,而无需对重复内容进行特殊处理。

将参数添加到 WebSocket URL:

wss://api.elevenlabs.io/v1/speech-to-text/realtime?model_id=scribe_v2_realtime&commit_strategy=vad&keepalive_interval_ms=1000

支持的音频格式

格式采样率说明
pcm_80008 kHz16 位 PCM,小端序
pcm_1600016 kHz16 位 PCM,小端序(推荐)
pcm_2205022.05 kHz16 位 PCM,小端序
pcm_2400024 kHz16 位 PCM,小端序
pcm_4410044.1 kHz16 位 PCM,小端序
pcm_4800048 kHz16 位 PCM,小端序
ulaw_80008 kHz8 位 μ-law 编码

最佳实践

音频质量

  • 为在质量和带宽之间取得最佳平衡,请使用 16 kHz 采样率。
  • 确保音频输入清晰,尽量减少背景噪音。
  • 使用合适的麦克风增益,避免削波。
  • 目前仅支持单声道音频。

块大小

  • 为实现流畅传输,请发送时长为 0.1 - 1 秒的音频块。
  • 较小的音频块延迟更低,但开销更大。
  • 较大的音频块效率更高,但可能增加延迟。

后续步骤