@dsh-gis/dsh-video-studio-skill 1.0.2 → 1.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/CHANGELOG.md +49 -0
  2. package/README.md +84 -108
  3. package/THIRD_PARTY_NOTICES.md +2 -2
  4. package/package.json +1 -1
  5. package/schemas/design.schema.json +5 -5
  6. package/schemas/film.schema.json +31 -31
  7. package/skills/video-studio/SKILL.md +168 -268
  8. package/skills/video-studio/assets/film.json +2 -3
  9. package/skills/video-studio/assets/golden_frames.json +11 -11
  10. package/skills/video-studio/assets/scenes.py +92 -49
  11. package/skills/video-studio/references/{style-packs.md → appearance.md} +17 -15
  12. package/skills/video-studio/references/audio-variation.md +73 -96
  13. package/skills/video-studio/references/audio.md +40 -44
  14. package/skills/video-studio/references/change-impact.md +2 -2
  15. package/skills/video-studio/references/{v08-quality.md → delivery-gates.md} +9 -11
  16. package/skills/video-studio/references/frame-qa.md +47 -15
  17. package/skills/video-studio/references/pipeline.md +4 -4
  18. package/skills/video-studio/references/pitfalls.md +22 -3
  19. package/skills/video-studio/references/proposal.md +19 -36
  20. package/skills/video-studio/references/quality-gates.md +11 -11
  21. package/skills/video-studio/references/scene-authoring.md +2 -2
  22. package/skills/video-studio/references/scene-grammar.md +17 -24
  23. package/skills/video-studio/references/sfx-design.md +7 -5
  24. package/skills/video-studio/references/web-engine.md +7 -7
  25. package/skills/video-studio/references/word-timeline.md +7 -7
  26. package/skills/video-studio/requirements.txt +9 -13
  27. package/skills/video-studio/scripts/designkit.py +84 -89
  28. package/skills/video-studio/scripts/filmcheck.py +19 -19
  29. package/skills/video-studio/scripts/filmkit.py +2949 -2948
  30. package/skills/video-studio/scripts/gates.py +4 -4
  31. package/skills/video-studio/scripts/grammar.py +10 -10
  32. package/skills/video-studio/scripts/musicgen.py +3 -4
  33. package/skills/video-studio/scripts/preflight.py +5 -5
  34. package/skills/video-studio/scripts/previewkit.py +11 -12
  35. package/skills/video-studio/scripts/propose.py +11 -11
  36. package/skills/video-studio/scripts/qa_frames.py +34 -35
  37. package/skills/video-studio/scripts/qaasr.py +26 -7
  38. package/skills/video-studio/scripts/qavmaf.py +19 -19
  39. package/skills/video-studio/scripts/render.py +137 -141
  40. package/skills/video-studio/scripts/scorekit.py +21 -23
  41. package/skills/video-studio/scripts/selfcheck.py +208 -135
  42. package/skills/video-studio/scripts/sfxkit.py +27 -26
  43. package/skills/video-studio/scripts/stagewatch.py +4 -4
  44. package/skills/video-studio/scripts/stylekit.py +77 -282
  45. package/skills/video-studio/scripts/voicekit.py +43 -44
  46. package/skills/video-studio/scripts/webengine.py +62 -64
  47. package/tools/audio_similarity.py +12 -12
  48. package/tools/ci_check.py +16 -16
  49. package/tools/estimate.py +24 -25
  50. package/tools/golden_frames.py +17 -18
  51. package/tools/silhouette_qa.py +13 -14
package/CHANGELOG.md CHANGED
@@ -6,6 +6,55 @@
6
6
  与 `package.json` 的 `version` 字段只差前缀。历史上曾同时出现 `0.7.1` 与 `v0.7.1` 两种写法
7
7
  (前者指向一个未推送的孤儿提交,已删除),此后不再产生不带 `v` 的 tag。
8
8
 
