字节笔记本

2026年2月22日

WAAS:基于 OpenAI Whisper 的开源语音转录服务

本文介绍 WAAS (Whisper as a Service),一个基于 OpenAI Whisper 的开源语音转录服务。该项目提供了 Web GUI 和 REST API,支持音频/视频文件的批量转录、队列处理和多种输出格式,帮助开发者和内容创作者快速构建语音转文字的工作流。

项目简介

WAAS 是由 Schibsted 开发并开源的语音转录服务,基于 OpenAI 的 Whisper 模型构建。该项目最初由 VG(挪威最大媒体公司)内部开发,后开源供社区使用。截至目前,该项目在 GitHub 上已获得超过 2000 stars,是一个成熟稳定的语音转录解决方案。

项目包含两个核心组件:

  • Jojo:用户友好的 Web 界面,支持上传音频/视频文件并管理转录任务
  • REST API:提供完整的 API 接口,支持程序化访问和集成

核心特性

  • 🎙️ 多种输入格式支持:支持音频和视频文件上传
  • 📧 邮件通知:转录完成后自动发送邮件通知,包含下载链接
  • 📝 内置编辑器:100% 浏览器本地运行的编辑器,支持分段播放和错误修正
  • 🔄 异步队列处理:基于 Redis 的任务队列,支持大规模并发处理
  • 🌐 多语言支持:自动检测语言,支持 99 种语言的转录
  • 📤 多种输出格式:支持 SRT、VTT、TXT、JSON 等字幕和文本格式
  • 🔗 Webhook 回调:支持自定义 Webhook 接收转录完成通知
  • 🐳 Docker 部署:提供完整的 Docker Compose 配置,一键部署
  • ⚡ GPU 加速:支持 NVIDIA CUDA 加速,大幅提升转录速度

技术栈

  • 后端:Python 3.8-3.10 + Flask
  • 任务队列:Redis + RQ (Redis Queue)
  • 语音模型:OpenAI Whisper
  • 容器化:Docker + Docker Compose
  • 前端:原生 JavaScript(编辑器完全本地运行)
  • 邮件服务:SMTP 支持

安装指南

前置要求

  • Python 3.8-3.10
  • 至少 1GB VRAM(使用 tiny 模型)
  • Redis 服务

本地安装

bash
# 克隆仓库
git clone https://github.com/schibsted/WAAS.git
cd WAAS

# 创建虚拟环境
python3 -m venv .venv
source .venv/bin/activate

# 安装依赖
pip install -r requirements.txt

Docker Compose 部署(推荐)

  1. 创建 .envrc 配置文件:
sh
export BASE_URL=https://example.com
export EMAIL_SENDER_ADDRESS=example@example.com
export EMAIL_SENDER_PASSWORD=example
export EMAIL_SENDER_HOST=smtp.example.com
export DISCLAIMER='This is a <a href="example.com">disclaimer</a>'
export ALLOWED_WEBHOOKS_FILE='allowed_webhooks.json'
export LOG_EMAIL=true  # 可选,将邮件内容输出到控制台
  1. 创建 Webhook 配置文件 allowed_webhooks.json
json
[
  {
    "id": "77c500b2-0e0f-4785-afc7-f94ed529c897",
    "url": "https://myniceserver.com/mywebhook",
    "token": "frKPI6p5LxxpJa8tCvVr=u5NvU66EJCQdybPuEmzKNeyCDul2-zrOx05?LwIhL5N"
  }
]
  1. 启动服务:
bash
docker-compose --env-file .envrc up

这将启动三个容器:Redis、API 服务和 Worker 服务。

GPU 加速配置

如需使用 NVIDIA GPU 加速,需要:

  1. 安装 nvidia-docker

  2. 修改 docker-compose.yml,使用 Dockerfile.gpu

yaml
build:
  context: .
  dockerfile: Dockerfile.gpu  # 使用 GPU 版本的 Dockerfile
  1. 取消 docker-compose.yml 中设备预留的注释:
yaml
deploy:
  resources:
    reservations:
      devices:
        - driver: nvidia
          capabilities: [gpu]

快速开始

