视频加字幕
本地视频 → 提取文字稿(或使用已有字幕文件)→ 自动识别语种 → ASS 字幕 → FFmpeg 烧录
前置条件
首次使用前,需确保已配置阿里云凭据:
- 将
config.example.json复制为config.json - 填入阿里云 OSS 凭据(AccessKey ID/Secret、Bucket、Endpoint)
- 填入 DashScope API Key(用于 FunASR 转录)
工作流
路径判断:根据用户输入的路径类型自动选择场景:
- 目录路径 → 场景 C(批量处理)
- 视频文件路径 → 场景 A 或 B(单视频处理)
场景 A:用户提供视频(无字幕文件)
步骤 1 — 选择样式(用文字列出选项,禁止使用 AskUserQuestion 工具)
判断逻辑:如果用户输入中仅包含视频路径(无字体/颜色/阴影等选项),直接使用全部默认值启动流水线,不展示选项列表。
默认值:字体=微软雅黑(1)、颜色=黄色(1)、阴影距离=2、不透明度=100、模糊度=15
只有用户明确要修改字体/颜色/阴影时,才展示选项列表:
请确认以下设置,直接回复即可(如:2 1 D:\video.mp4 或 D:\video.mp4 2 1):
1. 字体:
1-微软雅黑(默认) 2-Noto Sans SC 3-黑体 4-宋体 5-仿宋 6-楷体
输入"查看全部字体"展示所有可用字体
2. 颜色:1-黄色(默认) / 2-白色 / 3-绿色 / 4-青色 / 5-红色 / 6-粉色 / 7-自定义(#RRGGBB)
3. 阴影效果(可选,直接回车使用默认值):
阴影距离:[2] 不透明度(%):[100] 阴影模糊度:[15]
4. 视频路径:请粘贴文件路径
视频路径可放在任意位置。阴影效果可省略,省略时使用默认值。
语种自动识别:脚本根据字幕文本的字符组成自动检测语种,无需手动选择。中文自动启用中英双语模式。
步骤 2 — 自动提取文字稿 + 烧录
流水线依次自动执行:提取音频 → 上传 OSS → FunASR 转录 → 烧录字幕
中间文件命名规则:所有中间文件以 <视频stem>_ 前缀命名,保存在源视频同目录:
<视频stem>_audio.wav— 提取的音频<视频stem>_transcript.json— FunASR 转录结果<视频stem>_translation_input.json— 待翻译条目<视频stem>_translation_output.json— 翻译结果
复用机制:执行每步前先检查对应文件是否已存在,如存在则跳过该步。
# 设置视频变量(以下命令中 <视频stem> = 视频文件名去扩展名)
VIDEO_DIR=<视频所在目录>
VIDEO_STEM=<视频stem>
# 2a. 从视频提取音频(如已存在则跳过)
if [ ! -f "$VIDEO_DIR/${VIDEO_STEM}_audio.wav" ]; then
python scripts/extract_audio.py <视频路径> "$VIDEO_DIR/${VIDEO_STEM}_audio.wav"
fi
# 2b. 上传音频到 OSS → 返回 OSS URL(仅在需要转录时执行)
if [ ! -f "$VIDEO_DIR/${VIDEO_STEM}_transcript.json" ]; then
python scripts/upload_to_oss.py "$VIDEO_DIR/${VIDEO_STEM}_audio.wav"
# 2c. FunASR 转录
python scripts/transcribe_with_funasr.py <OSS_URL> "$VIDEO_DIR/${VIDEO_STEM}_transcript.json"
fi
# 2d. 烧录字幕(--no-interact 跳过交互,使用步骤 1 所选样式)
python scripts/burn_subtitles.py \
--video <视频路径> \
--transcript "$VIDEO_DIR/${VIDEO_STEM}_transcript.json" \
--font <字体> \
--color <颜色> \
--shadow <阴影距离> \
--opacity <不透明度> \
--blur <模糊度> \
--no-interact
自动翻译:如果烧录时脚本因检测到中文而导出 <视频stem>_translation_input.json(需要英文翻译才能完成双语字幕),Claude 必须:
- 读取
<视频stem>_translation_input.json内容 - 用自身语言能力将每条中文翻译为地道英文
- 写入同目录的
<视频stem>_translation_output.json(格式:[{"index": 0, "translation": "..."}, ...]) - 重新运行烧录脚本(相同参数),脚本会自动读取翻译文件并完成双语烧录
禁止将翻译任务交给用户处理。Claude 直接完成翻译并继续流水线。
场景 B:用户提供视频 + 字幕文件
字幕文件可以是 .lrc 或 .ass 格式。
检测到字幕文件 <文件名>,询问用户选择处理方式:
选项 1 — 直接烧录(快速,适合已验证的字幕)
# .lrc 文件
python scripts/burn_subtitles.py \
--video <视频路径> \
--lrc <LRC文件路径> \
--font <字体> --color <颜色>
# .ass 文件(直接用 FFmpeg)
ffmpeg -i <视频> -vf "ass=<ASS文件>" -c:v libx264 -preset medium -crf 23 -c:a copy <输出.mp4>
选项 2 — 先比对再烧录(更准确,适合未验证的字幕)
先从视频提取 transcript.json(FunASR 词级时间戳),与字幕文件逐句对比文本和时间轴差异,用户确认后烧录。
场景 C:用户提供目录(批量处理)
用户输入目录路径(非视频文件) → 自动进入批量模式。
步骤 1 — 扫描视频
ls -1 <目录路径>/*.{mp4,mov,avi,mkv,flv,webm} 2>/dev/null | grep -v '/output/'
扫描完成后直接进入处理流程,无需用户确认。
步骤 2 — 选择样式(仅一次),所有视频共用同一套样式。
步骤 3 — 逐一处理,对每个视频执行场景 A 的完整流水线。
语种自动识别
| 字符特征 | 识别结果 | |----------|----------| | CJK 汉字为主,无假名 | 中文 → 自动启用中英双语模式 | | 含平假名/片假名 | 日语 → 单语模式 | | 韩文字母为主 | 韩语 → 单语模式 | | 拉丁字母为主 | 拉丁语系 → 单语模式 |
脚本
| 脚本 | 功能 |
|------|------|
| scripts/burn_subtitles.py | transcript.json / LRC → 自动识别语种 → 断句 → ASS → FFmpeg 烧录 |
| scripts/extract_audio.py | 本地视频文件 → 提取音频 WAV |
| scripts/upload_to_oss.py | 音频文件 → 上传阿里云 OSS → 返回公开 URL |
| scripts/transcribe_with_funasr.py | OSS URL → DashScope FunASR 转录 → transcript.json |
参数参考
--video PATH 视频路径(必需)
--transcript PATH transcript.json 路径(优先于 LRC)
--lrc PATH LRC 字幕文件路径
--font ID 字体编号或ID,运行 --list-fonts 查看全部
--color ID 颜色: 1-黄色(默认)/2-白色/3-绿色/4-青色/5-红色/6-粉色, 或 #RRGGBB
--fontsize N 字号 (0=自动)
--shadow N 阴影距离 (默认: 2)
--opacity N 不透明度 0-100 (默认: 100)
--blur N 阴影模糊度 (默认: 15)
--out PATH 输出 MP4 路径
--list-fonts 列出可选字体和颜色
--no-interact 跳过交互,使用默认值
依赖
- FFmpeg(full 版,含 libx264 + ass 滤镜)
- Python 依赖:
requests、oss2 - 阿里云配置:
config.json(OSS 凭据 + DashScope API Key)
输出
带字幕的 MP4 视频(默认保存于视频同目录)
微信扫一扫