9
+ ## 1.0.4 — 全项目去历史化:文档与注释只描述当前版本(2026-11-12)
10
+
11
+ > 依据:一次全项目审查。v1.0.3 之前每个版本都在文档里留了一层"我以前怎么错、现在怎么对"的叙述,
12
+ > 累积结果是**读文档的人要自己判断哪句是现状、哪句是考古**——SKILL.md 1317 行里 125 处版本标记,
13
+ > 15 篇 references 里 92 处,19 个脚本里 496 处。本版不动任何行为,只做一件事:
14
+ > **把「当前怎么工作」和「历史上曾经怎样」切开,前者留下,后者交给这份 CHANGELOG。**
15
+
16
+ | 项 | 内容 |
17
+ |---|---|
18
+ | 范围 | SKILL.md / README.md / 15 篇 references / scripts 注释与 docstring / tools |
19
+ | 删掉的四类 | ① 标题与正文里的版本标签 ② "以前…现在…/旧版/早期实现"的考古句 ③ 迁移表与"已删除的东西"章节 ④ 过时计数与已删目录引用 |
20
+ | 保留的 | 全部阈值、判据、命令、字段名、实测数字、坑与验收口径;代码里的因果解释改成现在时 |
21
+ | 删掉的死代码 | `stylekit` 的 `style_ids / get / theme_of / is_legacy / visual_lint_all / lint_all / fingerprint / _digest / _text_of / _pick_from_pool / _as_bool / _persona_to_voice_id / _warn_auto_style_once / blend_theme` 与 `_PERSONA_VOICE`(无调用者;其中 `lint_all` 引用的 `THEMES` 已空,调用即 NameError) |
22
+ | 结构性调整 | SKILL.md 的「升级须知」整节删除,原 §14「换机自检」升为 §13;README 去掉"历史快照图片"段落与版本演进口径;ci.yml 的断言计数对齐为 69 |
23
+ | 兼容性 | `resolve_script_style` 的 fail-closed 报错、`STYLE_IDS == ()` 契约、三张空表(`STYLES`/`THEMES`/`VISUAL_LANGUAGES`)全部保留——它们是"没有模板"这一契约的执行点,selfcheck 第 57/64 条守着 |
24
+
25
+ 自检 **69 条全绿**,`tools/ci_check.py` **12 项全绿**。
26
+
27
+ ## 1.0.3 — 真实会话复盘:从 46 个视频会话里修掉"用户说得出、门禁查不到"的两类缺陷(2026-11-12)
28
+
29
+ > 依据:本机 46 个未归档视频会话(2026-11-08 ~ 11-11)逐条回放,统计了 8308 次工具调用、
30
+ > 150 条工具错误、18 个多轮会话里用户的每一次"不对"反馈。只改有实测证据的:
31
+ > ① 整片发抖(用户原话"明显的抖动感")② ASR 掉分说不清掉在哪。
32
+
33
+ ### P0:整片抖动(噪声沸腾)—— 现有门禁全绿也挡不住
34
+
35
+ | 项 | 内容 |
36
+ |---|---|
37
+ | 现象 | 用户:"生成的视频有明显的抖动感,这是为啥?" 而 `flicker_scan` 0 条、VMAF 97+、SSIM 0.999 |
38
+ | 根因 | 底图把颗粒烘进静态图层,逐帧用 `EXTENT + NEAREST` 按缓推比例取景;采样网格随 `s` 整像素跳变,颗粒整体错位 1px。实测背景-only 相邻帧差 4~6 灰阶 |
39
+ | 为什么漏 | 这是**位移型**瑕疵;单帧闪烁判据比的是前后帧平均亮度(**亮度型**),对它天然不敏感 |
40
+ | 修法 | `_plate_zoom`:`s=1.0` 与 `s=1+push` 端点各烘一张 BILINEAR 底版(60 ms 一次性),逐帧 `Image.blend` 插值(4.4 ms/帧)。相邻帧差降到 0~1 灰阶 |
41
+ | 为什么不用 BILINEAR/BICUBIC 直采 | 整帧重采样 29 / 64 ms,超 15 ms 单帧预算(实测) |
42
+ | 护栏 | `selfcheck` 第 68 条 `t_zoom_stability`:20 帧缓推,相邻帧最大差 <= 2 灰阶。旧实现在这条上 fail |
43
+ | 金帧基线 | 画面确实变了(取景改平滑),`tools/golden_frames.py --write` 已重录 |
44
+
45
+ ### P1:ASR 掉分说不清掉在哪(可解释性)
46
+
47
+ `qaasr` 以前只报"召回 0.813 < 0.85",agent 拿到这句不知道改哪。现在低于 pass 线时会额外列出
48
+ **"剧本里有、成片里没对上"的字符 Top-12(带次数)**,并写进 `--asr-json` 的 `lost_top`。
49
+ 实测掉分点几乎全是中英混排专名(DeepSeek 4.1 Flash / 3DGS / 实景三维),有了这份清单就能改写法或
50
+ 在 `film.json` 的 `qa.asr` 按片放宽,而不是盲目调阈值。
51
+
52
+ ### 其它
53
+
54
+ - `references/frame-qa.md` 新增 §11「取景抖动(噪声沸腾)」:现象 / 根因 / 10 秒探测脚本 / 修法 / 护栏。
55
+ - `references/pitfalls.md`:反模式 17 条,补复盘 ④(含"质检要按瑕疵的物理类型分类"的教训)。
56
+ - 文档里"EXTENT + NEAREST,1.7~3.5ms"这类过时描述同步改成端点 blend 的实际数字。
57
+
9
58
  ## 1.0.2 — 审查修复:把"文档写着支持、实际不生效"的一批缺陷修掉;零拷贝出片;片内/片间双重反重复(2026-11-11)
10
59
 
11
60
  > 本轮是**全项目审查**(文档 / 脚本 / 可用性 / 成本四个方向并行实测)后的修复版。
package/README.md CHANGED
@@ -1,65 +1,37 @@
1
1
  # @dsh-gis/dsh-video-studio-skill
2
2
 
