RealtimeSTT Server 实战指南:基于 WebSocket 的实时语音转写服务端与客户端
【免费下载链接】RealtimeSTTA robust, efficient, low-latency speech-to-text library with advanced voice activity detection, wake word activation and instant transcription.项目地址: https://gitcode.com/GitHub_Trending/re/RealtimeSTT
本文围绕仓库 RealtimeSTT_server 目录下的
stt-server与stt两条 CLI 命令展开,系统讲解如何将 RealtimeSTT 库以「服务端 + 客户端」的形态部署为可远程调用的实时语音转写系统。读完本文,你将掌握双 WebSocket 通道(控制通道 + 数据通道)的通信架构、全部服务端/客户端命令行参数的语义与调优建议、通过控制命令动态设置参数与调用录音器方法,以及如何对接浏览器等自定义客户端。
一、整体架构:控制通道与数据通道分离
RealtimeSTT Server 的核心设计是「控制与数据分离」的双 WebSocket 通道,这一设计让音频数据的吞吐不受控制指令的干扰:
- 控制 WebSocket(默认
ws://127.0.0.1:8011):用于收发控制命令,例如设置录音器参数、读取参数值、调用录音器方法(set_microphone、abort、stop、clear_audio_queue、wakeup等)。 - 数据 WebSocket(默认
ws://127.0.0.1:8012):用于上行传输音频数据(二进制帧),并向所有已连接客户端广播实时转写结果与录音事件(文本帧)。
从 stt_server.py 的main_async()可以看到,服务端同时启动两个websockets.serve监听器,并通过broadcast_audio_messages()协程把录音器回调产生的 JSON 消息广播给所有数据通道客户端——这意味着多个客户端可以同时订阅同一份转写结果,非常适合会议纪要、多屏展示等一对多场景。
在服务端内部,AudioToTextRecorder运行在一个独立线程(_recorder_thread)中,麦克风被关闭(use_microphone=False),音频完全由数据通道feed_audio()注入;回调函数则通过make_callback(loop, callback)绑定到 asyncio 事件循环,再以asyncio.run_coroutine_threadsafe安全地投递到audio_queue,最终由广播协程统一分发,见 stt_server.py 与 stt_server.py。
二、安装与启动前置条件
原 README 要求 Python 3.8+;以仓库实际配置为准,setup.py 中声明python_requires='>=3.11',因此建议使用 Python 3.11 或更高版本。
安装 RealtimeSTT(包含RealtimeSTT_server包及其stt-server、stt命令入口,见 setup.py):
pip install realtimestt如需本地默认推荐依赖(faster-whisper 转写后端 + Silero ONNX CPU VAD),可安装:
pip install "realtimestt[recommended]"如果你已克隆本仓库,也可以直接在仓库根目录执行pip install .完成安装。服务端在启动时会通过 install_packages.py 自检RealtimeSTT、websockets、numpy、scipy等依赖,缺失时会交互式提示安装。
首次启动stt-server会自动下载 Whisper 模型权重(默认large-v2,体积较大),请确保网络可达且磁盘空间充足;也可用--model指定更小的模型以加速冷启动。
三、服务端使用指南(stt-server)
3.1 启动服务端
stt-server [OPTIONS]服务端初始化后会在指定端口监听 WebSocket 连接。最简单的启动方式:
stt-server此时默认加载large-v2主模型与tiny.en实时模型,监听控制端口8011、数据端口8012,语言为英语。
一个精简的典型启动示例(换用小模型、指定语言、改端口):
stt-server -m small.en -l en -c 9001 -d 90023.2 服务端参数全表
以下参数均可在启动时通过命令行指定,其定义与默认值可在 stt_server.py 的parse_arguments()中核对:
模型与语言
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
-m,--model | str | large-v2 | 主转写模型路径或模型规格,可选tiny、tiny.en、base、base.en、small、small.en、medium、medium.en、large-v1、large-v2,或任意 HuggingFace CTranslate2 STT 模型(如deepdml/faster-whisper-large-v3-turbo-ct2) |
-r,--rt-model,--realtime_model_type | str | tiny.en | 实时转写模型规格,仅当启用实时转写(--enable_realtime_transcription)时生效 |
-l,--lang,--language | str | en | 转写语言代码;留空则根据输入音频自动检测 |
-b,--batch,--batch_size | int | 16 | 推理批大小,控制并行处理的音频块数量 |
--root,--download_root | str | None | Whisper 模型下载根目录 |
--compute_type | str | default | CTranslate2 计算类型(量化方式),可参考 CTranslate2 量化文档 |
--gpu_device_index | int | 0 | 使用的 GPU 设备索引 |
--device | str | cuda | 计算设备,cuda或cpu |
音频输入与端口
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
-i,--input-device,--input_device_index | int | 1 | 音频输入设备索引,服务端本身不采集麦克风,该值会透传给录音器配置 |
-c,--control,--control_port | int | 8011 | 控制 WebSocket 端口 |
-d,--data,--data_port | int | 8012 | 数据 WebSocket 端口 |
VAD 与静音检测
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
--silero_sensitivity | float | 0.05 | Silero VAD 灵敏度,范围0~1;值越低越不敏感,适合嘈杂环境 |
--silero_use_onnx | store_true | False | 使用 Silero ONNX 版本,更快且资源占用更低 |
--webrtc_sensitivity | int | 3 | WebRTC VAD 灵敏度,范围0~3;值越高越不敏感,适合干净环境 |
--silero_deactivity_detection | store_true | True | 使用 Silero 模型做说话结束检测,嘈杂环境更稳健,但更耗 GPU 资源 |
--deactivity_silence_confirmation_duration | float | 0.16 | 确认说话结束前需要连续 VAD 静音的秒数,默认值来自 audio_recorder_client.py 的DEACTIVITY_SILENCE_CONFIRMATION_DURATION |
--min_length_of_recording | float | 1.1 | 有效录音的最小时长(秒),过滤噪声或意外声响产生的过短片段 |
--min_gap_between_recordings | float | 0 | 相邻两次录音之间的最小间隔(秒),避免短暂静音导致录音重叠 |
--early_transcription_on_silence | float | 0.2 | 检测到该秒数静音后提前触发转写,用于句中短暂停顿;应小于post_speech_silence_duration,设0关闭 |
-s,--silence_timing | store_true | True | 根据句子结构与标点动态调整话后静音时长(见下文"动态静音时长"一节) |
实时转写
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
--enable_realtime_transcription | store_true | True | 启用边接收边转写,结果近乎实时下发 |
--realtime_processing_pause | float | 0.02 | 处理音频块的时间间隔(秒),越小响应越快、CPU 负载越高 |
--init_realtime_after_seconds | float | 0.2 | 会话开始后延迟启动实时转写的秒数,避免开场误判 |
--realtime_batch_size | int | 16 | 实时转写模型批大小 |
--beam_size | int | 5 | 主模型 beam 大小,越大越准、越慢 |
--beam_size_realtime | int | 3 | 实时模型 beam 大小,越小越快、精度略降 |
--initial_prompt | str | 见下文 | 引导主模型输出风格的初始提示词 |
--initial_prompt_realtime | str | "" | 引导实时转写模型输出风格的初始提示词 |
--use_main_model_for_realtime | store_true | False | 用主模型替代小模型做实时转写,精度更高但更慢 |
--allowed_latency_limit | int | 100 | 实时队列中允许积压的最大音频块数,超出则丢弃旧块 |
--faster_whisper_vad_filter | store_true | False | 为 Faster Whisper 启用 VAD 过滤 |
--suppress_tokens | int 列表 | [-1] | 转写时抑制的 token 列表 |
--handle_buffer_overflow | store_true | False | 转写期间处理缓冲区溢出 |
--initial_prompt的默认值为一段引导模型正确使用省略号标注未完成句子的提示:
Incomplete thoughts should end with '...'. Examples of complete thoughts: 'The sky is blue.' 'She walked home.' Examples of incomplete thoughts: 'When the sky...' 'Because he...'源码提示:
parse_arguments()会在解析后把initial_prompt/initial_prompt_realtime中的\n转义还原为真实换行(stt_server.py),因此命令行传入多行提示词时需用\\n转义。
句子边界检测(动态静音时长)
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
--end_of_sentence_detection_pause | float | 0.45 | 被解释为句子结束的静音时长(秒) |
--unknown_sentence_detection_pause | float | 0.7 | 被解释为不完整/未知句子的停顿时长(秒),用于识别句子拖尾或未说完 |
--mid_sentence_detection_pause | float | 2.0 | 被解释为句中停顿的时长(秒),长停顿可能只是思考而非句子结束 |
这三者并非同时生效,而是由-s/--silence_timing驱动的动态策略:在 stt_server.py 的text_detected()回调中,服务端根据实时文本的形态切换recorder.post_speech_silence_duration——文本以省略号结尾时切换为mid_sentence_detection_pause;连续两句都以句号等结束标点结尾时切换为end_of_sentence_detection_pause;其余情况使用unknown_sentence_detection_pause。
唤醒词
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
-w,--wake_words | str | "" | 触发服务端开始监听的唤醒词,如"Jarvis" |
--wake_words_sensitivity | float | 0.5 | 唤醒词灵敏度,范围0(最灵敏)~1(最不灵敏) |
--wake_word_timeout | float | 5.0 | 等待唤醒词的超时秒数,超时后停止监听直到重新激活 |
--wake_word_activation_delay | float | 见下文 | 开始监听后延迟激活唤醒检测的秒数,避免会话开始的误触发 |
--wakeword_backend | str | none | 唤醒词后端,可指定"default"或自定义实现(如pvporcupine、openwakeword) |
--openwakeword_model_paths | str(可多值) | 无 | OpenWakeWord 自定义模型文件路径列表 |
--openwakeword_inference_framework | str | tensorflow | OpenWakeWord 推理框架(tensorflow、pytorch等) |
--wake_word_buffer_duration | float | 1.0 | 唤醒词检测缓冲时长(秒),决定唤醒前后保留多少音频 |
版本差异提示:README 将
--wake_word_activation_delay默认值标注为20,而仓库源码 stt_server.py 的 argparse 实际默认值为0;客户端侧的初始常量同样为0.0(audio_recorder_client.py)。以源码为准,如需防止开场误触发请显式传入较大值。
调试与日志
| 参数 | 类型 | 说明 |
|---|---|---|
-D,--debug | store_true | 开启详细调试日志 |
--debug_websockets | store_true | 额外开启 websockets 库的调试日志 |
-W,--write | FILE(metavar) | 把收到的音频保存为 WAV 文件 |
--use_extended_logging | store_true | 为处理音频块的录音工作线程输出大量日志 |
--logchunks | store_true | 记录收到的每个音频块(用.标记) |
四、客户端使用指南(stt)
4.1 启动客户端
stt [OPTIONS]客户端会连接服务端的控制与数据 WebSocket 地址,完成实时语音转写。客户端还内置了「服务端未运行时自动拉起」的能力:当--control指定的地址无法建立 WebSocket 握手时,AudioToTextRecorderClient.ensure_server_running()会尝试以stt-server子进程启动服务端(Windows 下用start /min cmd /c,Unix 下用subprocess.Popen),详见 audio_recorder_client.py。
注意:服务端需要先启动(或保证客户端能自动拉起它),再启动客户端。
4.2 客户端参数全表
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
-i,--input-device | int(metavarINDEX) | 无 | 音频输入设备索引,用-L列出可用设备 |
-l,--language | str(metavarLANG) | en | 转写语言代码 |
-sed,--speech-end-detection | store_true | 关 | 启用智能说话结束检测(见 4.3 节) |
-D,--debug | store_true | 关 | 调试模式 |
-n,--norealtime | store_true | 关 | 关闭实时转写输出 |
-W,--write | FILE(metavar) | 无 | 把录音保存为 WAV 文件 |
-s,--set | list(('PARAM','VALUE'),可多次) | 无 | 设置一个录音器参数 |
-m,--method | list(可多次) | 无 | 调用一个录音器方法,可带参数 |
-g,--get | list(可多次) | 无 | 获取录音器参数当前值 |
-c,--continuous | store_true | 关 | 连续转写模式,转完一句话不退出 |
-L,--list | store_true | 关 | 列出所有可用音频输入设备并退出 |
--control,--control_url | str | ws://127.0.0.1:8011 | 控制 WebSocket URL |
--data,--data_url | str | ws://127.0.0.1:8012 | 数据 WebSocket URL |
4.3 speech-end-detection 专属参数
仅在启用-sed/--speech-end-detection后生效,用于精细化句子边界判断(默认值均可在 stt_cli_client.py 核对):
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
--post-silence | float | 1.0 | 话后静音时长(秒) |
--unknown-pause | float | 1.3 | 未知句子检测停顿(秒) |
--mid-pause | float | 3.0 | 句中停顿检测(秒) |
--end-pause | float | 0.7 | 句末检测停顿(秒) |
--hard-break | float | 3.0 | 有背景噪声时的硬中断阈值(秒) |
--min-texts | int | 3 | 硬中断检测所需的最少文本条数 |
--min-similarity | float | 0.99 | 硬中断检测的最小文本相似度 |
--min-chars | int | 15 | 硬中断检测所需的最少字符数 |
这些参数对应客户端侧的「硬中断」机制:客户端维护一个 3 秒窗口内的文本队列,当窗口内文本数量 ≥--min-texts、首尾文本相似度 >--min-similarity且长度 >--min-chars时,判定为背景噪声重复,主动调用client.call_method("stop")中断录音(stt_cli_client.py)。服务端text_detected()中也有完全对应的逻辑(stt_server.py)。
4.4 客户端常用示例
# 列出可用音频设备 stt -L # 指定输入设备与语言 stt -i 1 -l en # 启用智能说话结束检测并进入连续模式 stt -sed -c # 设置参数并把录音保存到文件 stt -s silero_sensitivity 0.1 -W recording.wav # 使用自定义 WebSocket 地址 stt --control ws://localhost:9001 --data ws://localhost:9002-s的值会先尝试解析为 float,再尝试 int,失败则保留字符串(stt_cli_client.py),所以stt -s silero_sensitivity 0.1会把 0.1 作为浮点数下发。
五、WebSocket 协议细节
5.1 控制通道:JSON 文本命令
客户端通过控制连接发送 JSON 命令,服务端在 stt_server.py 的control_handler()中分发:
set_parameter:{"command": "set_parameter", "parameter": "...", "value": ...},执行setattr(recorder, parameter, value),并返回{"status": "success"}或错误信息;get_parameter:{"command": "get_parameter", "parameter": "...", "request_id": N},服务端回带request_id的响应,客户端据此匹配挂起的请求(超时 5 秒,见 audio_recorder_client.py);call_method:{"command": "call_method", "method": "...", "args": [...], "kwargs": {...}},动态调用录音器方法。
出于安全考虑,服务端维护了两份白名单(stt_server.py):
allowed_methods:set_microphone、abort、stop、clear_audio_queue、wakeup、shutdown、text;allowed_parameters:language、silero_sensitivity、wake_word_activation_delay、post_speech_silence_duration、deactivity_silence_confirmation_duration、listen_start、recording_stop_time、last_transcription_bytes、last_transcription_bytes_b64、speech_end_silence_start、is_recording、use_wake_words。
不在白名单中的参数或方法会被拒绝并返回错误,这防止了客户端通过控制通道任意修改内部状态。
5.2 数据通道:二进制音频帧 + 事件广播
上行(客户端 → 服务端):每个音频帧为二进制消息,结构为4 字节小端序元数据长度 + JSON 元数据 + PCM 音频数据(组装逻辑见 audio_recorder_client.py)。元数据必须包含sampleRate字段;服务端在 stt_server.py 中解析该字段,若采样率不是 16000,则通过scipy.signal.resample重采样后再调用recorder.feed_audio()注入。
下行(服务端 → 客户端):服务端把录音器事件序列化为 JSON 文本帧广播给所有数据连接,常用类型包括:
| 消息类型 | 触发时机 |
|---|---|
realtime | 实时转写更新,{"type": "realtime", "text": "..."} |
fullSentence | 一句话的最终转写结果,{"type": "fullSentence", "text": "..."} |
recording_start/recording_stop | 录音开始 / 结束 |
vad_detect_start/vad_detect_stop | VAD 检测开始 / 结束 |
wakeword_detected/wakeword_detection_start/wakeword_detection_end | 唤醒词相关事件 |
transcription_start | 转写开始,附带 Base64 编码的音频字节(audio_bytes_base64) |
start_turn_detection/stop_turn_detection | 轮次检测开始 / 结束 |
客户端侧的消息分发与回调映射实现在 audio_recorder_client.py 的on_data_message()中。仓库还自带一个纯前端浏览器客户端示例 RealtimeSTT_server/index.html,仅通过数据 WebSocket 接收realtime与fullSentence消息即可在网页中实时展示转写,可作为自定义客户端的参考实现。
六、端到端实战演练
6.1 默认设置启动服务端与客户端
# 终端 1:启动服务端(默认 large-v2 / tiny.en,端口 8011、8012) stt-server # 终端 2:启动客户端(默认连接 ws://127.0.0.1:8011 与 ws://127.0.0.1:8012) stt6.2 动态设置参数
# 把 Silero VAD 灵敏度设为 0.1(更不敏感,适合嘈杂环境) stt -s silero_sensitivity 0.16.3 动态获取参数
# 读取当前 Silero 灵敏度 stt -g silero_sensitivity # 输出形如:Parameter silero_sensitivity = 0.16.4 调用录音器方法
# 关闭(静音)麦克风采集 stt -m set_microphone False6.5 调试模式
stt -D服务端可配合-D(含--debug_websockets)、--use_extended_logging、--logchunks观察音频块流入与转写文本的实时打印,客户端-D会输出连接建立、参数设置等详细过程。
七、常见问题排查
- 服务端无法启动:确认依赖已安装(可用
pip install "realtimestt[recommended]"补齐默认后端),并确认8011/8012端口未被占用——端口冲突时服务端会打印明确的 OSError 提示(stt_server.py)。 - 没有声音 / 转写为空:用
stt -L检查可用的音频输入设备,通过-i指定正确的设备索引。 - WebSocket 连接失败:核对
--control/--data地址与端口是否与服务端实际监听一致;确保服务端先于客户端启动,或允许客户端自动拉起服务端。 - 首次启动慢:
large-v2主模型下载与加载耗时较长,可先用-m small.en -r tiny.en验证链路,再按需升级模型。
八、许可证
RealtimeSTT 项目基于 MIT License 发布,详见 LICENSE。服务端与客户端脚本设计为无缝配合工作,在配置灵活性与转写延迟之间取得平衡,你可以根据环境噪声调节 VAD 灵敏度,也可以根据资源条件选择主模型与实时模型的大小组合。
【免费下载链接】RealtimeSTTA robust, efficient, low-latency speech-to-text library with advanced voice activity detection, wake word activation and instant transcription.项目地址: https://gitcode.com/GitHub_Trending/re/RealtimeSTT
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考