@remixmate/cli 0.9.14 → 0.9.16

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 (36) hide show
  1. package/README.md +1 -1
  2. package/README.zh-CN.md +1 -1
  3. package/dist/billing.d.ts +44 -0
  4. package/dist/billing.js +76 -0
  5. package/dist/capabilities.d.ts +5 -1
  6. package/dist/cli.js +0 -0
  7. package/dist/http.d.ts +3 -0
  8. package/dist/http.js +4 -0
  9. package/dist/manifest.json +13 -13
  10. package/dist/runner.js +9 -0
  11. package/package.json +1 -1
  12. package/skills/export-jianying/version.json +1 -1
  13. package/skills/gen-digital-human/SKILL.md +12 -0
  14. package/skills/gen-digital-human/skill.json +9 -3
  15. package/skills/gen-digital-human/version.json +1 -1
  16. package/skills/gen-image/SKILL.md +51 -17
  17. package/skills/gen-image/skill.json +11 -3
  18. package/skills/gen-image/version.json +1 -1
  19. package/skills/gen-script/SKILL.md +17 -21
  20. package/skills/gen-script/version.json +1 -1
  21. package/skills/gen-video/SKILL.md +17 -3
  22. package/skills/gen-video/skill.json +10 -2
  23. package/skills/gen-video/version.json +1 -1
  24. package/skills/gen-voice/SKILL.md +13 -1
  25. package/skills/gen-voice/version.json +1 -1
  26. package/skills/prepare-video-assets/SKILL.md +12 -0
  27. package/skills/prepare-video-assets/version.json +1 -1
  28. package/skills/render-video/SKILL.md +12 -0
  29. package/skills/render-video/scripts/render_video.py +63 -0
  30. package/skills/render-video/version.json +1 -1
  31. package/skills/template-registry/scripts/render_job_client.py +27 -0
  32. package/skills/template-registry/version.json +1 -1
  33. package/skills/video-parser/version.json +1 -1
  34. package/skills/web-record/SKILL.md +131 -133
  35. package/skills/web-screenshot/SKILL.md +93 -96
  36. package/skills/web-screenshot/version.json +1 -1
@@ -1,60 +1,58 @@
1
1
  ---
2
2
  name: web-record
3
3
  description: |
4
- 网页录屏 / 分镜视频技能(录制 webm,默认转码 mp4 + 抽封面 + 上传 VOD 并返回 CDN 地址),基于 Playwright Python
5
- 支持:固定时长 / 条件触发(元素出现 / 消失)停止、自动滚动录屏(从头划到尾)、自定义分镜(storyboard)、参数化模板。
6
- 分镜场景:高亮 / 聚焦 / 放大 / 滚动 / 虚拟光标点击 / 打字 / 悬停 / 字幕 / 标题卡 / 箭头 / 编号序列 / 打码 / 代码行高亮。
7
-
8
- 只出视频。要静态截图(png/jpg)请用 web-screenshot / `web_screenshot`。
9
-
10
- 当用户提到以下任何需求时,立即使用本 skill
11
- - 录屏、网页录制、录制视频、录一段操作、生成 webmscreencast
12
- - 滚动录屏、页面从头划到尾的视频
13
- - 多场景视频、分镜视频、storyboard、按时间线编排(红框高亮 / 局部放大 / 滚动介绍)
14
- - 演示点击 / 输入 / 悬停(虚拟鼠标 + 涟漪 / 打字机 / 触发 tooltip)的动态视频
15
- - 用模板一行出片(github-repo-intro / github-readme-tour / github-code-tour 等)
4
+ Web-page recording / storyboard video skill (records webm, then by default transcodes to mp4 + grabs a cover frame + uploads to VOD and returns a CDN URL), built on Playwright Python.
5
+ Supports: fixed-duration recording, condition-triggered stop (element appears / disappears), auto-scroll recording (top to bottom), custom storyboards, and parameterized templates.
6
+ Storyboard scenes: highlight / focus / zoom / scroll / virtual-cursor click / type / hover / caption / title card / arrow / numbered sequence / redact / code-line highlight.
7
+
8
+ Video only. For still screenshots (png/jpg) use web-screenshot / `web_screenshot`.
9
+
10
+ Use this skill immediately whenever the user asks for any of:
11
+ - Screen recording, record a web page, record a video, capture an interaction, produce a webm, screencast
12
+ - Scroll recording, a video that pans the page from top to bottom
13
+ - Multi-scene video, storyboard video, timeline-sequenced clips (highlight box / zoom-in / scrolling walkthrough)
14
+ - Animated demos of clicks / typing / hover (virtual cursor + ripple / typewriter / triggering tooltips)
15
+ - One-command clips from a template (github-repo-intro / github-readme-tour / github-code-tour, etc.)
16
16
  triggers:
