B/C 栏目编制规程 v1
B/C 两栏目的生产规范与验收口径。
# B/C 栏目编制规程 v2 > 适用范围:**B 类《一课看懂》**、**C 类《邵先生拆课》**每一集的「稿件 → 执行包 → 出片 → 声音 → 成片」。 > 本规程由 **S1E01《七寸雪》** 的实跑固化(2026-10);下文每条命令与判据都是该项目上真跑过的那一套。 > **v2(2026-10 用户裁定)**:B 类改为**固定场景人物**(A 类州衙偏厅 + 邵先生 + 记录者 + 书案式盘,对话讲四课三传、式盘随指亮微光); > C 类**只用邵公配音**、不设中性辅助旁白;B/C 成片须补 **.srt 字幕轨**。 > 配套旧文:`README_工程索引.md`(目录导航)、`账号与发布规范_v1.md`(合规标识)。 --- ## 0. 栏目分工(长期口径,2026-10 用户裁定) | | 讲什么 | 不讲什么 | |---|---|---| | **B《一课看懂》** | 这门课**怎么读**:四课是什么、三传是什么、**风起/下雨/作雪从哪一重读出来** | 不点具体时刻、不说量 | | **C《邵先生拆课》** | 凭什么断得**这么具体**:为什么是**雪**(时令)、为什么**七寸**(形制)、为什么是**巳时/未时/亥时**(应期) | 不复述四课、三传是什么 | - C 与 B 的**差异化手法不固定**,按案情另选(S1E01 用的是「反证分叉」:若只取一重水象会断成什么)。 - 红线:**深解不可凭通俗六壬常识补原案**;台词内容以对应原案 + 已核材料为边界,节目化措辞须在稿内标注。 **视觉与声音口径(v2,2026-10 用户裁定)**: - **B 类固定场景人物**:场景取 A 类 `A-ENV-S1E01-HALL-01`(州衙偏厅),人物取 A 类 `A-CHAR-G-SHAO-01`(邵先生)与 `A-CHAR-G-REC-01`(记录者/书生),书案置 A 类道具 `A-PROP-G-DIVINATION-01`(式盘);四课、三传由二人**对谈**讲出, 式盘随指亮极淡微光(正向描述,**删去**与之冲突的 `no fantasy glow` 负面句——cfg=1 下否定句压不住正面描述); 三传等仍用 B 类既有的 `B-PROP-*E*-TOKEN-01` 标记物表示。**B 类 100 集共用此设定**。 已退役(图移入 `02_资产\参考图\_wip\`):`B-ENV-G-LAB-01`、`B-ENV-S1E01-MICRO-01`、`B-CHAR-S1E01-CASE-01`。 - **C 类只用邵公配音**(`C-VO-G-SHAO-01`):**不设中性辅助旁白**——原 `C-VO-G-NARR-01` 已删,旁白基座归 `A-VO-G-NARR-01`。 - **字幕轨**:B/C 成片须产出 `.srt`(见 §9.1)。 - **式盘带字口径(v3,2026-10 用户裁定)**:B 类**直接沿用 A 类实物式盘** `A-PROP-G-DIVINATION-01` 作桌面道具(约 **25cm×25cm**、平放于桌上),**式盘上可以带字**(随该资产自身刻字呈现,不再压制)。**其余画面文字一律「无字或虚化到不可读」**——送 H3 的文本不得含可读中文串(走 `--dialogue omit` + `--defs-english` 默认口径),字幕仍归后期 `.srt`。⇒ 制作稿 §4 不得再要求「素盘/无标记」(那会让 `h3_batch._prompt_conflict` 跳过式盘参考图,反而出不来字)。 --- ## 1. 改稿(`01_剧本\`) - B:`01_剧本\B类_一课看懂100集\{总序}_S{季}E{集}_{标题}_一课看懂_制作稿.md` - C:`01_剧本\C类_邵先生拆课30集\{总序}_S{季}E{集}_{标题}_邵先生拆课_制作稿.md` - 结构:§0 史料状态与原案锁定 / §1 视觉与声音 Bible / §2 结构与课理 / §3 参考图资产 / §4 每镜生成 Prompt。 - §4 每镜字段(**顺序与名称不可改,`smoke_pack.py` 按此解析**): `生成类型:` `时长:` `上传:` + `Picture N = <资产ID>`、`subject_definitions` / `summary` / `retention_analysis` / `detailed_description` / `overall_soundscape` / `non_diegetic_music`。 - 台词就地写在 `detailed_description` 里,形如 `... He says: [Chinese] 台词。`(C 类,人物口播)或 `Shao says: [Chinese] 台词。` / `the clerk asks: [Chinese] 台词。`(B 类,邵先生与记录书生**对谈**)。 - §3 参考图表**必须把该集用到的全部资产列全**(含 KEY/PLAN)——漏列会触发 `npm test` 的「参考图无孤儿」门禁。 --- ## 2. 时长口径(最容易出错的一环) 1. **H3 只认 `(5+17k)/24` 秒**(k≥0 整数,即 6.583 / 7.292 / 8.000 / 8.708 / 9.417 / 10.125 / 11.542 …)。写稿时**必须落在这组档上**。 2. **镜长由台词反推**,判据:`0.3s(镜内起手留白 MARK) + 台词实测时长 ≤ 镜长`(`assemble.py` 的 `audio_fit` 即此式)。 3. **不要为了迁就时长去删台词**——台词定稿、时长可调。(S1E01 实测:改台词会让已生成的 TTS 全部错位,代价远高于加长镜。) --- ## 3. 生成执行包 ```bash # B 类 python 00_工程管理/工具/smoke_pack.py \ --draft "01_剧本/B类_一课看懂100集/001_S1E01_七寸雪_一课看懂_制作稿.md" \ --mapping "03_映射/H3参考资产映射/B类/001_S1E01_七寸雪_H3映射.md" \ --shots B01,B02,B03,B04,B05 --label "5镜全集" \ --out "04_工程/B类/S1E01/smoke" --title "B类 S1E01《七寸雪》" # C 类同理:--draft C 稿 / --mapping C 映射 / --shots C01..C08 / --label "8镜全集" ``` - **槽位权威源是映射表**(`--mapping`),不是制作稿 §4 的 `上传` 块;§4 那块只作人读参考。 - 产物:`04_工程/{B类,C类}\S1E01\smoke\S1E01_{N}镜全集执行包.md` + `seeds_{N}镜全集.csv`。 - 收尾看输出里的 `注册表缺失 ID:`——应为「无」。 --- ## 4. 出片前两道门禁(都必须绿) ```bash # ① 计划校验(不联网):看时长、参考数、BLOCK 是否被正确跳过 python 00_工程管理/工具/h3_batch.py --pack "<执行包.md>" --dry-run # ② 音频 vs 分镜时长(fail-closed:rc=0 合格 / 1 有镜超限 / 2 数据缺失) python 00_工程管理/工具/assemble.py --pack "<执行包.md>" \ --shots-root "05_成片/B类/S1E01" --nominal --check --ep B001 ``` - **生成前一律加 `--nominal`**:不加会去读已出片素材的**实测镜长**,拿旧素材比新镜号必出假结论。 - `--ep` 是录音清单的「集」值:A 类 `001`、B 类 `B001`、C 类 `C001`。 --- ## 5. 出片 ```bash python 00_工程管理/工具/h3_batch.py --pack "<执行包.md>" \ --out "05_成片/B类/S1E01/h3" --url "<实例地址>" --yes ``` - ⚠ **输出必须落在 `<集目录>/h3/` 子树,不要平铺进集目录**。原因:`stitch_final.find_shot` 取 `sorted(glob(...))[0]`,而 H3 服务端的文件名计数是全局递增的——重出时新片编号更大、排序在后,若与旧片同目录,会被**静默选到旧视频**。 - 实例地址是 lightcc 随机子域、随时会变:首选 `python 00_工程管理/工具/lightcc_url.py`(需 `LIGHTCC_API_KEY`)解析,或直接用当前地址。 - 实例自检:`python 00_工程管理/工具/refgen.py --probe --url "<实例>"`;`MiniMaxH3ImageToVideo` / `MiniMaxH3` 节点在位即可出片。 - 单镜失败不中断整批(`h3_batch` 逐镜循环,汇总行会给 `合计 N/M 成功`);跑完按第 9 节核规格。 - 参考数据(S1E01 实测):T8·turbo、seed 20260925,单镜实耗约 **4–6 分钟**(8.7s 片 318s、11.5s 片更长)。 --- ## 6. 片头 / 片尾 ```bash python 00_工程管理/工具/make_titles.py --class B # 片头 + 片尾 python 00_工程管理/工具/make_titles.py --class C # 只有片头 ``` - 类别差异(用户 2026-10 确认):**A/B 有片尾;C 类制作稿 §2 无「片尾」节拍,只有片头**。 - 合规标识「本内容由 AI 生成」按 `ai_note` 落点:A/B 落**片尾**、C 落**片头**(`账号与发布规范_v1.md:52` 硬性要求,必须落在成片某处)。 - 产物:`{集目录}\{类}S1E01_736p_opener.mp4` / `_ender.mp4` + `_{片头,片尾}_样帧.png`(样帧供人眼确认)。 --- ## 7. 台词入清单 + TTS 1. 台词写进 `02_资产\声音\台本\_录音清单.csv`(**BOM + CRLF,必须二进制追加**,`集` 列用 `B001`/`C001`): `集,镜次,说话人,音色ID,台词,来源` 2. 音色 ID 必须在 **`声音资产注册表.csv`** 里有条目、且**已在 `voicebank.py` 的 `VOICE_ASSIGN` 里映射**(否则 `--batch` fail-closed 拒绝)。B/C 现有映射:`A-VO-G-SHAO-01→shao_c`(B 类主讲=邵公,映射 A1 列)、`A-VO-G-REC-01→rec_a`(B 类书生)、 `B-VO-G-NARR-01→narr_c`(**保留登记但 B 类已改对谈、不再使用**)、`C-VO-G-SHAO-01→shao_c`。 **C 类不设辅助旁白**(原 `C-VO-G-NARR-01` 于 2026-10 删除,旁白基座归 `A-VO-G-NARR-01`)。 3. 生成: ```bash python 00_工程管理/工具/声音/voicebank.py --url "<实例>" \ --batch "02_资产/声音/台本/_录音清单.csv" --only B001 # C 用 --only C001 ``` - 产物:`02_资产\声音\_synth\lines\{音色ID}__{镜次}[-NN].wav`(同镜多条自动加序号)。 - 音色母版的权威副本在 `02_资产\声音\_audition\`;换实例后远端音色丢失时用 `--save` 重建。 --- ## 8. 人声轨(把整集台词排成一条) ```bash python 00_工程管理/工具/make_voice.py --class B # C 用 --class C ``` - 产物:`{集目录}\{类}S1E01_736p_voice.wav`(48kHz / mono / 24bit,长度=各镜总长,**不含片头片尾**)。 - 秒点口径与 `assemble.py --dialogue_plan` 完全一致;无台词处静音。 - **默认取实测镜长**(分镜已按新时长重出时必须如此);分镜还没出、或镜位未更新时用 `--nominal`。 - ⚠ `make_voice.py` 的 `--class` 里存着各类的分镜目录;**分镜一旦换落点(如迁进 `h3/`),必须同步改 `CFG`**——否则它会打印 `⚠ … 退回标称` 后继续跑(半静默降级)。 --- ## 9. 成片 / 混音版 ```bash # 无声版(片头 + 各镜 + 片尾,各镜原生音轨) python 00_工程管理/工具/stitch_final.py \ --opener "05_成片/B类/S1E01/B类S1E01_736p_opener.mp4" \ --shots-root "05_成片/B类/S1E01/h3" --shots B01,B02,B03,B04,B05 \ --ender "05_成片/B类/S1E01/B类S1E01_736p_ender.mp4" \ --out "05_成片/B类/S1E01/B类S1E01_736p_final.mp4" # 混音版(再加 --voice,另存 _mix.mp4,不覆盖无声版) ... --voice "05_成片/B类/S1E01/B类S1E01_736p_voice.wav" --out "..._final_mix.mp4" ``` - 人声轨时间轴起点=**各镜**起点、成片起点=**片头**,故 `stitch_final` 自动按**片头实测时长**延迟叠加;原音降 `volume=0.35` 垫底(口径同 `assemble.py --audio-mix`)。 - C 类不给 `--ender`。 - **最终混音由用户合成**(需先分离合并分镜的人声与环境音)——我方交付到「各镜 + 人声轨 + 字幕」为止。 ### 9.1 字幕轨(.srt,v2 新增) ```bash python 00_工程管理/工具/assemble.py \ --pack "04_工程/{B类,C类}/S1E01/smoke/S1E01_{N}镜全集执行包.md" \ --shots-root "05_成片/{B类,C类}/S1E01/h3" --nominal --ep {B001,C001} \ --srt "05_成片/{B类,C类}/S1E01/{B,C}类S1E01_七寸雪.srt" --dry-run ``` - 台词取自 `_录音清单.csv`;秒点口径 `assemble.srt_from_lines`(镜内顺排,与 `--audio-mix` 同一套)。 - **必须给 `--dry-run`**:不给会继续尝试编码成片(缺素材时直接报错);给 `--dry-run --srt` 时「字幕已写、不编码」。 - `--shots-root` 指向**分镜所在层**(`.\h3`)——否则 `build_concat_list` 取不到素材、在写字幕前就 `raise SystemExit`。 - 产物 `.srt` 入库(`.gitignore` 只忽略媒体),用户在剪映/播放器导入即可当字幕轨。 --- ## 10. 验收(每条都要有真输出,不许"看起来对") | 项 | 命令 / 判据 | |---|---| | 项目门禁 | `npm test` → `tests 72 / pass 72 / fail 0` | | 单镜规格 | `ffmpeg -i <镜>.mp4` → Duration 与**标称逐镜吻合**、`1280x736`、24fps | | 成片规格 | 时长 = 片头 + 各镜之和 (+ 片尾);`1280x736 / h264 Main / 48kHz stereo` | | 人声轨秒点 | `ffmpeg -ss <点> -t <窗> -i