remotion-claude-agent-demo 0.1.0
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/README.md +160 -0
- package/apps/web/README.md +36 -0
- package/apps/web/env.example +20 -0
- package/apps/web/eslint.config.mjs +18 -0
- package/apps/web/next.config.ts +7 -0
- package/apps/web/package-lock.json +10348 -0
- package/apps/web/package.json +35 -0
- package/apps/web/postcss.config.mjs +7 -0
- package/apps/web/public/file.svg +1 -0
- package/apps/web/public/globe.svg +1 -0
- package/apps/web/public/next.svg +1 -0
- package/apps/web/public/vercel.svg +1 -0
- package/apps/web/public/window.svg +1 -0
- package/apps/web/src/app/.well-known/agent-card.json/route.ts +50 -0
- package/apps/web/src/app/background-tasks/[jobId]/cancel/route.ts +29 -0
- package/apps/web/src/app/events/stream/route.ts +58 -0
- package/apps/web/src/app/favicon.ico +0 -0
- package/apps/web/src/app/globals.css +174 -0
- package/apps/web/src/app/layout.tsx +34 -0
- package/apps/web/src/app/messages/answer/route.ts +57 -0
- package/apps/web/src/app/messages/stream/route.ts +381 -0
- package/apps/web/src/app/page.tsx +358 -0
- package/apps/web/src/app/tasks/[taskId]/cancel/route.ts +24 -0
- package/apps/web/src/app/tasks/[taskId]/route.ts +24 -0
- package/apps/web/src/app/tasks/route.ts +13 -0
- package/apps/web/src/components/chat/agent-blocks.tsx +111 -0
- package/apps/web/src/components/chat/ask-user-question-panel.tsx +172 -0
- package/apps/web/src/components/chat/session-sidebar.tsx +222 -0
- package/apps/web/src/components/chat/subagent-activity-sidebar.tsx +248 -0
- package/apps/web/src/components/chat/tool-blocks.tsx +550 -0
- package/apps/web/src/lib/a2a/activity-store.ts +150 -0
- package/apps/web/src/lib/a2a/client.ts +357 -0
- package/apps/web/src/lib/a2a/sse.ts +19 -0
- package/apps/web/src/lib/a2a/task-store.ts +111 -0
- package/apps/web/src/lib/a2a/types.ts +216 -0
- package/apps/web/src/lib/agent/answer-store.ts +109 -0
- package/apps/web/src/lib/agent/background-delivery.ts +343 -0
- package/apps/web/src/lib/agent/background-tool.ts +78 -0
- package/apps/web/src/lib/agent/background.ts +452 -0
- package/apps/web/src/lib/agent/chat.ts +543 -0
- package/apps/web/src/lib/agent/session-store.ts +26 -0
- package/apps/web/src/lib/chat/types.ts +44 -0
- package/apps/web/src/lib/env.ts +31 -0
- package/apps/web/src/lib/hooks/useA2AChat.ts +863 -0
- package/apps/web/src/lib/state/chat-atoms.ts +52 -0
- package/apps/web/src/lib/workspace.ts +9 -0
- package/apps/web/tsconfig.json +35 -0
- package/bin/remotion-agent.js +451 -0
- package/package.json +34 -0
- package/templates/.claude/CLAUDE.md +95 -0
- package/templates/.claude/README.md +129 -0
- package/templates/.claude/agents/composer-agent.md +188 -0
- package/templates/.claude/agents/crafter.md +181 -0
- package/templates/.claude/agents/creator.md +134 -0
- package/templates/.claude/agents/perceiver.md +92 -0
- package/templates/.claude/settings.json +36 -0
- package/templates/.claude/settings.local.json +39 -0
- package/templates/.claude/skills/agent-browser/SKILL.md +349 -0
- package/templates/.claude/skills/agent-browser/references/authentication.md +188 -0
- package/templates/.claude/skills/agent-browser/references/proxy-support.md +175 -0
- package/templates/.claude/skills/agent-browser/references/session-management.md +181 -0
- package/templates/.claude/skills/agent-browser/references/snapshot-refs.md +186 -0
- package/templates/.claude/skills/agent-browser/references/video-recording.md +162 -0
- package/templates/.claude/skills/agent-browser/templates/authenticated-session.sh +91 -0
- package/templates/.claude/skills/agent-browser/templates/capture-workflow.sh +68 -0
- package/templates/.claude/skills/agent-browser/templates/form-automation.sh +64 -0
- package/templates/.claude/skills/algorithmic-art/LICENSE.txt +202 -0
- package/templates/.claude/skills/algorithmic-art/SKILL.md +405 -0
- package/templates/.claude/skills/algorithmic-art/templates/generator_template.js +223 -0
- package/templates/.claude/skills/algorithmic-art/templates/viewer.html +599 -0
- package/templates/.claude/skills/asset-validator/SKILL.md +376 -0
- package/templates/.claude/skills/audio-video-sync/SKILL.md +219 -0
- package/templates/.claude/skills/bgm-manager/SKILL.md +334 -0
- package/templates/.claude/skills/remotion-best-practices/SKILL.md +45 -0
- package/templates/.claude/skills/remotion-best-practices/rules/3d.md +86 -0
- package/templates/.claude/skills/remotion-best-practices/rules/animations.md +29 -0
- package/templates/.claude/skills/remotion-best-practices/rules/assets/charts-bar-chart.tsx +173 -0
- package/templates/.claude/skills/remotion-best-practices/rules/assets/text-animations-typewriter.tsx +100 -0
- package/templates/.claude/skills/remotion-best-practices/rules/assets/text-animations-word-highlight.tsx +108 -0
- package/templates/.claude/skills/remotion-best-practices/rules/assets.md +78 -0
- package/templates/.claude/skills/remotion-best-practices/rules/audio.md +172 -0
- package/templates/.claude/skills/remotion-best-practices/rules/calculate-metadata.md +104 -0
- package/templates/.claude/skills/remotion-best-practices/rules/can-decode.md +75 -0
- package/templates/.claude/skills/remotion-best-practices/rules/charts.md +58 -0
- package/templates/.claude/skills/remotion-best-practices/rules/compositions.md +141 -0
- package/templates/.claude/skills/remotion-best-practices/rules/display-captions.md +126 -0
- package/templates/.claude/skills/remotion-best-practices/rules/extract-frames.md +229 -0
- package/templates/.claude/skills/remotion-best-practices/rules/fonts.md +152 -0
- package/templates/.claude/skills/remotion-best-practices/rules/get-audio-duration.md +58 -0
- package/templates/.claude/skills/remotion-best-practices/rules/get-video-dimensions.md +68 -0
- package/templates/.claude/skills/remotion-best-practices/rules/get-video-duration.md +58 -0
- package/templates/.claude/skills/remotion-best-practices/rules/gifs.md +138 -0
- package/templates/.claude/skills/remotion-best-practices/rules/images.md +130 -0
- package/templates/.claude/skills/remotion-best-practices/rules/import-srt-captions.md +67 -0
- package/templates/.claude/skills/remotion-best-practices/rules/lottie.md +68 -0
- package/templates/.claude/skills/remotion-best-practices/rules/maps.md +403 -0
- package/templates/.claude/skills/remotion-best-practices/rules/measuring-dom-nodes.md +35 -0
- package/templates/.claude/skills/remotion-best-practices/rules/measuring-text.md +143 -0
- package/templates/.claude/skills/remotion-best-practices/rules/parameters.md +98 -0
- package/templates/.claude/skills/remotion-best-practices/rules/sequencing.md +118 -0
- package/templates/.claude/skills/remotion-best-practices/rules/tailwind.md +11 -0
- package/templates/.claude/skills/remotion-best-practices/rules/text-animations.md +20 -0
- package/templates/.claude/skills/remotion-best-practices/rules/timing.md +179 -0
- package/templates/.claude/skills/remotion-best-practices/rules/transcribe-captions.md +19 -0
- package/templates/.claude/skills/remotion-best-practices/rules/transitions.md +122 -0
- package/templates/.claude/skills/remotion-best-practices/rules/trimming.md +53 -0
- package/templates/.claude/skills/remotion-best-practices/rules/videos.md +171 -0
- package/templates/.claude/skills/remotion-components/SKILL.md +453 -0
- package/templates/.claude/skills/render-config/SKILL.md +290 -0
- package/templates/.claude/skills/script-writer/SKILL.md +59 -0
- package/templates/.claude/skills/style-director/script-writer/SKILL.md +82 -0
- package/templates/.claude/skills/style-director/style-director/SKILL.md +287 -0
- package/templates/.claude/skills/style-director/style-director/references/audience-and-scenarios.md +43 -0
- package/templates/.claude/skills/style-director/style-director/references/interaction-innovation.md +26 -0
- package/templates/.claude/skills/style-director/style-director/references/motion-grammar.md +66 -0
- package/templates/.claude/skills/style-director/style-director/references/quality-checklist.md +29 -0
- package/templates/.claude/skills/style-director/style-director/references/scene-recipes.md +38 -0
- package/templates/.claude/skills/style-director/style-director/references/visual-style-system.md +148 -0
- package/templates/.claude/skills/subtitle-composer/SKILL.md +304 -0
- package/templates/.claude/skills/subtitle-processor/SKILL.md +308 -0
- package/templates/.claude/skills/timeline-generator/SKILL.md +253 -0
- package/templates/.claude/skills/video-preflight-check/SKILL.md +353 -0
- package/templates/.claude/skills/voice-synthesizer/SKILL.md +296 -0
- package/templates/.claude/skills/voice-synthesizer/scripts/synthesize_voice.py +315 -0
- package/templates/.claude/skills/voice-synthesizer/scripts/tts_cli.py +142 -0
- package/templates/.claude/skills/web-design-guidelines/SKILL.md +36 -0
- package/templates/.claude/skills/youtube-downloader/SKILL.md +99 -0
- package/templates/.claude/skills/youtube-downloader/scripts/download_video.py +145 -0
package/templates/.claude/skills/style-director/style-director/references/audience-and-scenarios.md
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# 受众与场景定位
|
|
2
|
+
|
|
3
|
+
用于确定叙事语气、视觉密度、动效节奏和信息层级。
|
|
4
|
+
|
|
5
|
+
## 受众分层
|
|
6
|
+
|
|
7
|
+
1) 决策者 / 企业客户
|
|
8
|
+
- 关键词:可信、稳重、结果导向
|
|
9
|
+
- 视觉:低饱和、留白、结构清晰、少特效
|
|
10
|
+
- 动效:慢、少、重点明确
|
|
11
|
+
- 叙事:问题 → 方案 → 证据 → CTA
|
|
12
|
+
|
|
13
|
+
2) 产品 / 运营团队
|
|
14
|
+
- 关键词:效率、流程、可控
|
|
15
|
+
- 视觉:干净 UI、步骤清晰、信息层级明确
|
|
16
|
+
- 动效:逐步引导、聚焦重点
|
|
17
|
+
- 叙事:输入 → 处理 → 输出
|
|
18
|
+
|
|
19
|
+
3) 开发者 / 技术群体
|
|
20
|
+
- 关键词:真实、效率、工具链
|
|
21
|
+
- 视觉:IDE / 终端 / API / 日志
|
|
22
|
+
- 动效:打字 + 命令执行 + 结果可视化
|
|
23
|
+
- 叙事:代码 → 命令 → 结果
|
|
24
|
+
|
|
25
|
+
4) 团队协作 / 创作者
|
|
26
|
+
- 关键词:友好、灵活、协作
|
|
27
|
+
- 视觉:柔和渐变、圆角卡片、低压感
|
|
28
|
+
- 动效:轻弹性、层级展示
|
|
29
|
+
- 叙事:协作流程 → 产出结果
|
|
30
|
+
|
|
31
|
+
5) 大众 / 用户侧
|
|
32
|
+
- 关键词:易懂、直接
|
|
33
|
+
- 视觉:大字、强对比、低密度
|
|
34
|
+
- 动效:直观入场、停顿充分
|
|
35
|
+
|
|
36
|
+
## 快速匹配
|
|
37
|
+
|
|
38
|
+
- 企业级 B2B / SaaS:Premium UI / Clean Minimal
|
|
39
|
+
- AI 工具 / 开发者:Dark Tech / 真实交互
|
|
40
|
+
- 教育 / 亲和型产品:Soft Paper / 手绘元素
|
|
41
|
+
- 强冲击营销:Bold Kinetic / 高对比
|
|
42
|
+
|
|
43
|
+
保持一个主受众 + 一个次受众,避免语气冲突。
|
package/templates/.claude/skills/style-director/style-director/references/interaction-innovation.md
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# 新奇交互与视觉冲击
|
|
2
|
+
|
|
3
|
+
每条视频建议用 1–2 个创新点,避免堆砌。
|
|
4
|
+
|
|
5
|
+
## 交互创新(AI & UX)
|
|
6
|
+
|
|
7
|
+
- Prompt to Reality:左侧输入文本,右侧组件由粒子聚合成型
|
|
8
|
+
- Neural Mapping:两卡片间生成流动线条,线上带发光数据包
|
|
9
|
+
- Streaming Result:内容像 ChatGPT 一样流式出现,容器高度自动撑开
|
|
10
|
+
- 磁吸对齐:元素靠近目标时回弹吸附
|
|
11
|
+
- 指令回响:点击点触发波纹 (Ripple),附近元素轻微震动
|
|
12
|
+
- 智能聚焦:讲解局部功能时,背景组件渐模糊 (0 → 10px)
|
|
13
|
+
- Dark/Light Mode Flip:场景背景色平滑翻转
|
|
14
|
+
|
|
15
|
+
## 视觉冲击
|
|
16
|
+
|
|
17
|
+
- 柔和聚光:焦点区域渐亮
|
|
18
|
+
- 轻微扫描线:技术段落使用
|
|
19
|
+
- 边缘渐光:仅关键卡片
|
|
20
|
+
- 慢速推近:强化价值感
|
|
21
|
+
|
|
22
|
+
## 使用原则
|
|
23
|
+
|
|
24
|
+
- 单屏最多 2 个效果
|
|
25
|
+
- 先可读,再惊艳
|
|
26
|
+
- 企业场景更克制,技术场景更真实
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# 动效语法(含真实交互)
|
|
2
|
+
|
|
3
|
+
动效应传达“意义”,不是装饰。
|
|
4
|
+
|
|
5
|
+
## 核心技术约定(Remotion)
|
|
6
|
+
|
|
7
|
+
- FPS:30(标准)/ 60(丝滑),必要时可用 24
|
|
8
|
+
- 分辨率:1920×1080(16:9)/ 1080×1920(9:16)
|
|
9
|
+
- 动效引擎:位移用 `spring`,透明度/缩放/颜色用 `interpolate`
|
|
10
|
+
- 入场动作:必须带 10–20px 位移补偿(大元素可到 40px)
|
|
11
|
+
|
|
12
|
+
## 时间与节奏
|
|
13
|
+
|
|
14
|
+
- 微交互:160–240ms
|
|
15
|
+
- 文案/卡片入场:400–700ms
|
|
16
|
+
- 重点强调:800–1200ms
|
|
17
|
+
- 转场:300–600ms
|
|
18
|
+
|
|
19
|
+
## 缓动函数库 (Easing Library)
|
|
20
|
+
|
|
21
|
+
- 入场 (Entrance):`spring`(弹性与高级感)
|
|
22
|
+
- 强调 (Emphasis):`cubic-bezier(0.34, 1.56, 0.64, 1)`(Back Out)
|
|
23
|
+
- 持续动量 (Sustaining):1.0 → 1.01–1.03 的慢速呼吸(周期 2.5–6s)
|
|
24
|
+
|
|
25
|
+
## 镜头语言 (Virtual Camera)
|
|
26
|
+
|
|
27
|
+
- 微推 (Slow Zoom):全局 scale 1.00 → 1.03–1.06(镜头 ≥ 2s)
|
|
28
|
+
- 平移 (The Pan):长图 UI 用缓慢扫掠(上→下 或 左→右)
|
|
29
|
+
- 视差 (Parallax):装饰层速度 = 内容层的 1.2–1.6 倍
|
|
30
|
+
|
|
31
|
+
## 核心动效动词
|
|
32
|
+
|
|
33
|
+
- 淡入 + 缩放(轻强调)
|
|
34
|
+
- 滑入 + 遮罩(结构引导)
|
|
35
|
+
- 描边绘制(手绘/强调线)
|
|
36
|
+
- 视差漂移(层次感)
|
|
37
|
+
- 轮廓 → 填充(科技感)
|
|
38
|
+
- 轻微扫描线(仅技术段落)
|
|
39
|
+
|
|
40
|
+
## 转场规则
|
|
41
|
+
|
|
42
|
+
- 同主题:滑动/遮罩
|
|
43
|
+
- 新主题:淡出 + 短暂停顿
|
|
44
|
+
- 关键揭示:慢推近 + 提亮
|
|
45
|
+
|
|
46
|
+
## 打字与光标交互(真实感)
|
|
47
|
+
|
|
48
|
+
- AI 打字:6–12 chars/sec,非线性节奏(含思考停顿)
|
|
49
|
+
- 光标:必须存在;输入结束后闪烁 2–4 次再淡出
|
|
50
|
+
- 选中效果:高亮从左向右擦除 (Wipe)
|
|
51
|
+
- 输出呈现:逐行出现,不要整块跳出
|
|
52
|
+
|
|
53
|
+
## 真实交互(IDE/终端/UI)
|
|
54
|
+
|
|
55
|
+
- 终端提示符:`user@host ~/path`
|
|
56
|
+
- IDE 结构:活动栏 + 文件树 + 编辑区 + 状态栏
|
|
57
|
+
- 选中行高亮:低透明度、单行
|
|
58
|
+
- 活动区域轻微高亮/聚焦
|
|
59
|
+
|
|
60
|
+
## 立体感与镜头
|
|
61
|
+
|
|
62
|
+
- 卡片轻微倾斜(2–6°)
|
|
63
|
+
- 前景清晰、背景轻模糊
|
|
64
|
+
- 轻推镜头用于强调
|
|
65
|
+
|
|
66
|
+
避免随机抖动或过度闪烁。
|
package/templates/.claude/skills/style-director/style-director/references/quality-checklist.md
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# 质量检查清单(Standard Excellence)
|
|
2
|
+
|
|
3
|
+
## 结构与叙事
|
|
4
|
+
- [ ] 每屏只有一个主信息
|
|
5
|
+
- [ ] 输入 → 处理 → 输出清晰
|
|
6
|
+
- [ ] CTA 足够明显且停留时间充足
|
|
7
|
+
|
|
8
|
+
## 视觉一致性
|
|
9
|
+
- [ ] 所有元素遵循 8px 网格(允许 6–10px 基准)
|
|
10
|
+
- [ ] 文字在复杂背景下有阴影或遮罩保护可读性
|
|
11
|
+
- [ ] Primary Color 全片一致
|
|
12
|
+
- [ ] 所有 3D 容器有 0.5–1px 的内描边 (Inner Glow)
|
|
13
|
+
|
|
14
|
+
## 质感与纹理
|
|
15
|
+
- [ ] Grain 纹理透明度 0.02–0.04,避免色彩断层
|
|
16
|
+
- [ ] 暗角存在但不过重(聚焦即可)
|
|
17
|
+
|
|
18
|
+
## 动效与镜头
|
|
19
|
+
- [ ] 存在直线 Linear 运动时,已替换为 Ease-out 或 Spring
|
|
20
|
+
- [ ] 动效节奏统一,时长一致
|
|
21
|
+
- [ ] 关键文本有 0.3–0.8s 阅读停顿
|
|
22
|
+
|
|
23
|
+
## 真实交互
|
|
24
|
+
- [ ] 光标/打字/输出节奏可信
|
|
25
|
+
- [ ] 终端/IDE 结构真实
|
|
26
|
+
|
|
27
|
+
## 技术
|
|
28
|
+
- [ ] 导出分辨率一致
|
|
29
|
+
- [ ] 无闪烁/过度噪点
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# 场景结构配方
|
|
2
|
+
|
|
3
|
+
每个场景只有一个主信息。
|
|
4
|
+
|
|
5
|
+
## 15s 结构
|
|
6
|
+
- 0–2s:Hook
|
|
7
|
+
- 2–5s:痛点
|
|
8
|
+
- 5–9s:AI 流程(输入 → 处理 → 输出)
|
|
9
|
+
- 9–12s:结果
|
|
10
|
+
- 12–15s:CTA
|
|
11
|
+
|
|
12
|
+
## 30s 结构
|
|
13
|
+
- 0–3s:Hook
|
|
14
|
+
- 3–8s:痛点
|
|
15
|
+
- 8–16s:工作流演示
|
|
16
|
+
- 16–23s:功能亮点
|
|
17
|
+
- 23–27s:信任证明
|
|
18
|
+
- 27–30s:CTA
|
|
19
|
+
|
|
20
|
+
## 45s 结构
|
|
21
|
+
- 0–4s:Hook
|
|
22
|
+
- 4–10s:痛点
|
|
23
|
+
- 10–22s:AI 工作流(多步骤)
|
|
24
|
+
- 22–32s:功能卡片(3 项)
|
|
25
|
+
- 32–40s:口碑或数据
|
|
26
|
+
- 40–45s:CTA
|
|
27
|
+
|
|
28
|
+
## 60s 教程结构
|
|
29
|
+
- 0–5s:目标
|
|
30
|
+
- 5–15s:步骤概览
|
|
31
|
+
- 15–40s:真实演示(IDE/终端/UI)
|
|
32
|
+
- 40–52s:结果总结
|
|
33
|
+
- 52–60s:CTA
|
|
34
|
+
|
|
35
|
+
## 读感规则
|
|
36
|
+
|
|
37
|
+
- 关键文案后停顿 0.3–0.8s
|
|
38
|
+
- 重点元素一屏最多 2 个
|
package/templates/.claude/skills/style-director/style-director/references/visual-style-system.md
ADDED
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
# 视觉风格系统(Advanced Aesthetics)
|
|
2
|
+
|
|
3
|
+
目标:高端、结构化、低噪点、可读性强。
|
|
4
|
+
|
|
5
|
+
## 1. 图层合成架构 (Layering Strategy)
|
|
6
|
+
|
|
7
|
+
每一个场景必须由以下四层组成:
|
|
8
|
+
|
|
9
|
+
1) 背景层 (Ambient Layer)
|
|
10
|
+
- 动态网格 (Grid),轻微漂移或视差
|
|
11
|
+
- 径向渐变 (Radial Gradient),形成聚光中心
|
|
12
|
+
|
|
13
|
+
2) 中景层 (Content Layer)
|
|
14
|
+
- 主体 UI / 视频 / 关键图形
|
|
15
|
+
- 允许 2–6° 的轻微 3D 倾斜
|
|
16
|
+
|
|
17
|
+
3) 装饰层 (Accent Layer)
|
|
18
|
+
- 悬浮粒子、线条、光点
|
|
19
|
+
- 只强化重点,避免干扰阅读
|
|
20
|
+
|
|
21
|
+
4) 覆盖层 (Overlay Layer)
|
|
22
|
+
- 极轻微胶片颗粒 (Film Grain, Opacity 0.02–0.04)
|
|
23
|
+
- 边缘暗角 (Vignette) 提升聚焦
|
|
24
|
+
|
|
25
|
+
图层运动原则:
|
|
26
|
+
- 背景层移动最慢,装饰层次之,内容层最清晰
|
|
27
|
+
- 同屏不超过 2 种装饰效果,避免“廉价感”
|
|
28
|
+
|
|
29
|
+
## 2. 核心 CSS 视觉配方
|
|
30
|
+
|
|
31
|
+
### 高端毛玻璃 (Premium Glass)
|
|
32
|
+
```css
|
|
33
|
+
/* Light preset */
|
|
34
|
+
background: rgba(255, 255, 255, 0.60-0.80);
|
|
35
|
+
border: 1px solid rgba(255, 255, 255, 0.25-0.40);
|
|
36
|
+
backdrop-filter: blur(10-16px) saturate(130-180%);
|
|
37
|
+
box-shadow: 0 12-24px 36-60px rgba(0, 0, 0, 0.10-0.20);
|
|
38
|
+
|
|
39
|
+
/* Dark preset */
|
|
40
|
+
background: rgba(255, 255, 255, 0.05-0.12);
|
|
41
|
+
border: 1px solid rgba(255, 255, 255, 0.08-0.18);
|
|
42
|
+
backdrop-filter: blur(12-20px) saturate(140-200%);
|
|
43
|
+
box-shadow: 0 12-24px 36-60px rgba(0, 0, 0, 0.25-0.45);
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### AI 逻辑流光 (Logic Flow Stroke)
|
|
47
|
+
```css
|
|
48
|
+
/* 用渐变描边模拟“AI 正在处理” */
|
|
49
|
+
border: 1px solid transparent;
|
|
50
|
+
background: linear-gradient(#0000, #0000) padding-box,
|
|
51
|
+
conic-gradient(from 0deg, #00F5FF, #8B5CF6, #00F5FF) border-box;
|
|
52
|
+
filter: drop-shadow(0 0 10px rgba(0, 245, 255, 0.35));
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### 3D 空间配置 (Perspective)
|
|
56
|
+
```css
|
|
57
|
+
container: perspective(1000-1400px);
|
|
58
|
+
card: rotateY(-8deg to -18deg) rotateX(6deg to 12deg) scale(0.95-1.00);
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### 轻量暗角 (Vignette)
|
|
62
|
+
```css
|
|
63
|
+
background: radial-gradient(ellipse at center,
|
|
64
|
+
rgba(0,0,0,0.00) 55%,
|
|
65
|
+
rgba(0,0,0,0.30) 100%);
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## 风格家族
|
|
69
|
+
|
|
70
|
+
### 1) Dark Grid Tech
|
|
71
|
+
- 背景:黑色网格,细微星点
|
|
72
|
+
- 色彩:霓虹强调色(控制在 1–2 个)
|
|
73
|
+
- 字体:几何无衬线 + 细描边标题
|
|
74
|
+
- 质感:轻微扫描线或噪点(克制)
|
|
75
|
+
- 适用:AI 工具、技术发布、开发者向产品
|
|
76
|
+
|
|
77
|
+
### 2) Soft Paper AI
|
|
78
|
+
- 背景:浅色网格纸感 + 柔和渐变
|
|
79
|
+
- 色彩:粉/蓝/薄荷等低饱和
|
|
80
|
+
- 字体:人文无衬线 + 轻量衬线点缀
|
|
81
|
+
- 质感:手绘线条、软阴影
|
|
82
|
+
- 适用:友好型 AI、教育、协作产品
|
|
83
|
+
|
|
84
|
+
### 3) Premium UI Glass
|
|
85
|
+
- 背景:深灰 + 聚光渐亮
|
|
86
|
+
- 色彩:中性为主 + 单一强调
|
|
87
|
+
- 字体:干净、层级强
|
|
88
|
+
- 表面:圆角卡片 + 玻璃质感
|
|
89
|
+
- 适用:企业级 SaaS
|
|
90
|
+
|
|
91
|
+
### 4) Clean Corporate Minimal
|
|
92
|
+
- 背景:白或近白
|
|
93
|
+
- 色彩:小范围渐变 + 单色强调
|
|
94
|
+
- 字体:高可读性
|
|
95
|
+
- 适用:可信、稳重的发布
|
|
96
|
+
|
|
97
|
+
### 5) Bold Kinetic Type
|
|
98
|
+
- 背景:纯色高对比
|
|
99
|
+
- 色彩:2–3 色以内
|
|
100
|
+
- 字体:大字号标题为主
|
|
101
|
+
- 适用:短促、高冲击营销
|
|
102
|
+
|
|
103
|
+
## Remotion 预设主题(Master Themes)
|
|
104
|
+
|
|
105
|
+
### A. Elite Dark AI(深度科技感)
|
|
106
|
+
- 适用:AI 模型发布、开发者工具、黑科技展示
|
|
107
|
+
- 色彩体系:
|
|
108
|
+
- Background: #050505 (Obsidian)
|
|
109
|
+
- Primary: #8B5CF6 (Vivid Violet)
|
|
110
|
+
- Accent: #00F5FF (Cyber Cyan)
|
|
111
|
+
- Text: #F8FAFC
|
|
112
|
+
- 视觉特征:动态网格背景、霓虹流光边框、3D 空间感
|
|
113
|
+
- Spring Config: `{ stiffness: 120, damping: 14, mass: 1 }`
|
|
114
|
+
|
|
115
|
+
### B. Glassmorphism SaaS(现代高端感)
|
|
116
|
+
- 适用:办公协作、B2B 产品 Demo、数据分析
|
|
117
|
+
- 色彩体系:
|
|
118
|
+
- Background: 线性渐变 (135deg, #F1F5F9 0%, #E2E8F0 100%)
|
|
119
|
+
- Primary: #2563EB (Royal Blue)
|
|
120
|
+
- Secondary: #6366F1 (Indigo)
|
|
121
|
+
- Card: rgba(255, 255, 255, 0.6–0.8) + blur(10–16px)
|
|
122
|
+
- 视觉特征:柔和多重阴影、毛玻璃容器、多层景深
|
|
123
|
+
- Spring Config: `{ stiffness: 80, damping: 12, mass: 0.8 }`
|
|
124
|
+
|
|
125
|
+
### C. Apple-style Minimalist(极致简洁感)
|
|
126
|
+
- 适用:消费级 AI、创意工具、高端品牌展示
|
|
127
|
+
- 色彩体系:
|
|
128
|
+
- Background: #FFFFFF 或 #F5F5F7
|
|
129
|
+
- Primary: #1D1D1F (Jet Black)
|
|
130
|
+
- Accent: #06C (Classic Blue)
|
|
131
|
+
- 视觉特征:极宽留白、超大粗体字、平滑推近镜头
|
|
132
|
+
- Spring Config: `{ stiffness: 60, damping: 15, mass: 1.2 }`
|
|
133
|
+
|
|
134
|
+
## 统一原则
|
|
135
|
+
|
|
136
|
+
- 统一网格(8 或 12 列)和边距
|
|
137
|
+
- 每屏一个主视觉 + 一个辅助信息
|
|
138
|
+
- 统一圆角、阴影、线宽
|
|
139
|
+
- 渐变方向一致(横向或纵向统一)
|
|
140
|
+
- 控制纹理与噪点强度,避免廉价感
|
|
141
|
+
|
|
142
|
+
## 视觉原子参数(Visual Polish)
|
|
143
|
+
|
|
144
|
+
- 圆角:L 24–32px / M 12–16px / S 6–8px
|
|
145
|
+
- 阴影:
|
|
146
|
+
- Float: 0 20px 50px rgba(0,0,0,0.12–0.20)
|
|
147
|
+
- Glow: 0 0 12–18px ${color}66–99
|
|
148
|
+
- 模糊:Standard 10–16px / Deep 18–28px
|
|
@@ -0,0 +1,304 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: subtitle-composer
|
|
3
|
+
version: 1.0.0
|
|
4
|
+
description: 字幕合成技能。处理字幕样式、自动分割长句、生成Remotion字幕数据。
|
|
5
|
+
triggers:
|
|
6
|
+
- 字幕
|
|
7
|
+
- subtitle
|
|
8
|
+
- 分割字幕
|
|
9
|
+
- 字幕样式
|
|
10
|
+
tools:
|
|
11
|
+
- Read
|
|
12
|
+
- Write
|
|
13
|
+
- Bash
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
# 字幕合成技能 (Subtitle Composer)
|
|
17
|
+
|
|
18
|
+
将语音合成产生的VTT字幕转换为Remotion可用的字幕数据,并确保字幕样式符合视频规范。
|
|
19
|
+
|
|
20
|
+
## 核心原则
|
|
21
|
+
|
|
22
|
+
1. **单行显示** - 字幕不换行,超长文本分割成多个片段
|
|
23
|
+
2. **最大字符数** - 中文约25字符,英文约50字符
|
|
24
|
+
3. **自然断句** - 在标点符号或语义边界处分割
|
|
25
|
+
4. **时间精确** - 字幕时间与语音严格同步
|
|
26
|
+
|
|
27
|
+
## 字幕样式预设
|
|
28
|
+
|
|
29
|
+
### 1. 简约风格 (Minimal)
|
|
30
|
+
```typescript
|
|
31
|
+
const minimalStyle = {
|
|
32
|
+
position: "bottom", // bottom | top | center
|
|
33
|
+
paddingBottom: 70,
|
|
34
|
+
backgroundColor: "rgba(0, 0, 0, 0.8)",
|
|
35
|
+
padding: "14px 40px",
|
|
36
|
+
borderRadius: 8,
|
|
37
|
+
fontSize: 36,
|
|
38
|
+
fontWeight: 600,
|
|
39
|
+
color: "#FFFFFF",
|
|
40
|
+
maxWidth: 1600,
|
|
41
|
+
animation: "fade", // fade | slide | pop | none
|
|
42
|
+
};
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### 2. 卡拉OK风格 (Karaoke)
|
|
46
|
+
```typescript
|
|
47
|
+
const karaokeStyle = {
|
|
48
|
+
position: "bottom",
|
|
49
|
+
highlightColor: "#FFD700",
|
|
50
|
+
baseColor: "#FFFFFF",
|
|
51
|
+
animation: "highlight", // 逐字高亮
|
|
52
|
+
};
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### 3. 渐显风格 (Typewriter)
|
|
56
|
+
```typescript
|
|
57
|
+
const typewriterStyle = {
|
|
58
|
+
position: "bottom",
|
|
59
|
+
animation: "typewriter", // 逐字显示
|
|
60
|
+
cursorColor: "#22D3EE",
|
|
61
|
+
};
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## VTT 解析规则
|
|
65
|
+
|
|
66
|
+
```typescript
|
|
67
|
+
// 解析VTT文件获取字幕数据
|
|
68
|
+
function parseVTT(vttContent: string, fps: number = 30): SubtitleCue[] {
|
|
69
|
+
const cues: SubtitleCue[] = [];
|
|
70
|
+
const lines = vttContent.trim().split('\n');
|
|
71
|
+
|
|
72
|
+
let i = 0;
|
|
73
|
+
while (i < lines.length) {
|
|
74
|
+
const line = lines[i].trim();
|
|
75
|
+
|
|
76
|
+
// 匹配时间戳行: 00:00:00,100 --> 00:00:05,237
|
|
77
|
+
if (line.includes('-->')) {
|
|
78
|
+
const [startStr, endStr] = line.split('-->').map(s => s.trim());
|
|
79
|
+
const start = parseVttTime(startStr, fps);
|
|
80
|
+
const end = parseVttTime(endStr, fps);
|
|
81
|
+
|
|
82
|
+
// 获取字幕文本
|
|
83
|
+
i++;
|
|
84
|
+
let text = '';
|
|
85
|
+
while (i < lines.length && lines[i].trim() && !lines[i].match(/^\d+$/)) {
|
|
86
|
+
text += (text ? ' ' : '') + lines[i].trim();
|
|
87
|
+
i++;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
if (text) {
|
|
91
|
+
cues.push({ start, end, text });
|
|
92
|
+
}
|
|
93
|
+
} else {
|
|
94
|
+
i++;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
return cues;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// 时间戳转帧数
|
|
102
|
+
function parseVttTime(timeStr: string, fps: number): number {
|
|
103
|
+
const parts = timeStr.split(':');
|
|
104
|
+
const seconds =
|
|
105
|
+
parseFloat(parts[0]) * 3600 +
|
|
106
|
+
parseFloat(parts[1]) * 60 +
|
|
107
|
+
parseFloat(parts[2].replace(',', '.'));
|
|
108
|
+
return Math.round(seconds * fps);
|
|
109
|
+
}
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
## 长句分割算法
|
|
113
|
+
|
|
114
|
+
```typescript
|
|
115
|
+
const MAX_CHARS = 25; // 中文最大字符数
|
|
116
|
+
|
|
117
|
+
function splitLongSubtitle(cue: SubtitleCue): SubtitleCue[] {
|
|
118
|
+
const { start, end, text } = cue;
|
|
119
|
+
|
|
120
|
+
// 如果文本足够短,直接返回
|
|
121
|
+
if (text.length <= MAX_CHARS) {
|
|
122
|
+
return [cue];
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// 分割点优先级:句号 > 逗号 > 顿号 > 空格 > 强制分割
|
|
126
|
+
const splitPoints = ['。', '!', '?', ',', '、', ';', ' '];
|
|
127
|
+
|
|
128
|
+
const segments: string[] = [];
|
|
129
|
+
let remaining = text;
|
|
130
|
+
|
|
131
|
+
while (remaining.length > MAX_CHARS) {
|
|
132
|
+
let splitIndex = -1;
|
|
133
|
+
|
|
134
|
+
// 在前MAX_CHARS字符中找分割点
|
|
135
|
+
for (const point of splitPoints) {
|
|
136
|
+
const idx = remaining.lastIndexOf(point, MAX_CHARS);
|
|
137
|
+
if (idx > 0) {
|
|
138
|
+
splitIndex = idx + 1;
|
|
139
|
+
break;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// 没找到分割点,强制在MAX_CHARS处分割
|
|
144
|
+
if (splitIndex === -1) {
|
|
145
|
+
splitIndex = MAX_CHARS;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
segments.push(remaining.slice(0, splitIndex).trim());
|
|
149
|
+
remaining = remaining.slice(splitIndex).trim();
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
if (remaining) {
|
|
153
|
+
segments.push(remaining);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// 按比例分配时间
|
|
157
|
+
const totalDuration = end - start;
|
|
158
|
+
const totalChars = segments.reduce((sum, s) => sum + s.length, 0);
|
|
159
|
+
|
|
160
|
+
const result: SubtitleCue[] = [];
|
|
161
|
+
let currentStart = start;
|
|
162
|
+
|
|
163
|
+
for (const segment of segments) {
|
|
164
|
+
const duration = Math.round((segment.length / totalChars) * totalDuration);
|
|
165
|
+
result.push({
|
|
166
|
+
start: currentStart,
|
|
167
|
+
end: currentStart + duration,
|
|
168
|
+
text: segment,
|
|
169
|
+
});
|
|
170
|
+
currentStart += duration;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
return result;
|
|
174
|
+
}
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
## Remotion 字幕组件
|
|
178
|
+
|
|
179
|
+
```typescript
|
|
180
|
+
// Subtitles.tsx
|
|
181
|
+
import { AbsoluteFill, interpolate, useCurrentFrame } from "remotion";
|
|
182
|
+
|
|
183
|
+
interface SubtitleCue {
|
|
184
|
+
start: number;
|
|
185
|
+
end: number;
|
|
186
|
+
text: string;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
interface SubtitlesProps {
|
|
190
|
+
cues: SubtitleCue[];
|
|
191
|
+
style?: "minimal" | "karaoke" | "typewriter";
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
export const Subtitles: React.FC<SubtitlesProps> = ({
|
|
195
|
+
cues,
|
|
196
|
+
style = "minimal"
|
|
197
|
+
}) => {
|
|
198
|
+
const frame = useCurrentFrame();
|
|
199
|
+
|
|
200
|
+
const currentCue = cues.find(
|
|
201
|
+
(cue) => frame >= cue.start && frame <= cue.end
|
|
202
|
+
);
|
|
203
|
+
|
|
204
|
+
if (!currentCue) return null;
|
|
205
|
+
|
|
206
|
+
// 淡入淡出动画
|
|
207
|
+
const fadeIn = interpolate(
|
|
208
|
+
frame,
|
|
209
|
+
[currentCue.start, currentCue.start + 6],
|
|
210
|
+
[0, 1],
|
|
211
|
+
{ extrapolateLeft: "clamp", extrapolateRight: "clamp" }
|
|
212
|
+
);
|
|
213
|
+
|
|
214
|
+
const fadeOut = interpolate(
|
|
215
|
+
frame,
|
|
216
|
+
[currentCue.end - 6, currentCue.end],
|
|
217
|
+
[1, 0],
|
|
218
|
+
{ extrapolateLeft: "clamp", extrapolateRight: "clamp" }
|
|
219
|
+
);
|
|
220
|
+
|
|
221
|
+
const opacity = Math.min(fadeIn, fadeOut);
|
|
222
|
+
|
|
223
|
+
// 上滑动画
|
|
224
|
+
const translateY = interpolate(
|
|
225
|
+
frame,
|
|
226
|
+
[currentCue.start, currentCue.start + 8],
|
|
227
|
+
[10, 0],
|
|
228
|
+
{ extrapolateLeft: "clamp", extrapolateRight: "clamp" }
|
|
229
|
+
);
|
|
230
|
+
|
|
231
|
+
return (
|
|
232
|
+
<AbsoluteFill
|
|
233
|
+
style={{
|
|
234
|
+
justifyContent: "flex-end",
|
|
235
|
+
alignItems: "center",
|
|
236
|
+
paddingBottom: 70,
|
|
237
|
+
}}
|
|
238
|
+
>
|
|
239
|
+
<div
|
|
240
|
+
style={{
|
|
241
|
+
opacity,
|
|
242
|
+
transform: `translateY(${translateY}px)`,
|
|
243
|
+
backgroundColor: "rgba(0, 0, 0, 0.8)",
|
|
244
|
+
padding: "14px 40px",
|
|
245
|
+
borderRadius: 8,
|
|
246
|
+
maxWidth: 1600,
|
|
247
|
+
textAlign: "center",
|
|
248
|
+
whiteSpace: "nowrap",
|
|
249
|
+
}}
|
|
250
|
+
>
|
|
251
|
+
<span
|
|
252
|
+
style={{
|
|
253
|
+
color: "#FFFFFF",
|
|
254
|
+
fontSize: 36,
|
|
255
|
+
fontWeight: 600,
|
|
256
|
+
letterSpacing: 1,
|
|
257
|
+
}}
|
|
258
|
+
>
|
|
259
|
+
{currentCue.text}
|
|
260
|
+
</span>
|
|
261
|
+
</div>
|
|
262
|
+
</AbsoluteFill>
|
|
263
|
+
);
|
|
264
|
+
};
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
## 使用流程
|
|
268
|
+
|
|
269
|
+
1. **读取VTT文件**
|
|
270
|
+
```bash
|
|
271
|
+
# VTT文件由voice-synthesizer生成
|
|
272
|
+
cat public/voices/seg_01_hook.vtt
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
2. **解析并分割字幕**
|
|
276
|
+
```typescript
|
|
277
|
+
const vttContent = fs.readFileSync('public/voices/seg_01_hook.vtt', 'utf-8');
|
|
278
|
+
const cues = parseVTT(vttContent, 30);
|
|
279
|
+
const splitCues = cues.flatMap(splitLongSubtitle);
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
3. **生成Remotion数据**
|
|
283
|
+
```typescript
|
|
284
|
+
const SUBTITLES = {
|
|
285
|
+
hook: splitCues,
|
|
286
|
+
// ... 其他场景
|
|
287
|
+
};
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
4. **在Sequence中使用**
|
|
291
|
+
```tsx
|
|
292
|
+
<Sequence from={0} durationInFrames={300}>
|
|
293
|
+
<MyScene />
|
|
294
|
+
<Audio src={staticFile("voices/seg_01_hook.mp3")} />
|
|
295
|
+
<Subtitles cues={SUBTITLES.hook} style="minimal" />
|
|
296
|
+
</Sequence>
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
## 质量检查
|
|
300
|
+
|
|
301
|
+
- [ ] 每条字幕不超过25个中文字符
|
|
302
|
+
- [ ] 字幕时间与语音同步
|
|
303
|
+
- [ ] 分割点在语义边界
|
|
304
|
+
- [ ] 无重叠或间隙过大
|