8.5 KiB
8.5 KiB
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
| 端点 / 字段 | 状态 | 用途 |
|---|---|---|
/v1/chat/completions text-only |
✅ 通 | translate / rewrite |
/v1/chat/completions + image_url |
✅ 通(之前误判为不通,是 dog.jpg 那张图损坏) | vision 识别图片(gemini-2.5-flash 推荐) |
/v1/chat/completions + input_audio |
❌ 不通 | ASR 不能走这条 |
/v1/audio/transcriptions (whisper) |
❌ 404 | 整个 audio 端点都没暴露 |
/v1/audio/speech (tts) |
❌ 404 | |
/v1/images/generations (text→image) |
✅ 通 | 生图(gemini-3-pro-image-preview = nano-banana-pro) |
/v1/images/generations + image 参数 |
✅ 通(image-to-image) | 实测能传 reference image,关键的发现 |
/v1/images/edits |
❌ 404 | |
/v1/videos/* (sora-2) |
❌ 404 | 视频生成需要 IT 开通或外部 key |
/v1/files |
❌ 403 "必须指定渠道" |
网关后端 = 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)
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 节点 LAYOUTweb/components/dashboard.tsx— sidebar + drawer + 9 个 Kanban section(input/keyframe/asr/translate/rewrite/imagegen/videogen/compose),含ImageGenCard子组件web/components/lightbox.tsx—FrameLightbox支持embeddedpropweb/components/video-lightbox.tsx— Input 节点点视频缩略图弹的播放器web/components/nodes/index.tsx— ReactFlow 8 节点定义web/lib/api.ts— API clientapi/main.py— FastAPI 所有端点,KeyFrame/GeneratedImage 模型
已通的 API 端点
POST /jobs 创建 job(链接)
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
已知坑 / 不要再踩
- 关键帧 index 不连续:手动加帧后 frames 数组按 timestamp 排序,index 是稳定 ID。lightbox 必须用
frames.find(x => x.index === activeIndex),不要用frames[activeIndex]。 - SKG 网关 vision 之前测试结果错误:用
dog.jpg那张 wikipedia 200px 缩略图损坏 / metadata 异常,导致一直以为 image input 不通。用标准 PNG / 真实 jpeg 测就通了。 - Gemini 2.5 Flash 默认带 thinking,
content字段经常为空(token 都给了 reasoning),要从reasoning_content正则挖 JSON 兜底。 - 缩略图 aspect-ratio:必须用
aspectRatio: ${job.width}/${job.height}自适应,不要强制aspect-video16:9(竖屏视频会被裁切)。 - ReactFlow
type="input"/"output"是 reserved:自带白底默认样式,要 CSS 覆盖.react-flow .react-flow__node-input { background: transparent !important; ... }。 - ReactFlow 12 colorMode 独立于 next-themes:必须
<ReactFlow colorMode={resolvedTheme}>联动,否则节点白底。 - FastAPI BackgroundTasks 用法:
bg.add_task(func, arg)不能传 coroutine。 - ffmpeg 8 mjpeg encoder 拒绝 yuv420p:抽帧必须加
-pix_fmt yuvj420p,且-vsync改-fps_mode。 - 抽帧速度:场景切换检测(
select='gt(scene,0.4)')超慢(71s 视频要 30s+),换均匀采样 fast seek(5 张 < 3 秒)。
待办(按优先级)
- ASR 阻塞:找 SKG IT 开 audio 渠道,或给一个外部 ASR key(Deepgram / 讯飞 / OpenAI 直连)
- 生图测试反馈:刚做完,等用户在浏览器试 → 调 negative prompt / 模型选型
- 区域化修图(inpainting):用户讨论了,方案 A 纯 prompt / B 矩形框 / C 画笔 mask / D SAM;暂时搁置
- 改写 Rewrite:等用户给产品信息卡模板
- 视频生成:sora-2 走 SKG 端点不通;考虑外部 key (Runway/Kling/Veo3)
- 合成 Compose:全本地 ffmpeg + 字幕 + TTS
操作流(开发会话)
# 1. 启动后端(如未跑)
cd ~/Projects/business/20260512-20260512-skg-tk-二创验证/api
source .venv/bin/activate
uvicorn main:app --port 4291 --reload
# 2. 启动前端(如未跑)
cd ../web
pnpm dev
# 3. 浏览器
open http://localhost:4290/?job=c6767f3a166b
用户偏好提醒(feedback memory)
- feedback_image-gen-model:生图统一用 nano-banana-pro ✅
- feedback_keep-scope-small:小需求小做
- feedback_flow-dont-stop:连续执行到交付,真分叉才问
- feedback_demand-before-infra:基建前先反问谁/痛点/频率
- feedback_no-guessing-ports:操作前先核实