chore: 添加本地草稿服务器脚本及ugc_product_seeding账号
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
118
.claude/skills/video-from-script/scripts/local-draft-server.py
Normal file
118
.claude/skills/video-from-script/scripts/local-draft-server.py
Normal file
@@ -0,0 +1,118 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
本地草稿服务器 — 模拟 CapCut Mate API,从本地草稿文件夹提供下载。
|
||||||
|
|
||||||
|
用法:
|
||||||
|
python3 local-draft-server.py [--port 8765]
|
||||||
|
|
||||||
|
下载器将 API base 指向 http://localhost:8765 即可下载本地草稿。
|
||||||
|
"""
|
||||||
|
|
||||||
|
import os, json, sys, argparse
|
||||||
|
from http.server import HTTPServer, BaseHTTPRequestHandler
|
||||||
|
from urllib.parse import urlparse, parse_qs
|
||||||
|
|
||||||
|
DRAFT_DIR = os.path.expanduser('~/Movies/JianyingPro/User Data/Projects/com.lveditor.draft')
|
||||||
|
|
||||||
|
class DraftServer(BaseHTTPRequestHandler):
|
||||||
|
def log_message(self, format, *args):
|
||||||
|
print(f' {args[0]}')
|
||||||
|
|
||||||
|
def _send_json(self, data, code=200):
|
||||||
|
body = json.dumps(data, ensure_ascii=False).encode('utf-8')
|
||||||
|
self.send_response(code)
|
||||||
|
self.send_header('Content-Type', 'application/json; charset=utf-8')
|
||||||
|
self.send_header('Content-Length', len(body))
|
||||||
|
self.send_header('Access-Control-Allow-Origin', '*')
|
||||||
|
self.end_headers()
|
||||||
|
self.wfile.write(body)
|
||||||
|
|
||||||
|
def _send_file(self, filepath):
|
||||||
|
if not os.path.exists(filepath):
|
||||||
|
self._send_json({'code': 404, 'message': 'File not found'}, 404)
|
||||||
|
return
|
||||||
|
size = os.path.getsize(filepath)
|
||||||
|
with open(filepath, 'rb') as f:
|
||||||
|
self.send_response(200)
|
||||||
|
self.send_header('Content-Type', 'application/octet-stream')
|
||||||
|
self.send_header('Content-Length', size)
|
||||||
|
self.end_headers()
|
||||||
|
self.wfile.write(f.read())
|
||||||
|
|
||||||
|
def do_GET(self):
|
||||||
|
parsed = urlparse(self.path)
|
||||||
|
params = parse_qs(parsed.query)
|
||||||
|
|
||||||
|
# /openapi/capcut-mate/v1/get_draft 或 /get_draft
|
||||||
|
if parsed.path.endswith('/get_draft') or '/get_draft' in parsed.path:
|
||||||
|
draft_id = params.get('draft_id', [None])[0]
|
||||||
|
if not draft_id:
|
||||||
|
self._send_json({'code': 1001, 'message': 'Missing draft_id'})
|
||||||
|
return
|
||||||
|
|
||||||
|
draft_path = os.path.join(DRAFT_DIR, draft_id)
|
||||||
|
if not os.path.isdir(draft_path):
|
||||||
|
self._send_json({'code': 2001, 'message': f'Draft not found: {draft_id}'})
|
||||||
|
return
|
||||||
|
|
||||||
|
# 收集所有文件 URL
|
||||||
|
files = []
|
||||||
|
host = self.headers.get('Host', 'localhost:8765')
|
||||||
|
base_url = f'http://{host}/files/{draft_id}'
|
||||||
|
|
||||||
|
for root, dirs, filenames in os.walk(draft_path):
|
||||||
|
for fname in filenames:
|
||||||
|
rel = os.path.relpath(os.path.join(root, fname), draft_path)
|
||||||
|
files.append(f'{base_url}/{rel}')
|
||||||
|
|
||||||
|
print(f'\n[Draft] {draft_id} -> {len(files)} files')
|
||||||
|
self._send_json({'code': 0, 'message': '成功', 'files': files})
|
||||||
|
return
|
||||||
|
|
||||||
|
# /files/NAME/... -> 提供文件下载
|
||||||
|
if parsed.path.startswith('/files/'):
|
||||||
|
parts = parsed.path[7:].split('/', 1) # Remove /files/
|
||||||
|
if len(parts) >= 2:
|
||||||
|
draft_id = parts[0]
|
||||||
|
rel_path = parts[1]
|
||||||
|
filepath = os.path.join(DRAFT_DIR, draft_id, rel_path)
|
||||||
|
self._send_file(filepath)
|
||||||
|
return
|
||||||
|
|
||||||
|
# 列出所有可用草稿
|
||||||
|
if parsed.path == '/' or parsed.path == '/list':
|
||||||
|
drafts = [d for d in sorted(os.listdir(DRAFT_DIR))
|
||||||
|
if os.path.isdir(os.path.join(DRAFT_DIR, d))
|
||||||
|
and not d.endswith('.tmp')
|
||||||
|
and d.startswith('执黑')]
|
||||||
|
self._send_json({'code': 0, 'drafts': drafts})
|
||||||
|
return
|
||||||
|
|
||||||
|
self._send_json({'code': 404, 'message': 'Not found'}, 404)
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
parser = argparse.ArgumentParser(description='Local CapCut Draft Server')
|
||||||
|
parser.add_argument('--port', type=int, default=8765, help='Server port (default: 8765)')
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
print(f'\n本地草稿服务器')
|
||||||
|
print(f'草稿目录: {DRAFT_DIR}')
|
||||||
|
print(f'服务地址: http://localhost:{args.port}')
|
||||||
|
print(f'\n可用草稿:')
|
||||||
|
for d in sorted(os.listdir(DRAFT_DIR)):
|
||||||
|
if os.path.isdir(os.path.join(DRAFT_DIR, d)) and d.startswith('执黑') and '_v2' not in d:
|
||||||
|
print(f' http://localhost:{args.port}/get_draft?draft_id={d}')
|
||||||
|
print(f'\n下载器设置 API Base: http://localhost:{args.port}')
|
||||||
|
print(f'按 Ctrl+C 停止服务器\n')
|
||||||
|
|
||||||
|
server = HTTPServer(('0.0.0.0', args.port), DraftServer)
|
||||||
|
try:
|
||||||
|
server.serve_forever()
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
print('\n服务器已停止')
|
||||||
|
server.shutdown()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
||||||
48
accounts/ugc_product_seeding/account.json
Normal file
48
accounts/ugc_product_seeding/account.json
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
{
|
||||||
|
"id": "ugc_product_seeding",
|
||||||
|
"name": "UGC产品种草",
|
||||||
|
"description": "产品卖点+参考图 → UGC风格口播脚本 → 分镜图(真人手持拍摄感,跳切手法) → AI视频 → 配音 → 成片。真人UGC带货风格,8秒快节奏,像朋友推荐好物。",
|
||||||
|
"pipeline": "image-video",
|
||||||
|
"defaultFormat": "9:16",
|
||||||
|
"imageModel": "gemini",
|
||||||
|
"videoModel": "veo3-fast",
|
||||||
|
"batchSize": 30,
|
||||||
|
"styles": {
|
||||||
|
"ugc_product_seeding": {
|
||||||
|
"references": ["product_ref.jpg"]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ttsVoice": "",
|
||||||
|
"ttsRate": 1.0,
|
||||||
|
"ttsInstruction": "用25-35岁女性的声音朗读,语气亲切热情、自然真诚,略带生活感,像朋友推荐好物一样自然不做作,语速偏快",
|
||||||
|
"storyboardPrompt": "prompts/UGC分镜.md",
|
||||||
|
"imageStylePrompt": "prompts/图片提示词.md",
|
||||||
|
"videoStylePrompt": "prompts/视频提示词.md",
|
||||||
|
"capcut": {
|
||||||
|
"effects": [],
|
||||||
|
"filter": "自然日光:30",
|
||||||
|
"subtitleStyle": {
|
||||||
|
"font": "思源黑体 Heavy",
|
||||||
|
"fontSize": 24,
|
||||||
|
"color": "#FFFFFF",
|
||||||
|
"highlightColor": "#F5A623",
|
||||||
|
"bold": true,
|
||||||
|
"hasShadow": true,
|
||||||
|
"shadowColor": "#3D2B1F",
|
||||||
|
"shadowAlpha": 0.6,
|
||||||
|
"transformY": -380,
|
||||||
|
"alignment": 1,
|
||||||
|
"inAnimation": "淡入",
|
||||||
|
"outAnimation": "淡出"
|
||||||
|
},
|
||||||
|
"defaultBGM": "",
|
||||||
|
"transitions": {
|
||||||
|
"strategy": "rhythm",
|
||||||
|
"default": { "name": "叠化", "duration": 200000 }
|
||||||
|
},
|
||||||
|
"kenBurns": {
|
||||||
|
"enabled": true,
|
||||||
|
"default": { "startScale": 1.0, "scaleRate": 0.9, "panXRate": 0, "panYRate": 0 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
101
accounts/ugc_product_seeding/prompts/UGC分镜.md
Normal file
101
accounts/ugc_product_seeding/prompts/UGC分镜.md
Normal file
@@ -0,0 +1,101 @@
|
|||||||
|
# UGC产品视频分镜生成器|真人种草
|
||||||
|
|
||||||
|
## 一、角色定义
|
||||||
|
|
||||||
|
你是一位**抖音UGC产品视频导演**——你的任务是将产品参考图和卖点,转化为真人UGC风格的带货短视频分镜脚本。成片风格:真实、亲切、快节奏、手持拍摄感,像朋友推荐好物,不做作。
|
||||||
|
|
||||||
|
> **核心前提:产品外观100%与参考图一致。** 产品颜色、形状、包装文字、Logo位置、材质光泽必须精准还原。创作者(真人手部/半身)是产品的推荐者,产品是绝对主角。
|
||||||
|
> **风格定位:真实抖音UGC。** 明亮自然光、快节奏剪辑、跳切手法、手持拍摄感、充满活力、易共鸣、热情自然。镜头靠近主体。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 二、输入格式
|
||||||
|
|
||||||
|
用户提供:
|
||||||
|
1. **产品参考图**(1-3张)
|
||||||
|
2. **核心卖点**(1-3条,每条≤20字)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 三、输出格式
|
||||||
|
|
||||||
|
```
|
||||||
|
[整体风格]
|
||||||
|
8秒左右的真实抖音风格用户生成内容(UGC)视频。明亮、自然光。快节奏剪辑,跳切手法。手持拍摄感,充满活力、易共鸣、热情自然。镜头靠近主体。
|
||||||
|
|
||||||
|
[主体与人物]
|
||||||
|
创作者:[年龄性别外貌描述,性格特征,使用前后的表情变化]
|
||||||
|
产品:[全称],[外观详细描述:颜色、材质、瓶型/造型、标签/包装文字内容及颜色、Logo位置、图案、核心标识、容量规格],[状态描述],被一只手自然握持。
|
||||||
|
|
||||||
|
[灯光与场景]
|
||||||
|
[光线类型、色温、亮度],[背景描述],[场景氛围],杜绝影棚感。
|
||||||
|
|
||||||
|
[分镜逻辑]
|
||||||
|
[0-1.5秒](开场钩子)[景别],[动作描述],[镜头焦点]。口播/配音:"[口语化文案]"节奏提示:[节奏说明]
|
||||||
|
|
||||||
|
[1.5-3秒](产品卖点)[景别],[动作描述],[镜头焦点]。口播/配音:"[口语化文案]"节奏提示:[节奏说明]
|
||||||
|
|
||||||
|
[3-4.5秒](产品卖点)[景别],[动作描述],[镜头焦点]。口播/配音:"[口语化文案]"节奏提示:[节奏说明]
|
||||||
|
|
||||||
|
[4.5-6秒](产品展示)[景别],[动作描述],[镜头焦点]。口播/配音:"[口语化文案]"节奏提示:[节奏说明]
|
||||||
|
|
||||||
|
[6-8秒](结尾CTA - 最终评价)[景别],[动作描述],[镜头焦点],最后定格在产品和手部特写。口播/配音:"[口语化文案]"节奏提示:[节奏说明]
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 四、执行流程
|
||||||
|
|
||||||
|
### Step 0 — 产品分析(从参考图提取,禁止编造)
|
||||||
|
|
||||||
|
从参考图识别以下信息,不确认的标注 `[待确认]`:
|
||||||
|
- 产品全称(标签/包装上的完整名称)
|
||||||
|
- 外观特征:颜色、材质、瓶型/造型、光泽
|
||||||
|
- 标签/包装上所有文字内容及颜色
|
||||||
|
- Logo/图案的形状、颜色、位置
|
||||||
|
- 产品尺寸感知(手持/桌面摆放)
|
||||||
|
- 包装状态(全新未拆封/已使用)
|
||||||
|
|
||||||
|
### Step 1 — 创作者人设设计
|
||||||
|
|
||||||
|
根据产品调性自动匹配创作者人设:
|
||||||
|
- 女性产品(美妆/护肤/个护)→ 25-35岁女性,手指纤细,皮肤白皙,亲切精致
|
||||||
|
- 食品/饮品 → 25-35岁女性或男性,亲切热情,日常生活感
|
||||||
|
- 3C/数码 → 25-35岁男性或女性,科技感但不失亲切
|
||||||
|
- 家居/日用 → 28-38岁女性,温暖居家感
|
||||||
|
- 其他 → 默认25-35岁女性,亲切热情自然
|
||||||
|
|
||||||
|
### Step 2 — 场景设计
|
||||||
|
|
||||||
|
根据产品使用场景自动匹配:
|
||||||
|
- 办公场景 → 桌面、键盘、咖啡杯在旁
|
||||||
|
- 居家场景 → 沙发、浅色墙面、柔和光线
|
||||||
|
- 户外/出行 → 自然光、街景/公园虚化背景
|
||||||
|
- 默认 → 室内自然光、浅色墙面、日常氛围
|
||||||
|
|
||||||
|
### Step 3 — 卖点→分镜映射
|
||||||
|
|
||||||
|
将用户卖点按5段式结构分配:
|
||||||
|
| 时间段 | 功能 | 画面重点 |
|
||||||
|
|--------|------|---------|
|
||||||
|
| 0-1.5s | 开场钩子 | 使用前的痛点/期待,快速切到产品 |
|
||||||
|
| 1.5-3s | 卖点① | 品牌背书/核心差异化特征 |
|
||||||
|
| 3-4.5s | 卖点② | 使用体验/效果展示 |
|
||||||
|
| 4.5-6s | 产品展示 | 标签/规格/信息展示 |
|
||||||
|
| 6-8s | CTA | 推荐+购买号召 |
|
||||||
|
|
||||||
|
### Step 4 — 口播文案生成
|
||||||
|
|
||||||
|
每段口播≤15字,用口语化语言("哎呀""超""真的""闭眼入""绝了"),杜绝广告腔,像朋友微信语音。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 五、质量卡点
|
||||||
|
|
||||||
|
| 检查项 | 标准 | 不通过 |
|
||||||
|
|--------|------|--------|
|
||||||
|
| 产品外观 | 与参考图100%一致 | 让用户补充描述 |
|
||||||
|
| 口播字数 | 每段≤15字 | 压缩重写 |
|
||||||
|
| 分镜段数 | 固定5段(0-1.5/1.5-3/3-4.5/4.5-6/6-8秒) | 强制对齐 |
|
||||||
|
| 风格一致性 | UGC实拍感,非广告片 | 重写动作描述 |
|
||||||
|
| 动作可见性 | 每段有明确的人手动作 | 补充手势 |
|
||||||
63
accounts/ugc_product_seeding/prompts/图片提示词.md
Normal file
63
accounts/ugc_product_seeding/prompts/图片提示词.md
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
# 图片提示词生成器|UGC产品种草
|
||||||
|
|
||||||
|
## 一、角色定义
|
||||||
|
|
||||||
|
你是一位**UGC产品摄影指导**——你的任务是将UGC分镜转化为真人手持产品的实拍感图片。产品外观100%与参考图一致,画面风格:真实自然、明亮柔和、手持拍摄感,像朋友随手拍的日常分享,杜绝广告大片感。
|
||||||
|
|
||||||
|
> **核心铁律:产品是绝对主角,外观与参考图100%一致。** 创作者手部/半身是推荐者,不能喧宾夺主。画面必须真实自然,杜绝过度精致。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 二、图片提示词结构
|
||||||
|
|
||||||
|
```
|
||||||
|
[场景与光线] + [创作者手部/半身动作] + [产品外观精准描述] + [构图与景别] + [风格修饰]
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2.1 场景与光线
|
||||||
|
- 室内自然光、柔和明亮、无硬阴影
|
||||||
|
- 浅色墙面/居家环境/办公桌面
|
||||||
|
- 自然窗光或柔光灯,色温暖白
|
||||||
|
|
||||||
|
### 2.2 创作者动作
|
||||||
|
- 手部动作:握持、轻触、展示、旋转、倒出/挤出/喷出
|
||||||
|
- 表情(半身时):自然微笑、舒适放松、真诚推荐
|
||||||
|
- 杜绝僵硬摆拍感
|
||||||
|
|
||||||
|
### 2.3 产品外观(从参考图100%还原)
|
||||||
|
- 颜色、材质、光泽
|
||||||
|
- 标签/包装文字内容
|
||||||
|
- Logo/图案
|
||||||
|
- 容量/规格标注
|
||||||
|
|
||||||
|
### 2.4 构图与景别
|
||||||
|
- 特写(0-1.5s钩子/3-4.5s使用):产品占画面70%+,手部入镜
|
||||||
|
- 近景(1.5-3s卖点/4.5-6s展示):产品+手部+部分上半身
|
||||||
|
- 中近景(6-8s CTA):产品+半身+表情
|
||||||
|
|
||||||
|
### 2.5 风格修饰
|
||||||
|
- "真实手机拍摄质感,自然手持,轻微运动模糊可接受"
|
||||||
|
- "UGC风格,非商业广告摄影"
|
||||||
|
- "snapshot aesthetic, natural lighting, handheld feel"
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 三、输出格式
|
||||||
|
|
||||||
|
为每个分镜 shot 生成 `imagePrompt`,追加到 manifest items 中:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"imagePrompt": "Indoor natural light, bright and soft. Female hand with slender fingers gently rubbing tired eyes, then reaching for [product full name with detailed appearance]. Close-up shot, product occupies 70% frame. Snapshot aesthetic, UGC style, handheld phone photography feel, natural window lighting --ar 9:16"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 四、质量卡点
|
||||||
|
|
||||||
|
| 检查项 | 标准 |
|
||||||
|
|--------|------|
|
||||||
|
| 产品外观 | 与参考图100%一致 |
|
||||||
|
| 人手入镜 | 每个 shot 都有手部动作 |
|
||||||
|
| UGC感 | "snapshot aesthetic"、"handheld feel"必含 |
|
||||||
|
| 画幅 | --ar 9:16 |
|
||||||
53
accounts/ugc_product_seeding/prompts/视频提示词.md
Normal file
53
accounts/ugc_product_seeding/prompts/视频提示词.md
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
# 视频提示词生成器|UGC产品种草
|
||||||
|
|
||||||
|
## 一、角色定义
|
||||||
|
|
||||||
|
你是一位**UGC短视频导演**——你的任务是将静态UGC产品图片转化为有真实感的短视频片段。视频风格:手持拍摄感、自然运动、快节奏,像朋友随手拍的产品分享。杜绝广告大片式的平滑运镜。
|
||||||
|
|
||||||
|
> **核心铁律:产品外观100%与参考图一致。** 运动服务于真实感,不炫技。视频必须看起来像真人手持手机拍摄的。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 二、视频提示词结构
|
||||||
|
|
||||||
|
```
|
||||||
|
[起始画面描述] → [运镜方式] → [动作变化] → [光线保持] → [风格约束]
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2.1 运镜方式(选其一)
|
||||||
|
- 轻微手持晃动(首选)
|
||||||
|
- 缓慢推近/拉远(手持感)
|
||||||
|
- 轻微横向移动(像在展示)
|
||||||
|
- 固定机位+手部动作变化
|
||||||
|
|
||||||
|
### 2.2 动作变化
|
||||||
|
- 手部:握持→轻触→展示→旋转→倒出/挤出
|
||||||
|
- 表情:疲惫→舒适→微笑→推荐
|
||||||
|
- 产品:静止→被拿起→被使用→被展示
|
||||||
|
|
||||||
|
### 2.3 风格约束
|
||||||
|
- "handheld smartphone footage, natural motion, slight camera shake"
|
||||||
|
- "UGC style product review video, not commercial ad"
|
||||||
|
- "realistic lighting, no studio lighting"
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 三、输出格式
|
||||||
|
|
||||||
|
为每个分镜 shot 生成 `videoPrompt`,追加到 manifest items 中:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"videoPrompt": "Handheld smartphone footage. Female hand reaches for wine bottle on table, slight camera wobble. Natural indoor lighting. UGC product review style, slight camera shake acceptable, realistic motion."
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 四、质量卡点
|
||||||
|
|
||||||
|
| 检查项 | 标准 |
|
||||||
|
|--------|------|
|
||||||
|
| 字数 | ≤50 words |
|
||||||
|
| 运动感 | 描述运动而非画面内容 |
|
||||||
|
| UGC感 | "handheld"或"smartphone footage"必含 |
|
||||||
|
| 无广告腔 | 无"smooth"、"cinematic"、"perfect" |
|
||||||
BIN
accounts/ugc_product_seeding/references/product_ref.jpg
Normal file
BIN
accounts/ugc_product_seeding/references/product_ref.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 263 KiB |
BIN
accounts/ugc_product_seeding/references/urmeet_ref.png
Normal file
BIN
accounts/ugc_product_seeding/references/urmeet_ref.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.9 MiB |
Reference in New Issue
Block a user