17
- - 录屏、网页录制、录制视频、录一段操作、生成 webmscreencast
18
- - 滚动录屏、页面从头划到尾的视频
19
- - 多场景视频、分镜视频、storyboard、按时间线编排
20
- - 演示点击 / 输入 / 悬停(虚拟鼠标 + 涟漪 / 打字机 / 触发 tooltip)
21
- - 模板视频一行出片、按顺序编号高亮多个区域并录制
17
+ - Screen recording, record a web page, record a video, capture an interaction, produce a webm, screencast
18
+ - Scroll recording, a video that pans the page from top to bottom
19
+ - Multi-scene video, storyboard video, timeline-sequenced clips
20
+ - Animated demos of clicks / typing / hover (virtual cursor + ripple / typewriter / triggering tooltips)
21
+ - One-command template clips, numbering and highlighting several regions in sequence and recording it
22
22
  ---
23
23
 
24
- # 网页录屏 / 分镜视频 Skillweb_record
24
+ # Web Recording / Storyboard Video Skill (`web_record`)
25
25
 
26
- 录屏入口。静态截图请改用 **web-screenshot / `web_screenshot`**。
26
+ The recording entry point. For still screenshots use **web-screenshot / `web_screenshot`** instead.
27
27
 
28
- **脚本位置**:本 skill 没有自己的 `scripts/`,复用 web-screenshot 目录下的 `record.py`
29
- `_media_screenshot/` 包(`skill.json` 的 `entry.scriptPath` 相对指向
30
- `../web-screenshot/scripts/record.py`)。下文命令里的 **`<RecordScript>`** 一律替换为:
28
+ **Script location**: this skill has no `scripts/` of its own — it reuses `record.py` and the `_media_screenshot/` package from the web-screenshot directory (`skill.json`'s `entry.scriptPath` points relatively at `../web-screenshot/scripts/record.py`). Everywhere the commands below say **`<RecordScript>`**, substitute:
31
29
 
32
30
  ```
33
31
  <SkillDir>/../web-screenshot/scripts/record.py
34
32
  ```
35
33
 
36
- > 路径约定:读取系统注入的 `Base directory for this skill: <path>` 作为 `<SkillDir>`,切勿硬编码绝对路径。`python` macOS 上可能需写成 `python3`。
34
+ > Path convention: read the system-injected `Base directory for this skill: <path>` as `<SkillDir>`. Never hardcode an absolute path.
37
35
 
38
- ## 前置依赖
36
+ ## Prerequisites
39
37
 
40
38
  - **Python 3.9+**
41
- - **`playwright` pip + chromium 内核**:首次运行**自动 bootstrap**(`pip install playwright` + `playwright install chromium`)。
42
- - **ffmpeg**(可选):只在 `--no-upload` 的单机路径下用于裁掉开头加载段。默认的上传路径由 ab-render 在转码同一 pass 里裁,本机不需要 ffmpeg
39
+ - **The `playwright` pip package + the chromium engine**: the first run **bootstraps automatically** (`pip install playwright` + `playwright install chromium`).
40
+ - **ffmpeg** (optional): only needed on the standalone `--no-upload` path, to trim the loading segment off the start. On the default upload path ab-render trims it in the same transcode pass, so no local ffmpeg is required.
43
41
 
44
- ## 输出与上传
42
+ ## Output and upload
45
43
 
46
- 默认行为(**不是**只落一个 webm):录制 `.webm` → 交给 ab-render 转码 mp4 + 抽封面上传 VOD → 打印可播放的 CDN 地址,并**删除本地 webm**(VOD 已持有)。
44
+ Default behavior (it does **not** just drop a webm): record `.webm` → hand off to ab-render to transcode to mp4 + grab a cover frame upload to VOD → print a playable CDN URL, and **delete the local webm** (VOD holds the copy).
47
45
 
48
- - `--no-upload`:跳过收尾,只保留本地 `.webm`(此时用本机 ffmpeg 尽力裁开头,缺 ffmpeg 则保留原片并提示)。
49
- - `--keep-webm`:上传成功后仍保留本地 `.webm`。
50
- - `--cover-at-sec`:封面抽帧时间点,默认 `0.5` 秒(避开首帧白屏)。
51
- - `--vod-title`:VOD 资源标题,默认取输出文件名。
46
+ - `--no-upload`: skip the finishing steps and keep only the local `.webm` (in this case local ffmpeg makes a best-effort trim of the start; without ffmpeg the raw clip is kept and a notice printed).
47
+ - `--keep-webm`: keep the local `.webm` even after a successful upload.
48
+ - `--cover-at-sec`: cover-frame timestamp, default `0.5` seconds (avoids a blank first frame).
49
+ - `--vod-title`: VOD asset title, defaults to the output file name.
52
50
 
53
- 需要 env **`PRIV_TOKEN`**(鉴权)与 **`REMOTION_RENDER_API_URL`**(ab-render 地址)。未设 `PRIV_TOKEN` 时自动降级为「仅本地文件」并在 stderr 提示;上传过程出错同样降级,不会丢掉已录好的文件。
51
+ Requires the env vars **`PRIV_TOKEN`** (auth) and **`REMOTION_RENDER_API_URL`** (ab-render address). Without `PRIV_TOKEN` it degrades automatically to "local file only" and says so on stderr; an upload failure degrades the same way, so an already-recorded file is never lost.
54
52
 
55
- ## 录屏用法
53
+ ## Recording usage
56
54
 
57
- ### 固定时长录屏
55
+ ### Fixed-duration recording
58
56
 
59
57
  ```bash
60
58
  python3 <RecordScript> \
@@ -64,17 +62,17 @@ python3 <RecordScript> \
64
62
  --duration 8000
65
63
  ```
66
64
 
67
- ### 等条件结束(推荐配合 max-duration 防卡死)
65
+ ### Stop on a condition (pair it with max-duration so it can't hang)
68
66
 
69
67
  ```bash
70
- # 等到 "加载完成" 元素出现就停
68
+ # Stop once the "loaded" element appears
71
69
  python3 <RecordScript> \
72
70
  --url "https://example.com" \
73
71
  --output "loaded.webm" \
74
72
  --stop-when-selector "div.loaded" \
75
73
  --max-duration 30000
76
74
 
77
- # 等到 loading 转圈消失就停
75
+ # Stop once the loading spinner disappears
78
76
  python3 <RecordScript> \
79
77
  --url "https://example.com" \
80
78
  --output "spinner_done.webm" \
@@ -82,7 +80,7 @@ python3 <RecordScript> \
82
80
  --max-duration 30000
83
81
  ```
84
82
 
85
- ### 组合:先满足谁就停
83
+ ### Combined: whichever fires first wins
86
84
 
87
85
  ```bash
88
86
  python3 <RecordScript> \
@@ -93,7 +91,7 @@ python3 <RecordScript> \
93
91
  --max-duration 20000
94
92
  ```
95
93
 
96
- ### 录屏前等页面就绪
94
+ ### Wait for the page to be ready before recording
97
95
 
98
96
  ```bash
99
97
  python3 <RecordScript> \
@@ -104,7 +102,7 @@ python3 <RecordScript> \
104
102
  --duration 6000
105
103
  ```
106
104
 
107
- ### 自动滚动录屏(从头划到尾)
105
+ ### Auto-scroll recording (top to bottom)
108
106
 
109
107
  ```bash
110
108
  python3 <RecordScript> \
@@ -118,36 +116,36 @@ python3 <RecordScript> \
118
116
  --scroll-pause-bottom 1500
119
117
  ```
120
118
 
121
- ### 模板视频(快捷出片)
119
+ ### Template videos (fast path)
122
120
 
123
- `templates/` 下提供参数化的 storyboard 模板,常见结构一行命令出片:
121
+ `templates/` ships parameterized storyboard templates that turn common structures into a one-line command:
124
122
 
125
123
  ```bash
126
- # 列出可用模板
124
+ # List available templates
127
125
  python3 <RecordScript> --list-templates
128
126
 
129
- # github-repo-intro 模板录任意 GitHub 仓库
127
+ # Record any GitHub repo with the github-repo-intro template
130
128
  python3 <RecordScript> \
131
129
  --template github-repo-intro \
132
130
  --param repo_url=https://github.com/user/repo \
133
131
  --output repo.webm
134
132
  ```
135
133
 
136
- 可重复 `--param key=value` 覆盖模板里的默认值(标签文字、颜色、缩放倍数等)。模板内 `_meta.params` 声明可接收的参数。
134
+ Repeat `--param key=value` to override the template's defaults (label text, colors, zoom factor, etc.). A template's `_meta.params` declares the parameters it accepts.
137
135
 
138
- **当前模板**:
136
+ **Current templates**:
139
137
 
140
- | 名字 | 说明 | 必填参数 |
141
- |------|------|---------|
142
- | `github-repo-intro` | GitHub 仓库三连:项目名红框 → star 页面 zoom → README 滚动 | `repo_url` |
143
- | `github-readme-tour` | 标题卡项目名光标 hover star → README 滚动结尾呼吁 | `repo_url` |
144
- | `github-code-tour` | 跳转到文件高亮行范围字幕讲解 | `file_url` / `start_line` / `end_line` |
138
+ | Name | Description | Required params |
139
+ |------|-------------|-----------------|
140
+ | `github-repo-intro` | GitHub repo trio: highlight the project name zoom the star countscroll the README | `repo_url` |
141
+ | `github-readme-tour` | Title card project name cursor hovers star → README scrollclosing call to action | `repo_url` |
142
+ | `github-code-tour` | Jump to a file highlight a line range caption walkthrough | `file_url` / `start_line` / `end_line` |
145
143
 
146
- **新增模板**:在 `<SkillDir>/../web-screenshot/templates/` 下放一个 JSON,按 storyboard 格式写场景,里面用 `{{var_name}}` 占位。可选加 `_meta.params` 声明参数(标 `required: true` / `default: ...`)。占位单独成串时会自动转 int/float/bool(如 `"scale": "{{zoom_scale}}"` 渲染后是数字)。
144
+ **Adding a template**: drop a JSON file under `<SkillDir>/../web-screenshot/templates/`, write the scenes in storyboard format, and use `{{var_name}}` placeholders. Optionally add `_meta.params` to declare parameters (marked `required: true` / `default: ...`). A placeholder that is the entire string is auto-converted to int/float/bool (e.g. `"scale": "{{zoom_scale}}"` renders as a number).
147
145
 
148
- ### 自定义分镜(storyboard)
146
+ ### Custom storyboards
149
147
 
150
- 把一系列「场景」组合成一段视频,场景间用 overlay 淡入淡出过渡(**不会黑屏**)。
148
+ Compose a sequence of "scenes" into one video; scenes are joined by an overlay cross-fade (**never a black frame**).
151
149
 
152
150
  ```bash
153
151
  python3 <RecordScript> \
@@ -157,7 +155,7 @@ python3 <RecordScript> \
157
155
  --storyboard story.json
158
156
  ```
159
157
 
160
- `story.json` 示例:
158
+ Example `story.json`:
161
159
 
162
160
  ```json
163
161
  {
@@ -173,7 +171,7 @@ python3 <RecordScript> \
173
171
  "color": "#ff3b30",
174
172
  "lineWidth": 5,
175
173
  "padding": 10,
176
- "label": "项目名称",
174
+ "label": "Project name",
177
175
  "duration": 3000
178
176
  },
179
177
  {
@@ -184,7 +182,7 @@ python3 <RecordScript> \
184
182
  "rampInMs": 900,
185
183
  "holdMs": 2200,
186
184
  "rampOutMs": 700,
187
- "label": "⭐ Star 数量"
185
+ "label": "⭐ Star count"
188
186
  },
189
187
  {
190
188
  "type": "scroll",
@@ -198,80 +196,80 @@ python3 <RecordScript> \
198
196
  }
199
197
  ```
200
198
 
201
- **场景类型**:
199
+ **Scene types**:
202
200
 
203
- *视觉强调*
204
- - `highlight` — 元素红框 + 标签,`padding` / `lineWidth` / `color` / `duration`
205
- - `focus` — 周围暗化(spotlight)+ 元素描边 + 标签
206
- - `zoom` — 放大动画
207
- - `target: "element"` (默认) — 缩放目标元素本身(弹性曲线)
208
- - `target: "page"` — 像浏览器 zoom 一样整个页面以目标元素中心放大
201
+ *Visual emphasis*
202
+ - `highlight` — box around an element + label; `padding` / `lineWidth` / `color` / `duration`
203
+ - `focus` — dim the surroundings (spotlight) + outline the element + label
204
+ - `zoom` — zoom animation
205
+ - `target: "element"` (default) — scale the target element itself (elastic curve)
206
+ - `target: "page"` — zoom the whole page around the target element's center, like browser zoom
209
207
  - `scale` / `rampInMs` / `rampOutMs` / `holdMs` / `dim` / `label` / `color`
210
- - `scroll` — 滚动到目标。`fromSelector` 起点、`toSelector` 终点、`step` / `interval` / `duration` / `holdAtEnd`
211
- - `wait` — 单纯停顿 `duration`
212
-
213
- *交互模拟(虚拟光标)*
214
- - `click` — 光标飞向元素涟漪真实触发 `el.click()`。`moveMs` / `preHoldMs` / `postHoldMs` / `rippleMs` / `color` / `realClick`(默认 true,可设 false 只动画不点)
215
- - `type` — 光标飞向输入框 → focus → 逐字打字。`text` / `delay`(ms/字) / `clearFirst` / `moveCursor`
216
- - `hover` — 光标移到元素并触发原生 hover,常用于悬出 tooltip / hover card。`moveMs` / `holdMs`
217
-
218
- *注释表达*
219
- - `arrow` — 从一个锚点画 SVG 弧线箭头指向另一个锚点。锚点 `from` / `to` 形如 `{selector, side}`(side: center/left/right/top/bottom)或 `{x, y}`。`color` / `lineWidth` / `label` / `duration`
220
- - `sequence` — 多个 selector 顺序出 ①②③ 圆形 badge + 红框 + 标签。`items: [{selector, label}, ...]` / `stepMs` 控制每步间隔 / `color` / `holdMs`
221
- - `caption` — 顶部/底部滑入字幕条。`text` / `position: top|bottom` / `background` / `color` / `fontSize` / `duration`
222
- - `title-card` — 全屏开场/结尾大标题卡。`title` / `subtitle`(可选) / `background` / `accent` / `duration`
223
- - `redact` — 局部打码:blur / pixelate / 实色。`selectors: [...]` `selector` / `mode: "blur" | "pixelate" | "solid"` / `color`(实色时) / `duration`
224
-
225
- *GitHub 专属*
226
- - `code-lines` — 高亮连续代码行范围(默认匹配新版 React blob `[data-line-number="{n}"]`;老版 blob 表格用 `linePattern: "#LC{n}"`)。`startLine` / `endLine` / `linePattern` / `color` / `label` / `duration`
227
-
228
- **自动裁剪**:storyboard 模式录制时会等待页面真正稳定(networkidle + skeleton 消失),并在事后用 ffmpeg 帧精度裁掉开头加载段,最终视频长度各场景总时长。
229
-
230
- ### 完整参数
231
-
232
- | 参数 | 说明 | 默认 |
233
- |------|------|------|
234
- | `-u` / `--url` | 目标 URL(必填) | — |
235
- | `-o` / `--output` | 本地输出 `.webm` 路径 | `recording.webm` |
236
- | `-b` / `--browser` | `chromium` / `firefox` / `webkit`(建议 chromium | `chromium` |
237
- | `--device` | 设备模拟 | |
238
- | `--viewport` | `"宽,高"` | |
239
- | `--duration` | 固定录制时长(ms | |
240
- | `--stop-when-selector` | 选择器出现就停 | |
241
- | `--stop-when-hidden` | 选择器消失就停 | |
242
- | `--max-duration` | 条件模式安全上限(ms | 60000 |
243
- | `--scroll-through` | 自动从顶部滚到底部 | |
244
- | `--scroll-step` | 每步像素 | 60 |
245
- | `--scroll-interval` | 每步间隔(ms | 50 |
246
- | `--scroll-pause-top` | 顶部停留(ms | 800 |
247
- | `--scroll-pause-bottom` | 底部停留(ms | 1200 |
248
- | `--storyboard` | 分镜 JSON 文件路径 | |
249
- | `--template` | 模板名(templates/<name>.json);与 `--storyboard` 互斥 | |
250
- | `--param` | 模板参数 `key=value`,可重复 | |
251
- | `--list-templates` | 列出可用模板并退出 | — |
252
- | `--wait-for-selector` | 开始录前等待出现 | |
253
- | `--wait-for-timeout` | 开始录前固定等待(ms | |
254
- | `--color-scheme` | prefers-color-scheme | |
255
- | `--user-agent` | 覆盖 UA | |
256
- | `--timeout` | Playwright 全局超时(ms | |
257
- | `--ignore-https-errors` | 忽略证书错误 | |
258
- | `--storage-state` | storageState JSON 文件 | |
259
- | `--cookies` | cookies JSON 字符串或文件 | |
260
- | `--no-upload` | 录完不上传,只保留本地 webm | 关(默认上传) |
261
- | `--vod-title` | 上传到 VOD 的标题 | 输出文件名 |
262
- | `--cover-at-sec` | 封面抽帧时间点(秒) | 0.5 |
263
- | `--keep-webm` | 上传成功后保留本地 webm | 关(默认删除) |
264
-
265
- 至少需提供 `--duration` / `--stop-when-selector` / `--stop-when-hidden` / `--scroll-through` / `--storyboard` / `--template` 之一;组合使用时**先满足谁就停**,同时受 `--max-duration` 兜底。模板 / storyboard JSON 可自带 `url`,此时可省略 `--url`。
266
-
267
- ## 错误处理
268
-
269
- - **首次跑慢**:脚本自动 `pip install playwright` + `playwright install chromium`,耐心等一次即可。
270
- - **`ModuleNotFoundError: playwright`**:bootstrap 没装上,手动跑 `pip install playwright && playwright install chromium`。
271
- - **`Executable doesn't exist`**:浏览器内核没装,跑 `playwright install chromium`。
272
- - **`Timeout ... exceeded`**:拉大 `--timeout`、`--wait-for-timeout`,或换更稳的 `--wait-for-selector`。
273
- - **录屏文件没产生**:检查 `--output` 后缀是否 `.webm`;查看 stderr `stop reason`。
274
- - **只拿到本地路径、没有 CDN 地址**:多半是没设 `PRIV_TOKEN`,或收尾失败降级了,stderr 里有原因。
275
- - **storyboard 开头还有加载残影**:加大 `settleMs` / `waitForReadySelectors`;`--no-upload` 路径还需本机装 ffmpeg
276
- - **登录态失效**:重新导出 `storageState` 或更新 `cookies` JSON;`domain` / `path` 必须匹配。
277
- - **HTTPS 证书报错**:测试环境可加 `--ignore-https-errors`。
208
+ - `scroll` — scroll to a target. `fromSelector` start, `toSelector` end, `step` / `interval` / `duration` / `holdAtEnd`
209
+ - `wait` — plain pause for `duration`
210
+
211
+ *Interaction simulation (virtual cursor)*
212
+ - `click` — cursor flies to the element ripplereally fires `el.click()`. `moveMs` / `preHoldMs` / `postHoldMs` / `rippleMs` / `color` / `realClick` (default true; set false to animate without clicking)
213
+ - `type` — cursor flies to the input → focus → types character by character. `text` / `delay` (ms per char) / `clearFirst` / `moveCursor`
214
+ - `hover` — cursor moves onto the element and triggers a native hover; typical for surfacing a tooltip / hover card. `moveMs` / `holdMs`
215
+
216
+ *Annotation*
217
+ - `arrow` — draw an SVG curved arrow from one anchor to another. Anchors `from` / `to` look like `{selector, side}` (side: center/left/right/top/bottom) or `{x, y}`. `color` / `lineWidth` / `label` / `duration`
218
+ - `sequence` — several selectors get ①②③ circular badges + boxes + labels in order. `items: [{selector, label}, ...]` / `stepMs` controls the gap between steps / `color` / `holdMs`
219
+ - `caption` — caption bar sliding in from the top/bottom. `text` / `position: top|bottom` / `background` / `color` / `fontSize` / `duration`
220
+ - `title-card` — full-screen opening/closing title card. `title` / `subtitle` (optional) / `background` / `accent` / `duration`
221
+ - `redact` — mask a region: blur / pixelate / solid. `selectors: [...]` or `selector` / `mode: "blur" | "pixelate" | "solid"` / `color` (when solid) / `duration`
222
+
223
+ *GitHub-specific*
224
+ - `code-lines` — highlight a contiguous code-line range (matches the new React blob `[data-line-number="{n}"]` by default; the old table-based blob needs `linePattern: "#LC{n}"`). `startLine` / `endLine` / `linePattern` / `color` / `label` / `duration`
225
+
226
+ **Automatic trimming**: in storyboard mode the recorder waits for the page to genuinely settle (networkidle + skeletons gone), then trims the leading load segment afterwards with frame-accurate ffmpeg, so the final video length the sum of the scene durations.
227
+
228
+ ### Full flag list
229
+
230
+ | Flag | Description | Default |
231
+ |------|-------------|---------|
232
+ | `-u` / `--url` | Target URL (required) | — |
233
+ | `-o` / `--output` | Local `.webm` output path | `recording.webm` |
234
+ | `-b` / `--browser` | `chromium` / `firefox` / `webkit` (chromium recommended) | `chromium` |
235
+ | `--device` | Device emulation | none |
236
+ | `--viewport` | `"width,height"` | none |
237
+ | `--duration` | Fixed recording length (ms) | none |
238
+ | `--stop-when-selector` | Stop once this selector appears | none |
239
+ | `--stop-when-hidden` | Stop once this selector disappears | none |
240
+ | `--max-duration` | Safety cap for condition modes (ms) | 60000 |
241
+ | `--scroll-through` | Auto-scroll from top to bottom | off |
242
+ | `--scroll-step` | Pixels per step | 60 |
243
+ | `--scroll-interval` | Interval between steps (ms) | 50 |
244
+ | `--scroll-pause-top` | Pause at the top (ms) | 800 |
245
+ | `--scroll-pause-bottom` | Pause at the bottom (ms) | 1200 |
246
+ | `--storyboard` | Storyboard JSON file path | none |
247
+ | `--template` | Template name (`templates/<name>.json`); mutually exclusive with `--storyboard` | none |
248
+ | `--param` | Template parameter `key=value` (repeatable) | none |
249
+ | `--list-templates` | List available templates and exit | — |
250
+ | `--wait-for-selector` | Wait for this selector before recording | none |
251
+ | `--wait-for-timeout` | Fixed wait before recording (ms) | none |
252
+ | `--color-scheme` | prefers-color-scheme | none |
253
+ | `--user-agent` | Override the User-Agent | none |
254
+ | `--timeout` | Playwright global timeout (ms) | none |
255
+ | `--ignore-https-errors` | Ignore certificate errors | off |
256
+ | `--storage-state` | storageState JSON file | none |
257
+ | `--cookies` | cookies JSON string or file | none |
258
+ | `--no-upload` | Skip the upload; keep only the local webm | off (uploads by default) |
259
+ | `--vod-title` | Title for the VOD upload | output file name |
260
+ | `--cover-at-sec` | Cover-frame timestamp (seconds) | 0.5 |
261
+ | `--keep-webm` | Keep the local webm after a successful upload | off (deleted by default) |
262
+
263
+ At least one of `--duration` / `--stop-when-selector` / `--stop-when-hidden` / `--scroll-through` / `--storyboard` / `--template` must be supplied; when several are combined, **whichever fires first stops the recording**, with `--max-duration` as the backstop. A template / storyboard JSON may carry its own `url`, in which case `--url` can be omitted.
264
+
265
+ ## Error handling
266
+
267
+ - **The first run is slow**: the script auto-runs `pip install playwright` + `playwright install chromium`. Wait it out once.
268
+ - **`ModuleNotFoundError: playwright`**: the bootstrap did not complete; run `pip install playwright && playwright install chromium` manually.
269
+ - **`Executable doesn't exist`**: the browser engine is missing; run `playwright install chromium`.
270
+ - **`Timeout ... exceeded`**: raise `--timeout` / `--wait-for-timeout`, or switch to a more reliable `--wait-for-selector`.
271
+ - **No recording file produced**: check that `--output` ends in `.webm`; read the `stop reason` on stderr.
272
+ - **Got a local path but no CDN URL**: usually `PRIV_TOKEN` is unset, or the finishing steps failed and it degraded — stderr has the reason.
273
+ - **Loading artifacts still visible at the start of a storyboard**: raise `settleMs` / add `waitForReadySelectors`; the `--no-upload` path additionally needs local ffmpeg.
274
+ - **Session expired**: re-export `storageState` or update the cookies JSON — `domain` / `path` must match.
275
+ - **HTTPS certificate errors**: in test environments add `--ignore-https-errors`.