@dsh-gis/dsh-video-studio-skill 0.9.1 → 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 (63) hide show
  1. package/CHANGELOG.md +473 -0
  2. package/README.md +263 -327
  3. package/THIRD_PARTY_NOTICES.md +2 -2
  4. package/package.json +9 -10
  5. package/schemas/design.schema.json +722 -0
  6. package/schemas/film.schema.json +31 -42
  7. package/schemas/proposal.schema.json +133 -0
  8. package/skills/video-studio/SKILL.md +1216 -1123
  9. package/skills/video-studio/assets/design_fixture.json +141 -0
  10. package/skills/video-studio/assets/film.json +2 -4
  11. package/skills/video-studio/assets/golden_frames.json +13 -10
  12. package/skills/video-studio/assets/scenes.py +153 -65
  13. package/skills/video-studio/assets/voice_loudness.json +16 -0
  14. package/skills/video-studio/references/appearance.md +123 -0
  15. package/skills/video-studio/references/audio-variation.md +74 -93
  16. package/skills/video-studio/references/audio.md +64 -66
  17. package/skills/video-studio/references/change-impact.md +5 -5
  18. package/skills/video-studio/references/{v08-quality.md → delivery-gates.md} +16 -18
  19. package/skills/video-studio/references/frame-qa.md +48 -16
  20. package/skills/video-studio/references/pipeline.md +4 -4
  21. package/skills/video-studio/references/pitfalls.md +22 -3
  22. package/skills/video-studio/references/proposal.md +160 -0
  23. package/skills/video-studio/references/quality-gates.md +11 -11
  24. package/skills/video-studio/references/scene-authoring.md +2 -2
  25. package/skills/video-studio/references/scene-grammar.md +40 -42
  26. package/skills/video-studio/references/sfx-design.md +8 -6
  27. package/skills/video-studio/references/web-engine.md +8 -8
  28. package/skills/video-studio/references/word-timeline.md +9 -9
  29. package/skills/video-studio/requirements.txt +9 -13
  30. package/skills/video-studio/scripts/designkit.py +2115 -0
  31. package/skills/video-studio/scripts/filmcheck.py +22 -48
  32. package/skills/video-studio/scripts/filmkit.py +2980 -2904
  33. package/skills/video-studio/scripts/gates.py +4 -4
  34. package/skills/video-studio/scripts/grammar.py +73 -13
  35. package/skills/video-studio/scripts/musicgen.py +2042 -0
  36. package/skills/video-studio/scripts/preflight.py +14 -7
  37. package/skills/video-studio/scripts/previewkit.py +848 -0
  38. package/skills/video-studio/scripts/propose.py +825 -0
  39. package/skills/video-studio/scripts/qa_frames.py +73 -39
  40. package/skills/video-studio/scripts/qaasr.py +26 -7
  41. package/skills/video-studio/scripts/qavmaf.py +89 -23
  42. package/skills/video-studio/scripts/render.py +545 -231
  43. package/skills/video-studio/scripts/scorekit.py +55 -1755
  44. package/skills/video-studio/scripts/selfcheck.py +815 -215
  45. package/skills/video-studio/scripts/sfxkit.py +27 -26
  46. package/skills/video-studio/scripts/stagewatch.py +24 -8
  47. package/skills/video-studio/scripts/stylekit.py +207 -888
  48. package/skills/video-studio/scripts/voicekit.py +508 -387
  49. package/skills/video-studio/scripts/webengine.py +71 -72
  50. package/tools/audio_similarity.py +64 -37
  51. package/tools/ci_check.py +20 -14
  52. package/tools/estimate.py +34 -29
  53. package/tools/golden_frames.py +72 -28
  54. package/tools/silhouette_qa.py +520 -168
  55. package/docs/demo-pil-sheet.png +0 -0
  56. package/docs/styles/demo-results.json +0 -76
  57. package/docs/styles/sheet-8-styles.png +0 -0
  58. package/docs/styles/sheet-ai.png +0 -0
  59. package/docs/styles/sheet-before-after.png +0 -0
  60. package/docs/styles/sheet-craft.png +0 -0
  61. package/docs/styles/sheet-night.png +0 -0
  62. package/skills/video-studio/assets/score_demo.json +0 -307
  63. package/skills/video-studio/references/style-packs.md +0 -283
