chore: 添加本地草稿服务器脚本及ugc_product_seeding账号

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
lc
2026-05-20 16:07:24 +08:00
parent 2d26eafb7d
commit 817c181cb5
7 changed files with 383 additions and 0 deletions

View 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()

View 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 }
}
}
}

View 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实拍感非广告片 | 重写动作描述 |
| 动作可见性 | 每段有明确的人手动作 | 补充手势 |

View 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 |

View 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" |

Binary file not shown.

After

Width:  |  Height:  |  Size: 263 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 MiB