PPT Master 如何为演讲备注生成逐页配音并嵌入 PPTX
当你已经用 PPT Master 生成了一份额可编辑的演示文稿,接下来想把每页的演讲备注变成配音,并让 PPTX 打开后自动播放音频、按音频时长自动翻页时,就是本文的任务。PPT Master 默认用 edge-tts(微软 Edge 的在线神经网络语音)把 notes/ 目录下的逐页备注合成为每页一个 MP3 和一个页面局部时间轴的字幕 SRT,再通过 svg_to_pptx.py 的 --recorded-narration audio 参数把音频嵌回 PPTX,写入 PowerPoint 的“录制计时和旁白”以及页面自动前进时长。前提:项目已完成一次基础 PPTX 导出,且每页都有非空的演讲备注;Python 3.10+,并已安装 edge-tts 与 ffprobe(嵌入导出时要从实际音频时长读取页面时长)。
准备条件
- 安装配音依赖。默认后端只需
edge-tts(已列在 skills/ppt-master/requirements.txt 中):
python3 -m pip install edge-tts
edge-tts 调用微软在线 TTS 服务,生成时需要联网;生成出的 MP3 是本地文件,之后的播放和嵌入不再依赖网络。
- 确认每页备注齐全。配音是页面级任务:一页备注对应一个音频文件。Generate 路线的备注先由
notes/total.md拆分到notes/<page>.md(后处理 Step 7.1 已完成这一步)。如果还没拆分,可以手动运行:
python3 skills/ppt-master/scripts/total_md_split.py <project_path>
<project_path> 替换为你的活动项目路径,即 agent 报告的工作目录下 projects/<generated-project-name>/。
- 嵌入导出依赖
ffprobe读取每个音频的实际时长,确保它已在 PATH 中。
notes_to_audio.py 在发出任何 TTS 请求前会做一次 notes 预检:所有预期备注必须存在、可读且包含口播文本;缺失或为空时退出码为 2,此时先生成备注再重跑音频,不能带着部分音频继续。
列出可用语音并选择
用 deck 的主语言 locale 列出 edge 语音,从清单里挑一个:
python3 skills/ppt-master/scripts/notes_to_audio.py --list-voices --locale ja-JP
locale 换成你的主语言,例如 zh-CN、en-US。edge 覆盖约 90 个 locale,包括中文大陆/繁体/粤语等变体。对 edge,--voice 是必填参数。文档给出的常见搭配示例:中文咨询/财务类 deck 用稳重的 zh-CN-YunjianNeural(男)或清晰的 zh-CN-XiaoxiaoNeural(女);英文咨询类 deck 用 en-US-GuyNeural 或 en-US-JennyNeural。
生成逐页音频(主路径:edge,无需 API key)
python3 skills/ppt-master/scripts/notes_to_audio.py <project_path> \
--voice zh-CN-YunjianNeural --rate +0%
执行成功后,项目下会得到:
audio/<stem>.mp3:每页一个,文件名与对应的 SVG 一致(如01_cover.mp3、02_market_landscape.mp3);audio/<stem>.srt:页面对应的字幕,使用以00:00:00,000为起点的页面局部时间轴,MP3 与 SRT 来自同一次 edge-tts 流式请求的WordBoundary时序;audio/manifest.json:只有整批全部成功才原子写入,记录 provider/模型、音频与字幕格式、相关语音设置和 SHA-256 语音指纹,不含 API key。
语速从 +0% 起步;备注密度高(每页超过约 4 个长句)可试 -5%,短而紧凑的备注可试 +5%。edge 默认并发生成 3 页的音频/SRT 对,用 --concurrency <N> 调整,排障时可加 --concurrency 1 串行运行。
可选分支:云端 provider。 需要更高质量或克隆音色时,在 shell 或 .env 中配置对应 API key 后改用 --provider:
# ElevenLabs(需 ELEVENLABS_API_KEY)
python3 skills/ppt-master/scripts/notes_to_audio.py <project_path> \
--provider elevenlabs --voice-id <elevenlabs-voice-id> \
--elevenlabs-model eleven_multilingual_v2
# MiniMax(需 MINIMAX_API_KEY,默认国内端点;海外访问设 MINIMAX_TTS_BASE_URL=https://api.minimax.io/v1/t2a_v2)
python3 skills/ppt-master/scripts/notes_to_audio.py <project_path> \
--provider minimax --voice-id <minimax-voice-id> \
--minimax-model speech-2.8-hd
# Qwen(需 DASHSCOPE_API_KEY;当前 TTS API 不返回时间戳,只产出音频,无页面 SRT)
python3 skills/ppt-master/scripts/notes_to_audio.py <project_path> \
--provider qwen --voice-id <qwen-voice> \
--qwen-model qwen3-tts-flash --qwen-language-type Chinese
# CosyVoice 带时间戳音色(需 COSYVOICE_API_KEY;模型与音色必须同族)
python3 skills/ppt-master/scripts/notes_to_audio.py <project_path> \
--provider cosyvoice --voice-id <cosyvoice-voice> \
--cosyvoice-model cosyvoice-v3-flash
--voice-id 既接受系统音色也接受在 provider 控制台克隆后返回的克隆音色 ID;克隆本身在 provider 侧完成。需要页面 SRT 时不要选 Qwen(以及显式 --cosyvoice-audio-only 的 CosyVoice),因为这两条路径没有 provider 时间戳,notes_to_audio.py 也不会估算 SRT 时序。云端 provider 串行生成。
将音频嵌入 PPTX 并写入自动翻页
嵌入用两条命令之一(docs/audio-narration.md 的“Two embedding paths”):
| 命令 | 用途 |
|---|---|
--recorded-narration audio |
准备 PowerPoint 的“录制计时和旁白”:要求每页音频齐全,并写入页面自动前进时长。配音和视频导出用这条。重新导出的文件保存为 exports/<name>_<timestamp>_narrated.pptx。 |
--narration-audio-dir audio |
更底层的音频嵌入:允许部分页面覆盖,适合测试或在 PowerPoint 里手动收尾。导出同样带 _narrated 后缀。 |
主路径(完整配音 deck):
python3 skills/ppt-master/scripts/svg_to_pptx.py <project_path> \
-o exports/final_narrated.pptx \
--recorded-narration audio \
--narration-start-floor 0.8 --narration-padding 0.5
-o 后的路径按你的实际输出位置替换。两个时长参数可省略,默认值就是 0.8 与 0.5:
--narration-start-floor(默认0.8秒):从目标页转场开始到旁白开始的最小间隔;0表示转场一结束就开口。实际转场后静默是max(0, narration_start_floor - transition_duration),改 floor 不会拉长转场本身。--narration-padding(默认0.5秒):旁白结束到翻页之间的静默。
如果基础导出时使用了动画,追加 --animation-config animations.json(旁白无关的自定义动效走规范时序),或 --inherit-motion-from "<base_postflight_report>" 继承基础导出报告里解析好的整 deck 动效(<base_postflight_report> 替换为基础导出时生成的 validation/<project_name>_<timestamp>.report.json 报告路径);两者都不需要时直接省略即可继承基础导出的解析动效。注意 --recorded-narration 会拒绝 on-click 对象动画,因为它不产生对象级点击时序——对象动画要用 after-previous / with-previous。
在聊天中的简单触发方式(让 AI 执行上述流程):
You: Generate narration for this deck and re-export with audio embedded.
AI 会检查 deck 主语言、拉取所选 provider 的语音目录、推荐 3–6 个候选并一次性确认 provider、语音、语速、是否嵌入、是否导出视频,然后执行。
验证结果
audio/目录下每页一个mp3+ 同名srt,且存在audio/manifest.json——manifest 是整批成功后才原子写入的,它是“这次生成完整成功”的标志。exports/下出现带_narrated后缀的新 PPTX。在 PowerPoint 中打开该文件:每页音频随页面自动播放,页面自动前进时长由“页面起始静默 + 音频时长 + 页尾 padding”决定,旁白不会在转场未完成前开始。- 原始演讲备注保留不变;字幕始终是外部 SRT 文件,不会嵌入 PPTX 或烧录进视频。
限制与常见调整
- 音频格式:嵌入 PPTX 的音频必须用 PowerPoint 可靠支持的
m4a(AAC)、mp3或wav。edge 默认mp3;provider 输出的pcm、opus、flac需要先转码再嵌入。 audio/是唯一的当前配音集:重跑notes_to_audio.py会先清掉旧的manifest.json和total.srt再覆盖全部 MP3——所以修改某一页的notes/<page>.md后要整 deck 重跑(文档说明成本很小),然后重新执行嵌入步骤。- 不支持长音频自动拆分:一条长音频对应多页的场景不支持,必须一页一个文件。
- edge SRT 分句规则:句末标点闭合一条 cue;超过 20 个可见字符(可用
--subtitle-max-chars调整)时先按逗号、分号、冒号切分,再按最近词边界切分;相邻 cue 重叠 100 ms 以内会自动把后一条起点移到前一条结束,更大重叠直接失败。
下一步:导出为视频(可选,Windows)
带配音的 PPTX 落在 exports/ 后,在装有 Windows PowerPoint 2016+ 的机器上可以自动导出 MP4:
python3 skills/ppt-master/scripts/powerpoint_video.py --check
python3 skills/ppt-master/scripts/powerpoint_video.py \
exports/final_narrated.pptx -o exports/final_narrated.mp4
该命令委托 PowerPoint 原生编码器(默认 1080p/30 fps),同步等待成功或失败;macOS 或没有兼容 PowerPoint 的环境保留带配音的 PPTX 手动导出即可。原生导出的 MP4 不保证包含转场和对象动画的声音;若最终动效里配置了这些声音 cue,需要再跑 video_sound_mix.py 做混音(依赖 ffmpeg/ffprobe 与 numpy),或用人工放映录制路径替代——这部分属于视频交付的边界,不影响本文“配音生成 + 嵌入 PPTX”这一任务本身。更完整的工具行为说明见 scripts/docs/narration.md,阶段编排见 workflows/stages/generate-audio.md。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0629
MiniCPM5-2BMiniCPM5-2B 是一款面向端侧、本地部署和资源受限场景的 2B 稠密 Transformer,能够达到同尺寸开源模型 SOTA 水平。Markdown00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
HivisionIDPhotos⚡️HivisionIDPhotos: a lightweight and efficient AI ID photos tools. 一个轻量级的AI证件照制作算法。Python07
DragonOSDragonOS is an operating system developed from scratch using Rust, with Linux compatibility. It is designed for **Serverless** scenarios. 使用Rust从0自研内核,具有Linux兼容性的操作系统,面向云计算Serverless场景而设计。Rust00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00