3
- ![version](https://img.shields.io/badge/version-1.0.2-blue) ![license](https://img.shields.io/badge/license-MIT-green)
3
+ ![version](https://img.shields.io/badge/version-1.0.4-blue) ![license](https://img.shields.io/badge/license-MIT-green)
4
4
 
5
5
  **DeepSeek Harness 技能插件:用代码从零生成中文视频。**
6
6
 
7
7
  写剧本 → edge-tts 旁白 → **实测时长**排时间轴 → **提示点**驱动配乐与音效 → PIL 或浏览器逐帧渲染 →
8
- ffmpeg 编码 → 采样级混音 → **四层质检**(容器 / 信号 / 时间 / 页面)+ **v0.8 的四个新闸**
8
+ ffmpeg 编码 → 采样级混音 → **四层质检**(容器 / 信号 / 时间 / 页面)+ **四道新闸**
9
9
  (渲前资源预检 `G0` / 词级时间戳 `G10` / 全片 VMAF `G11` / ASR 回读 `G12`)。
10
10
  零素材、可复现、可断点续跑、可脚本化验收;装成插件后,整片生产流程随技能一起进入每个会话。
11
11
 
12
- > **v1.0.2(当前)**:**零拷贝出片**——技能脚本留在技能目录里直接跑,工程目录里只需要一个 `film.json`;
13
- > `render.py` 不写 `--scenes` 就先用剧本同目录的 `scenes.py`、再回落到技能内置的 `assets/scenes.py`,
14
- > 不需要再拷脚本/模板。设计与画面新增两块可调:**字幕样式** `visual.subtitle`
15
- > (字号/位置/对齐/背板透明度/圆角/字族/颜色/最多几行,不写 = 与过去逐像素一致)与
16
- > **片内版式轮换** `visual.layout_cycle`(按章节换骨架,默认派生 2–3 种,防"全片一张版式")。
17
- > 同时修掉一批"照文档做就崩"的命令(`--stage style` 不再 KeyError、`--stage cues` 可单跑、
18
- > 已删除 API 改为明确报错 exit 2 而不是 NameError/假绿),并给"不同片不重复"加了**片间去重台账**
19
- > (`--confirm` 记录交付过的设计,下次提案主动避开)。
20
- > 另外 brief 里写「2 分钟 / 90 秒」现在会被接住:解析成 `duration_target`,决定候选段落数,
21
- > 渲染时对账并在差 >15% 时告警——但**成片长度仍由实测旁白决定,不会截断**。自检 **67 条**全绿。
22
-
23
- > 源自 `dsh-v` 资产包的 `02-技能包-video-studio`(817 个 DSH 会话的考古分析 + 5 套现存工程逆向 + 本机实测)。
24
- > 版本演进与每一版的实测证据都在 [CHANGELOG.md](CHANGELOG.md);这里只留一句方向:
25
- > **v1.0 起不再提供任何模板/风格目录**——技能给的是「生成视频的技术」,外观由每次现场采样的设计决定。
26
- >
27
- > 重要节点:v0.6 交付可信化(门禁账本 / QC 报告 / 签核)→ v0.7 声音片间差异 → v0.8 词级时间轴 + 四道新门禁
28
- > → v0.9 场景语法(10 类构图)与视觉语言 → **v1.0 提案优先**(先出方案再出片)→ **v1.0.1 清除全部模板**
29
- > → **v1.0.2 零拷贝 + 可定制字幕/版式轮换 + 片间去重台账**。
30
- >
31
- > 想直接看「这一版改了什么、为什么改、怎么验证」,读 [CHANGELOG.md](CHANGELOG.md) 的 1.0.2 段;
32
- > 想学怎么控制画面/声音/节奏,读 [SKILL.md](skills/video-studio/SKILL.md)。
33
- ## 安装
34
-
35
- 桌面版:插件管理器 → 填 `@dsh-gis/dsh-video-studio-skill`(或你的本地 checkout 目录,如 `D:/path/to/dsh-video-studio-skill`)
36
-
37
- 命令行:
38
-
39
- ```bash
40
- dsh plugin --profile desktop add "@dsh-gis/dsh-video-studio-skill"
41
- # 本地调试(不发布也能装):
42
- dsh plugin --profile desktop add "D:/path/to/dsh-video-studio-skill"
43
- ```
44
-
45
- 安装后在「插件」页启用 `video-studio` 这一行,新开会话即可在技能目录看到 **video-studio**。
46
-
47
- ### 与手工技能目录的关系
48
-
49
- 技能按 rank 解析:`~/.dsh/skills`(rank 400)**优先于**插件提供的 bundled 技能根(rank 600)。
50
- 如果你之前手工装过 `~/.dsh/skills/video-studio`,它会把插件版本遮住。装好插件后**把旧目录移出 `~/.dsh/skills` 根目录**(只改名不够——扫描认的是 `<root>/<name>/SKILL.md`,`.bak` 后缀的目录照样会被扫到):
51
-
52
- ```bash
53
- mkdir -p ~/.dsh/backup
54
- mv ~/.dsh/skills/video-studio ~/.dsh/backup/video-studio.bak-$(date +%Y%m%d)
55
- ```
12
+ ## 这个技能解决什么
56
13
 
57
- 需要回滚时把目录移回 `~/.dsh/skills/video-studio` 即可。
14
+ | 你的痛点 | 它的做法 |
15
+ |---|---|
16
+ | 音画不同步 | 时间轴由 TTS **实测时长**反推,绝不按字数估算 |
17
+ | 文字发虚 | PIL 帧走 `rawvideo` 直通 libx264,不用 cv2 中间文件二次压缩 |
18
+ | 后半段静音 | numpy 采样级混音,不用一条 ffmpeg 命令喂上百个输入 |
19
+ | 该有的淡入/字幕静默消失 | 质检门禁查"必须有"和"不能有"两类断言 |
20
+ | 成片"像草稿" | -16 LUFS / 真峰 ≤ -1 dBTP / 编码锐度比 ≥ 0.85 |
21
+ | 声音和画面对不上 | **提示点系统**:画面登记 cue → 音效按 cue 合成,改节奏不用重新对时间 |
22
+ | 声音单薄、只有"叮叮咚咚" | `sfxkit` 物理建模音效 + `musicgen` 按参数现场编排配乐(没有现成曲风可选) |
23
+ | 一帧白闪/两秒空窗没人发现 | `qa_frames` 帧级深检:单帧闪烁、画面空窗、音画同步、画面静止 |
24
+ | "我查过了"无法复现 | `out/QC-REPORT.md` + `work/gates.json`:三档 gate matrix,"没执行"独立成 `skipped` |
25
+ | "我签过了"变成空头支票 | 签核绑内容指纹:改剧本 / `scenes.py` / 引擎,旧签核自动失效 |
26
+ | 改一句台词不知道要重跑什么 | `work/manifest.json` 记每阶段输入/输出指纹,`--stage explain` 直接给最小重跑命令 |
27
+ | `holds` 写成拼写错误却静默失效 | `schemas/film.schema.json` + `filmcheck.py`,并接进 `ci_check` 第 12 项 |
28
+ | 机器替你选风格、你从头到尾没参与 | **提案优先**:`propose.py` 先出 N 个候选(各带静帧联系表 + 设计距离),人 `--confirm` 后才冻结 `design.json` |
29
+ | 每个视频都差不多 | 设计 DSL 现场采样(每次新 nonce)+ 候选两两 ≥2 维不同 + 底色色相分叉 + **片间去重台账** |
30
+ | 外观只能从几套模板里挑 | 没有内置风格表:配色是连续色相空间、母题/转场/缓动/版式/字幕全字段开放,且必须过 `theme_lint` 与 G13 剪影门禁 |
58
31
 
59
32
  ## 效果:同一个 brief,两次就是两部不同的片(可复现)
60
33
 
61
- 这一节不贴"宣传图"——**贴的是你现在就能跑出来的东西**。向同一个 brief 连续提案两次,
62
- 配色、母题、转场、配乐、声线、版式轮换、字幕样式都会不同(这就是 v1.0 提案优先 + v1.0.2 片间去重的目标):
34
+ 向同一个 brief 连续提案两次,配色、母题、转场、配乐、声线、版式轮换、字幕样式都会不同:
63
35
 
64
36
  ```bash
65
37
  # 第一轮:看 3 个候选并排(每个候选 = 一份完整设计 + 静帧联系表 + 与其它候选的设计距离)
@@ -73,10 +45,9 @@ python <SKILL_DIR>/scripts/propose.py --brief "AI 大模型的三年,30 秒科
73
45
  python <SKILL_DIR>/scripts/propose.py --brief "AI 大模型的三年,30 秒科普,深蓝" --script film.json --work work2
74
46
  ```
75
47
 
76
- > 实测(作者机器,2026-11-11):同一 brief 连跑 3 次,9 个候选的 `design_fingerprint` **两两不同**;
48
+ > 实测(作者机器):同一 brief 连跑 3 次,9 个候选的 `design_fingerprint` **两两不同**;
77
49
  > 每批 3 个候选的 `layout_cycle` 都是 2–3 种版式,`subtitle` 的字号/对齐/背板透明度/圆角/字族也各不相同。
78
- > 带「深蓝」这类配色约束时,v1.0.2 之前 n=3 有近一半概率采样失败(约束窗口只有 52°,
79
- > 而旧实现按 24° 分桶判重),现在实测 **10/10 成功**。
50
+ > 带「深蓝」这类配色约束时,实测 **10/10 成功**。
80
51
 
81
52
  **三个可复现的卖点**:
82
53
 
@@ -90,9 +61,34 @@ python <SKILL_DIR>/scripts/propose.py --brief "AI 大模型的三年,30 秒科
90
61
  compare / process / quote / chapter / chart / outro)× 8 种装饰母题 × 6 种转场 × 连续色相配色 ×
91
62
  字幕样式 × 按章节轮换的版式——而且每个候选都要过 `theme_lint` 对比度体检和 G13 剪影可区分门禁。
92
63
 
93
- > 说明:仓库里的 `docs/` 图片是 **v0.5/v0.9 时期的历史快照**,对应的 `style:auto` 选型与风格表
94
- > 在 v1.0.1 已删除,**这些图不能再当"现在跑出来就是这样"的证据**,所以本 README 不再引用它们。
95
- > 现在的证据是**命令 + 你机器上的实测输出**。
64
+ > 证据是**命令 + 你机器上的实测输出**,不是截图:这份仓库里没有"参考成片",
65
+ > 因为每次采样的外观都不一样,任何一张图都只代表某一次跑的结果。
66
+
67
+ ## 安装
68
+
69
+ 桌面版:插件管理器 → 填 `@dsh-gis/dsh-video-studio-skill`(或你的本地 checkout 目录,如 `D:/path/to/dsh-video-studio-skill`)
70
+
71
+ 命令行:
72
+
73
+ ```bash
74
+ dsh plugin --profile desktop add "@dsh-gis/dsh-video-studio-skill"
75
+ # 本地调试(不发布也能装):
76
+ dsh plugin --profile desktop add "D:/path/to/dsh-video-studio-skill"
77
+ ```
78
+
79
+ 安装后在「插件」页启用 `video-studio` 这一行,新开会话即可在技能目录看到 **video-studio**。
80
+
81
+ ### 与手工技能目录的关系
82
+
83
+ 技能按 rank 解析:`~/.dsh/skills`(rank 400)**优先于**插件提供的 bundled 技能根(rank 600)。
84
+ 如果你之前手工装过 `~/.dsh/skills/video-studio`,它会把插件版本遮住。装好插件后**把旧目录移出 `~/.dsh/skills` 根目录**(只改名不够——扫描认的是 `<root>/<name>/SKILL.md`,`.bak` 后缀的目录照样会被扫到):
85
+
86
+ ```bash
87
+ mkdir -p ~/.dsh/backup
88
+ mv ~/.dsh/skills/video-studio ~/.dsh/backup/video-studio.bak-$(date +%Y%m%d)
89
+ ```
90
+
91
+ 需要回滚时把目录移回 `~/.dsh/skills/video-studio` 即可。
96
92
 
97
93
  ## 用法(零拷贝:不拷脚本、不拷模板)
98
94
 
@@ -105,7 +101,7 @@ compare / process / quote / chapter / chart / outro)× 8 种装饰母题 × 6
105
101
  mkdir -p myfilm && cd myfilm