使用 Web 界面

  1. 访问 http://localhost:3000
  2. 上传音频或视频文件
  3. 等待转录完成(将通过邮件接收通知)
  4. 下载 SRT、VTT 或文本格式的转录结果
  5. 如需编辑,下载 Jojo 文件并在编辑器中打开

使用 API

提交转录任务

bash
# 使用邮件回调
curl --location --request POST 'localhost:3000/v1/transcribe?output=vtt&email_callback=test@localhost&language=norwegian&model=large' \
  --header 'Content-Type: audio/mpeg' \
  --data-binary '@/path/to/audio.mp3'

# 使用 Webhook 回调
curl --location --request POST 'localhost:3000/v1/transcribe?output=vtt&language=norwegian&model=large&webhook_id=your-webhook-id' \
  --header 'Content-Type: audio/mpeg' \
  --data-binary '@/path/to/audio.mp3'

查询任务状态

bash
curl 'localhost:3000/v1/jobs/<job_id>'

下载转录结果

bash
# 下载 SRT 格式(默认)
curl 'localhost:3000/v1/download/<job_id>'

# 下载 VTT 格式
curl 'localhost:3000/v1/download/<job_id>?output=vtt'

# 下载纯文本
curl 'localhost:3000/v1/download/<job_id>?output=txt'

API 参考

核心端点

端点方法说明
/v1/transcribePOST提交转录任务
/v1/detectPOST检测音频语言
/v1/jobs/<job_id>GET查询任务状态
/v1/download/<job_id>GET下载转录结果
/v1/queueGET获取队列长度

转录参数

参数类型必填说明
email_callbackstring条件邮件通知地址
webhook_idstring条件Webhook ID(与 email_callback 二选一)
languagestring语言代码(默认自动检测)
modelstring模型名称(默认 tiny)
taskstring任务类型:transcribe/translate
filenamestring文件名(默认 untitled-transcription)

支持的模型

模型VRAM 需求适用场景
tiny~1 GB快速测试、资源受限环境
base~1 GB平衡速度和准确度
small~2 GB较好的准确度
medium~5 GB高准确度
large~10 GB最高准确度

Webhook 响应格式

成功响应:

json
{
  "source": "waas",
  "job_id": "09d2832d-cf3e-4719-aea7-1319000ef372",
  "success": true,
  "url": "https://example.com/v1/download/09d2832d-cf3e-4719-aea7-1319000ef372",
  "filename": "untitled-transcription"
}

失败响应:

json
{
  "source": "waas",
  "job_id": "09d2832d-cf3e-4719-aea7-1319000ef372",
  "success": false
}

Webhook 请求包含 X-WAAS-Signature 头部,可用于验证请求真实性。

使用示例

场景 1:播客字幕生成

bash
# 提交播客音频进行转录
curl -X POST 'localhost:3000/v1/transcribe' \
  -d 'email_callback=podcaster@example.com' \
  -d 'language=chinese' \
  -d 'model=medium' \
  -d 'filename=my-podcast-episode-1' \
  --data-binary '@/path/to/podcast.mp3'

场景 2:视频字幕批量处理

python
import requests
import os

api_url = "http://localhost:3000/v1/transcribe"

for video_file in os.listdir("./videos"):
    with open(f"./videos/{video_file}", "rb") as f:
        response = requests.post(
            api_url,
            params={
                "webhook_id": "video-processing-hook",
                "model": "large",
                "output": "srt"
            },
            data=f
        )
        print(f"Submitted {video_file}: {response.json()['job_id']}")

场景 3:实时翻译工作流

bash
# 转录并翻译为英文
curl -X POST 'localhost:3000/v1/transcribe' \
  -d 'task=translate' \
  -d 'model=large' \
  -d 'email_callback=user@example.com' \
  --data-binary '@/path/to/foreign-audio.mp3'

注意事项

  1. 隐私保护:转录敏感内容时,建议使用本地部署而非第三方服务
  2. 资源规划:large 模型需要约 10GB VRAM,请根据硬件选择合适的模型
  3. 队列管理:大量任务提交时,可通过 /v1/queue 监控队列长度
  4. Webhook 安全:生产环境务必验证 X-WAAS-Signature 签名
  5. 邮件配置:确保 SMTP 配置正确,否则无法接收邮件通知

项目链接

分享: