@gitruck/cli 1.3.15 → 1.3.17
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.
- package/AGENT.md +40 -10
- package/CHANGELOG.md +1262 -1231
- package/README.en.md +1 -1
- package/README.md +1 -1
- package/assets/composite-kit/kit.css +66 -57
- package/assets/composite-kit/stage.html +164 -18
- package/dist/index.js +653 -343
- package/docs/reference.en.md +866 -852
- package/docs/reference.md +909 -895
- package/docs/workflow.en.md +4 -3
- package/docs/workflow.md +4 -3
- package/package.json +1 -1
- package/skills/gtrk-ai-drama/SKILL.md +7 -7
- package/skills/gtrk-composite/SKILL.md +428 -222
- package/skills/gtrk-composite/references/fullscreen-card-migration.md +99 -0
- package/skills/gtrk-food-recap/SKILL.md +6 -3
- package/skills/gtrk-live-slicing/SKILL.md +9 -6
- package/skills/gtrk-long2short/SKILL.md +3 -2
- package/skills/gtrk-matrix/SKILL.md +9 -9
- package/skills/gtrk-mg/SKILL.md +62 -48
- package/skills/gtrk-music-visualizer/SKILL.md +1 -1
- package/skills/gtrk-narration/SKILL.md +15 -8
- package/skills/gtrk-oralcut/SKILL.md +1 -1
- package/skills/gtrk-splitter/SKILL.md +116 -24
- package/skills/gtrk-splitter/references/example-visual-split.json +34 -13
- package/skills/gtrk-splitter/references/example-visual-split.md +28 -5
- package/skills/gtrk-splitter/references/field-schema.md +88 -3
- package/skills/gtrk-style-maker/SKILL.md +8 -4
- package/skills/gtrk-style-maker/references/seeds/seed-ecom-home-goods.md +2 -2
- package/skills/gtrk-style-maker/references/seeds/seed-psych-humanities.md +1 -1
- package/skills/gtrk-talking-head/SKILL.md +26 -20
- package/skills/gtrk-tools/SKILL.md +1 -1
- package/skills/gtrk-transcript/SKILL.md +1 -1
- package/skills/gtrk-travel-recap/SKILL.md +36 -28
- package/skills/gtrk-vlog-docu/SKILL.md +41 -33
- package/skills/gtrk-voiceover/SKILL.md +19 -11
|
@@ -1,222 +1,428 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: gtrk-composite
|
|
3
|
-
description:
|
|
4
|
-
metadata:
|
|
5
|
-
in_app_agent: true
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
# 合成层包装(gtrk-composite)
|
|
9
|
-
|
|
10
|
-
把粗剪工程里选定的时间窗做成**合成颗粒**:在这段时间里,整个画面由一颗代码颗粒接管——它决定画面怎么排、何时换、字幕怎么出;讲者与 B-roll 作为**槽位**由客户端把视频画进去。**CLI 是手(定窗口、解析、校验、机检、铺轨),你是脑(判断这段该怎么排、选哪张画面、写场景)。**
|
|
11
|
-
|
|
12
|
-
> 本 skill 已含你需要的全部信息。命令参数以 `gtrk composite --help` 为准。规则正本:合成颗粒契约在 infra `composite-particle-profile`;`struct_meta.composite` 写方契约在本仓 `composite-command`。
|
|
13
|
-
|
|
14
|
-
## 你在成片 SOP 的哪一步
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
```
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
1
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
gtrk composite
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
-
|
|
97
|
-
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
-
|
|
163
|
-
-
|
|
164
|
-
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
-
|
|
210
|
-
-
|
|
211
|
-
-
|
|
212
|
-
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
1
|
+
---
|
|
2
|
+
name: gtrk-composite
|
|
3
|
+
description: 合成层包装(合成颗粒,画面三层里的「版」)——粗剪、B-roll、字幕都定了之后、铺 MG 叠层之前,把选定时间窗做成「合成」:一段时间内的整个画面由一颗代码颗粒接管(画中画拼贴、逐句换画面、对照并排、并列卡片、字幕排版、满屏卡),讲者、B-roll 与图片作为槽位画进去;没有画面槽位的标题牌 / 章节卡 / 数据卡是满屏卡(零槽位合成)。四种入口:取拆分稿的版式窗口 / 整片铺满 / 让 AI 判定哪里值得做 / 用户指定区间;候选窗口显示在客户端大纲的 CP 行。当用户想「做合成 / 合成层 / 整片做一下合成包装 / 哪里适合做合成 / 这段做成画中画拼贴 / 11 秒到 32 秒做个合成 / 逐句换画面 / 把字幕排进画面里 / 按拆分的版式窗口做合成」时使用本 skill,驱动 `gtrk composite`(plan → review → scaffold → build → lint → lay → bake),别手搓 HTML 铺进工程。
|
|
4
|
+
metadata:
|
|
5
|
+
in_app_agent: true
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# 合成层包装(gtrk-composite)
|
|
9
|
+
|
|
10
|
+
把粗剪工程里选定的时间窗做成**合成颗粒**:在这段时间里,整个画面由一颗代码颗粒接管——它决定画面怎么排、何时换、字幕怎么出;讲者与 B-roll 作为**槽位**由客户端把视频画进去。**CLI 是手(定窗口、解析、校验、机检、铺轨),你是脑(判断这段该怎么排、选哪张画面、写场景)。**
|
|
11
|
+
|
|
12
|
+
> 本 skill 已含你需要的全部信息。命令参数以 `gtrk composite --help` 为准。规则正本:合成颗粒契约在 infra `composite-particle-profile`;`struct_meta.composite` 写方契约在本仓 `composite-command`。
|
|
13
|
+
|
|
14
|
+
## 你在成片 SOP 的哪一步
|
|
15
|
+
|
|
16
|
+
第 ⑥ 步:**① 剪口播 → ② 拆分(含版式窗口,满屏卡写成零槽位窗口)→ ③ 底轨三源铺齐 → ④ 全局抽帧检查 → ⑤ 字幕 → ⑥ 合成(本 skill,含满屏卡)→ ⑦ 叠层(`gtrk mg`)→ 出片**,BGM 不受顺序约束(位次正本 `production-order`,口径见《成片型图纸公约》§二⁗「画面三层」)。
|
|
17
|
+
- **字幕之后**:合成接管字幕时要读字幕输入,字幕后上场景就得重建;
|
|
18
|
+
- **`gtrk mg` 之前**:合成先落位,叠层只产在窗口以外——整段落在窗口里的叠层槽位被你接管,`gtrk mg` 不产不铺(看 `gtrk mg status` 的 `covered_by`)。
|
|
19
|
+
|
|
20
|
+
上游再改,对应颗粒在客户端变「需重渲」,重跑那几颗即可。
|
|
21
|
+
|
|
22
|
+
前置:
|
|
23
|
+
- 有粗剪工程(`<工程>/gtrk/project.gtrk`)和口播转写(`transcript/transcript.json`,新版 `gtrk oralcut` 恒出)。合成按**句**定窗口,没有转写就做不了。
|
|
24
|
+
- 字幕已上(`gtrk subtitle lay`,位次 ⑤):合成颗粒可以接管字幕、自己排。
|
|
25
|
+
- `gtrk composite --help` 能跑(CLI 版本含本命令族)。
|
|
26
|
+
|
|
27
|
+
⚠️ **出片口径要先说清**:合成颗粒出片靠本机烘焙(`gtrk composite bake`,见「出片:烘焙」一节;客户端导出时自动烘焙)——首次要装烘焙浏览器(约 110 MB),某颗烘焙失败时那一段按粗剪出画。用户要交付成片的话,这件事 MUST 在开工时告诉他。
|
|
28
|
+
|
|
29
|
+
## 入口:四选一(用户已说明就不再问)
|
|
30
|
+
|
|
31
|
+
| 情形 / 用户说 | 入口 | 命令 |
|
|
32
|
+
|---|---|---|
|
|
33
|
+
| 成片图纸跑到这一步、拆分稿带 `layouts` 键 | 取拆分窗口 | `gtrk composite plan --project <工程> --mode split` |
|
|
34
|
+
| 「整片做一下合成」 | 整片铺满 | `gtrk composite plan --project <工程> --mode full` |
|
|
35
|
+
| 「看看哪里适合做」「帮我挑」;不走拆分的链(直播切片、长剪短)与旧拆分稿 | AI 判定 | `gtrk composite plan --project <工程> --mode auto [--density 0.25]` |
|
|
36
|
+
| 「11 秒到 32 秒做一个」「u0004 到 u0009 那段」 | 用户指定 | `gtrk composite plan --project <工程> --range 11,32 --range u0020-u0024` |
|
|
37
|
+
|
|
38
|
+
- **取拆分窗口**(拆分是唯一规划者,公约 §二⁗):读 `split/dispatch.json` 的 `composite` 队列,按当刻时间线重投影、吸附句界与帧格(吸附量逐条写明);每个窗口的理由 = 拆分稿的 `visual_brief`,`slot_hints` 写进 `composite/scenes/cp-wNN.context.md`「拆分时的打算」一段;状态一律待审。拆分稿带 `layouts` 键时 **MUST NOT 再跑 `auto` 另挑**;用户主动问「还有哪里适合」才可 `auto` 补,补出的窗口不与拆分窗口重叠。拆分稿没有 `composite` 队列(旧稿)会报错指路:重跑拆分补版式窗口,或改用 `--mode auto`;队列为空(`layouts: []`)= 零窗口,回执引述拆分稿的 `layout_note`。派单 `layouts_declared: false`(拆分稿没写 `layouts`,窗口全是满屏 MG 转来的满屏卡)⇒ `--mode split` 之后接着 `--mode auto` 补其余窗口(满屏卡不占密度预算,补出的窗口不与它重叠),回执把两类分开列。
|
|
39
|
+
- **整片铺满**:窗口首尾相接覆盖全片,单窗 5–25 秒、在句界(有拆分派单时在 beat 边界)断开。
|
|
40
|
+
- **AI 判定**:按信号打分(几秒内多个 B-roll 短镜头、列举、对照 / 转折、具体数字、章节转折、开场 / 收尾),总时长不超过密度上限(缺省全片 25%)。超出的记「超出上限」,**列出来让用户挑,不静默丢**。信号只是起点——你要读审稿稿里每个窗口「这段在说什么」,判断它是否真值得做,不值得的建议用户不要。
|
|
41
|
+
- **用户指定**:区间吸附到句界、投影到帧格,回执里写明两端各挪了多少毫秒;直接记为已采纳。
|
|
42
|
+
|
|
43
|
+
`plan` 把候选写进工程的 `struct_meta.composite`(只动这一个键),另出审稿稿 `<工程>/composite/plan.md`。重跑时已做好的窗口原样保留、用户不要的区间不再提。
|
|
44
|
+
|
|
45
|
+
### 检查点①(必停):审窗口
|
|
46
|
+
|
|
47
|
+
写回后客户端会自动重新载入工程(没有自动载入时请用户手动重新载入),请用户看大纲的 **CP 行**:虚线框 = 待审,虚线框加浅底 = 已采纳,悬停能看理由与建议。同时把审稿稿的表格摘给他。他在对话里说哪些要、哪些不要、哪些调起止,你用 `review` 写回:
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
gtrk composite review --project <工程> --approve W01,W03 --reject W02 --adjust W04=80,90.9 --add 140,150
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
`--approve-all` 采纳全部待审。没有采纳的窗口,后面的步骤一概不做。
|
|
54
|
+
|
|
55
|
+
- **窗口两端自动对齐换片点**(编排规则 10):`plan` 各入口与 `review --adjust / --add` 定窗口时,吸附句界与帧格之后,再看两端外侧的可见视频轨(讲者主轨、B-roll 候选轨、AI 轨、画中画轨)——横跨窗口边的片段出窗后 0.6 秒内就换片的,把窗口**扩**到那个换片点;横跨窗口边的是一段**短插入**(短于 1 秒、不在口播主轨上、另一头落在窗口里:栏目 OP、转场、卡点短镜)时,把窗口**收**到它的边上让它完整露出,不外扩吞掉。回执(`edge_snaps`)逐条写明是收(`action: "shrink"`)还是扩(`"extend"`)、挪了多少毫秒、原因(`reason`,与 `plan.md` 同一句)。窗口边之后才开始的新片段(例如有意铺的转场)不碰;外扩不撞相邻窗口。
|
|
56
|
+
- **用户就要原样的起止**:`review --adjust W22=700,727.85 --no-edge-snap`(`--add` 同)——秒值原样保留(只投影到帧格),不吸附句界、不对齐换片点;回执 `warnings` 写明照常对齐会怎么挪;窗口记 `edge_snap: false`,之后 `lint` 对它的 `edge-flash` / `edge-insert` 只告警。只在用户明确要这个起止时用,MUST NOT 拿它绕开 lint。
|
|
57
|
+
- **调已起场景 / 已铺的窗口**:`review --adjust` 对已采纳和已做(已铺)的窗口都能用(已铺的仍记已做);已起场景的,命令同步场景规格里的 `window`(回执 `scene_sync`),之后照常 `build --only cp-wNN` → `lint` → `lay --only cp-wNN`(已铺的那颗 lay 会替换)。场景规格里认不出 `window` 时命令会提示,手改成回执给的起止再走这三步。`--only` 写窗口 id(`W21`)或颗粒 id(`cp-w21`)都行,大小写不敏感。
|
|
58
|
+
- **改起止要说理由**:审定窗口时改起止(`--adjust`、改场景 `window`),在回执或设计说明里写明为什么改、改成多少。**窗口任一端越过口播**(终点晚于最后一句口播结束 / 起点早于第一句开始)超过 1 秒时,`plan` / `review` / `build` 的回执 `warnings` 会写明「越过口播 N 秒、盖住的是什么」(母版黑场、片尾卡、空档……)——这种外扩 MUST 先问用户、得到同意再做,回执里照实说盖住了什么。
|
|
59
|
+
- ❌ 反例:收尾窗口从口播结束的 1109.45 秒直接拉到全片末尾 1124 秒,盖住了 14.5 秒母版黑场,没问用户、也没写理由。
|
|
60
|
+
|
|
61
|
+
## 逐窗口:设计说明 → 选片 → 场景 → 构建 → 机检
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
gtrk composite scaffold --project <工程> # 为已采纳窗口落场景骨架 composite/scenes/cp-wNN.html
|
|
65
|
+
# 与上下文 cp-wNN.context.md(这段在说什么、窗口内片段、已登记素材)
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
骨架按窗口形态给**带正确契约的起手模板**(讲者段 / 素材段 / 满屏卡),回执 `shapes` 与上下文文件写明是哪种、为什么:
|
|
69
|
+
- **讲者段**(讲者主轨在窗口里露出过半):三路同源毛玻璃——`frost` 满幅重糊垫底、`frost2` 轻糊过渡带、`presenter` 清晰讲者,`data-filter` 在开窗 0.6 秒内起雾、`data-crop` 左裁与框左边像素对齐;半透衬底 `#veil` 用 `mask-image` 向画面羽化;左板内容不越过过渡带的边。
|
|
70
|
+
- **素材段**(窗口里露出最久的是 B-roll / AI / 画中画轨):素材满幅 `ref-lane` 绑那条轨 + 半透衬底。
|
|
71
|
+
- **满屏卡**(零槽位窗口):只留字幕输入 `subs`,整张卡开窗 0.35 秒内落位,说到哪句亮哪句。
|
|
72
|
+
- 三种都把窗口里的口播原句预填成锚点(句 id 即锚点名,关键词从原句逐字取、已按 `build` 同一套规则解析过),分拍走 `A()`;颜色只用主题变量,类名带 `s-` 前缀不撞工具箱。竖屏 / 方形舞台按自己的版式算(竖屏讲者 / 素材在上、板在下)。
|
|
73
|
+
- 模板是起点不是成品:拍子里的占位文字是原句开头,换成这一拍要强调的词(仍从原句摘),版式按设计说明改。**已有场景不覆盖**(上下文照刷新),`--force` 才按模板重起。
|
|
74
|
+
|
|
75
|
+
对每个窗口:
|
|
76
|
+
|
|
77
|
+
1. **先读上下文、写设计说明**(写进对话给用户看,或写在场景文件开头的注释里)。窗口取自拆分稿时,上下文里有「拆分时的打算」(`visual_brief` 与 `slot_hints`)——设计说明从它起笔,`slot_hints` 是参考不是绑定:
|
|
78
|
+
- 这段话分几拍?每拍对应哪句、哪个关键词?
|
|
79
|
+
- 每拍画面是什么?为什么是一画 / 多画?(见下节规则 1)
|
|
80
|
+
- 字幕怎么处理(接管后自己排 / 屏上已写着同一句时隐藏)。
|
|
81
|
+
- **锚点照抄原文**:写锚点之前先读 `cp-wNN.context.md`「这段在说什么」里的原句,锚点的关键词从原句里逐字抄。MUST NOT 凭拆分稿的 `visual_brief`、`slot_hints` 或你自己的设计说明转述——那些是改写过的话,原句里往往没有这几个字。
|
|
82
|
+
- ❌ 反例:照拆分稿的画面描述写了九处锚点关键词,原句里一处都没有,九处全部落空、`build` 一条条报「找不到关键词」。
|
|
83
|
+
2. **选片**(需要 `own` 槽位时):
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
gtrk composite shots --project <工程> --material <素材 id 或文件> --around 246 --span 20
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
看联系表(每格左上是源时间码)、切点列表、黑边实测。入点与在场时长 MUST 落在一个镜头内(规则 6),`data-crop` 按黑边实测取(规则 4)。工程里还没登记的素材写进 `<工程>/composite/materials.json`(`[{ "id", "path", "duration" }]`),铺轨时一并登记。
|
|
90
|
+
- **省上下文**:选片、核对一律用 `composite shots` 联系表(一张图看几十格)和 `lint --stills` 的静帧,**一次读两三张**,看完再读下一批;MUST NOT 把整幅截帧逐张读进上下文。
|
|
91
|
+
- ❌ 反例:一个会话里逐张读进多张整幅截帧,上下文撑满,后面的窗口做不下去、会话卡死。
|
|
92
|
+
- **图片也当 `own` 素材**(公约 §二⁗「图片去处」:要看清的配图、论文页、新闻截图、照片进版的槽位,不内联进任何 MG 颗粒):用 `gtrk composite materials add <图片> --project <工程>` 登记(拷进 `gtrk/assets/web/`、写 `composite/materials.json`,别手写),槽位 `pin` 给 `material` 与 `dur_t`(图片没有入点,`src_in_ms` 留 0);圈重点由场景自己画。build、lint、烘焙与客户端预览都认图片(旧版客户端例外,见「已知限制」第 1 条)。**联网取回的图**带 `--from-web-source` 登记、必配出处卡,见下文「联网取回的图」一节。
|
|
93
|
+
3. **写场景**(格式见「场景写法速查」)。
|
|
94
|
+
4. **构建**:`gtrk composite build --project <工程> [--only cp-w03]`——先按浏览器同一套语法解析场景脚本(语法错就报错、指出场景文件第几行,这颗不产),再按 infra 规则解析(帧格窗口、轨身份、锚点、字幕输入、`inputs_hash`)并校验,产 `<工程>/gtrk/assets/composite/<id>.html`。回执里每颗应为 `fresh`;`warnings` 里有「越过口播」的,按上面「改起止要说理由」处理。
|
|
95
|
+
5. **机检**:`gtrk composite lint --project <工程> --stills 26,86.6`——静态校验(含场景脚本语法 `script-syntax`;窗口边闪帧 `edge-flash`:横跨窗口边的片段出窗后只露几帧就换片;`edge-insert`:窗口边盖住了一段短插入)+ 契约检查(渲染静帧之前就报、带改法:槽位上写了对视频无效的 CSS `slot-css-ignored`、`data-filter` 不在白名单 `slot-filter-unsupported`、画面槽位从没 `at()` 放置 / 全程不可见 `slot-never-placed`——这三条致命;有口播却没锚点也没 `A()` 的 `no-anchors`、与工具箱撞名的类 `kit-class-collision`、屏上文字有效字号 < 32px 的 `small-text`——这三条告警)+ 逐帧排版(页面上没有 `CP.render` 判 `render-missing`、render 抛错判 `script-error`;下层画面的前景描边压上层画面、前景线条穿过画面、画面越出舞台、容器里的元素写了偏移却没定位),顺带出静帧。场景脚本没跑起来的颗粒不出静帧(回执 `stills_failed` 写明原因)——画面停在默认位置不等于通过。**不过就改场景重跑,过了才往下走;lint 通过也不等于画面对,静帧照样要看。**
|
|
96
|
+
- **`--stills` 填时间线秒**(整条片子上的时刻),不是窗口内的局部秒(场景里 `t`、`A()` 才是局部秒):窗口 [77.483, 90.85] 里第 3 秒要写 `--stills 80.483`。填错了会报「该时刻没有合成颗粒」,并列出各窗口的时间线起止、给出按局部秒换算的时间线秒。
|
|
97
|
+
- 退出码 3 = 本机找不到 Chrome / Edge,**排版没机检**:照实告诉用户,用静帧(或客户端预览)人眼逐颗查穿模,MUST NOT 当成通过。
|
|
98
|
+
|
|
99
|
+
### 检查点②:看静帧
|
|
100
|
+
|
|
101
|
+
每颗至少给用户 2–3 张关键时刻的静帧(换画面前后、拆分并排时、结尾)。快速成片模式下全部窗口做完后一次给。用户点头再铺:
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
gtrk composite lay --project <工程> # 全量;--only cp-w03 只替换这颗
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
`lay` 铺之前会再跑一遍契约检查三条致命规则的静态部分(`slot-css-ignored`、写死的 `slot-filter-unsupported`、`slot-never-placed`),不过就拒铺、报文与 `lint` 同一句;循环里放这类静态认不出的不拦,回执 `warnings` 提示先跑 `lint`——**lay 不能代替 lint**,逐帧排版与静帧只有 `lint` 查。
|
|
108
|
+
|
|
109
|
+
铺完客户端会自动重新载入(没有自动载入时请用户手动重新载入):CP 行上的提案块变成实色合成块,预览即合成效果。
|
|
110
|
+
|
|
111
|
+
## 出片:烘焙
|
|
112
|
+
|
|
113
|
+
> 这一节是外部 agent(终端里的 Claude Code、Codex 等)的出片步骤。在即剪客户端的 AI 面板里做合成时,铺完轨就告诉用户「导出时会自动烘焙」,不运行 `bake`。
|
|
114
|
+
|
|
115
|
+
铺完、用户确认后、出片前,先在本机把合成烤成视频(`gtrk render` / `gtrk project export` 也会自动先烤,单独跑便于先看结果):
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
gtrk deps install --browser # 首次:装钉定版本的烘焙浏览器(约 110 MB)。MUST 先告诉用户再装
|
|
119
|
+
gtrk composite bake --project <工程> # 全部合成;--only cp-w03 只烤这颗
|
|
120
|
+
gtrk composite upgrade-kit --project <工程> # 旧颗粒换上当前工具箱(元数据与场景不动);用户调窗口后边框 / 阴影才跟着走
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
- **缓存即复用**:没改过的颗粒二次运行全部命中;改了场景、素材文件、上游时间线或帧率才重烤。
|
|
124
|
+
- **没装钉定浏览器**也能烤(退回本机 Chrome / Edge,截图模式,更慢)——回执会提示,**MUST NOT 自作主张下载**;用户同意后再 `gtrk deps install --browser`,或本命令加 `--install-browser`。
|
|
125
|
+
- **某颗失败**(退出码 1):其余照常。回执给出原因(常见:素材丢失、窗口为零、未解析——重跑 `build`);修好再烤那一颗。不修的话出片时该段按粗剪出画,MUST 照实告诉用户。
|
|
126
|
+
- **出片时**:成功的那段以烘焙视频出画;**整段落在合成窗口内的 MG / OV 不再预渲、不计费**(被合成接管了)。
|
|
127
|
+
- 帧纯度(`lint` 的 `impure-frame`)不过的颗粒,烘焙段首帧会与连续播放不同——**lint 过了再烤**。
|
|
128
|
+
- **产物尺寸 = 舞台 = 工程画布**:竖屏 1080×1920 与横屏 1920×1080 像素数相同、耗时相同;4K 画布像素是 1080p 的 4 倍,烘焙明显更慢,开烤前照实告诉用户。
|
|
129
|
+
|
|
130
|
+
## 编排规则(每条都是测试工程走查时真犯过的)
|
|
131
|
+
|
|
132
|
+
1. **画面数由内容定,不照搬粗剪的轨结构。** 逐句看台词:一句话说到什么就换成什么;没有具体可看的,让讲者本人占画框或用纯排版;**只有内容本身是两个以上的东西才同时放多画**——关系(「你再指点妈妈」→ 女儿 / 妈妈并排)、对照(「她会化浓妆」VS「妈妈没化过妆」)、并列(「打耳钉 / 抽烟 / 喝酒」三张卡逐词亮起)。
|
|
133
|
+
- ❌ 反例:粗剪在这段有两条 B-roll 候选轨,就放一个大框 + 一个小框,两条轨各占一个——画面数由轨数决定,跟内容无关。
|
|
134
|
+
- 画面多用 `own` 槽位按内容另挑入点(粗剪轨上的片段只是候选之一);用 `ref-lane` 的前提是那条轨在这段的时序恰好就是你要的。
|
|
135
|
+
- **没有讲者的工程**(解说、配音、旅拍等主画面不是真人口播):只用 B-roll 画面与排版;没有具体可看的段交给纯排版或不做,MUST NOT 造讲者画框、MUST NOT 拿空白圆窗或占位图充当讲者。
|
|
136
|
+
2. **任一时刻画面互不重叠。** 客户端先画全部画面、再画前景层,**下层画面的前景描边一定压在上层画面上**。同一位置交替换画面时,**等前一张的框到位、两框重合后再换**(`seq` 已按此写);版式切换(一画 → 并排)时,先让旧画面缩到位,新画面再进来。讲者不在同一时刻出现两次(大框里是讲者时不放讲者圆窗)。
|
|
137
|
+
- **工程铺过画中画(`gtrk pip lay`)时**:客户端在合成窗口里只藏字幕与 MG 颗粒,**不藏画中画轨**——合成画在最上层,出片烘焙成不透明视频会把下面各轨整个盖住,预览里却只有场景画了底的地方盖得住。所以这类窗口的场景 MUST 铺满幅底(`.bed`),讲者 / 屏录要出现就用 `ref-lane` 槽位绑人像主轨 / 屏录轨;MUST NOT 只在局部排版、让下面的人像画中画圆窗透出来与讲者槽同屏。
|
|
138
|
+
- ❌ 反例:讲者圆窗与小画面叠在大画框的边线上,边线横穿它们;分叉曲线从一张画中画中间穿过去。
|
|
139
|
+
3. **合成与底轨融合,不切两半。** MUST NOT 用不透明底板把画面切成「左板右人 / 左板右图」、留一条硬边——审片原话:「这种划分方法依旧比较违和」「现在这种处理观感上比较突兀」。栏目 MG 风格 skill 对衬底(scrim)有更具体的规则时,以栏目为准。
|
|
140
|
+
- **讲者 / 素材满幅不挪**:与窗口外是同一画面,进窗不跳。
|
|
141
|
+
- **包装叠在半透明衬底上**:约 0.6 不透明度,`color-mix(in srgb, var(--bg) 62%, transparent)`;在 `data-layer="front"` 的容器上用 `mask-image: linear-gradient(90deg, #000 0, #000 ~700px, transparent ~960px)` 向画面羽化。线稿与文字保持不透明,内容盒的实心填充也改半透。
|
|
142
|
+
- **讲者段可加毛玻璃**:同一路讲者另开一个满幅槽位,`data-filter="blur(…)"` 垫底;清晰讲者用 `data-crop` 左裁,从某个 x 起,像素对齐。清 / 糊分界选在画面素净处,藏在衬底的满浓度区里;可再加一级轻糊过渡带(例如 blur 7px)分两级退到清晰。开窗时模糊从 0 渐起,在 render 里改 `dataset.filter`,首帧与窗口外一致。
|
|
143
|
+
- **衬底给视频槽位开洞**:前景层画在所有视频之上——衬底范围内有视频槽位时,要给槽位开洞(衬底拆成几块围着它),槽位浮出时洞里那块同步退掉,否则衬底会糊在视频上。
|
|
144
|
+
- **进出窗口**:外侧接的是同一段画面时,开窗渐起,出窗前约 0.4 秒退让——这是交接让位,画面始终是讲者 / 素材,不算「整体退场」;接的是换片时,随剪点切走。
|
|
145
|
+
- 满屏卡(零槽位)是整幅纯排版,不受本条约束。
|
|
146
|
+
- ❌ 反例:左半屏实色纸板摆图解,右半屏讲者裁成半幅,中间一条硬边。
|
|
147
|
+
4. **裁掉画面里的黑边与烧录字幕。** 电影源常带信箱黑边,综艺源常有烧录字幕与人名条;按 `shots` 的实测写 `data-crop="上,右,下,左"`(比例)。片段在时间线上已挂了去字幕 / 水印遮罩的,烧录字幕交给遮罩,别再硬裁(见「槽位里的去字幕 / 去水印」)。
|
|
148
|
+
- ❌ 反例:画框里留一道黑带。
|
|
149
|
+
5. **人脸构图:眼睛落在上三分线附近,头顶留约一成余量。** 讲者大框、圆窗、素材里的人脸都一样。
|
|
150
|
+
- ❌ 反例:裁切把眼睛放在画框正中,头顶上方空出一大片窗户。
|
|
151
|
+
6. **选片不跨切点。** `own` 的取用段 `[入点, 入点 + 在场时长)` MUST 落在一个镜头内;镜头不够长就接受最后一帧定格或换一个镜头,MUST NOT 拉伸或变速。
|
|
152
|
+
7. **字幕:接管就自己排,而且与窗口外全片字幕同款。** 场景声明 `takeover: ["subtitles","overlay"]` 后,窗口内原字幕与 MG 叠层不再显示,字幕由场景用 `caption()` 或对话气泡排出;屏上排版已经写着同一句话时可以在那段隐藏字幕。接管后排的常规字幕 MUST 与窗口外的全片字幕同款——字体、字号、颜色、投影、中线位置都一样,从工程字幕样式读(`.gtrk` 字幕车道里 `subtitleCue` 文字元素的样式,即 `gtrk subtitle lay` 铺的那套;用户在客户端调过就以工程里的为准,抽一帧窗口外的字幕对照),写成 `theme.css` 里一个字幕类、全片窗口共用,进出窗口时字幕不跳。只有底色太浅、白字看不清时,才在字幕下垫一条贴字宽的半透明底条(也写在 `theme.css` 里)。工具箱的 `.cap` 只是中性缺省,不等于工程字幕样式。
|
|
153
|
+
- ❌ 反例:窗口外的全片字幕是工程定的字体、字号与投影,窗口内却用了工具箱 `.cap` 的缺省样式、中线位置也不同——合成一进一出,字幕跳一下。
|
|
154
|
+
- **窗口里的叠层出片一律不出**:整段落在合成窗口里的 MG 颗粒,不论场景写没写 `overlay`,出片时都不出画,`gtrk mg` 也就不产不铺——要强调一个词、一个数,写进这颗合成场景本身(标签、印章、`typeOn`),别指望叠层。
|
|
155
|
+
8. **先求准,再求满。** AI 判定模式的密度上限是对成片吵闹度的约束;整片铺满时也要让「没有具体可看的段」安静(讲者 + 少量排版),别为了铺满每段都堆画面。
|
|
156
|
+
9. **舞台随工程画布,竖屏 / 方形按自己的版式写。** `scaffold` 按工程画布写舞台(规格里的 `stage`),场景坐标一律是这块舞台的像素;横屏工程的版式不能拿到竖屏工程里用(`build` 会报「场景舞台 A,工程画布 B」)。竖屏与方形舞台:
|
|
157
|
+
- 多画并置优先**上下分区**(关系、对照都上下摆),MUST NOT 把横屏的左右并排硬塞进窄舞台;
|
|
158
|
+
- 字幕与关键信息避开上下边缘与右侧按钮区(平台界面会盖住),字幕放画面中下部;
|
|
159
|
+
- 人脸构图规则(规则 5)照旧;机检规则对任何舞台同样适用。
|
|
160
|
+
- ❌ 反例:竖屏里左右各放一张 540 宽的画面,人脸被挤成一条缝,右边那张还被点赞按钮压住。
|
|
161
|
+
10. **窗口边与底轨片段边对齐,不留几帧残段。** 合成一结束(或出现前),底下横跨窗口边的那段画面会先露出来;只露几帧就换片,观感就是闪了一下。`plan` / `review` 会自动把窗口外扩到换片点(阈值 0.6 秒),`lint` 的 `edge-flash` 会点名没对齐的窗口——**只吞横跨窗口边的片段尾巴**:窗口边之后才开始的新片段(有意铺的转场、闪白、短镜头)一律不碰,不管多短。**短插入先收**:横跨窗口边的是一段短于 1 秒、不在口播主轨上、从窗口里开始(入窗一端:在窗口里结束)的独立插入时,它不是「窗口里本来就在播的尾巴」,窗口收到它的起点(终点)让它完整露出;`lint` 的 `edge-insert` 点名盖住了短插入的窗口。改起止后(含上游改了 B-roll 之后)重新 build → lint → lay。这条以后所有窗口都要注意。
|
|
162
|
+
- ❌ 反例:窗口在 15.90 秒结束,底下 B-roll 那段到 16.0 秒才完——合成一结束先闪 6 帧 B-roll 再回到讲者。
|
|
163
|
+
- ❌ 反例:为了「对齐」把窗口外扩到 0.417 秒的胶片灼烧转场结束,合成画在最上层,把有意铺的转场整个盖住。
|
|
164
|
+
- ❌ 反例:窗口末尾 727.2–727.85 秒是主理人铺的 0.65 秒栏目 OP 插入,起点在窗口里、横跨窗口终点;按「外扩到它的终点」把它整个吞进窗口盖住了——应收到 727.2 秒。
|
|
165
|
+
|
|
166
|
+
## 场景写法速查
|
|
167
|
+
|
|
168
|
+
场景文件四段(下例舞台 1920×1080;竖屏工程 `stage` 是 `[1080, 1920]`,坐标按它写):
|
|
169
|
+
|
|
170
|
+
```html
|
|
171
|
+
<script type="application/x-cp-spec">
|
|
172
|
+
{
|
|
173
|
+
"id": "cp-w03",
|
|
174
|
+
"stage": [1920, 1080], // 舞台 = 工程画布(scaffold 写好,别手改)
|
|
175
|
+
"window": [77.483, 90.85], // 时间线秒;build 会吸附到帧格
|
|
176
|
+
"takeover": ["subtitles", "overlay"],
|
|
177
|
+
"slots": {
|
|
178
|
+
"teacher": { "bind": { "kind": "ref-lane", "role": "a-roll" }, "label": "讲者", "pin": { "track": 0 } },
|
|
179
|
+
"heavy": { "bind": { "kind": "own", "facet": "化浓妆的少女近景", "starts_at": "浓妆" }, "label": "浓妆",
|
|
180
|
+
"pin": { "material": "broll-local-xxx", "src_in_ms": 116250, "dur_t": 3.8, "starts_at_f": "浓妆" } },
|
|
181
|
+
"subs": { "bind": { "kind": "text", "source": "subtitles" }, "label": "字幕" }
|
|
182
|
+
},
|
|
183
|
+
"anchors": { "浓妆": ["u0026", "特别会化浓妆"], "因为妈妈": ["u0028", "因为妈妈"] }
|
|
184
|
+
}
|
|
185
|
+
</script>
|
|
186
|
+
<style> /* 这颗的版式 */ </style>
|
|
187
|
+
<div class="bed dark"></div>
|
|
188
|
+
<div class="shadow" data-for="heavy" style="border-radius:16px"></div>
|
|
189
|
+
<div data-slot="heavy" data-z="11" data-fit="cover" data-shape="roundrect" data-radius="16" data-crop="0,0,0.2,0"></div>
|
|
190
|
+
<div class="frame light thin" data-for="heavy" data-layer="front" style="border-radius:16px"></div>
|
|
191
|
+
<div id="tg1" class="ptag warm" data-layer="front">浓妆</div>
|
|
192
|
+
<div id="cap" class="cap dark" data-layer="front"></div>
|
|
193
|
+
<script>
|
|
194
|
+
const { A, prog, at, mix, seq, place, reveal, caption, ease } = CP;
|
|
195
|
+
const R = [96, 120, 1160, 652];
|
|
196
|
+
CP.render = (t) => {
|
|
197
|
+
at("heavy", R, seq(t, A("浓妆")));
|
|
198
|
+
place("tg1", R[0] + 20, R[1] + 20, seq(t, A("浓妆")));
|
|
199
|
+
caption("cap", "subs", t, ["浓妆"]);
|
|
200
|
+
};
|
|
201
|
+
</script>
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
- **槽位绑定**:`ref-lane {track}`(某条轨在该时刻的画面,讲者常用);`ref {clip_id}`(某个片段,窗口外定格首末帧);`own {material, src_in_ms, dur_t | dur_f, starts_at: 锚点名 | starts_at_t: 时间线秒}`(自选素材的一段;之前首帧、之后末帧定格);`text`(字幕文本输入,无几何)。
|
|
205
|
+
- **锚点**:`[句 id, 关键词, 第几处(0 起)]`,取关键词首字在时间线上的时刻;场景里 `A("名字")` 得局部秒。关键词所在的字被剪掉时取其后第一个保留的字。匹配时关键词与句子都忽略空格、标点与大小写,英文按整词(`["u0001", "cold brew"]` 直接写;`"tea"` 不会命中 `teas`)。关键词 MUST 从 `cp-wNN.context.md` 的原句里逐字抄,不凭拆分稿或设计说明转述(见上文「锚点照抄原文」)。
|
|
206
|
+
- **脚本语法**:`build` 先按浏览器同一套语法解析场景脚本,语法错就拒、指出场景文件第几行。最常见的坑是**行内 `//` 注释吃掉同一行后面的括号**:`at("a", R); // 左上 }` 里的 `}` 被注释掉,整段脚本语法错、`CP.render` 设不上,画面全停在默认位置。注释写在单独一行,或用 `/* … */`。
|
|
207
|
+
- **槽位元素**:`data-slot` 一槽一个;`data-z` 叠放次序;`data-fit` cover / contain;`data-shape` rect / roundrect / circle;`data-crop` 上右下左比例;`data-filter` 只收白名单滤镜。槽位元素是隐形占位框,CSS 的滤镜 / 裁切 / 遮罩 / 圆角 / 旋转对视频无效——全部写法与边界见下文「槽位契约一页纸」。
|
|
208
|
+
- **装饰跟随**:`data-for="<槽位>"` 的元素与槽位同框(`data-pad` 外扩);`.shadow` 在下(背景层),`.frame` / `.ring` 加 `data-layer="front"` 在上——**只给最上层的画面加前景描边**(规则 2)。用户在客户端挪、放大窗口后,`data-for` 装饰会跟着覆盖后的窗口走(工具箱 @2 起);所以**围着槽位的边框、阴影、角标一律用 `data-for`**,不要按槽位坐标手摆。场景里自己摆的标签(`place`)要贴着窗口时,用 `CP.boxed("<槽位>", [x, y, w, h])` 取覆盖后的窗口再算位置。旧工程(工具箱 @1 做的颗粒)先跑 `gtrk composite upgrade-kit --project <工程>`,装饰才会跟随。
|
|
209
|
+
- **分层**:缺省是背景层(画在视频之下);`data-layer="front"` 的子树在视频之上(文字、标签、描边、线条)。
|
|
210
|
+
- **定位**:工具箱只给**舞台的直接子元素**绝对定位(`#stage > *`)。放进容器里的子元素(如 `<div id="grid">` 下的一排徽章)不会自动定位,`left` / `top` 不生效、按文档流挤成一列(lint 报 `unpositioned-offset`)——容器内要摆位置的子元素自己写 `position:absolute`,或加工具箱的 `.abs` 类;坐标相对容器(容器自己要写宽高)。
|
|
211
|
+
- **工具箱 `CP`**:`boxed(槽位, [x,y,w,h])` 用户窗口覆盖后的框;`prog(t, 起, 时长, ease)` 进度;`span` 进出;`at(id, [x,y,w,h], 透明度)` 定框;`mix(矩形A, 矩形B, p)` 版式插值;`seq(t, 到点, 下一张到点)` 同一位置逐句换画面的透明度;`place(el, x, y, o)`;`reveal / look / wipe / draw / typeOn`;`caption(el, "subs", t, 高亮词[], 隐藏区间[])`;`cues("subs")` 取字幕条目(局部帧);`fps()`。
|
|
212
|
+
- **常用样式**:`.bed`(底色)/ `.bed.dark`;`.kicker` `.h1` `.h2` `.h3` `.body` `.tag` `.num`;`.ptag` / `.ptag.warm`(画面标签);`.cap` / `.cap.dark`(字幕,中性缺省,见编排规则 7);`.bubble`(对话气泡);`.stamp`(印章);`.card` `.pill` `.rule`;`.credit`(出处卡)。配色与字体都是变量,缺省值写在 `:root` 上:`--bg --bg2 --ink --muted --line --accent --accent2 --accent3 --alert --font --font-serif`。这些类对场景里所有同名 class 生效,自己起类名别撞(见下文「工具箱预置类一览」)。
|
|
213
|
+
- **字号地板**:屏上文字(正文、标签、角标、数字)不小于 32px——社媒有效地板,横屏、竖屏舞台同一口径;工具箱缺省已守住(标签类 `.tag` `.kicker` `.num` `.pill` `.ptag` 都是 32px),场景自己写字号时 MUST NOT 往下压,缩放(`look` 的 `s`、SVG 的 viewBox)之后的有效字号也算——`lint` 报 `small-text`(逐帧机检按完全显现时的有效字号量)。没写字号的文字是浏览器缺省 16px。出处卡 `.credit` 例外:贴图小字,缺省 24px 白字配深色半透明底条。栏目风格 skill 有更高的地板以它为准。
|
|
214
|
+
- **槽位属性每帧重读**:`data-filter`、`data-crop`、槽位框每帧都会重读,可以在 render 里动态改(起雾、压暗、推近)。
|
|
215
|
+
- **窗内底色迁移(暗底 → 亮底)**:主题若按 `#stage:has(> .bed.dark)` 这类选择器切暗色变量,它看的是节点在不在、不看透明度——把 `.bed.dark` 淡出到透明度 0,暗色变量照样生效,文字仍是暗底配色。所以按 `t` 决定 `.bed` 上挂不挂 `dark` 类(`classList.toggle("dark", t < 切换点)`;render 是 `t` 的纯函数,这样是确定性的);过渡那一小段用 `color-mix(in srgb, <暗底文字色> p%, <亮底文字色>)` 混两档文字、线条颜色(`p` 由 `prog(t, …)` 算,写进元素的 `style`),切换点前后颜色连续,不会一帧跳色。底色本身照常用两层 `.bed` 交叉淡化。
|
|
216
|
+
- **字幕底条的空档**:窗口内字幕若带贴字底条(例如 `.cap.film.paper > span` 这类给 `span` 加 `padding` 与底色的写法),MUST 同时写 `span:empty { padding: 0; background: transparent; }`(选择器按你的字幕类写)——句与句之间的空档里 `span` 是空的,不写这条就画出一个空的小灰块,看起来就是闪一下。
|
|
217
|
+
- **前景层的 `<path>` 会被当线条查**:前景层的 `<path>`(包括 `<mask>` 里的)会被 lint 当线条查「穿过画面」——描边遮罩用 `<rect>`。
|
|
218
|
+
- **图标飞入别扫过画面**:前景层图标的飞入路径别扫过可见视频槽位。
|
|
219
|
+
- **纯函数**:场景脚本 MUST NOT 用 `Date`、`Math.random`、`requestAnimationFrame`、`setInterval`、`setTimeout`(lint 会拦)——同一帧号永远画出同一画面,客户端是逐帧 seek 的。
|
|
220
|
+
|
|
221
|
+
### 工具箱预置类一览
|
|
222
|
+
|
|
223
|
+
`build` 把工具箱样式 `kit.css` 内联在每颗颗粒的最前面(之后接 `theme.css`、再接场景样式),下面这些类会作用到场景里**任何**用了同名 class 的元素。场景或风格里自己起同名的类(例如拿 `.card` 当镂空视频窗、拿 `.rule` 当「规矩」条目),工具箱给它的样式会一起套上——白底圆角挡住视频、高度锁成 3px 文字叠在一起都是这么来的(`lint` 报 `kit-class-collision`)。自己的类一律起不撞名的名字(带前缀,如 `.s-card`、`.w18-rule`);就要用同名类时,把下表「撞名时要覆盖」那几项写全。改工具箱的类本身(`.pill` 改高度圆角、`.frame` 换描边色、`.bed.dark` 换底、`.cap.film` 改字幕)是正常用法,不算撞名。
|
|
224
|
+
|
|
225
|
+
| 类 | 关键缺省值 | 撞名时要覆盖 |
|
|
226
|
+
|---|---|---|
|
|
227
|
+
| `.bed` / `.bed.dark` | 满幅底色:`left/top 0`、`width/height: 100%`、`background: var(--bg)`;`.dark` 换深色径向渐变 | 底色专用,别另作他用 |
|
|
228
|
+
| `.cap` / `.cap.dark` / `.cap b` | 字幕:`left: 160px; top: 958px; width: 1600px; height: 70px; line-height: 70px`、44px、居中、不换行;`b` 用强调色 | `top` `height` `line-height` `white-space`(竖屏舞台必改,位置是按 1920×1080 写的) |
|
|
229
|
+
| `.card` | `background: #FFFFFF; border-radius: 22px; box-shadow: 0 10px 30px rgba(0,0,0,.08)` | `background` `border-radius` `box-shadow` |
|
|
230
|
+
| `.rule` | `height: 3px; background: var(--ink)`(一条分隔线) | `height` `background` |
|
|
231
|
+
| `.pill` | `height: 60px; line-height: 60px; padding: 0 28px; border-radius: 30px`、32px 700、不换行 | `height` `line-height` `border-radius` `padding` `white-space` |
|
|
232
|
+
| `.stamp` | 72px 900 警示色、`border: 6px solid var(--alert); border-radius: 14px; padding: 6px 26px`、不换行 | `border` `border-radius` `padding` `font-size` |
|
|
233
|
+
| `.bubble`(`.now`) | `height: 76px; line-height: 76px; border-radius: 38px 38px 10px 38px; background: #FFFFFF`、阴影、`border: 2px solid transparent`、32px、不换行 | `height` `line-height` `background` `border-radius` `box-shadow` |
|
|
234
|
+
| `.ptag`(`.warm`) | `height: 54px; line-height: 54px; border-radius: 27px; background: rgba(20,20,22,.74)`、白字 32px 700 | `height` `background` `border-radius` `color` |
|
|
235
|
+
| `.credit` | 出处卡:`background: rgba(20,20,22,.72); border-radius: 8px; padding: 4px 14px`、白字 24px | 出处卡专用(字号地板的唯一例外),别另作他用 |
|
|
236
|
+
| `.shadow`(`.round`) | 槽位阴影:`border-radius: 18px; box-shadow: …; background: #000` | `background` `box-shadow` `border-radius` |
|
|
237
|
+
| `.frame`(`.round` `.thin` `.light`) | 槽位描边:`border: 3px solid var(--ink); border-radius: 18px` | `border` `border-radius` |
|
|
238
|
+
| `.ring`(`.light`) | 圆形描边:`border: 4px solid var(--ink); border-radius: 50%` | `border` `border-radius` |
|
|
239
|
+
| `.h1` `.h2` `.h3` | 96 / 64 / 44px、900 / 900 / 700、`white-space: nowrap` | 要换行就覆盖 `white-space` |
|
|
240
|
+
| `.kicker` `.tag` `.num` | 32px;`.kicker` 强调色 700 字距 .28em、`.tag` 次要色字距 .2em、`.num` 强调色 800;都不换行 | `letter-spacing` `color` `white-space` |
|
|
241
|
+
| `.body` | 34px、`line-height: 1.5`、正文色 | — |
|
|
242
|
+
| `.serif` | `font-family: var(--font-serif)` | — |
|
|
243
|
+
| `.abs` | `position: absolute; box-sizing: border-box`(容器里的子元素要定位就加它) | — |
|
|
244
|
+
|
|
245
|
+
另有几条不是类、但同样作用到场景:
|
|
246
|
+
- `#stage > *` 一律 `position: absolute; box-sizing: border-box`——只管舞台的**直接子元素**,容器里的子元素要自己定位(见上文「定位」)。
|
|
247
|
+
- `#stage` 没写字号:没写 `font-size` 的文字是浏览器缺省 **16px**,低于字号地板(`lint` 报 `small-text`)。
|
|
248
|
+
- `[data-slot] { visibility: hidden !important; }`:槽位元素永远不显示,见下节。
|
|
249
|
+
- 修饰类 `.dark` `.round` `.thin` `.light` `.warm` `.now` 只在与上表的类组合时有样式,单独用不受影响。
|
|
250
|
+
|
|
251
|
+
### 槽位契约一页纸
|
|
252
|
+
|
|
253
|
+
**槽位元素只是一个隐形的占位框**(工具箱 `[data-slot] { visibility: hidden !important; }`):每帧工具箱量出它的框和几个 `data-*`,交给宿主(客户端预览 / 出片烘焙 / `lint` 静帧)把视频或图片画进去。所以它身上的 CSS 视觉效果一概不作用在视频上,只有下面这些算数:
|
|
254
|
+
|
|
255
|
+
| 写法 | 作用 | 取值与边界 |
|
|
256
|
+
|---|---|---|
|
|
257
|
+
| `data-slot="<槽位>"` | 认领规格 `slots` 里的一个槽位 | 每个槽位恰好一个元素(`build` 校验);文本输入 `text` 槽位不要元素 |
|
|
258
|
+
| 框(位置、大小) | 视频画在哪 | 量的是 `getBoundingClientRect()`(相对舞台)——`at()` 写的 `left/top/width/height` 为准;CSS `transform` 的位移、缩放会算进框,旋转只得到外接矩形(视频不转) |
|
|
259
|
+
| 透明度 | 视频的不透明度 | 只读槽位元素**自己**的 `opacity`;祖先容器的透明度不传给视频。不透明度 ≤ 0.001 或框小于 0.5px 视为不可见 |
|
|
260
|
+
| `data-z` | 槽位之间谁在上 | 整数(客户端不收小数,按 0 算),小的先画;所有视频都在背景层之上、前景层之下,`z-index` 不管用 |
|
|
261
|
+
| `data-fit` | 铺法 | `cover`(缺省,裁满)/ `contain`(留边) |
|
|
262
|
+
| `data-shape` / `data-radius` | 画框形状 | `rect`(缺省)/ `roundrect`(配 `data-radius="N"` 像素圆角,最大取宽高的一半)/ `circle`(内切椭圆) |
|
|
263
|
+
| `data-crop` | 先裁源画面再铺 | `"上,右,下,左"`——**顺序是上、右、下、左**(与 CSS 的 `inset()` 同序),各为源画面宽 / 高的比例,`[0, 1)`;任一项越界整串作废。左裁 0.427083 = 去掉源画面左边 42.7%。源画面与舞台同宽高比、框从 x 起铺到舞台右缘且满高时,左裁 = x / 舞台宽 即与满幅画面像素对齐 |
|
|
264
|
+
| `data-filter` | 视频滤镜 | 白名单:`blur(Npx)`、`brightness(N 或 N%)`、`contrast(…)`、`saturate(…)`、`grayscale(…)`,空格分隔至多 5 个;数字要有整数位(写 `0.8` 不写 `.8`),`blur` 带 `px`、其余不带 `px`。任一项不合法,客户端**整串丢弃**(不加滤镜),烘焙与静帧却照原样画——预览与成片对不上(`lint` 报 `slot-filter-unsupported`) |
|
|
265
|
+
| `data-layer="front"` | 这棵子树画在视频**之上** | 文字、标签、描边、线条、半透衬底(`#veil`)都放前景层;缺省(不写)是背景层,画在视频之下。前景层里不透明的填充会盖住视频,衬底要半透(`color-mix(… 62–64%, transparent)`) |
|
|
266
|
+
| `data-for="<槽位>"`(`data-pad="N"`) | 装饰跟着槽位走 | 边框、阴影、角标:`at()` 放槽位时同框(外扩 N 像素)、同透明度;用户在客户端挪、放大窗口时跟着覆盖后的窗口走。只有 `at()` / `slot()` 放的槽位带得动它 |
|
|
267
|
+
|
|
268
|
+
**每帧重读**:框、透明度、`data-filter`、`data-crop`、`data-shape`、`data-radius`、`data-fit`、`data-z` 每帧都重新量,可以在 `render` 里动态改(起雾改 `el.dataset.filter`,推近改 `at()` 的框)。
|
|
269
|
+
|
|
270
|
+
**工具箱函数对槽位做什么**:
|
|
271
|
+
- `at(id, [x, y, w, h], 透明度 = 1)`(= `slot(id, x, y, w, h, 透明度)`):给槽位元素写 `left/top/width/height` 与 `opacity`,同时把 `data-for` 装饰摆到同一个框(外扩 `data-pad`)、同一透明度。**放槽位只用它**——一次都没 `at()` 的槽位是 0×0 的空框,整段看不见(`lint` 报 `slot-never-placed`)。
|
|
272
|
+
- `look(el, 透明度, dx, dy, 缩放)`:写 `opacity` 与 `transform: translate() scale()`(不旋转)。用在槽位上位移缩放会算进框,但 `data-for` 装饰不跟——槽位的运动用 `at()` + `mix()`,`look` / `reveal` 留给文字和装饰。
|
|
273
|
+
- `place(el, x, y, 透明度)`:只写 `left/top` 与 `opacity`,不改宽高、不带装饰——给标签、角标用;要贴着槽位用 `CP.boxed(槽位, 框)` 取用户调整后的框。
|
|
274
|
+
- `box(el, x, y, w, h)`:只写框,不写透明度、不带装饰。
|
|
275
|
+
- `wipe(el, p)`:写的是 `clip-path`——对槽位无效。
|
|
276
|
+
|
|
277
|
+
**对视频无效的 CSS**(写在槽位元素上、或命中它的样式规则里、或脚本里给它赋值,`lint` 都报 `slot-css-ignored`,致命):
|
|
278
|
+
|
|
279
|
+
| 写了 | 视频上 | 改成 |
|
|
280
|
+
|---|---|---|
|
|
281
|
+
| `filter` / `backdrop-filter` | 不糊、不压暗 | `data-filter`;毛玻璃 = 同一路画面另开满幅槽位、`data-filter="blur(Npx)"` 垫底 |
|
|
282
|
+
| `clip-path`、`wipe()` | 不裁 | `data-crop="上,右,下,左"`;形状用 `data-shape` |
|
|
283
|
+
| `mask` / `mask-image` | 不羽化 | 前景层盖半透衬底,`mask-image` 写在衬底上 |
|
|
284
|
+
| `border-radius` | 不圆角 | `data-shape="roundrect" data-radius="N"` / `data-shape="circle"` |
|
|
285
|
+
| 带 `rotate` / `skew` / `matrix` / `perspective` 的 `transform` | 不转、不斜切(按外接矩形画) | 去掉旋转;位置大小用 `at()` |
|
|
286
|
+
| `object-fit` / `object-position` | 不管用 | `data-fit` |
|
|
287
|
+
| `mix-blend-mode` | 不混合 | `data-filter` 的 `brightness` / `contrast` / `saturate` / `grayscale` |
|
|
288
|
+
| `border` / `box-shadow` / `background` | 看不见(元素是隐形的) | 描边、阴影用 `data-for` 装饰(`.frame` / `.shadow`) |
|
|
289
|
+
| `visibility`、祖先容器的 `opacity` | 不隐藏 | 槽位自己的透明度:`at(id, 框, 0)` |
|
|
290
|
+
|
|
291
|
+
### 槽位里的去字幕 / 去水印
|
|
292
|
+
|
|
293
|
+
时间线片段上挂的「去字幕 / 水印」遮罩会自动带进合成槽位:`ref` 槽位用被引用片段的遮罩,`ref-lane` 用该时刻轨上那段的,`own` 槽位用时间线上同一素材所有片段的遮罩(取并集)。客户端预览、`gtrk composite bake` 成片、`gtrk composite lint --stills` 静帧三处一致,模糊度与羽化同时间线。不要为了躲烧录字幕另画遮罩或硬裁 `data-crop`(裁切只用于构图)。遮罩改了下次烘焙自动重烤,没改则命中缓存。客户端完成页若提示「本机 gtrk CLI 过旧,合成画面里这些片段没有去字幕 / 水印」,升级 CLI 后重导。
|
|
294
|
+
|
|
295
|
+
## 风格
|
|
296
|
+
|
|
297
|
+
配色、字体、纹理不在工具箱里,写在 `<工程>/composite/theme.css`(构建时接在工具箱样式之后)。工具箱的缺省变量写在 `:root` 上,theme 写 `:root { --bg: …; }` 即生效;旧工程里写成 `:root, #stage { … }` 的照样生效,不用改。按顺序找风格的正本:
|
|
298
|
+
|
|
299
|
+
1. 当前栏目配置 `style.skills` 里有 `produces == "composite"` 的条目 → 触发它产 `theme.css`(与 `gtrk-mg`、`gtrk-ai-drama` 的栏目解析同一套);
|
|
300
|
+
2. 没有 composite 条目、但有 `produces == "MG"` 的栏目风格 skill → **MUST 先读它,以它为正本、按它的硬规则定 `theme.css`**,逐条照做:主题怎么选(按什么决定这一期用哪套主题)、同一期内底色是否分阶段迁移、焦点色的稀缺规则、单页语义色上限、字号地板与字幕安全区、动效密度、图标与线型规则等。它写了的你不改,它没写的才按片子补、补的不得与它冲突;回执里写明 `theme.css` 依据了它的哪几条,并建议栏目照迁移说明补一份 composite 风格;
|
|
301
|
+
3. 都没有 → 按这条片子的内容临场定一套(讲什么、什么调性 → 配色倾向、字体气质、动效克制度)。
|
|
302
|
+
|
|
303
|
+
不论哪种来源:**全片所有合成颗粒沿用同一份 `theme.css`**;场景里 MUST NOT 写死色值(一律 `var(--…)`,栏目要的额外色在 `theme.css` 里另起变量);MUST NOT 每颗各自为政,也 MUST NOT 套一个与内容无关的固定模板。
|
|
304
|
+
|
|
305
|
+
- ❌ 反例:栏目有自己的 MG 风格 skill,对主题配色有明令(比如按本期题材选主题、禁止某种每期都用的固定配色),合成却没去读它、临场定了一套与它冲突的配色——满屏卡、合成与叠层成了几套视觉语法。
|
|
306
|
+
|
|
307
|
+
**派单给颗粒档 / 合成档时带上栏目硬规则**:把场景(或叠层颗粒)交给另一个子代理 / 档位去写时,订单里写了「不要再读 skill」「照订单做即可」这类话,就 MUST 把栏目 MG 风格 skill 的**硬规则要点原文写进订单**——按栏目 skill 的实际条目逐条抄,通常包括:衬底(scrim)不透明度区间、不切两半、字号地板、字幕安全区(底部留给字幕的范围)、焦点色稀缺规则、单页语义色上限等。没抄进订单的规则,接单方就不知道,等于没有。订单里也照抄上下文文件里的原句(锚点关键词要用)。
|
|
308
|
+
- ❌ 反例:订单只写「按栏目风格做,不要再读 skill」,接单方没见过栏目对衬底不透明度的上限,四颗叠层底板做到 0.8–0.96;另一颗把左半屏铺成实色底板盖住画面(违反编排规则 3)。
|
|
309
|
+
|
|
310
|
+
## 满屏卡(零槽位合成)
|
|
311
|
+
|
|
312
|
+
标题牌、章节卡、数据卡、纯排版的并置面板——整幅纯排版、没有画面槽位的那种版,是**满屏卡**:一颗零槽位合成,随合成在本机烘焙出片、不再云渲。
|
|
313
|
+
|
|
314
|
+
- **入口**:拆分稿的零槽位版式窗口(`zero_slot: true`;旧稿里的满屏 MG 由 `gtrk split` 落地时自动转来,窗口 id 形如 `LB07`)经 `plan --mode split` 进来,审定与逐窗口流程同其它合成。CP 行与 `composite status` 里它带 `zero_slot: true`;审稿稿「建议画面」一格写「纯排版(满屏卡)」,不给画面数。
|
|
315
|
+
- **骨架**:`scaffold` 给它只写字幕输入 `subs`——工程有讲者轨也不写讲者槽位,MUST NOT 为满屏卡造讲者框或占位画面;`takeover` 固定字幕 + 叠层;窗口有 `bg` 时 `.bed` 已按它写底色。
|
|
316
|
+
- **`subs` 不用也要留着**:合成颗粒要求槽位非空,零槽位靠这个字幕输入满足——删掉它 `build` 就报 `$.slots:必须为非空对象`(命令会补一句提示)。
|
|
317
|
+
- **屏上文字只用口播原话**:经 `caption()` / `cueAt()` 从 `subs` 取,不另编文案。上下文文件「满屏卡(零槽位)」一段列着原 MG 派单的 `theme`、`bg` 与被接管叠层的要点(`covered_overlays`)——它们是设计参考,叠层要强调的词句由这张卡自己画。
|
|
318
|
+
- **风格**:与其它合成同一份 `theme.css`,正本按「风格」一节的顺序找——`produces == "composite"` 条目;没有就 MUST 先读同栏目 `produces == "MG"` 的风格 skill、按它的硬规则定(全片满屏卡、合成与叠层看起来是一套),回执里建议栏目照迁移说明补一份 composite 风格;都没有才按片子临场定一套。
|
|
319
|
+
- **迁移说明**:栏目 MG 风格 skill 里原有的满屏卡写法(GSAP 时间线、实心底、配色字体)怎么改写成场景,见随 CLI 分发的 `references/fullscreen-card-migration.md`。
|
|
320
|
+
- **放图就成了带槽位的合成**:满屏卡里要放一张图(例如联网取回的图,见「联网取回的图」),加 `own` 槽位即可——它就不再是纯排版满屏卡,`build` 提示「按带槽位的合成计」,照常构建。
|
|
321
|
+
- **计价与出片**:满屏卡随合成本机烘焙、不走云渲;内置 AI 写一张满屏卡按「颗」计价(`composite status --json` 的 `pending_cards` 数的就是它),带画面的合成按「段」。
|
|
322
|
+
|
|
323
|
+
## 与 `/gtrk-mg` 的分工(按画面三层)
|
|
324
|
+
|
|
325
|
+
口径正本是《成片型图纸公约》§二⁗「画面三层」:底(拍到的、找到的画面)/ 版(一个时间窗里整幅画面怎么排)/ 叠(在现有画面上点出一个对象)。一句话:**叠层 → `/gtrk-mg`;版(带槽位的合成与满屏卡)→ 合成(本 skill)。**
|
|
326
|
+
|
|
327
|
+
- **合成是版**:一段时间内整幅画面由它重排——画中画拼贴、逐句换画面、对照并排、并列卡片、字幕排版;讲者、B-roll、图片作为槽位进来;没有画面槽位的纯排版整幅是满屏卡(上一节)。凡要改变讲者在画面里的位置、大小或可见区域的、凡整幅纯排版的,都归你。
|
|
328
|
+
- **叠层是 `/gtrk-mg` 的透明颗粒**:只在现有画面上点出一个对象(点题词、单个数、印章、角标)。整段落在合成窗口里的叠层不产不铺(`gtrk mg status` 标 `covered_by`)——出片时一律不出画,与场景的 `takeover` 声明无关;用户就要在这段强调一个词时,写进合成场景本身。
|
|
329
|
+
- **旧工程已铺满屏 MG 的段**:没重跑拆分的旧派单里,满屏 MG 照旧由 `/gtrk-mg` 产铺、云渲出片(AI 判定不会在已铺满屏 MG 的段提窗口);重跑 `gtrk split` 后它们转成满屏卡归你,满屏卡做成之前旧颗粒会先留着,做成之后再跑 `gtrk mg` 剥掉。
|
|
330
|
+
- **大图走你,不走颗粒**:要看清内容的图片进合成的 `own` 槽位(或底轨),MUST NOT 内联进任何 MG 颗粒。
|
|
331
|
+
|
|
332
|
+
## 联网取回的图
|
|
333
|
+
|
|
334
|
+
去处口径见《成片型图纸公约》§二⁗「画面三层」的「图片去处」。联网取回、要看清内容的图(新闻截图、论文页、产品图、照片)一律当合成的 `own` 槽位画进场景,**MUST NOT 内联进叠层颗粒**。
|
|
335
|
+
|
|
336
|
+
1. **取图**:内置 AI 用 `web_fetch` 取回,文件落在工程 `web/`,每次取回往 `web/sources.jsonl` 追加一行出处(回执里给来源 id)。网页原图可能很大,取图时挑合适尺寸。
|
|
337
|
+
2. **登记**(别手写 `composite/materials.json`):
|
|
338
|
+
|
|
339
|
+
```bash
|
|
340
|
+
gtrk composite materials add --from-web-source <来源 id> --project <工程> # 用取回的原图
|
|
341
|
+
gtrk composite materials add work/crop.png --from-web-source <来源 id> --project <工程> # 裁过 / 标注过的图:记 derived_from,出处不变
|
|
342
|
+
gtrk composite materials list --project <工程> # 看已登记素材、出处与被哪些槽位引用
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
命令确认是图片(扩展名 + ffprobe 宽高)、拷进 `gtrk/assets/web/<素材 id>.<扩展名>`(工程自包含,`web/` 被清理也不缺图),素材 id 缺省 `web-<来源 id>`;出处文字 `credit` 由命令按 `sources.jsonl` 原文字段拼(`站点|标题`,缺一取一,都缺取网址主机名),**不经你之手**。同一个 id 已登记另一张图时报错,用 `--id <新 id>` 另起;来源记录改过(同一来源追加了新行)就重跑 `materials add` 刷新 `credit`。
|
|
346
|
+
3. **放进场景**:`own` 槽位 `pin` 写 `{ "material": "<素材 id>", "dur_t": <秒> }`——图片入点写 0、在场时长按版式定;`shots` 不适用于图片(联系表与切点是视频概念)。圈重点、标注由场景自己画。
|
|
347
|
+
4. **出处卡**:绑定联网素材的**每个**槽位配一个出处元素,文字**原样照抄**上下文文件(`cp-wNN.context.md`「联网素材与出处」)里的 `credit`——MUST NOT 改写、翻译、截断或润色;小字、贴着图、与图同进同出(图出现时出处卡可见,图退场时一起退):
|
|
348
|
+
|
|
349
|
+
```html
|
|
350
|
+
<div class="credit" data-credit-for="paper" data-layer="front">arXiv|Scaling Laws for Neural Language Models</div>
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
想加「来源」之类的固定标签,放在出处元素**之外**;几张同源图各配一个(可以叠在同一位置)。文字里的 `&` `<` `>` 写成实体,核对按解码后的文字比。
|
|
354
|
+
5. **`lint`**:静态核对四条,任一不过即机检不过(退出码 1)——缺出处卡(`credit-missing`)、出处卡文字与 `credit` 不一致(`credit-mismatch`)、`credit` 与当前 `sources.jsonl` 重拼的不一致(`credit-stale`)、`data-credit-for` 指向不存在的槽位(`credit-orphan`);有浏览器时另做帧检,图可见而出处卡看不见报 `credit-hidden`(告警,不拦)。
|
|
355
|
+
|
|
356
|
+
- **外部 agent 自己下载的网络图**(不经 `web_fetch`):先按 `web_fetch` 的来源记录格式往 `web/sources.jsonl` 追加一行(`{"id","kind":"image","url","title","site_name","date","fetched_at","path","mime","bytes","sha256"}`,`id` 用「短名-内容哈希前 8 位」,`path` 相对工程目录),再 `materials add --from-web-source`。来自网络的图 MUST 带来源登记;`web/` 下的图不带 `--from-web-source` 登记时命令会告警。
|
|
357
|
+
- **出处卡不等于获得使用许可**:标注来源不代表能用,商用前自己确认授权;有疑虑照实告诉用户。
|
|
358
|
+
- **叠层要的图标、logo**:用 SVG 文本直接写进叠层颗粒,不走素材登记(叠层小图内联暂不提供登记入口)。
|
|
359
|
+
|
|
360
|
+
## 已知限制
|
|
361
|
+
|
|
362
|
+
1. **图片当 `own` 槽位要新版两端**:新版 gtrk 的 `lint` 与新版客户端的预览都已认图片槽位(unify-visual-layer-planning 3.5 / link-visual-layer-planning 3.3)。用户的客户端还是旧版时,预览里图片槽位会空着(出片不受影响,烘焙一直认图片);要在旧版上预览,先把图片转成一段视频(本地 ffmpeg 转成与在场时长等长的静帧 mp4,零计费;或 `gtrk tool image_move` 运镜,按张计费),再当 `own` 视频素材登记。
|
|
363
|
+
2. **客户端不在合成窗口里隐藏画中画轨**:见编排规则 2 的画中画一条;场景要铺满幅底,讲者只出现一次。
|
|
364
|
+
3. **lint 静帧放不了 m2ts 这类素材**:lint 出静帧用的浏览器打不开 m2ts / mts / ts(MPEG-TS 封装)以及 avi / mpg / wmv / flv,静帧里绑这类素材的槽位是空的(`lint` 会逐个告警、回执 `stills_skipped_materials`)——以烘焙结果或客户端预览为准。烘焙正常:它先用 ffmpeg 把素材转成中间文件再取帧,不受影响。排版机检本来就不取视频帧,也不受影响。
|
|
365
|
+
|
|
366
|
+
## 排错
|
|
367
|
+
|
|
368
|
+
| 现象 | 处理 |
|
|
369
|
+
|---|---|
|
|
370
|
+
| plan `--mode split` 报「拆分稿没有版式窗口」 | 旧拆分稿(没有 `composite` 队列):重跑拆分补版式窗口,或改用 `--mode auto` |
|
|
371
|
+
| build 告警「是满屏卡,场景却声明了画面槽位」 | 零槽位窗口的场景放了讲者 / 素材 / 图:要纯排版就删掉那个槽位;就要放图,照常构建(它成了带槽位的合成,按段计) |
|
|
372
|
+
| build 报 `$.slots:必须为非空对象` | 满屏卡把字幕输入 `subs` 删了:加回 `"subs": { "bind": { "kind": "text", "source": "subtitles" } }`(不用也留着) |
|
|
373
|
+
| build 报「素材 X 未登记」 | 图片用 `gtrk composite materials add` 登记;视频写进 `composite/materials.json`(`id` + `path`);或换工程里已登记的素材 |
|
|
374
|
+
| lint 报 `credit-missing`(联网素材缺出处卡) | 给绑定联网素材的槽位加 `data-credit-for="<槽位>"` 元素,文字照抄上下文里的 `credit`(见「联网取回的图」第 4 步) |
|
|
375
|
+
| lint 报 `credit-mismatch` | 出处卡文字被改写了:原样换成报错里给的 `credit`,不改、不译、不截断 |
|
|
376
|
+
| lint 报 `credit-stale` | 来源记录变了(或 `web/sources.jsonl` 不在了):重跑 `gtrk composite materials add --from-web-source <来源 id>`,再照新的 `credit` 改出处卡 |
|
|
377
|
+
| lint 报 `credit-orphan` | `data-credit-for` 写错了槽位 id:改成真实槽位,或删掉多余的出处元素 |
|
|
378
|
+
| lint 告警 `credit-hidden` | 图可见时出处卡看不见(透明 / 隐藏 / 出了舞台):让出处卡与图同进同出 |
|
|
379
|
+
| materials add 报「同一个 id 不能指两张图」 | 同一来源登记了另一张图(裁切 / 换图):加 `--id <新 id>` 另起,场景改绑新 id |
|
|
380
|
+
| build 报「锚点落在窗口外 / 找不到关键词」 | 关键词照句子原文抄(看 `context.md`;空格、标点、大小写不影响,英文按整词),或换一个落在窗口内的词;MUST NOT 凭拆分稿的画面描述转述 |
|
|
381
|
+
| build 报「场景脚本语法错误(场景文件第 N 行)」 / lint 报 `script-syntax` | 按报文行号改;「疑似病因」点名的多半是行内 `//` 注释吃掉了同一行后面的 `}` `)`——注释挪到单独一行或改 `/* … */`。改好再 build → lint |
|
|
382
|
+
| lint 报 `render-missing`(页面上没有 `CP.render`) | 场景脚本没跑到 `CP.render = …`:先看同一颗的 `script-error`(「颗粒加载时场景脚本就报错」带行号),多半是顶层代码报错;render 写成空函数也报这条。静帧不出,修好再 build → lint |
|
|
383
|
+
| lint 报 `edge-insert`(窗口边盖住了一段短插入) | 照报文给的起止 `review --adjust Wnn=起,止` 收到短插入的边上(会同步场景 `window`),再 `build --only` → `lint` → `lay --only`;用户就要盖住它时才 `--no-edge-snap` 原样保留 |
|
|
384
|
+
| plan / review / build 告警「越过口播 N 秒」 | 窗口伸到了口播之外,回执写明盖住的是什么(黑场、片尾卡、空档):不是用户要的就收回到口播内;用户要的,回执里照实写明理由 |
|
|
385
|
+
| `--only W21` 报「没有选中任何…」 | 报文列着现有的窗口 / 颗粒:窗口 id(`W21`)与颗粒 id(`cp-w21`)都认、大小写不敏感,照列出的写 |
|
|
386
|
+
| build 报「轨 N 在窗口内没有片段」 | 那条轨这段是空的:换轨,或改用 `own` |
|
|
387
|
+
| lint 报 `slot-css-ignored`(槽位上的 CSS 对视频无效) | 报文点名写在哪(内联 style / 样式规则 / 脚本 / 计算样式):滤镜改 `data-filter`、裁切改 `data-crop="上,右,下,左"`、圆角改 `data-shape` + `data-radius`、羽化改前景层衬底、旋转去掉(见「槽位契约一页纸」) |
|
|
388
|
+
| lint 报 `slot-filter-unsupported` | `data-filter` 只写白名单:`blur(Npx)` / `brightness` / `contrast` / `saturate` / `grayscale`,数字写 `0.8` 不写 `.8`,`blur` 带 `px`、其余不带——否则客户端整串丢弃、成片却照画 |
|
|
389
|
+
| lint 报 `slot-never-placed`(画面槽位从没放置 / 全程不可见) | render 里 `at("<槽位>", [x, y, w, h], 透明度)` 放它(满幅就是 `[0, 0, 舞台宽, 舞台高]`);这颗用不着它就从规格 `slots` 里删掉。在循环里放、静态认不出的,有浏览器时逐帧兜底,看得见就不报 |
|
|
390
|
+
| lint 告警 `no-anchors` | 照 `cp-wNN.context.md` 的原句在规格 `anchors` 里写 `[句 id, 关键词]`,分拍改用 `A("名字")`,别写死秒数 |
|
|
391
|
+
| lint 告警 `kit-class-collision` | 自己起的类撞了工具箱同名类:换不撞名的类名(加前缀),或覆盖报文列出的那几项(见「工具箱预置类一览」);有意沿用工具箱样式可忽略 |
|
|
392
|
+
| lint 告警 `small-text` | 屏上文字有效字号 < 32px:调大字号,缩放后也别压到 32px 以下;没写字号的文字是浏览器缺省 16px |
|
|
393
|
+
| lint 报 `border-over-slot` | 两张画面重叠且下层有前景描边:错开时序(等前一张到位再换)或去掉下层的前景描边 |
|
|
394
|
+
| lint 报 `stroke-through-slot` | 前景线条穿过画面:挪画面或改线条走向 |
|
|
395
|
+
| lint 报 `slot-out-of-stage` | 画面出了舞台:收回到舞台(= 工程画布,竖屏是 1080×1920)内(满屏底图除外) |
|
|
396
|
+
| lint 报 `edge-flash`(窗口边外只露几帧底轨就换片) | 照报文给的起止 `gtrk composite review --adjust Wnn=起,止`(会同步场景 `window`),或直接改场景规格的 `window`;再 `build --only` → `lint` → `lay --only`。报文点名的是横跨窗口边的那段;窗口边之后才开始的转场不会报。窗口按 `--no-edge-snap` 原样保留的,这条只告警 |
|
|
397
|
+
| lint 报「该时刻没有合成颗粒」 | `--stills` 填成了窗口内的局部秒:按报错里给的时间线秒重填(报错列着各窗口的时间线起止) |
|
|
398
|
+
| lint 告警 `empty-path`(前景层有空的 `<path d="">`) | 机检已跳过它、照常查完;不用就删掉,要画就给它路径(场景里随时间填 `d` 的,空着的那几帧也会告警) |
|
|
399
|
+
| lint 报 `lint-error` / `lint-aborted` | 工具箱排版自检在某帧报错 / 这颗的逐帧机检没跑完:报文里是浏览器给的原因,多半是场景脚本改坏了 DOM 或几何取不到;按原因改场景重跑 |
|
|
400
|
+
| lint 报 `unpositioned-offset`(容器里的徽章 / 卡片挤成一列、`left` / `top` 不生效) | 它们不是舞台的直接子元素:自己写 `position:absolute` 或加 `.abs`(见场景速查「定位」);本来就想按文档流 / flex 排的,删掉偏移 |
|
|
401
|
+
| build 报「场景舞台 A,工程画布 B」 | 工程画布改过(或拿了别的画幅的场景):按新画布重写场景,`gtrk composite scaffold --force` 重起骨架 |
|
|
402
|
+
| lint / lay 报「需重渲」 | 上游(粗剪 / 素材 / 字幕)改过:重跑 `build`(再 `lint`、`lay`) |
|
|
403
|
+
| lint 退出码 3 | 本机没 Chrome / Edge:排版未机检,用静帧人眼查,照实告诉用户 |
|
|
404
|
+
| lint 报 `impure-frame` | 同一帧号随渲染顺序画出不同画面:多半读了带变换元素的渲染后几何(如对正在缩放的元素用 `getBoundingClientRect` 量宽度)——改读 `offsetWidth` / `offsetLeft` 等不含变换的布局值 |
|
|
405
|
+
| bake 报「找不到可用的浏览器」(退出码 2) | 本机没有钉定浏览器也没有 Chrome / Edge:征得用户同意后 `gtrk deps install --browser` |
|
|
406
|
+
| bake 报「素材缺失:<路径>」 | 素材移动或删除了:恢复文件或重新登记路径后再烤这颗 |
|
|
407
|
+
| lay 报「没铺:时间线上已有同 id 的片段」 | 用户在客户端改过那颗:要重铺先请他在客户端删掉它 |
|
|
408
|
+
| 客户端 CP 行没出现提案块 | 请用户重新载入工程(客户端有未保存的改动时不会自动载入外部写入) |
|
|
409
|
+
|
|
410
|
+
## 被图纸快速成片接力调用
|
|
411
|
+
|
|
412
|
+
成片图纸(口播 / 解说 / 美食 / 配音 / 旅拍 / Vlog;直播切片与长剪短在用户答要时)的快速成片跑到「精剪包装」交棒本 skill 时,按《成片型图纸公约》§三⁵ 一杆到底,**不停**:
|
|
413
|
+
|
|
414
|
+
- **检查点①由你代审**:拆分稿带 `layouts` 键 ⇒ `plan --mode split`(窗口由拆分定,不再跑 `auto` 另挑);拆分稿没写 `layouts` 但转出了满屏卡(派单 `layouts_declared: false`)⇒ 先 `--mode split` 再 `--mode auto`,回执把「满屏卡(由满屏 MG 转来)」与「auto 补充的窗口」分开列;没有拆分稿或旧稿 ⇒ `plan --mode auto`(缺省密度 25%)。之后逐窗口读 `composite/plan.md`,判断这段是否真值得做,用 `review --approve / --reject` 写回;拆分的打算与信号都只是起点,不值得的不做。拆分写了 `layouts: []` ⇒ 零窗口,回执引述 `layout_note`。
|
|
415
|
+
- **逐窗口照常写设计说明、选片、场景、构建、机检**;机检不过改场景重跑,**至多三轮**,仍不过就 `review --reject` 该窗口,不阻塞其余窗口与交付。
|
|
416
|
+
- **不越过口播**:接力时不停、无从问用户,MUST NOT 自行把窗口伸到口播之外(回执出现「越过口播」告警就收回到口播内),交付回执里列出被收回的窗口。
|
|
417
|
+
- **检查点②并入图纸交付**:铺轨、烘焙之后,各窗口静帧随图纸交付时的那次检查一次给出。
|
|
418
|
+
- **回执**:交付时「精剪包装」一节列三项——做了的(时间、对应句、为什么做)、建议了没做的(超上限 / 不值得 / 机检三轮不过,各带原因)、烘焙结果(失败段按粗剪出画并点名)。
|
|
419
|
+
|
|
420
|
+
用户直接要合成(「看看哪里适合做合成」)或走逐步推进时,照下面「双模式」停。
|
|
421
|
+
|
|
422
|
+
## 双模式
|
|
423
|
+
|
|
424
|
+
| 模式 | 停点 |
|
|
425
|
+
|---|---|
|
|
426
|
+
| 快速成片 | 检查点①(审窗口)必停;全部窗口做完、lint 过后,检查点②一次给静帧,点头后一次铺完 |
|
|
427
|
+
| 逐步推进 | 检查点①;每个窗口的设计说明、静帧各停一次 |
|
|
428
|
+
| 图纸快速成片接力 | 不停:检查点①你代审、检查点②并入图纸交付(见上节) |
|