106
102
  # 1) 只写一个 film.json(工程目录里唯一需要你手写的文件;最小骨架见 SKILL.md §1)
107
103
 
108
- # 2) 环境自检(可选,67 条断言,不联网)
104
+ # 2) 环境自检(可选,69 条断言,不联网)
109
105
  python <SKILL_DIR>/scripts/selfcheck.py
110
106
 
111
107
  # 3) 先出方案:3 个候选,各带静帧联系表;2 秒级、全程离线
@@ -135,8 +131,8 @@ python <SKILL_DIR>/scripts/render.py --script film.json --work work --stage acce
135
131
  | 想控制 | 改哪里 | 怎么验证 |
136
132
  |---|---|---|
137
133
  | 画面配色/字体/装饰/转场/版式 | `work/design.json` 的 `visual.*`(或重新提案 `--revise`) | `render.py --stage style`;`designkit.py --lint work/design.json` |
138
- | 字幕字号/位置/对齐/背板/圆角/字族/颜色/行数 | `visual.subtitle`(v1.0.2) | `--stage style` 打印的「字幕」行;改前后抽帧对比 |
139
- | 片内版式轮换(防全片一张版式) | `visual.layout_cycle`(v1.0.2),不写则自动派生 2–3 种 | `work/storyboard.json` 每段的 `layout` |
134
+ | 字幕字号/位置/对齐/背板/圆角/字族/颜色/行数 | `visual.subtitle` | `--stage style` 打印的「字幕」行;改前后抽帧对比 |
135
+ | 片内版式轮换(防全片一张版式) | `visual.layout_cycle`,不写则自动派生 2–3 种 | `work/storyboard.json` 每段的 `layout` |
140
136
  | 这段画面的构图类型 | `film.json` 的 `lines[].type`(10 类之一),不写由 grammar 选 | `--stage layout` 打印的分镜表 |
141
137
  | 配乐调式/BPM/调性/情绪 | `work/design.json` 的 `audio.music.*`(`film.json` 的 `music.*` 可覆盖) | `--stage score` 的打印 + 听 |
142
138
  | 旁白声线与语气 | `audio.voice.*`(裸 edge voice id + tone);`voicekit.py --list` 查音色 | `--stage tts`;`work/voice_plan.json` |
@@ -162,26 +158,6 @@ python <SKILL_DIR>/scripts/render.py --script film.json --work work --stage acce
162
158
 
163
159
  长片:`--stage frames --jobs 4`(按绝对帧号分块并行)+ `--resume`(中断只补缺块)。
164
160
 
165
- ## 这个技能解决什么
166
-
167
- | 铁律 | 怎么保证 |
168
- |---|---|
169
- | 音画不同步 | 时间轴由 TTS **实测时长**反推,绝不按字数估算 |
170
- | 文字发虚 | PIL 帧走 `rawvideo` 直通 libx264,不用 cv2 中间文件二次压缩 |
171
- | 后半段静音 | numpy 采样级混音,不用一条 ffmpeg 命令喂上百个输入 |
172
- | 该有的淡入/字幕静默消失 | 质检门禁查"必须有"和"不能有"两类断言 |
173
- | 成片"像草稿" | -16 LUFS / 真峰 ≤ -1 dBTP / 编码锐度比 ≥ 0.85 |
174
- | **声音和画面对不上(v0.3)** | **提示点系统**:画面登记 cue → 音效按 cue 合成,改节奏不用重新对时间 |
175
- | **声音单薄、只有"叮叮咚咚"(v0.3)** | `sfxkit` 物理建模音效 + `musicgen` 按参数现场编排配乐(没有现成曲风可选) |
176
- | **一帧白闪/两秒空窗没人发现(v0.3)** | `qa_frames` 帧级深检:单帧闪烁、画面空窗、音画同步 |
177
- | **"我查过了"无法复现(v0.6)** | `out/QC-REPORT.md` + `work/gates.json`:三档 gate matrix,"没执行"独立成 `skipped` |
178
- | **"我签过了"变成空头支票(v0.6)** | 签核绑内容指纹:改剧本 / `scenes.py` / 引擎,旧签核自动失效 |
179
- | **改一句台词不知道要重跑什么(v0.6)** | `work/manifest.json` 记每阶段输入/输出指纹,`--stage explain` 直接给最小重跑命令 |
180
- | **`holds` 写成拼写错误却静默失效(v0.6)** | `schemas/film.schema.json` + `filmcheck.py`,并接进 `ci_check` 第 12 项 |
181
- | **机器替你选风格、你从头到尾没参与(v1.0)** | **提案优先**:`propose.py` 先出 N 个候选(各带静帧联系表 + 设计距离),人 `--confirm` 后才冻结 `design.json` |
182
- | **每个视频都差不多(v1.0/v1.0.2)** | 设计 DSL 现场采样(每次新 nonce)+ 候选两两 ≥2 维不同 + 底色色相分叉 + **片间去重台账**(默认记录交付过的设计并主动避开) |
183
- | **外观只能从几套模板里挑(v1.0.1)** | 没有内置风格表:配色是连续色相空间、母题/转场/缓动/版式/字幕全字段开放,且必须过 `theme_lint` 与 G13 剪影门禁 |
184
-
185
161
  ## 文件结构
186
162
 
187
163
  ```
@@ -191,23 +167,23 @@ icon.svg / locale/*.json 插件页展示元数据
191
167
  skills/video-studio/
192
168
  SKILL.md 主线:零拷贝上手 / 提案 / 设计 DSL / 八阶段 / 引擎 / 画质 / 声音 / 提示点 / 质检 / 升级
193
169
  references/ proposal · scene-grammar · pipeline · scene-authoring · audio · audio-variation
194
- sfx-design · web-engine · frame-qa · quality-gates · word-timeline · v08-quality
195
- change-impact · style-packs(v1.0.2 重写为设计 DSL 外观定制)· pitfalls
196
- scripts/propose.py v1.0 提案器(--brief/--revise/--confirm/--diff;v1.0.2 片间去重台账)
197
- scripts/designkit.py v1.0 设计 DSL(采样/校验/转计划/设计距离/字幕参数)
198
- scripts/previewkit.py v1.0 离线预览(合成时间轴 + 联系表,不联网)
199
- scripts/grammar.py v0.9 场景语法(10 类构图 -> storyboard.json)
200
- scripts/voicekit.py v1.0 声线/语气计划(裸 edge voice id + 响度补偿)
170
+ sfx-design · web-engine · frame-qa · quality-gates · word-timeline · delivery-gates
171
+ change-impact · appearance · pitfalls
172
+ scripts/propose.py 提案器(--brief/--revise/--confirm/--diff + 片间去重台账)
173
+ scripts/designkit.py 设计 DSL(采样/校验/转计划/设计距离/字幕参数)
174
+ scripts/previewkit.py 离线预览(合成时间轴 + 联系表,不联网)
175
+ scripts/grammar.py 场景语法(10 类构图 -> storyboard.json)
176
+ scripts/voicekit.py 声线/语气计划(裸 edge voice id + 响度补偿)
201
177
  scripts/filmkit.py 生产内核(字体/排版/字幕/音频总线/CueBus/TTS/时间轴/编码/质检)
202
- scripts/gates.py v0.6 门禁账本 / QC 报告渲染 / 人工签核(绑内容指纹)
203
- scripts/stagewatch.py v0.6 阶段新鲜度(work/manifest.json + --stage explain)
204
- scripts/filmcheck.py v0.6 film.json 契约校验(未知键/枚举/跨字段;style 键为 inert 警告)
178
+ scripts/gates.py 门禁账本 / QC 报告渲染 / 人工签核(绑内容指纹)
179
+ scripts/stagewatch.py 阶段新鲜度(work/manifest.json + --stage explain)
180
+ scripts/filmcheck.py film.json 契约校验(未知键/枚举/跨字段;style 键为 inert 警告)
205
181
  scripts/render.py 编排器(14 个 stage、pil|web 双引擎、分块并行、断点续跑、母版预览、门禁账本;
206
- v1.0.2 起 --scenes 缺省回落到技能内置 scenes.py)
207
- scripts/preflight.py v0.8 渲染前资源预检(字形 / TTS 音频 / 字体 / web 入口页,门禁 G0)
208
- scripts/qavmaf.py v0.8 全片 VMAF/SSIM(参考帧由场景函数实时重渲,门禁 G11)
209
- scripts/qaasr.py v0.8 ASR 回读(成片音轨转文字对账,门禁 G12)
210
- scripts/selfcheck.py 回归自检(67 条"曾真的坏过"的断言)
182
+ --scenes 缺省回落到技能内置 scenes.py)
183
+ scripts/preflight.py 渲染前资源预检(字形 / TTS 音频 / 字体 / web 入口页,门禁 G0)
184
+ scripts/qavmaf.py 全片 VMAF/SSIM(参考帧由场景函数实时重渲,门禁 G11)
185
+ scripts/qaasr.py ASR 回读(成片音轨转文字对账,门禁 G12)
186
+ scripts/selfcheck.py 回归自检(69 条针对真实缺陷的断言)
211
187
  scripts/sfxkit.py 物理建模音效库(24 配方,scipy 可选)
212
188
  scripts/scorekit.py 配乐合成原语(和声 / 律动 / 混音 / 响度 / 24-bit 落盘)
213
189
  scripts/musicgen.py 参数化配乐编排器(没有风格表:和弦进行 / 动机 / 鼓型 / 音色全可传参)
@@ -218,15 +194,15 @@ skills/video-studio/
218
194
  assets/scenes.py 技能内置渲染器(10 类构图 + draw_frame + cues() 钩子;--scenes 的默认回退)
219
195
  assets/design_fixture.json 金帧基准设计(像素回归绑它,不绑任何内置风格)
220
196
  assets/voice_loudness.json 音色响度补偿实测表
221
- assets/golden_frames.json v0.8 金帧基线(3 帧 sha256 + 字体/环境指纹,改绘制代码后重录)
197
+ assets/golden_frames.json 金帧基线(3 帧 sha256 + 字体/环境指纹,改绘制代码后重录)
222
198
  assets/web/ 浏览器页面示例(--engine web 需要你自己的页面;不是出片模板)
223
- schemas/design.schema.json 设计 DSL 契约(v1.0;含 visual.subtitle / layout_cycle)
224
- schemas/proposal.schema.json 提案契约(v1.0)
199
+ schemas/design.schema.json 设计 DSL 契约(含 visual.subtitle / layout_cycle)
200
+ schemas/proposal.schema.json 提案契约
225
201
  schemas/film.schema.json film.json 的契约(draft-07 子集)
226
202
  tools/ci_check.py 仓库级体检(12 项;语法/JSON/依赖白名单/打包卫生/文档引用/film 契约,不需 ffmpeg)
227
203
  tools/estimate.py 开渲前成本预演(帧数/耗时/磁盘/分块建议,--json 可机读;含 preflight/vmaf/asr)
228
- tools/golden_frames.py v0.8 金帧像素回归(--write 重录 / --check 校验;同环境像素变了 = fail)
229
- tools/silhouette_qa.py v0.9 剪影可区分门禁 G13(换设计不能只是换色)
204
+ tools/golden_frames.py 金帧像素回归(--write 重录 / --check 校验;同环境像素变了 = fail)
205
+ tools/silhouette_qa.py 剪影可区分门禁 G13(换设计不能只是换色)
230
206
  tools/audio_similarity.py 音频差异/相似度验收(--strict 阈值判定,改音频代码后必跑)
231
207
  tools/selftest_noscipy.py 无 scipy 兜底路径自检(CI 用;屏蔽 scipy 后跑 sfxkit/musicgen 自检)
232
208
  .github/workflows/ci.yml CI:repo 体检(ubuntu+windows)+ 技能自检(ubuntu)
@@ -238,8 +214,8 @@ tools/selftest_noscipy.py 无 scipy 兜底路径自检(CI 用;屏蔽 scip
238
214
  **必需**:ffmpeg + Python 的 numpy / Pillow / edge-tts。
239
215
  **可选**:cv2(编码锐度比)、scipy(音效滤波加速,缺了走 FFT 卷积)、
240
216
  playwright + Chromium/Edge(只在 `--engine web` 时需要)、
241
- faster-whisper(v0.8 的 ASR 回读门禁 G12;没装会降级到 ffmpeg whisper 滤镜,仍不可用则记 skipped)。
242
- v0.8 的 G11(全片 VMAF)不需要新依赖,但要求 ffmpeg 构建**带 libvmaf**(9.0.2 full_build 有)。
217
+ faster-whisper(ASR 回读门禁 G12;没装会降级到 ffmpeg whisper 滤镜,仍不可用则记 skipped)。
218
+ G11(全片 VMAF)不需要新依赖,但要求 ffmpeg 构建**带 libvmaf**(9.0.2 full_build 有)。
243
219
  不需要 moviepy / pydub / soundfile / librosa / manim——本技能一行都不 import 它们。
244
220
 
245
221
  依赖清单有机器可读的一份,别再手抄:
@@ -248,7 +224,7 @@ v0.8 的 G11(全片 VMAF)不需要新依赖,但要求 ffmpeg 构建**带 l
248
224
  pip install -r skills/video-studio/requirements.txt # 必需 + 强烈建议;可选项目已注释,按需打开
249
225
  ```