@@ -23,18 +23,7 @@
23
23
  },
24
24
  "style": {
25
25
  "type": "string",
26
- "enum": [
27
- "auto",
28
- "tech-deep",
29
- "magazine",
30
- "paper",
31
- "vivid",
32
- "mono",
33
- "cinema",
34
- "lo-fi",
35
- "epic"
36
- ],
37
- "description": "风格包 id:一套决定画风+配乐+旁白+节奏。“auto”= 按内容自动选;不写这个键 = v0.4 legacy 行为(逐样本兼容)。枚举真值来自 stylekit.STYLES,新增风格时先改那边再改这里"
26
+ "description": "**已废弃**:技能里没有内置风格表,这个键不决定任何外观,写了也不生效(保留只为了让老剧本继续通过契约校验)。外观的唯一来源是 work/design.json(propose.py --confirm 冻结,渲染前由 designkit.design_to_plan 解析);没有设计就渲染会明确报错,而不是回落到某个默认风格。这里**故意不放 enum**:没有任何合法风格 id 可列,列一份清单只会误导 IDE 补全。"
38
27
  },
39
28
  "engine": {
40
29
  "type": "string",
@@ -49,7 +38,7 @@
49
38
  "string",
50
39
  "object"
51
40
  ],
52
- "description": "字符串 = edge-tts voice id(如 zh-CN-YunxiNeural,legacy 单声线路径);对象 = v0.5 声线策略(map 按 kind 映射 persona、auto、jitter、max_distinct、rate_range、cps_band),此时忽略 rate/pitch 的单值覆盖语义",
41
+ "description": "字符串 = edge-tts voice id(如 zh-CN-YunxiNeural,legacy 单声线路径);对象 = 声线策略(map 按 kind 映射音色、auto、jitter、max_distinct、rate_range、cps_band),此时忽略 rate/pitch 的单值覆盖语义",
53
42
  "properties": {
54
43
  "map": {
55
44
  "type": "object",
@@ -254,7 +243,7 @@
254
243
  "chart",
255
244
  "outro"
256
245
  ],
257
- "description": "视觉场景类型(v0.9,可选):决定这段画面长成什么构图——hero 封面 / statement 金句 / list 要点列表 / stat 数字卡 / compare 左右对比 / process 流程轴 / quote 引语 / chapter 章节卡 / chart 数据条 / outro 收尾。与 kind **正交**:kind 管声线、语气、配乐能量,type 只管构图,所以没有新增 kind 值;不写 = 由 grammar.py 按内容自动推导(写错值 filmcheck.py 会报 error)。枚举真值来自 grammar.SCENE_TYPES 与 assets/scenes.py 的 _DRAWERS 键,改那边要同步这里"
246
+ "description": "视觉场景类型(可选):决定这段画面长成什么构图——hero 封面 / statement 金句 / list 要点列表 / stat 数字卡 / compare 左右对比 / process 流程轴 / quote 引语 / chapter 章节卡 / chart 数据条 / outro 收尾。与 kind **正交**:kind 管声线、语气、配乐能量,type 只管构图,所以没有新增 kind 值;不写 = 由 grammar.py 按内容自动推导(写错值 filmcheck.py 会报 error)。枚举真值来自 grammar.SCENE_TYPES 与 assets/scenes.py 的 _DRAWERS 键,改那边要同步这里"
258
247
  },
