这是一个“智能体编排+确定性生产引擎”的中文书籍解读视频项目。Codex 负责理解原著、编写与复审脚本、规划分镜、生成原创插画并推进制作;Node.js、豆包 TTS 与 Remotion 负责来源校验、音频主时钟、视频渲染和交付验收。每本书拥有独立工程,最终交付有声 MP4、两种发布封面和发布文案;剪映只负责根据最终音频识别并校对字幕。
查看完整制作过程(Bilibili) · 查看最终成品(抖音)
本项目代码采用 MIT License 开源。原著文本、生成素材、成片以及第三方服务仍分别受其来源版权、平台条款和依赖许可证约束。
这个项目把生成式 AI 擅长的语义决策,与传统程序擅长的稳定执行拆成两层:
flowchart LR
A[本地合法原文] --> B[Codex 制作智能体]
B --> C[脚本与来源映射]
C --> D[自审与 SHA-256 审批门]
D --> E[语义分镜与原创插画]
E --> F[豆包 TTS]
F --> G[真实音频时间轴]
G --> H[Remotion 画面合成]
H --> I[MP4 封面与发布文案]
I --> J[交付文件验收]
- 智能体层处理需要理解和判断的任务:读完整原著、提炼故事、区分原著内容与现代类比、设计留存节奏、规划关键画面,以及根据检查结果修复问题。
- 确定性引擎层处理必须可复现的任务:绑定原文哈希、锁定批准脚本、调用固定 TTS、按真实采样数生成时间轴、用 Remotion 合成音画,并验证交付文件。
- 质量门位于两层之间。智能体不能跳过来源、审批、素材、配音或交付检查,也不能为了让流程通过而降低标准。
当前工作流主要在 Windows 与 PowerShell 下验证。建议准备:
- Node.js 20 或更高版本;
- 已安装并登录的 Codex CLI,以及可用的内置
imagegenSkill; - Git LFS,用于获取和管理仓库声明保留的完整媒体示例;
- 火山引擎豆包语音合成 API Key;
- 一本合法取得、内容完整的 UTF-8
.txt或.md原文。
git clone https://github.com/Mars13333/reader.git
Set-Location reader
npm install
git lfs install
codex login
Copy-Item .env.example .env.local编辑 .env.local,填入:
MODEL_SPEECH_API_KEY=你的火山引擎语音APIKey
MODEL_SPEECH_API_BASE=openspeech.bytedance.com原文只放在根目录 source/,不要提交到 Git。项目会在建书时记录其相对路径、UTF-8 编码和 SHA-256,并在恢复运行时重新校验。
npm run book:auto:check这个命令只检查 Codex CLI、登录状态、仓库 Skill 和图片生成能力,不会创建书籍,也不会调用图片生成或 TTS。
交互运行:
npm run book:auto或者直接传入参数:
npm run book:auto -- --title "活着" --author "余华" --audience "25~40岁泛读书用户" --source "活着.txt"book:auto 会创建单本书工程,并启动一次可恢复的 Codex 非交互会话,依次完成:
- 校验并读取绑定原文;
- 编写脚本、来源映射和发布文案;
- 完成语义自审、质量检查和脚本哈希审批;
- 规划关键画面并生成原创分镜与无字封面插画;
- 调用豆包 TTS 生成 WAV 主音频;
- 按音频真实采样数生成镜头时间轴;
- 用 Remotion 渲染视频与两种封面;
- 验证全部声明交付物。
默认终端只显示阶段、素材计数、渲染帧数、耗时与网络恢复状态。完整 JSONL、stderr 和交付复检日志保存在 .runtime/book-auto/。
网络、认证、额度或渲染中断后,不需要重新制作仍然有效的内容和素材:
npm run book:auto -- --resume --book "book-003-活着"需要查看完整工具输出时追加 --verbose:
npm run book:auto -- --resume --book "book-003-活着" --verbose制作完成后,当前书的 output/ 包含:
output/final.mp4
output/cover-3x4.png
output/cover-4x3.png
output/publish-copy.txt
把 final.mp4 导入剪映识别并校对字幕,再手动上传。book:auto 不联网搜索书评或剧情梗概,也不会自动发布到抖音或其他平台。
book:auto:check、来源校验和本地质量门不会产生图片或 TTS 调用费用。- 当前方案不依赖逐镜视频生成 API;原创插画使用现有 Codex 图片生成能力,另行配置的云端服务主要是豆包 TTS。个人试验中其免费额度通常足以完成口播,但具体额度与规则以服务商当期说明为准。
- 分镜插画降低了角色一致性、动作连续性和逐镜抽卡成本,但不等于没有生成成本。希望改成漫剧或图生视频时,可以替换视觉资产层,来源、脚本、TTS、音频时间轴和 Remotion 交付链仍可复用。
- 用户必须自行确认原文和最终发布内容的合法使用边界。仓库不收录原著正文,不使用原书封面、影视截图或演员形象。
- 正式口播固定使用火山引擎豆包语音合成 2.0 的刘飞男声
zh_male_liufei_uranus_bigtts。 - 语速固定为
-10,书籍配置不得覆盖。 - 1080×1920、30 FPS;新书按原著内容量在 8~19 分钟内确定目标时长,不再固定为 10 分钟。
- 从
book-003开始执行hook-payoff-loops-v1留存标准:脚本第一句话直接落钩,钩子在正文开始后 2 秒内出现,前 10~20 秒兑现第一份价值;之后每 20~40 秒完成一次“小兑现+新悬念”,不得只靠一个开场钩子支撑整条长视频。 - 配图数量由关键剧情、原著核心案例、关键概念、现代类比和局限反思决定,不再按固定时间间隔或固定张数生成;镜头按内容重要性分配停留时间,不抖动、不逐字跳动。
- 不生成 SRT、不烧录口播字幕、不交付独立 MP3。
- 不生成自制播放进度条,不生成视频内 AI 提示标签。
- 从
book-003开始,首张插画淡入前露出的画布固定为纯黑色;这只约束空白首帧,不把后续原创插画改成黑暗风格。 - 顶部常驻书名使用左右对称安全边距、横向居中并下移到搜索框遮挡区以下;新书只显示准确书名,不再附加“10分钟读书”等全局标签。字号为 42~48px,但必须小于章节重点字。章节重点字也整体下移,至少展示 6 秒,并按每字约 0.35 秒延长阅读时间。
- 从
book-002开始,分镜和封面默认使用明亮通透的日光处理:暗部必须保留细节,不得用大面积纯黑、重度暗角或浑浊棕灰制造氛围。 - 之后通过
book:new创建的新书固定使用portrait-2x2-9x16-v1:每张分镜母图是纵向 9:16 PNG,内部 2×2 的四个子画面也分别为 9:16;允许 0.5% 像素取整误差。正方形或其他比例会在 TTS 和渲染前被拒绝,已发布的book-003不追溯修改。 - 新书最后一句固定为“这里是陈拾叁,陪你一起读书破万卷。”;旧的“这里是十分钟读懂一本书”继续禁止。
- 新书只使用用户放入根目录
source/的完整原文,不联网搜索书评、剧情梗概或访谈补足内容;原文路径和 SHA-256 在建书时绑定,恢复运行时重新校验。 - 频道不限题材,所有新书默认服务没读过原著的观众。小说、经济学、历史、社会科学等都采用“现实问题→具体场景→原著核心案例或剧情→解释原理→回到现实→补充局限”的内容链;相邻环节可以自然交织,不写成六个生硬栏目。
- 口播要自然提示哪些是原著内容、哪些是现代类比、哪些是本频道判断;内部计划必须明确分类,成片表达不能泾渭分明到破坏叙事。
- 脚本引言目标为 30~45 秒,脚本第一句话在正文开始后 2 秒内落钩、前 10~20 秒首次兑现,并最迟在正文开始后 45 秒进入第一个具体场景。
- 以后新建的书开头启用
book-picker-v2:用 6.8~8.8 秒的纵向书架滚动选书,落定后展开本期原创封面,再由配音引擎固定说“大家好,今天我们讲《书名》。”,说完才进入脚本正文。旧项目的book-picker-v1与已有成片保持不变。 - 选书动画由当前书的
content/video-layout.json.bookPickerIntro控制:enabled开关、durationSeconds时长、seed确定滚动顺序、candidateLabels配置中文候选书名、selectedLabel配置落定提示;真实本期书名和固定开场口播始终读取book.json/cover.json,不得在脚本中重复填写,也不得手填成另一版本。当前书使用原创无字封面底图和代码排版书名,不需要、也不使用原书版本封面截图。 - 生成插画内禁止英文、字母、数字、标志、水印和乱码文字;必要中文统一由 Remotion 排版。
- 脚本完成后,Codex 必须自行完成专名与读音、开场留存、持续留存结构、逐句通顺、来源一致性、原著覆盖、六步内容链、三层内容区分、关键视觉点、固定收尾和原创评论审核;默认不再要求用户逐字审稿,工程校验也不能代替内容自审。
- 以上新标准只作用于之后由
book:new/book:auto创建的作品;book-001~book-004的内容、配置和成片均不追溯修改。 - 从
book-003开始,每本书交付 1 个有声 MP4、3:4 与 4:3 两种发布封面,以及一份可直接复制上传的标题与作品简介;不再生成无实际发布入口的 9:16 封面。前两本书的既有配置和交付文件保持不变。 - 新封面采用原创“书籍正面/书封”版式:真实书名必须是封面最大、最醒目的文字,作者和一句推荐语只能作为次级信息;书名由代码排版,不要求图片模型在插画中生成中文。
ai_media/
├─ active-book.json # 当前选中的书
├─ source/ # 用户提供的本地原文;正文默认不纳入 Git
├─ books/
│ └─ book-010-浮生六记/ # 开源仓库唯一完整媒体示例
│ ├─ book.json # 书籍元数据与制作状态
│ ├─ approval.json # 已批准脚本的 SHA-256
│ ├─ content/ # 人工/Codex 编辑的输入
│ ├─ generated/ # 时间轴、审稿文件、镜头表等生成数据
│ ├─ public/assets/ # 本书音频、封面插画和分镜插画
│ └─ output/ # 本书正式交付文件
├─ scripts/ # 多书管理、审批、配音与渲染脚本
├─ src/ # 所有书共用的 Remotion 模板
├─ .runtime/ # 当前书的临时运行时数据
└─ docs/ # 全局工作流与验收规范
先把合法取得的完整原文保存为 UTF-8 .txt 或 .md,放入根目录 source/。再执行 codex update 确保 Codex CLI 已升级并登录,然后运行:
npm run book:auto命令会沿用 book:new 的交互提问;填写书名、作者、目标观众和 source/ 下的原文文件名后,由一次可恢复的 Codex 非交互会话只根据该原文完成脚本与发布物料、自审和审批、原创分镜与封面插画、配音、渲染及全部声明交付物的验收。执行 book:auto 即表示授权当前书完成这些本地制作步骤,但不包含联网研究、自动上传或发布。
默认终端采用安静进度模式:Codex 的命令、英文过程说明、Starship 警告和工具原始输出只写入日志,终端只保留一条动态进度栏,显示当前八阶段进度、插画完成数、渲染帧数、已用时间和最近活动时间。网络波动时会明确显示重连次数、等待网络或 WebSocket 降级状态,并提示切换网络节点;收到下一条正常事件后显示“网络已恢复,继续执行”。
› [██████████░░░░░░] 5/8 原创插画生成|原创插画 12/19|已用时 43:28|最近活动 8 秒前
完整事件保存在 .runtime/book-auto/<book-id>.jsonl,Codex 标准错误和最终交付复检分别保存在相邻的 <book-id>-stderr.log、<book-id>-verification.log。排错时追加 --verbose 恢复详细终端输出:
npm run book:auto -- --resume --book "book-003-活着" --verbose也可以直接传参:
npm run book:auto -- --title "活着" --author "余华" --audience "25~40岁泛读书用户" --source "活着.txt"中途因网络、额度或工具失败而停止时,修复原因后继续同一 Codex 会话:
npm run book:auto -- --resume --book "book-003-活着"运行环境检查不会创建书籍或产生图片、配音费用:
npm run book:auto:check需要临时指定模型或沙箱时,可追加 --model <model> 或 --sandbox <mode>;需要查看完整过程时追加 --verbose。默认沿用 Codex 当前模型配置,并使用 workspace-write。
下面的分步流程继续保留,用于人工干预、排错或只生成某一阶段。
npm run book:new脚本会询问书名、作者、目标观众和 source/ 下的原文文件名,先验证 UTF-8 编码并记录 SHA-256,再创建下一个编号,例如 book-002-活着,并将它设为当前书籍。原文缺失或不在 source/ 内时不会创建书籍。
也可以非交互创建:
npm run book:new -- --title "活着" --author "余华" --audience "25~40岁泛读书用户" --source "活着.txt"Codex 只读取 source-map.json 已绑定的本地原文,并只填写当前书的 content/script.json、content/source-map.json 和 content/publish.json。此阶段禁止联网搜索,也禁止生成分镜、插画、配音和视频。
原文规则:
source-map.json固定使用local-source,保存项目相对路径、UTF-8 编码和 SHA-256。- 人物、情节、反转、结局、短引文和作品主题只以绑定原文为内容事实来源;不得引用书评、公开剧情梗概、作者访谈或模型记忆补足。
- 原文缺失、哈希变化、正文不完整、无法读取或与书名不符时立即停止,不得把完整解读降级为主题评论后继续制作。
初稿完成后,Codex 必须先逐句复审,不能直接交给用户逐字找错:
- 专名与读音:从来源中提取人名、地名、书中专名、多音字和别名,写入
source-map.json的terminology;记录标准写法、读音、允许别名和禁用错字,并逐项回查脚本。 - 开场留存:
book-picker-v2的固定开场口播由生产引擎根据book.json自动生成,不写入脚本。固定口播结束后,第一段第一句话直接进入冲突、反常识、代价或结果,钩子不得晚于正文开始后 2 秒;脚本不得再次报书名、作者、栏目或重复“今天我们来讲”。正文前 10~20 秒必须给出第一个事实、结论或证据,不能只提问不兑现。默认禁止把“小说不能当史书”“先分清史实和小说”等内容做成独立开场段;必要边界应在相关事实出现时用最短语句自然说明。 - 持续留存结构:每段都要先兑现上一问题,再自然引出下一问题;长视频约每 20~40 秒刷新一次冲突、证据、反转或代价。新书在
script.json.retentionPlan中记录openingHook、firstPayoff和与口播段落一一对应的segmentBeats,由book:quality阻断空计划、慢开场和断裂的悬念链。 - 统一内容链:不限题材,
script.json.contentFlow.loops至少记录一条“现实问题→具体场景→原著核心案例或剧情→解释原理→回到现实→补充局限”。相邻阶段可以引用同一段,以保留自然叙事。 - 内容层区分:每个
segmentBeat.contentLayers标记source、analogy、commentary或bridge。口播用“书中写到”“换到今天”“我的理解是”等自然连接,不在画面上机械贴分类标签。 - 故事覆盖:脚本先讲清主角目标、主要阻碍、关键场景、重要反转、后果和结局,再进行分析。每个
segmentBeat.sourceAnchor写明该段新增的具体原文场景;纯分析段留空。至少 60% 段落必须有场景锚点,且不得连续超过两个纯分析段;分析必须能回指前文具体人物与事件。 - 逐句通顺:按真实口播逐句朗读,删除病句、生造口语、指代不清、同义反复和只为凑时长的句子。
- 来源一致:每个人物、小说情节、短引文和作品判断都能回指绑定原文的具体行号;评论判断不得伪装成原著原句或作者结论。
- 原创评论:避免照搬上一册结构,不用固定“阅读边界”模板,不用大段剧情复述代替观点。
自审完成后,Codex 在 source-map.json.selfReview 中记录全部自审结果、时间和当前脚本 SHA-256,然后运行只读质量门:
npm run book:quality需要获取当前脚本哈希时可运行:
npm run book:quality -- --hash-only质量门未通过时,Codex 必须继续修改,不得把问题转交给用户逐字排查。质量门负责阻断可机械发现的问题;Codex 的逐句语义复审仍然是必做步骤。
生成内部审稿归档:
npm run book:reviewbook:review 会自动再次运行 book:quality。自审缺失、术语未登记、开场免责声明、引用失效,或脚本在自审后被修改,都会拒绝生成审稿归档。
归档文件位于当前书的 generated/script-review.md,包含完整口播、章节、字符数、目标时长、出处和脚本 SHA-256。脚本阶段还必须完成 content/publish.json:title 为 6~30 字的简洁吸睛标题,descriptionLines 为 1~2 句有趣且与作品一致的简介。最终发布文案固定追加 #保持阅读 #书籍分享 #个人成长 #认知提升。用户默认不需要逐字审阅;如果质量门和 Codex 语义自审都通过,Codex 只向用户交接:
审核通过,继续下一步就行。
用户如果主动提出修改意见,Codex 修改脚本后必须重新完成第二步全部自审。默认情况下,用户无需阅读审稿文件,只需在收到“审核通过,继续下一步就行”后回复:
脚本已批准,开始生成分镜、原创插画和两种发布封面。
这句话是进入付费视觉生成阶段的明确授权。Codex 收到后先执行:
npm run book:approve
npm run book:approval-checkapproval.json 会锁定已自审脚本的 SHA-256。批准后修改任何一个字符,后续制作都会拒绝执行,必须重新自审、重新归档并重新获得用户授权。
多音字不通过改写已批准脚本来迁就 TTS。制作前将需要强制读音的词写入当前书 content/narration-config.json 的 pronunciationOverrides:term 保留正文标准写法,ttsText 只作为合成时的同音替代,pronunciation 记录目标读音。发音规则拥有独立 SHA-256;规则变化后旧音频缓存立即失效。
只有批准完成后,Codex 才能编写 content/visual-plan.json、生成分镜插画和两种发布封面所需的封面插画。先在 keyMoments 中挑出关键剧情、原著核心案例、关键概念、现代类比和局限,再为每段按语义需要安排 1~4 个镜头,并用 weight 按重要性分配停留时间;不得按固定时长倒推图片数量。新书的每张分镜母图必须是纵向 9:16 的 2×2 四宫格,不得使用正方形母图;素材落盘后逐张检查关键内容覆盖和英文/乱码,再把 assetReview 标为通过并运行 npm run book:storyboards-check。封面插画只提供原创无字背景与主体,真实书名由代码排版。
npm run book:produce命令严格依次执行:
- 验证脚本批准哈希。
- 验证刘飞男声和语速
-10。 - 验证分镜与封面素材完整。
- 生成或复用与批准脚本匹配的 WAV 主音频。
- 按真实音频生成画面时间轴。
- 执行工程验收。
- 渲染有声视频和 3:4、4:3 两种封面,并生成发布标题、作品简介与固定话题标签。
- 验证四个正式交付文件。
正式输出固定为:
output/final.mp4
output/cover-3x4.png
output/cover-4x3.png
output/publish-copy.txt
将 final.mp4 导入剪映,一键识别字幕并调整字幕样式。导出后,在抖音网页版分别上传 3:4 竖封面和 4:3 横封面。标题和作品简介直接从 output/publish-copy.txt 复制。
npm run book:list
npm run book:status
npm run book:use -- "book-001-长安的荔枝"book:list:列出全部书籍,*表示当前书。book:status:显示当前书、状态、目录和固定配音。book:use:切换当前书,不移动或覆盖任何文件。
npm run book:approval-check
npm run book:quality
npm run book:voice
npm run book:prepare
npm run book:check
npm run book:covers
npm run book:render
npm run book:studio正常情况下优先使用 book:produce。脚本发生变化并重新批准后,book:voice 会发现哈希不一致并自动重新生成口播;画面修改但脚本未变时会直接复用原音频。
book:covers 只依赖已批准脚本、封面配置和封面插画,可在尚未生成配音时独立渲染当前书声明的封面。旧书仍按原配置保留 9:16、3:4、4:3;book-003 起只渲染 3:4 和 4:3。
book:preflight 是 book:produce 内部自动执行的诊断命令,日常流程不需要手动运行;仅在排查素材缺失时单独使用。
《浮生六记》位于 books/book-010-浮生六记,是开源仓库唯一保留完整分镜、封面插画、WAV 主音频和正式 MP4 的端到端示例。book-001~book-009 继续保留脚本、来源映射、视觉计划、时间轴和发布文案等工程文本,但不在当前版本中携带大体积媒体。
历史书缺少 public/assets 或 output 媒体是有意的开源体积控制,不代表这些旧工程仍能直接通过 --outputs 验收。需要复现时,应使用合法原文和自己的服务额度重新生成素材,或从项目维护者另行发布的演示中查看成片。
book-010-浮生六记是当前唯一完整媒体示例,其分镜、封面插画、WAV 主音频、正式 MP4 和两种封面通过 Git LFS 跟踪。book-001~book-009以及以后新建书籍默认只提交工程文本;本地public/assets、QA 截图和output媒体由.gitignore排除,除非明确将另一部书指定为新的完整示例。- 所有需要提交的视频、音频和位图仍必须通过 Git LFS,禁止把大二进制文件直接写入普通 Git 历史。
source/中的原文、output/preview.mp4、.runtime、临时配音片段、依赖、日志和本机密钥继续忽略;只跟踪source/README.md。- 克隆完整示例或更换完整示例前,应确认
git lfs install和追踪规则正常。
- 用户提供的原文只用于本地分析,不复制到正式交付。
- 原文不纳入 Git,不复制进单本书目录;书籍项目只保存项目相对路径和 SHA-256。
- 成片属于评论性二次创作,不是有声书或逐章复述。
- 不使用原书封面、书页截图、影视剧照或演员形象。
- 小说情节、史实和解读判断必须明确区分。