本教程面向已安装 FFmpeg 和 Python 3.9+ 的用户,使用 Whisper 模型自动识别视频语音,并生成带样式的硬字幕。最终输出 1080x1920 竖屏视频,字幕位置固定在下方安全区,适合抖音、快手等平台。
1. 准备环境
# 安装 OpenWhisper(官方支持 PyTorch)
pip install openai-whisper
确保 FFmpeg 可用(Windows 需要将 ffmpeg.exe 加入 PATH)
ffmpeg -version
2. 提取音频并生成字幕
新建gen_sub.py,内容如下:
import whisper
model = whisper.load_model("base") # 可选 tiny/base/small/medium/large
result = model.transcribe("input.mp4")
with open("subtitle.srt", "w", encoding="utf-8") as f:
for seg in result["segments"]:
start = seg["start"]
end = seg["end"]
text = seg["text"].strip()
# 时间戳格式:HH:MM:SS,mmm
s_h = int(start // 3600)
s_m = int((start % 3600) // 60)
s_s = int(start % 60)
s_ms = int((start - int(start)) 1000)
e_h = int(end // 3600)
e_m = int((end % 3600) // 60)
e_s = int(end % 60)
e_ms = int((end - int(end)) 1000)
f.write(f"{s_h:02d}:{s_m:02d}:{s_s:02d},{s_ms:03d} --> "
f"{e_h:02d}:{e_m:02d}:{e_s:02d},{e_ms:03d}\n{text}\n\n")
print("字幕已生成 subtitle.srt")
运行:
python gen_sub.py
提示:若视频较长,建议用--model medium提高准确率。也可用model.transcribe("input.mp4", language="zh")锁定中文。
3. 用 FFmpeg 硬编码字幕并转竖屏
创建burn_subtitle.sh(Windows 用户用 .bat),核心命令如下:
ffmpeg -i input.mp4 -vf \
"scale=1920:1080:force_original_aspect_ratio=decrease,pad=1920:1080:(ow-iw)/2:(oh-ih)/2,crop=1080:1920,ass=subtitle.ass" \
-c:v libx264 -preset medium -crf 18 -c:a aac -b:a 192k output_vertical.mp4
但这会直接烧录 SRT 默认样式,不够美观。推荐先转换为 ASS 字幕并定义样式:
# 将 SRT 转换为 ASS
ffmpeg -i subtitle.srt output.ass
然后手动编辑 output.ass 中的 [V4+ Styles] 部分,例如设置字体大小、位置、描边:
Style: Default,MSYH,58,&H00FFFFFF,&H000000FF,&H00000000,&H80000000,-1,0,0,0,100,100,2,0,1,2,2,30,30,40
这段样式表示:微软雅黑 58 号,白色字体,半透明黑色描边,底部居中。
最后执行烧录:
ffmpeg -i input.mp4 -vf "scale=1920:1080:force_original_aspect_ratio=decrease,pad=1920:1080:(ow-iw)/2:(oh-ih)/2,crop=1080:1920,ass=output.ass" \
-c:v libx264 -preset medium -crf 18 -c:a aac -b:a 192k output_vertical.mp4
4. 一键批量处理多个视频
将以上逻辑封装成auto_subtitle.sh,循环处理当前目录下所有 .mp4 文件:
#!/bin/bash
for video in .mp4; do
if [[ "$video" == "output_" ]]; then continue; fi
# 提取音频并生成 SRT
python gen_sub.py "$video"
# 转换为 ASS 并烧录(假设样式已预设)
ffmpeg -i "$video" -vf "scale=1920:1080:force_original_aspect_ratio=decrease,pad=1920:1080:(ow-iw)/2:(oh-ih)/2,crop=1080:1920,ass=output.ass" \
-c:v libx264 -preset medium -crf 18 -c:a aac -b:a 192k "output_${video}"
done
5. 常见问题排查
- 字幕不显示:检查 FFmpeg 是否包含 libass 支持,可用
ffmpeg -filters | findstr ass查看。 - 音频不同步:Whisper 识别时若原视频有片头,可以在
transcribe中增加initial_prompt或先裁剪。 - 竖屏模糊:
crop=1080:1920将从 1080p 视频中心裁剪,如果视频源是 4:3,可先放大再裁,用scale=1920:1920:force_original_aspect_ratio=decrease,crop=1080:1920。