259
248
  "quote": {
260
249
  "type": "string",
@@ -413,12 +402,12 @@
413
402
  "lead": {
414
403
  "type": "number",
415
404
  "minimum": 0,
416
- "description": "全局句前留白(秒)。缺省取风格 pacing(v0.5 body 基准 0.62)"
405
+ "description": "全局句前留白(秒)。缺省取设计的 pacing(body 基准 0.62)"
417
406
  },
418
407
  "tail": {
419
408
  "type": "number",
420
409
  "minimum": 0,
421
- "description": "全局句后留白(秒)。缺省取风格 pacing(v0.5 body 基准 0.92)"
410
+ "description": "全局句后留白(秒)。缺省取设计的 pacing(body 基准 0.92)"
422
411
  },
423
412
  "min_dur": {
424
413
  "type": "number",
@@ -475,7 +464,7 @@
475
464
  },
476
465
  "whoosh": {
477
466
  "type": "boolean",
478
- "description": "v0.2 兼容:没有 cues.json 时每段开头一声 whoosh(默认 true)"
467
+ "description": "兼容行为:没有 cues.json 时每段开头一声 whoosh(默认 true)"
479
468
  },
480
469
  "whoosh_amp": {
481
470
  "type": "number",
@@ -521,7 +510,7 @@
521
510
  "visual": {
522
511
  "type": "object",
523
512
  "additionalProperties": true,
524
- "description": "视觉覆盖(v0.5):一般不用写,风格包已经决定;要锁主题/版式时才用",
513
+ "description": "视觉覆盖:一般不用写,设计已经决定;要锁主题/版式时才用",
525
514
  "properties": {
526
515
  "theme": {
527
516
  "type": "string",
@@ -540,7 +529,7 @@
540
529
  "music": {
541
530
  "type": "object",
542
531
  "additionalProperties": true,
543
- "description": "配乐:scorekit 程序化生成 / v0.2 和弦床 / 外部 wav / 关掉。不写 mode 时走 v0.2 兼容链(有 bpm 就生成,没有就沿用)",
532
+ "description": "配乐:musicgen 按参数现场编排 / 和弦床 / 外部 wav / 关掉。不写 mode 时走兼容链(有 bpm 就生成,没有就沿用)。没有配乐风格表,不要指望选一个 id 得到一种现成配乐",
544
533
  "properties": {
545
534
  "enabled": {
546
535
  "type": "boolean",
@@ -554,11 +543,11 @@
554
543
  "file",
555
544
  "off"
556
545
  ],
557
- "description": "score = scorekit 程序化配乐;bed = v0.2 和弦床;file = 用外部 work/music.wav;off = 不要配乐(不读也不删 music.wav)"
546
+ "description": "score = musicgen 参数化编排(bpm/key/scale/mood/sections 全可写);bed = 和弦床;file = 用外部 work/music.wav;off = 不要配乐(不读也不删 music.wav)"
558
547
  },
559
548
  "style": {
560
549
  "type": "string",
561
- "description": "\"auto\" 或风格 id:配乐风格(缺省跟随全片 style)"
550
+ "description": "已废弃:删除了配乐风格表,写风格 id 没有意义(保留字段只为老剧本校验不失败)"
562
551
  },
563
552
  "mood": {
564
553
  "type": "string",
@@ -587,59 +576,59 @@
587
576
  },
588
577
  "gain_db": {
589
578
  "type": "number",
590
- "description": "配乐总线增益 dB(v0.7.1 默认 -12:视频以旁白为主,背景必须明显低于人声;旧版 -1.5 会让背景与台词几乎等高)"
579
+ "description": "配乐总线增益 dB(默认 -12:视频以旁白为主,背景必须明显低于人声;-1.5 会让背景与台词几乎等高)"
591
580
  },
592
581
  "duck_db": {
593
582
  "type": "number",
594
- "description": "音效响起时配乐让位深度 dB(v0.7 默认按风格 3.0–5.5)"
583
+ "description": "音效响起时配乐让位深度 dB(默认按设计 3.0–5.5)"
595
584
  },
596
585
  "voice_duck_db": {
597
586
  "type": "number",
598
- "description": "v0.7.1:旁白说话时配乐额外让位深度 dB(默认 6;0 = 关闭旁白侧链)"
587
+ "description": "旁白说话时配乐额外让位深度 dB(默认 6;0 = 关闭旁白侧链)"
599
588
  },
600
589
  "voice_duck_sfx_db": {
601
590
  "type": "number",
602
- "description": "v0.7.1:旁白说话时音效额外让位深度 dB(默认 3;0 = 关闭)"
591
+ "description": "旁白说话时音效额外让位深度 dB(默认 3;0 = 关闭)"
603
592
  },
604
593
  "voice_thresh_db": {
605
594
  "type": "number",
606
- "description": "v0.7.1:语音活跃度阈值 dBFS(默认 -42;低于它算静音间隙,背景恢复)"
595
+ "description": "语音活跃度阈值 dBFS(默认 -42;低于它算静音间隙,背景恢复)"
607
596
  },
608
597
  "voice_floor_db": {
609
598
  "type": "number",
610
- "description": "v0.7.1:语音包络的地板 dBFS(默认 -60;与阈值之间做 0~1 映射)"
599
+ "description": "语音包络的地板 dBFS(默认 -60;与阈值之间做 0~1 映射)"
611
600
  },
612
601
  "guard_snr_db": {
613
602
  "type": "number",
614
- "description": "v0.7.1:旁白清晰度兜底(默认 12)。混音后实测人声活跃区的人声/背景响度差,不足就整体再压背景;0 = 关闭"
603
+ "description": "旁白清晰度兜底(默认 12)。混音后实测人声活跃区的人声/背景响度差,不足就整体再压背景;0 = 关闭"
615
604
  },
616
605
  "guard_cap_db": {
617
606
  "type": "number",
618
- "description": "v0.7.1:SNR 兜底最多补压多少 dB(默认 30,防止把背景压成忽有忽无;补压 >18 dB 会提示检查素材电平)"
607
+ "description": "SNR 兜底最多补压多少 dB(默认 30,防止把背景压成忽有忽无;补压 >18 dB 会提示检查素材电平)"
619
608
  },
620
609
  "seg": {
621
610
  "type": "number",
622
611
  "minimum": 0,
623
- "description": "v0.2 和弦床的段长秒数(默认 4.0)"
612
+ "description": "和弦床的段长秒数(默认 4.0)"
624
613
  },
625
614
  "amp": {
626
615
  "type": "number",
627
616
  "minimum": 0,
628
- "description": "v0.2 和弦床幅度(默认 0.055)"
617
+ "description": "和弦床幅度(默认 0.055)"
629
618
  },
630
619
  "gain": {
631
620
  "type": "number",
632
621
  "minimum": 0,
633
- "description": "v0.2 和弦床增益(默认 0.9)"
622
+ "description": "和弦床增益(默认 0.9)"
634
623
  },
635
624
  "xfade": {
636
625
  "type": "number",
637
626
  "minimum": 0,
638
- "description": "v0.2 和弦床交叉淡化秒数(默认 1.2)"
627
+ "description": "和弦床交叉淡化秒数(默认 1.2)"
639
628
  },
640
629
  "chords": {
641
630
  "type": "array",
642
- "description": "v0.2 兼容:和弦频率表 [[220, 261.63, 329.63], ...];只有 mode=bed/兼容链用得到",
631
+ "description": "兼容行为:和弦频率表 [[220, 261.63, 329.63], ...];只有 mode=bed/兼容链用得到",
643
632
  "items": {
644
633
  "type": "array",
645
634
  "items": {
@@ -681,11 +670,11 @@
681
670
  },
682
671
  "content_seed": {
683
672
  "type": "boolean",
684
- "description": "v0.7:true(默认)= 每条 cue 的 seed 由 style/content_fp 派生(不同影片同一位置也不同);false = 回到 v0.6 的 seed_base+i 位置派生(老片逐样本兼容)"
673
+ "description": "true(默认)= 每条 cue 的 seed 由 style/content_fp 派生(不同影片同一位置也不同);false = 按 seed_base+i 的位置派生(只跟 cue 顺序,逐样本稳定)"
685
674
  },
686
675
  "duck_transitions": {
687
676
  "type": "boolean",
688
- "description": "v0.7:true(默认)= 段落边界前 2.2s 内的 whoosh/riser/reverse_swell 自动 -3 dB,避免与配乐过门在同一频段撞车;false = 不处理"
677
+ "description": "true(默认)= 段落边界前 2.2s 内的 whoosh/riser/reverse_swell 自动 -3 dB,避免与配乐过门在同一频段撞车;false = 不处理"
689
678
  },
690
679
  "cues": {
691
680
  "type": "array",
@@ -767,12 +756,12 @@
767
756
  },
768
757
  "words": {
769
758
  "type": "boolean",
770
- "description": "v0.8 词级时间戳开关(默认 true)。true 时 --stage tts 会额外收 edge-tts 的 WordBoundary 事件落 work/words.json,字幕按词边界折行、cue 可用词锚点 l03:w2、QA 走 G10 门禁;false = 退回整句字幕(不影响出片)。"
759
+ "description": "词级时间戳开关(默认 true)。true 时 --stage tts 会额外收 edge-tts 的 WordBoundary 事件落 work/words.json,字幕按词边界折行、cue 可用词锚点 l03:w2、QA 走 G10 门禁;false = 退回整句字幕(不影响出片)。"
771
760
  },
772
761
  "tts": {
773
762
  "type": "object",
774
763
  "additionalProperties": true,
775
- "description": "v0.8 TTS 后端选择(接口化,默认 edge;其它后端需先 filmkit.register_tts_backend 注册)。",
764
+ "description": "TTS 后端选择(接口化,默认 edge;其它后端需先 filmkit.register_tts_backend 注册)。",
776
765
  "properties": {
777
766
  "backend": {
778
767
  "type": "string",
@@ -790,7 +779,7 @@
790
779
  "video": {
791
780
  "type": "object",
792
781
  "additionalProperties": true,
793
- "description": "v0.8 画幅/帧率(**只支持 16:9 横屏**)。内部构图恒为 1920x1080,输出只能更小(编码时 lanczos 下采样);竖屏 / 非 16:9 / 上采样 / 非法 fps 会被 filmkit.video_plan 直接报错。",
782
+ "description": "画幅/帧率(**只支持 16:9 横屏**)。内部构图恒为 1920x1080,输出只能更小(编码时 lanczos 下采样);竖屏 / 非 16:9 / 上采样 / 非法 fps 会被 filmkit.video_plan 直接报错。",
794
783
  "properties": {
795
784
  "width": {
796
785
  "type": "integer",
@@ -828,12 +817,12 @@
828
817
  "qa": {
829
818
  "type": "object",
830
819
  "additionalProperties": true,
831
- "description": "v0.8 质检门禁参数:全片 VMAF/SSIM(G11)与 ASR 回读(G12)。",
820
+ "description": "质检门禁参数:全片 VMAF/SSIM(G11)与 ASR 回读(G12)。",
832
821
  "properties": {
833
822
  "vmaf": {
834
823
  "type": "object",
835
824
  "additionalProperties": true,
836
- "description": "全片 VMAF/SSIM 门禁(参考帧由场景函数实时渲染,不是成片抽帧)。注意:本对象里的 enabled 与 qa.require_vmaf 是**惰性键**(v0.8 起草时留下,代码无读取点),真正生效的开关是 mode=off / --vmaf off;filmcheck.py 对惰性键会报 WARN。",
825
+ "description": "全片 VMAF/SSIM 门禁(参考帧由场景函数实时渲染,不是成片抽帧)。注意:本对象里的 enabled 与 qa.require_vmaf 是**惰性键**(代码无读取点),真正生效的开关是 mode=off / --vmaf off;filmcheck.py 对惰性键会报 WARN。",
837
826
  "properties": {
838
827
  "enabled": {
839
828
  "type": "boolean",
@@ -852,7 +841,7 @@
852
841
  "type": "number",
853
842
  "minimum": 0,
854
843
  "maximum": 100,
855
- "description": "VMAF 低于此值 -> fail(默认 92,权威定义在 qavmaf.py 的 VMAF_PASS;标定依据见 references/v08-quality.md)"
844
+ "description": "VMAF 低于此值 -> fail(默认 92,权威定义在 qavmaf.py 的 VMAF_PASS;标定依据见 references/delivery-gates.md)"
856
845
  },
857
846
  "warn": {
858
847
  "type": "number",
@@ -0,0 +1,133 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "$id": "https://github.com/znlgis/dsh-video-studio-skill/schemas/proposal.schema.json",
4
+ "title": "video-studio proposal(v1.0 提案)",
5
+ "description": "work/proposal.json:一次提案的 N 个候选 + 用户确认状态。status=confirmed 才允许出片。",
6
+ "type": "object",
7
+ "required": [
8
+ "schema",
9
+ "rev",
10
+ "status",
11
+ "candidates"
12
+ ],
13
+ "additionalProperties": true,
14
+ "properties": {
15
+ "schema": {
16
+ "type": "integer",
17
+ "const": 1
18
+ },
19
+ "rev": {
20
+ "type": "integer",
21
+ "minimum": 1
22
+ },
23
+ "parentRev": {
24
+ "type": [
25
+ "integer",
26
+ "null"
27
+ ]
28
+ },
29
+ "at": {
30
+ "type": "string"
31
+ },
32
+ "status": {
33
+ "type": "string",
34
+ "enum": [
35
+ "draft",
36
+ "confirmed",
37
+ "rejected"
38
+ ]
39
+ },
40
+ "chosen": {
41
+ "type": [
42
+ "string",
43
+ "null"
44
+ ],
45
+ "description": "confirmed 时必填的候选 id"
46
+ },
47
+ "confirmedAt": {
48
+ "type": "string"
49
+ },
50
+ "confirmedBy": {
51
+ "type": "string"
52
+ },
53
+ "confirmNote": {
54
+ "type": "string"
55
+ },
56
+ "designHash": {
57
+ "type": "string",
58
+ "description": "确认时 design.json 的指纹(用于判 stale)"
59
+ },
60
+ "brief": {
61
+ "type": "object"
62
+ },
63
+ "feedback": {
64
+ "type": "string"
65
+ },
66
+ "seed": {},
67
+ "wall_s": {
68
+ "type": "number"
69
+ },
70
+ "candidates": {
71
+ "type": "array",
72
+ "minItems": 2,
73
+ "items": {
74
+ "type": "object",
75
+ "required": [
76
+ "id",
77
+ "design",
78
+ "design_fp"
79
+ ],
80
+ "properties": {
81
+ "id": {
82
+ "type": "string",
83
+ "pattern": "^[A-H][0-9]*$"
84
+ },
85
+ "label": {
86
+ "type": "string"
87
+ },
88
+ "pitch": {
89
+ "type": "string"
90
+ },
91
+ "design": {
92
+ "type": "object"
93
+ },
94
+ "design_fp": {
95
+ "type": "string"
96
+ },
97
+ "preview": {
98
+ "type": "object"
99
+ },
100
+ "cost": {
101
+ "type": "object"
102
+ },
103
+ "diversity": {
104
+ "type": [
105
+ "object",
106
+ "null"
107
+ ]
108
+ }
109
+ }
110
+ }
111
+ }
112
+ },
113
+ "allOf": [
114
+ {
115
+ "if": {
116
+ "properties": {
117
+ "status": {
118
+ "const": "confirmed"
119
+ }
120
+ },
121
+ "required": [
122
+ "status"
123
+ ]
124
+ },
125
+ "then": {
126
+ "required": [
127
+ "chosen",
128
+ "designHash"
129
+ ]
130
+ }
131
+ }
132
+ ]
133
+ }