250
226
 
251
- `SKILL.md` 第 12 节是作者机器(Windows 11 + Ryzen AI 9 HX 370)的实测基准,**换机请先重测**:
227
+ `SKILL.md` 第 12 节是参考机器(Windows 11 + Ryzen AI 9 HX 370)的实测基准,**换机请先重测**:
252
228
  `ffmpeg -version`、`python -c "import numpy,PIL,cv2"`、中文字体文件、`edge-tts --list-voices`。
253
229
  ffmpeg 路径可用环境变量 `FILMKIT_FFMPEG` 覆盖,字体候选在 `filmkit.FONT_CANDIDATES`。
254
230
 
@@ -269,19 +245,19 @@ peer 范围 `@deepseek-ai/dsh-skill-filesystem >=0.1.0-rc.6 <0.3.0-0`,覆盖 D
269
245
 
270
246
  ```bash
271
247
  python tools/ci_check.py -v # 12 项:py 语法(含 tools/,SyntaxWarning 记失败)/ node --check /
272
- # JSON + 版本号一致性(package.json vs README 徽章)/ 技能清单 /
273
- # 依赖白名单 / npm pack 打包卫生 / 文档路径 + 正文相对链接 /
274
- # Python 3.9 语法 / Markdown 围栏(状态机)/ CI workflow
275
- # (裸冒号 + run 里的 python 脚本是否存在)/ 单文件体积 /
276
- # film.json 契约(调 filmcheck.py,规则只留一份)
248
+ # JSON + 版本号一致性(package.json vs README 徽章 vs CHANGELOG)/
249
+ # 技能清单 / 依赖白名单 / npm pack 打包卫生 /
250
+ # 文档路径 + 正文相对链接 / Python 3.9 语法 /
251
+ # Markdown 围栏(状态机)/ CI workflow /
252
+ # 单文件体积 / film.json 契约(调 filmcheck.py,规则只留一份)
277
253
  ```
278
254
 
279
255
  它**不需要 ffmpeg、字体或网络**,任何机器都能跑;它检查的是"这个仓库作为可分发包是否完整"。
280
256
  **它不能替代** `skills/video-studio/scripts/selfcheck.py`——那个要 ffmpeg + 中文字体,真的调编码器,
281
- 查的是"技能本身还能不能出片"(**67 条**断言)。两层都在 `.github/workflows/ci.yml` 里跑。
257
+ 查的是"技能本身还能不能出片"(**69 条**断言)。两层都在 `.github/workflows/ci.yml` 里跑。
282
258
 
283
259
  ## License
284
260
 
285
261
  MIT。新增的四个模块(sfxkit / scorekit / webengine / qa_frames)的**算法思想**改编自
286
262
  [ai-history-film](https://github.com/Re-Summer75/ai-history-film)(MIT),未复制其文件、未引入其三方依赖;
287
- 详见 [THIRD_PARTY_NOTICES.md](THIRD_PARTY_NOTICES.md)。
263
+ 详见 [THIRD_PARTY_NOTICES.md](THIRD_PARTY_NOTICES.md)。
@@ -4,13 +4,13 @@
4
4
 
5
5
  ## 1. 算法思想改编(非代码拷贝)
6
6
 
7
- `skills/video-studio/scripts/` 下四个 v0.3.0 新增模块的**算法思想**改编自开源项目
7
+ `skills/video-studio/scripts/` 下四个模块(sfxkit / scorekit / webengine / qa_frames)的**算法思想**改编自开源项目
8
8
  [ai-history-film](https://github.com/Re-Summer75/ai-history-film)(**MIT**,作者 Re-Summer75):
9
9
 
10
10
  | 本项目的文件 | 改编自 | 改编内容 |
11
11
  |---|---|---|
12
12
  | `sfxkit.py` | `sfx/`(core, synth, filters, modal, texture, space, dynamics, analysis, master, recipes) | 模态合成的物理模型(材质损耗因子、形状模态比、接触力脉冲)、泊松/Cox 事件纹理、镜像声源混响、BS.1770 响度与块级动态处理 |
13
- | `scorekit.py` | `video/audio/film_score.py`、`inst.py` | 一张和弦表贯穿全片的编排思路、分段能量与律动层、重击前"吸气"、段落边界对齐小节线(v1.0.1 起只保留这些合成原语;9 套配乐风格表已删除) |
13
+ | `scorekit.py` | `video/audio/film_score.py`、`inst.py` | 一张和弦表贯穿全片的编排思路、分段能量与律动层、重击前"吸气"、段落边界对齐小节线(只保留这些合成原语,不提供曲风表) |
14
14
  | `webengine.py` + `assets/web/` | `video/render.py`、`video/web/js/engine.js` | 无头浏览器逐帧 seek + CDP 截图的确定性渲染流程、分块并行与断点续跑、音效提示点(cue)导出 |
15
15
  | `qa_frames.py` | `video/qa_sync.js`、`video/qa_text.js`、`docs/开发日志.md` | 单帧闪烁的分块判据、画面空窗检测、音画事件同步对照、页面文字重叠/出画/一闪而过检查 |
16
16
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dsh-gis/dsh-video-studio-skill",
3
- "version": "1.0.2",
3
+ "version": "1.0.4",
4
4
  "description": "Video Studio skill plugin for DeepSeek Harness: proposal-first, zero-template code-generated Chinese videos — run the skill's scripts in place (no copying) and keep only a film.json in your project; each brief is sampled into several distinct design candidates (no built-in style packs) and frozen into a design DSL after user confirmation; visual.subtitle / visual.layout_cycle make caption style and per-chapter layout adjustable; a cross-film design ledger keeps delivered videos from repeating; measured TTS timeline, deterministic PIL/browser rendering, programmatic SFX and score, cue-driven sound sync, sample-level mixing, ffmpeg encoding, batch production and multi-layer QA gates (preflight, full-film VMAF/SSIM, ASR readback).",
5
5
  "type": "module",
6
6
  "main": "index.js",
@@ -423,12 +423,12 @@
423
423
  "split-right"
424
424
  ]
425
425
  },
