本技能将 PDF 幻灯片 + 演讲稿转换为带同步字幕的完整演讲视频。所有处理均在本地运行(Qwen3-TTS)或使用免费在线服务(edge-tts),无需付费 API。
TTS 引擎(二选一,优先 Qwen3-TTS):
核心流水线:演讲稿处理 → 语音合成(可选声音克隆) → 视频生成 → 最终合并
> 当用户明确要求使用 Remotion 生成视频时,启用此模式。
禁止使用 PPT/PDF 截图作为视频内容。必须用 Remotion 原生 TSX 组件重新设计每一页的视觉内容。
动画触发帧必须与 timing_data.json 中对应句子的时间戳对齐。禁止使用固定帧数或固定循环触发动画。
原因:截图分辨率低、有白边、无法动画、无法响应字幕节奏;原生组件全矢量、动画精确可控、体积更小。
| 步骤 | 传统模式(FFmpeg) | Remotion 模式 |
|---|---|---|
| ------ | ----------------- | -------------- |
| 步骤 0-3 | 相同(演讲稿处理 + TTS 合成) | 相同 |
| 步骤 4 | PDF → 截图 → FFmpeg 合成 | TSX 组件设计每页 + Remotion 渲染 |
| 字幕 | ASS/SRT 烧录 | Remotion 原生字幕组件(精确逐句同步) |
| 音频 | FFmpeg 混流 | 组件(每页独立音频) |
完整的设计规范、布局模板、hooks 使用规则、字幕同步机制见:
开始前,请确认以下工具和模型已安装。
首次使用前,运行环境检查脚本确认所有依赖已就绪:
python {SKILL_DIR}/scripts/check_environment.py
该脚本会检查:
如果检测到缺失依赖,脚本会给出具体的安装命令。
brew install ffmpeg-full(macOS,完整版)或系统包管理器pip install numpy PyMuPDF
# 方式一(推荐):Qwen3-TTS — 本地高质量语音合成
pip install -U qwen-tts
# 方式二:edge-tts — 微软在线 TTS,无需 GPU
pip install edge-tts
pip install openai-whisper):语音转文字(步骤1筛选参考片段时需要)pip install demucs):人声分离(仅需从视频中提取人声时使用)# 核心依赖
pip install numpy PyMuPDF
# 推荐 TTS 引擎
pip install -U qwen-tts
# 可选:完整功能
pip install edge-tts openai-whisper demucs
重要:用户提供的演讲稿可能是各种格式(Word 导出、笔记软件导出、手动编写等),在调用 step2_process_speech.py 之前,必须先使用 LLM 将演讲稿整理成标准格式。
演讲稿必须符合以下 Markdown 结构:
## 第 1 页 幻灯片标题
第 1 页的演讲内容第一段。
第 1 页的演讲内容第二段。
---
## 第 2 页 另一页标题
第 2 页的演讲内容。
当用户提供了演讲稿但格式不符合标准时,执行以下步骤:
1. 调用 LLM 整理格式:
你是一个专业的演讲稿整理助手。请将用户输入的演讲稿整理成标准格式。
## 输出格式要求
1. 使用 ## 第 X 页 标题 的格式来标识每一页幻灯片的开始
2. 每页内容放在标题下方,使用连续的自然段落
3. 删除所有与演讲内容无关的元信息(如备注、作者、时间戳、邮箱等)
4. 保留演讲的核心文字内容和标点符号
5. 清理特殊格式字符,但保留标点
6. 如果原稿件没有明确的页码划分,请根据内容逻辑合理分页(每页建议200-400字)
7. 保持原文语义不变,不要添加或删减实质内容
8. 使用 --- 作为页面之间的分隔符
## 示例
### 示例输入(混乱格式):
各位朋友大家好
Page 1
欢迎致辞
今天非常高兴...
### 示例输出:
## 第 1 页 欢迎致辞
各位朋友大家好,今天非常高兴。
---
## 第 2 页 主题介绍
...
2. 将 LLM 返回的标准格式内容写入文件(如 output/step0_manuscript_formatted.md)
3. 后续步骤使用整理后的文件,而非原始文件
| 输入 | 必需 | 说明 | 示例 |
|---|---|---|---|
| ------ | ------ | ------ | ------ |
| 演讲稿 | ✅ 必需 | 按页划分的 Markdown 演讲稿 | slides-speech.md |
| PDF 幻灯片 | ✅ 必需 | 演示文稿 PDF 文件 | slides.pdf |
| 参考音频 | ❌ 可选 | 用于 Qwen3-TTS 声音克隆的参考音频 | reference_voice.wav |
运行流水线前,可使用校验脚本检查输入文件格式:
python {SKILL_DIR}/scripts/validate_inputs.py \
--speech_md <演讲稿.md> \
--slides_pdf <幻灯片.pdf> \
--reference_voice <参考音频.wav> # 可选
该脚本会检查:
## 第 X 页 格式)如果发现问题,脚本会给出具体的修复建议。
使用 Qwen3-TTS + 声音克隆(推荐,需提供参考音频)
python {SKILL_DIR}/scripts/run_pipeline.py \
--speech_md <演讲稿.md> \
--slides_pdf <幻灯片.pdf> \
--output_dir <输出目录> \
--tts_engine qwen3 \
--reference_voice <参考音频.wav>
使用 Qwen3-TTS + 预设音色(无参考音频时)
python {SKILL_DIR}/scripts/run_pipeline.py \
--speech_md <演讲稿.md> \
--slides_pdf <幻灯片.pdf> \
--output_dir <输出目录> \
--tts_engine qwen3 \
--speaker "Vivian"
指定使用 edge-tts
python {SKILL_DIR}/scripts/run_pipeline.py \
--speech_md <演讲稿.md> \
--slides_pdf <幻灯片.pdf> \
--output_dir <输出目录> \
--tts_engine edge \
--edge_voice "zh-CN-XiaoxiaoNeural"
将 {SKILL_DIR} 替换为本技能目录的绝对路径。
常用选项:
| 选项 | 默认值 | 说明 |
|---|---|---|
| ------ | -------- | ------ |
--tts_engine | auto | TTS 引擎:auto(自动选择)/ qwen3 / edge |
--reference_voice | 无 | 参考音频路径(Qwen3-TTS 声音克隆用,提供即克隆) |
--speaker | Vivian | Qwen3-TTS 预设音色(无参考音频时使用) |
--edge_voice | zh-CN-XiaoxiaoNeural | edge-tts 语音名称 |
--resolution | 1920x1080 | 视频分辨率 |
--sentence_pause | 0.4 | 句子间停顿(秒) |
--slide_pause | 1.0 | 页面间停顿(秒) |
--subtitle_mode | burn | burn(烧录)/soft(软字幕)/both(两者) |
--font_name | PingFang SC | 字幕字体 |
--font_size | 38 | 字幕字号 |
--skip_steps | 无 | 跳过的步骤(如 1 跳过声音提取) |
--dpi | 200 | PDF 渲染质量 |
| 音色名称 | 描述 | 母语 |
|---|---|---|
| ---------- | ------ | ------ |
| Vivian | 明亮的年轻女声 | 中文 |
| Serena | 温暖、温柔的年轻女声 | 中文 |
| Uncle_Fu | 成熟的男性声音,醇厚音色 | 中文 |
| Dylan | 年轻的北京男声 | 中文(北京) |
| Eric | 活泼的成都男声 | 中文(四川) |
| Ryan | 富有节奏感的男声 | 英文 |
| Aiden | 阳光的美国男声 | 英文 |
| 语音名称 | 描述 |
|---|---|
| ---------- | ------ |
zh-CN-XiaoxiaoNeural | 晓晓(女,温暖自然) |
zh-CN-XiaoyiNeural | 晓伊(女,亲切活泼) |
zh-CN-YunjianNeural | 云健(男,沉稳大气) |
zh-CN-YunxiNeural | 云希(男,年轻阳光) |
zh-CN-YunyangNeural | 云扬(男,新闻播报) |
如需更精细控制,可逐步运行:
(步骤 0 在上方"步骤 0(必需)"中说明,推荐在所有步骤之前执行)
从参考视频/音频中提取纯净人声,自动筛选最佳参考片段(5~10秒)。
处理流程:
python {SKILL_DIR}/scripts/step1_extract_voice.py \
--input <视频或音频路径> \
--output_dir <输出目录>/step1_voice
脚本位置:scripts/step1_extract_voice.py
筛选评分维度:
输出:
reference_voice.wav — 最佳参考音频片段(5~10秒)reference_text.txt — 对应的转录文字reference_info.json — 片段详细信息(时间、文字、评分等)解析并清洗 Markdown 演讲稿,生成结构化 TTS 数据。
python {SKILL_DIR}/scripts/step2_process_speech.py \
--input <演讲稿.md> \
--output <输出目录>/step2_speech_data.json
脚本位置:scripts/step2_process_speech.py
处理流程:
## 第 X 页 标题解析页面边界粗体、斜体、时间标注、引用tts_sentences),包括:config/pronunciation_map.json 加载)目录路径读音规则:
字幕(sentences)保持原始书面写法不变,TTS 文本(tts_sentences)按以下规则转换:
| 书面写法 | TTS 读音 | 规则 |
|---|---|---|
| ---------- | ---------- | ------ |
~/.codebuddy/skills/ | 家目录下 codebuddy skills 目录 | ~/ → "家目录下",末尾 / → "目录" |
.codebuddy/skills/ | codebuddy skills 目录 | 隐藏目录去掉前导 .,末尾 / → "目录" |
./config/ | 当前目录下 config 目录 | ./ → "当前目录下" |
references/api.md | references api点md | 文件扩展名用"点"连接 |
> 💡 智能去重:如果路径后面已有"目录"或"下"等字样,不会重复追加"目录"。例如 scripts/ 目录下 → "scripts 目录下"。
输出:包含每页句子的结构化 JSON
使用 Qwen3-TTS(支持声音克隆)或 edge-tts(预设音色)生成演讲音频。
# Qwen3-TTS + 声音克隆
python {SKILL_DIR}/scripts/step3_clone_voice.py \
--speech_json <演讲数据.json> \
--output_dir <输出目录>/step3_tts \
--tts_engine qwen3 \
--reference_voice <参考音频.wav>
# Qwen3-TTS + 预设音色
python {SKILL_DIR}/scripts/step3_clone_voice.py \
--speech_json <演讲数据.json> \
--output_dir <输出目录>/step3_tts \
--tts_engine qwen3 \
--speaker "Vivian"
# edge-tts(预设音色)
python {SKILL_DIR}/scripts/step3_clone_voice.py \
--speech_json <演讲数据.json> \
--output_dir <输出目录>/step3_tts \
--tts_engine edge \
--edge_voice "zh-CN-XiaoxiaoNeural"
脚本位置:scripts/step3_clone_voice.py
处理流程:
输出:
full_speech.wav — 完整演讲音频timing_data.json — 精确时间数据(含 tts_engine 字段标记引擎)sentences/ — 逐句音频文件slides/ — 逐页音频文件将 PDF 幻灯片转换为与音频时长匹配的视频。
python {SKILL_DIR}/scripts/step4_generate_video.py \
--pdf <幻灯片.pdf> \
--timing_json <时间数据.json> \
--output_dir <输出目录>/step4_video
脚本位置:scripts/step4_generate_video.py
输出:slides_video.mp4 — 无声幻灯片视频
将所有组件合并为最终演讲视频。
python {SKILL_DIR}/scripts/step5_merge_all.py \
--video <幻灯片视频.mp4> \
--audio <完整音频.wav> \
--timing_json <时间数据.json> \
--output <最终输出.mp4>
脚本位置:scripts/step5_merge_all.py
字幕样式:白色文字,PingFang SC 字体,黑色描边,半透明阴影,底部居中。
输出:final_presentation.mp4 — 带字幕的完整演讲视频
如果对某一句的 TTS 效果不满意,可以使用 --regenerate 参数只重新生成指定的句子,其余句子复用已有音频,然后自动重新拼接并合成最终视频。
查看当前所有句子:
# 查看 timing_data.json 中的句子列表
cat <输出目录>/step3_tts/timing_data.json | python3 -c "
import json,sys
data=json.load(sys.stdin)
for s in data['slides']:
for sent in s['sentences']:
print(f\"slide{s['slide_number']}_sent{sent['index']:03d}: {sent['text'][:60]}\")
"
重新生成指定句子(支持多种格式):
# 格式1: slide<页码>_sent<句号>
python {SKILL_DIR}/scripts/run_pipeline.py \
--speech_md <演讲稿.md> \
--slides_pdf <幻灯片.pdf> \
--output_dir <输出目录> \
--reference_voice <参考音频.wav> \
--regenerate slide1_sent000 slide3_sent002
# 格式2: <页码>:<句号>(更简洁)
python {SKILL_DIR}/scripts/run_pipeline.py \
--speech_md <演讲稿.md> \
--slides_pdf <幻灯片.pdf> \
--output_dir <输出目录> \
--regenerate 1:0 3:2
# 格式3: 整页重新生成
python {SKILL_DIR}/scripts/run_pipeline.py \
--speech_md <演讲稿.md> \
--slides_pdf <幻灯片.pdf> \
--output_dir <输出目录> \
--regenerate slide2
注意事项:
--regenerate 时,步骤 1(声音提取)和步骤 2(演讲稿处理)会自动跳过timing_data.json 会自动更新--temperature 0.5 使用--regenerate演讲稿应遵循标准 Markdown 结构(详见上方"步骤 0")。step2_process_speech.py 会自动清洗以下格式:
自动清洗处理:
文字 → 文字(约 1 分钟) → 移除> 文字 → 文字 代码 → 代码`—— → ,(符合自然语流)流水线内置了三重防护机制,避免并发冲突和重复工作:
run_pipeline.py 和 step3_clone_voice.py 均使用 fcntl.flock() 文件锁。同一输出目录下只允许一个流水线实例运行,重复启动会立即报错退出,不会产生多个进程竞争写入的问题。qwen3 切换到 edge),会自动清除旧引擎生成的音频并重新生成,避免混用不同引擎的音频导致音色不一致。pip install -U qwen-tts,需要较大内存(建议 8GB+)pip install -U qwen-tts 或 pip install edge-ttspip install PyMuPDF)作为主后端pip install pdf2image + 安装 popplerfc-list | grep "PingFang"Noto Sans CJK SC 替代 PingFang SCMicrosoft YaHei 替代timing_data.json 时间数据一致references/pipeline_guide.md — 详细技术架构与设计scripts/ — 所有可执行的流水线脚本共 1 个版本