127 lines
8.3 KiB
Markdown
127 lines
8.3 KiB
Markdown
# SKG TK 二创验证 — 当前状态(2026-05-13)
|
||
|
||
## 一句话
|
||
SKG AI 素材生产管线第二条思路:TK 链接/上传 → 拆轨 → 抽关键帧(5 张+手动加)→ Vision 识别 → 改写文案 → 生图 → 生视频 → 合成。**MVP 通到生图,剩余 3 个节点占位**。
|
||
|
||
## 路径 / 端口
|
||
- 路径:`~/Projects/business/20260512-20260512-skg-tk-二创验证/`
|
||
- web dev:`cd web && pnpm dev`(端口 **4290**)
|
||
- api dev:`cd api && source .venv/bin/activate && uvicorn main:app --port 4291 --reload`
|
||
- 测试 job:`?job=c6767f3a166b`(chrisorb 71s 竖屏 TK)
|
||
|
||
## SKG 网关能力(实测 · 关键!)
|
||
`base_url: https://ai.skg.com/ezlink/v1`
|
||
key 写在 `api/.env` 的 `LLM_API_KEY`
|
||
|
||
| 端点 / 字段 | 状态 | 用途 |
|
||
|---|---|---|
|
||
| 远端 ASR | `ASR_MODEL=whisper-1` | 失败后进本机 ASR,再进多模态兜底。 |
|
||
| 本机 ASR | `LOCAL_ASR_MODEL=mlx-community/whisper-tiny` | 默认二级兜底,优先产出真实逐句时间轴。 |
|
||
| ASR 兜底 / 音频分析 | `ASR_FALLBACK_MODEL=gemini-2.5-flash` | 多模态音频兜底;后端会拒绝假字幕、重复文本和覆盖率过低结果。 |
|
||
| 字幕翻译 | `TRANSLATE_MODEL=gemini-2.5-flash` | 保留 Gemini。 |
|
||
| 画面理解 | `VISION_MODEL=gpt-4o` | 关键帧 Vision 已切 GPT;旧环境若写 `gemini-*` 会自动归一化到 `GPT_TEXT_MODEL`。 |
|
||
| 通用改写 / 分镜描述 | `REWRITE_MODEL=gpt-4o` | 已切 GPT;旧 Gemini 覆盖值会自动归一化。 |
|
||
| 新口播改写 | `AUDIO_REWRITE_MODEL=gpt-4o` | 默认跟随 `REWRITE_MODEL`;旧 Gemini 覆盖值会自动归一化。 |
|
||
| 产品视角识别 | `PRODUCT_VIEW_MODEL=gpt-image-2` | 产品图批量识别视角、左右 / 上下 / 内外侧、用途和风险。 |
|
||
| 所有生图 / 修图 | `gpt-image-2` | 服务端硬锁,无图片模型 fallback;覆盖关键帧生图、水印清理、元素提取、主体资产包、产品补角度、首尾帧。 |
|
||
| 配音 | `VOICE_PROVIDER=azure_openai` + `AZURE_TTS_MODEL=gpt-4o-mini-tts` | 语音固定 Azure OpenAI TTS;MiniMax 不再作为 fallback。后端会按 `AZURE_TTS_PATHS` 依次尝试路径,便于区分路径错误和整条语音服务不可用。 |
|
||
| 视频 | `VIDEO_MODEL=seedance` | 当前主流程暂停直接提交;生产通道默认 `ai.skg.com/doubao`,Seedance 真实 ID 由 `VIDEO_MODEL_SEEDANCE` 配置。 |
|
||
|
||
**网关后端 = one-hub 多渠道代理**。当前 key 分组叫「纯OpenAI+AWSClaude+Gemini官方」,缺 audio 渠道(`gpt-4o-audio-preview` 503 "无可用渠道")和 video 渠道。
|
||
|
||
## 模型选型(已写入 api/.env)
|
||
```
|
||
ASR_MODEL=whisper-1 # ⚠️ 端点 404,ASR 还没真跑通
|
||
TRANSLATE_MODEL=gemini-2.5-flash # ✅ text 已通
|
||
REWRITE_MODEL=gemini-2.5-pro # 占位
|
||
VISION_MODEL=gemini-2.5-flash # ✅ 识别已通
|
||
IMAGE_MODEL=gemini-3-pro-image-preview # ✅ nano-banana-pro,i2i 已通
|
||
```
|
||
|
||
## Pipeline 状态(8 节点合并版)
|
||
原 10 节点已合并:input + download + split 合一;translate 合到 transcript;videogen 和 compose 占位。
|
||
|
||
| 步 | 节点 | 状态 | 备注 |
|
||
|---|---|---|---|
|
||
| 1 | **输入·Input**(合并下载+拆分) | ✅ | yt-dlp 真下 + ffmpeg 拆 wav |
|
||
| 2 | **关键帧·Keyframes** | ✅ | D 启发式:候选 30 张 → pHash 去重 + Laplacian variance 评分 + 时序分桶 → 5 张;手动加帧 OK |
|
||
| 3 | **转录·ASR** | ❌ 阻塞 | SKG 网关 audio 不通;待 IT 开 audio 渠道 / 外部 key |
|
||
| 4 | **翻译·Translate** | ❌ 阻塞 | 依赖 ASR |
|
||
| 5 | **改写·Rewrite** | ⏳ 占位 | 等用户给产品信息模板 |
|
||
| 6 | **生图·Image Gen** | ✅ **刚做完** | nano-banana-pro i2i + 正负 prompt |
|
||
| 7 | **生视频·Video Gen** | ⏳ 占位 | sora-2 端点不通 |
|
||
| 8 | **合成·Compose** | ⏳ 占位 | 本地 ffmpeg + 字幕 + TTS |
|
||
|
||
## UI 架构(重要)
|
||
- **左侧 sidebar**(108px 极窄):8 个 stage tile 竖排 + DAG 路径分叉表达
|
||
- **主区 ReactFlow**:8 节点 DAG(input → keyframe/asr → ... → compose)
|
||
- **点 sidebar tile**:从左滑出 drawer panel(粉/紫/橙 Kanban 风格)
|
||
- **关键帧 lightbox**:**embedded 嵌入到 keyframe drawer**(不全屏)—— `<FrameLightbox embedded ... />`,drawer 宽度有 expandedFrame 时 760,无时 400
|
||
- **Input 节点上方**:多视频缩略图浮条 + 「+」加新视频
|
||
- **关键帧节点上方**:5+ 张缩略图按视频原比例(aspect-ratio: width/height)
|
||
- **缩略图 hover**:弹大图静态(关键帧是垫图素材,不放视频)
|
||
- **缩略图点击**:打开 keyframe drawer 内的 lightbox(左大图 + 右识别面板)
|
||
|
||
## 数据模型(关键 typescript / pydantic)
|
||
```typescript
|
||
KeyFrame {
|
||
index: number // 稳定 ID(不连续!frames 数组按 timestamp 排序)
|
||
timestamp: number
|
||
url: string
|
||
description?: {
|
||
scene, objects: [{name, position, color, extract_prompt}],
|
||
style, suggested_prompt
|
||
}
|
||
generated_images?: [{ id, prompt, model, mode, url, selected, created_at }]
|
||
}
|
||
|
||
Job { frames: KeyFrame[] ... }
|
||
```
|
||
|
||
**前端取帧必须用 `frames.find(x => x.index === activeIndex)` 不能用数组下标**(之前的 bug)。
|
||
|
||
## 关键文件
|
||
- `web/app/page.tsx` — 多 job state 管理(jobs[] + activeJobId),8 节点 LAYOUT
|
||
- `web/components/dashboard.tsx` — sidebar + drawer + 9 个 Kanban section(input/keyframe/asr/translate/rewrite/imagegen/videogen/compose),含 `ImageGenCard` 子组件
|
||
- `web/components/lightbox.tsx` — `FrameLightbox` 支持 `embedded` prop
|
||
- `web/components/video-lightbox.tsx` — Input 节点点视频缩略图弹的播放器
|
||
- `web/components/nodes/index.tsx` — ReactFlow 8 节点定义
|
||
- `web/lib/api.ts` — API client
|
||
- `api/main.py` — FastAPI 所有端点,KeyFrame/GeneratedImage 模型
|
||
|
||
## 已通的 API 端点
|
||
```
|
||
POST /jobs 创建 job(链接)
|
||
POST /jobs/{id}/download/retry TK 链接下载失败后重新下载
|
||
POST /jobs/upload 上传视频
|
||
GET /jobs/{id} job 状态
|
||
POST /jobs/{id}/analyze?frames=5 拆轨+抽帧+ASR 自动一气呵成
|
||
POST /jobs/{id}/frames?t=<sec> 手动按时间戳加帧
|
||
POST /jobs/{id}/frames/{idx}/describe ✅ Vision 识别(3 次重试 + reasoning_content 兜底)
|
||
POST /jobs/{id}/frames/{idx}/generate ✅ 生图(i2i / text-only, 含 negative_prompt)
|
||
GET /jobs/{id}/frames/{idx}/gen/{gen_id}.jpg 生成图二进制
|
||
POST /jobs/{id}/frames/{idx}/gen/{gen_id}/select 选用某 gen 给下游
|
||
GET /jobs/{id}/video.mp4 原视频
|
||
GET /jobs/{id}/frames/{idx}.jpg 关键帧 jpg
|
||
GET /health
|
||
```
|
||
|
||
## 当前约束 / 不要踩
|
||
1. 图片 / 视频 / 抽帧 / 产品图 / 生成图 / 首尾帧 / 视频候选缩略图默认复用 `web/components/media-asset-tile.tsx`。
|
||
2. 所有生图入口服务端只允许 `gpt-image-2`,不要重新加 Gemini 图片模型或其他 fallback。
|
||
3. 画面理解和文案改写默认归 GPT:`VISION_MODEL`、`REWRITE_MODEL`、`AUDIO_REWRITE_MODEL` 会拦截旧 `gemini-*` 覆盖值。
|
||
4. Gemini 仍保留在 ASR fallback / 音频分析 / 翻译链路,不要误删。
|
||
5. 语音只走 Azure OpenAI TTS;不要新增或依赖其他配音通道配置。
|
||
6. TikTok 受限下载遇到 `Log in for access` 不是后端没接到任务;需要 `YTDLP_COOKIES_FILE` 或 `YTDLP_COOKIES_FROM_BROWSER`,配置后可点“重新下载”。
|
||
7. 当前主流程不直接批量提交视频;先走“分镜规划 → 首尾帧 → 人工审核”。
|
||
8. 后端长任务不要用 `--reload`。
|
||
9. 关键帧 `index` 是稳定 ID,不等于数组下标;前端取帧用 `frames.find(x => x.index === idx)`。
|
||
|
||
## 最近变更
|
||
- 2026-05-18:清理个人语音通道残留,`/health`、前端类型、环境模板和文档不再暴露相关字段或配置。
|
||
- 2026-05-18:`VISION_MODEL`、`REWRITE_MODEL`、`AUDIO_REWRITE_MODEL` 切到 GPT 默认模型 `gpt-4o`,并加旧 Gemini 环境变量归一化保护。
|
||
- 2026-05-18:语音通道固定 Azure OpenAI TTS,并按 `AZURE_TTS_PATHS` 尝试语音路径。
|
||
- 2026-05-18:TikTok 受限链接支持 cookies 配置和失败素材“重新下载”。
|
||
- 2026-05-18:媒体素材交互统一收口到 `MediaAssetTile`。
|
||
- 2026-05-18:产品图视角识别和产品缺角度补图收敛到 `gpt-image-2`。
|