手把手教你用 Whisper 实现视频字幕自动提取:从原理到工程化落地
文章目录
前言
做视频处理的同学一定遇到过这种场景:拿到一段没有字幕的会议录像、教学视频或海外素材,想要提取其中的文字内容,只能一边播放一边手动听写,效率极低。虽然市面上有各种在线工具,但要么收费、要么有文件大小限制、要么隐私数据无法把控。
本文将带你从零搭建一套基于 OpenAI Whisper 的视频字幕自动提取系统。内容覆盖 Whisper 模型架构原理、完整流水线设计、核心代码实现,以及基于 WhisperX 和 FastAPI 的工程化进阶方案。适合有 Python 基础、希望深入理解 ASR(自动语音识别)技术栈的中高级开发者。
一、 整体架构设计
在深入代码之前,我们先理清视频字幕提取的完整技术链路。一个生产级的字幕提取系统通常包含以下核心模块:

核心链路拆解:
- 视频输入:支持 MP4、AVI、MKV 等主流格式
- 音频提取:使用
ffmpeg抽离音轨并转换为 16kHz 单声道 PCM - 音频预处理:可选的降噪、VAD(语音活动检测)分段
- Whisper 推理:Encoder-Decoder Transformer 模型进行语音识别
- 文本后处理:时间戳对齐、标点补全、格式转换
- 字幕输出:生成 SRT、VTT 或 ASS 标准字幕文件
右侧虚线框中的 WhisperX 是本文重点推荐的进阶方案,提供词级时间戳和说话人分离能力。
二、 Whisper 模型架构与核心原理
2.1 为什么选择 Whisper?
OpenAI 于 2022 年开源的 Whisper 模型在 ASR 领域堪称"破局者"。相比传统的 CRNN-CTC 架构,Whisper 采用了经典的 Encoder-Decoder Transformer 结构,具有以下核心优势:
| 特性 | 说明 |
|---|---|
| 多语言支持 | 内置 99 种语言训练,自动语言检测 |
| 鲁棒性强 | 在噪声环境、口音、专业术语场景下表现优异 |
| 多任务统一 | 同一个模型同时处理转录、翻译、时间戳预测 |
| 开源可用 | 提供 base → large-v3 共 5 个尺寸,灵活选择 |
2.2 模型架构简述
Whisper 的架构本质上是 Seq2Seq Transformer:
音频输入 → 30秒音频片段分块 → Log-Mel 频谱图(80维)
→ Encoder(多层 Self-Attention)
→ Decoder(带交叉注意力的自回归生成)
→ Token 序列(文本 + 特殊标记)
关键设计亮点:
- 输入表示:将 30 秒音频转换为 80 维 Log-Mel 频谱图,作为 Encoder 的输入。
- ** multitask tokens**:在 Decoder 的输入中注入
<|transcribe|>、<|zh|>等特殊标记,控制任务类型和输出语言。 - 时间戳预测:模型天然支持输出
<|0.00|>格式的时间戳 token,这是生成 SRT 字幕的基础。
2.3 模型尺寸对比
| 模型 | 参数量 | 显存需求 | 适用场景 |
|---|---|---|---|
tiny |
39M | ~1GB | 快速验证,资源受限 |
base |
74M | ~1GB | 简单场景,快速出结果 |
small |
244M | ~2GB | 中文识别推荐起点 |
medium |
769M | ~5GB | 较高准确率 |
large-v3 |
1550M | ~10GB | 生产级精度,推荐 |
建议:中文场景下
medium及以上模型能显著降低识别错误率,尤其在专业术语较多的视频中。
三、 环境准备与核心实现
3.1 安装依赖
# 核心依赖
pip install openai-whisper ffmpeg-python srt
# Whisper 依赖的系统工具(Ubuntu)
sudo apt-get install -y ffmpeg
openai-whisper会自动下载模型权重到~/.cache/whisper,首次加载可能需要几分钟。
3.2 基础实现:视频 → SRT 字幕
下面是最精简的完整实现,涵盖了 音频提取 → Whisper 推理 → SRT 生成 三个核心步骤:
import whisper
import ffmpeg
import srt
from datetime import timedelta
from pathlib import Path
def extract_audio(video_path: str, audio_path: str = "temp_audio.wav"):
"""
使用 ffmpeg 从视频中提取音频
转换为 16kHz 单声道 WAV(Whisper 要求格式)
"""
(
ffmpeg
.input(video_path)
.output(audio_path, ar=16000, ac=1, format="wav")
.overwrite_output()
.run(quiet=True)
)
return audio_path
def generate_srt(transcript, output_path: str = "output.srt"):
"""
将 Whisper 输出转换为 SRT 格式
"""
subtitles = []
for i, segment in enumerate(transcript["segments"], start=1):
start = timedelta(seconds=segment["start"])
end = timedelta(seconds=segment["end"])
text = segment["text"].strip()
subtitles.append(srt.Subtitle(
index=i,
start=start,
end=end,
content=text
))
srt_content = srt.compose(subtitles)
Path(output_path).write_text(srt_content, encoding="utf-8")
return output_path
def video_to_subtitle(
video_path: str,
model_size: str = "medium",
language: str = "zh",
output_srt: str = "output.srt"
):
"""
主函数:视频字幕提取完整流程
"""
# Step 1: 提取音频
print("🎵 正在提取音频...")
audio_path = extract_audio(video_path)
# Step 2: 加载 Whisper 模型并推理
print(f"🧠 正在加载 Whisper {model_size} 模型...")
model = whisper.load_model(model_size)
print("🔊 正在进行语音识别...")
result = model.transcribe(
audio_path,
language=language,
verbose=False,
# 关键参数:启用时间戳
word_timestamps=False, # 段落级时间戳,如需词级请改 True
)
# Step 3: 生成 SRT 文件
print(f"📝 正在生成字幕文件: {output_srt}")
generate_srt(result, output_srt)
# 清理临时音频
Path(audio_path).unlink(missing_ok=True)
print("✅ 完成!")
return output_srt
if __name__ == "__main__":
video_to_subtitle(
video_path="input_video.mp4",
model_size="medium",
language="zh",
output_srt="output.srt"
)
3.3 关键参数说明
| 参数 | 说明 | 推荐值 |
|---|---|---|
language |
指定输入语言,不指定则自动检测 | "zh"(中文) |
word_timestamps |
是否输出词级时间戳 | False(基础版用段落级即可) |
condition_on_previous_text |
是否用上文辅助预测下一段 | True(默认) |
temperature |
采样温度,0 表示贪婪解码 | 0(字幕场景追求确定性) |
beam_size |
Beam Search 宽度 | 5(默认) |
四、 进阶优化:WhisperX 方案
基础 Whisper 方案在长视频场景下存在两个痛点:
- 时间戳精度不够:段落级时间戳对齐偶尔会漂移
- 无法区分说话人:多人对话场景下字幕混在一起
WhisperX 是针对这些问题的高性能增强方案。
4.1 WhisperX 的核心增强
- 词级时间戳(Forced Alignment):使用 wav2vec2 对 Whisper 输出做强制对齐,时间戳精度从段落级提升到词级。
- 说话人分离(Speaker Diarization):集成 pyannote.audio,自动标注
[Speaker 1]、[Speaker 2]。 - 批处理加速:大段音频批量推理,比原生 Whisper 快 4-8 倍。
4.2 WhisperX 实现代码
pip install whisperx
# 首次运行会自动下载 wav2vec2 对齐模型
import whisperx
import gc
import torch
def video_to_subtitle_whisperx(
video_path: str,
model_size: str = "large-v3",
language: str = "zh",
output_srt: str = "output_whisperx.srt"
):
device = "cuda" if torch.cuda.is_available() else "cpu"
batch_size = 16 # GPU 批处理大小,根据显存调整
# Step 1: 音频提取(同上)
audio_path = extract_audio(video_path)
# Step 2: Whisper 推理
print("🧠 加载 Whisper 模型...")
model = whisperx.load_model(model_size, device, compute_type="float16")
print("🔊 语音识别中...")
audio = whisperx.load_audio(audio_path)
result = model.transcribe(audio, batch_size=batch_size, language=language)
# Step 3: 词级时间戳对齐
print("🔗 词级时间戳对齐中...")
model_a, metadata = whisperx.load_align_model(
language_code=result["language"], device=device
)
result = whisperx.align(
result["segments"], model_a, metadata, audio, device
)
del model_a
gc.collect()
# Step 4: 说话人分离(可选)
print("👥 说话人分离中...")
diarize_model = whisperx.DiarizationPipeline(use_auth_token="YOUR_HF_TOKEN", device=device)
diarize_segments = diarize_model(audio)
result = whisperx.assign_word_speakers(diarize_segments, result)
# Step 5: 生成带说话人标记的 SRT
print("📝 生成字幕...")
generate_srt_with_speakers(result, output_srt)
Path(audio_path).unlink(missing_ok=True)
print("✅ WhisperX 处理完成!")
def generate_srt_with_speakers(result, output_path: str):
"""生成带说话人标记的 SRT 文件"""
import srt
from datetime import timedelta
subtitles = []
for i, segment in enumerate(result["segments"], start=1):
start = timedelta(seconds=segment["start"])
end = timedelta(seconds=segment["end"])
# 拼接说话人标记
speaker_text = ""
for word in segment.get("words", []):
speaker = word.get("speaker", "")
text = word["word"]
if speaker and speaker not in speaker_text:
speaker_text += f"[{speaker}] "
speaker_text += text
subtitles.append(srt.Subtitle(
index=i, start=start, end=end,
content=speaker_text.strip()
))
Path(output_path).write_text(srt.compose(subtitles), encoding="utf-8")
五、 工程化实践:FastAPI 服务封装
实际业务中,我们需要将上述能力封装为可调用的 API 服务。以下是一个精简的 FastAPI 实现:
from fastapi import FastAPI, UploadFile, File, HTTPException
from fastapi.responses import FileResponse
import os
import tempfile
import whisper
app = FastAPI(title="Whisper 字幕提取服务")
model = None
@app.on_event("startup")
def load_model():
global model
model = whisper.load_model("medium")
print("✅ Whisper 模型加载完成")
@app.post("/api/v1/subtitle")
async def extract_subtitle(file: UploadFile = File(...)):
"""
上传视频文件,返回 SRT 字幕
"""
if not file.filename.endswith((".mp4", ".avi", ".mkv", ".mov")):
raise HTTPException(400, "仅支持 MP4/AVI/MKV/MOV 格式")
# 保存临时文件
with tempfile.NamedTemporaryFile(delete=False, suffix=".mp4") as tmp:
tmp.write(await file.read())
video_path = tmp.name
try:
# 提取音频
audio_path = video_path + ".wav"
extract_audio(video_path, audio_path)
# 推理
result = model.transcribe(audio_path, language="zh")
# 生成 SRT
srt_path = video_path + ".srt"
generate_srt(result, srt_path)
return FileResponse(srt_path, filename="subtitle.srt")
finally:
# 清理临时文件
for p in [video_path, audio_path, video_path + ".srt"]:
if os.path.exists(p):
os.remove(p)
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=8000)
启动服务:uvicorn app:app --host 0.0.0.0 --port 8000 --workers 2
调用示例:
curl -X POST "http://localhost:8000/api/v1/subtitle" \
-F "file=@test_video.mp4" \
-o subtitle.srt
六、 性能优化与生产建议
6.1 GPU 加速策略
| 策略 | 效果 | 说明 |
|---|---|---|
compute_type="float16" |
显存减半,速度提升 30%+ | 需要 GPU 支持 FP16 |
compute_type="int8" |
显存减至 1/4 | 使用 ctranslate2,速度最快 |
| 分块并行推理 | 长视频加速 2-3 倍 | 按 30 秒切片后多线程提交 |
6.2 常见问题排查
- 显存不足(OOM):换用
small模型,或启用int8量化。 - 中文识别效果差:确认
language="zh"已显式指定;尝试large-v3模型。 - 时间戳漂移:切换到 WhisperX 做强制对齐。
- 长视频处理慢:启用批处理 + GPU,或使用 ctranslate2 推理后端。
七、 总结与选型建议
| 方案 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| Whisper 基础版 | 简单、开箱即用、单文件部署 | 时间戳精度有限 | 快速验证、短视频、个人使用 |
| WhisperX | 词级时间戳、说话人分离、批处理加速 | 依赖较多、显存需求高 | 生产环境、长视频、多人对话 |
| 商用 API(阿里云/腾讯云) | 无需 GPU、稳定性高 | 按量收费、隐私顾虑 | 高并发、无 GPU 服务器 |
技术选型建议:
- 个人开发者 / 小规模使用 → Whisper
medium+ 基础 SRT 生成 - 生产环境 / 长视频 → WhisperX + 词级对齐 + 说话人分离
- 高并发场景 → FastAPI 多实例 + GPU 服务器 + Redis 任务队列
视频字幕自动提取是 AI 工程化的一个典型落地场景。掌握 Whisper 的架构原理和工程实践后,你可以进一步扩展到 视频内容摘要、关键词提取、多语言字幕翻译 等更高阶的应用。
如果你有更好的实现方式或踩过的坑,欢迎在评论区交流 🙌
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)