426
- "description": "片内版式轮换顺序(v1.0.2,可选)。grammar.plan_scenes 在 plan 没有显式 chapter_layout 时,按「章节首次出现的顺序」依次取 cycle[0]、cycle[1]… 循环;同一章内版式固定(观众视角一章是一段整体),换章才换版式——这正是「同一视频内部不要大面积重复」的实现。至少 2 种不同版式(只写一种等于不轮换,designkit.validate_design 报错)。不写 = design_to_plan 按设计指纹自动派生 2–3 种;老 design.json 没有这个键,grammar 走 layout_default,逐字节与过去一致。"
426
+ "description": "片内版式轮换顺序(可选)。grammar.plan_scenes 在 plan 没有显式 chapter_layout 时,按「章节首次出现的顺序」依次取 cycle[0]、cycle[1]… 循环;同一章内版式固定(观众视角一章是一段整体),换章才换版式——这正是「同一视频内部不要大面积重复」的实现。至少 2 种不同版式(只写一种等于不轮换,designkit.validate_design 报错)。不写 = design_to_plan 按设计指纹自动派生 2–3 种;没有这个键时 grammar 走 layout_default。"
427
427
  },
428
428
  "subtitle": {
429
429
  "type": "object",
430
430
  "additionalProperties": false,
431
- "description": "字幕样式(v1.0.2,可选)。为什么要有:v1.0.1 及以前字幕的字号 / 位置 / 背板透明度 / 圆角全是 filmkit.py 里的写死常量,于是**任何两条片子**的字幕带一模一样。全部字段可选,不写 = 补齐下面的默认值(与过去逐像素一致,老 design.json 不受影响)。默认值:size=46、y=null、align=center、plate_alpha=170、radius=10、family=null、color=null、max_lines=2。",
431
+ "description": "字幕样式(可选)。字号 / 位置 / 背板透明度 / 圆角 / 字族 / 颜色 / 折行数全部可写:不写就是 filmkit.py 的默认值(不写时任何两条片子确实会得到同样的字幕带,所以要不同就该改这里)。默认值:size=46、y=null、align=center、plate_alpha=170、radius=10、family=null、color=null、max_lines=2。",
432
432
  "properties": {
433
433
  "size": {
434
434
  "type": "integer",
@@ -513,7 +513,7 @@
513
513
  "1280x720",
514
514
  "960x540"
515
515
  ],
516
- "description": "画幅(v1.0.2)。本版**仅支持 16:9 横屏**(1920x1080 内部构图,可 lanczos 下采样到 1280x720 / 960x540);竖屏、非 16:9 或上采样一律拒绝。与 film.json 的 video 块(width/height/fps)冲突时报错(fail-closed,绝不静默取其一)。"
516
+ "description": "画幅。本版**仅支持 16:9 横屏**(1920x1080 内部构图,可 lanczos 下采样到 1280x720 / 960x540);竖屏、非 16:9 或上采样一律拒绝。与 film.json 的 video 块(width/height/fps)冲突时报错(fail-closed,绝不静默取其一)。"
517
517
  },
518
518
  "fps": {
519
519
  "type": "integer",
@@ -524,7 +524,7 @@
524
524
  50,
525
525
  60
526
526
  ],
527
- "description": "帧率(v1.0.2)。与 film.json 的 video.fps 冲突时报错(fail-closed)。缺省 30。"
527
+ "description": "帧率。与 film.json 的 video.fps 冲突时报错(fail-closed)。缺省 30。"
528
528
  }
529
529
  }
530
530
  },
@@ -603,7 +603,7 @@
603
603
  },
604
604
  "style": {
605
605
  "type": "string",
606
- "description": "已废弃:v1.0.1 删除了配乐风格表,这个键不决定任何东西(保留只为老 design.json / 既有 fixture 能继续通过契约校验;designkit.validate_design 也接受它)"
606
+ "description": "已废弃:配乐没有风格表,这个键不决定任何东西(保留只为老 design.json / 既有 fixture 能继续通过契约校验;designkit.validate_design 也接受它)"
607
607
  },
608
608
  "bpm": {
609
609
  "type": [