Source Analysis · 2026-05-13

这个页面是产品协作地图,不是应用功能页。

它把“你看到的界面、你想改的功能、实际要动的源码、可能影响的数据和接口”放在同一个地方。 后续描述需求时,可以直接说“改源码地图里的某个区域 / 某个节点职责 / 某个接口行为”,这样改动范围会更准,也更容易追踪每次变更带来的影响。

项目路径/Users/kangwan/Projects/business/20260512-20260512-skg-tk-二创验证
前端Next.js 16 · 端口 4290 · web/app/page.tsx
后端FastAPI · 端口 4291 · api/main.py
本文档位置docs/source-analysis.html · 独立文件,不接入应用

怎么用它描述需求

1. 先说你在改哪个产品区

例如“镜头拆解 / 元素提取面板”、“元素改造 Storyboard 节点”、“分镜头编排工作台 4 图槽”。不要只说“这里乱”,要指向页面里的功能区。

2. 再说这个区应该承担什么职责

例如“Vision 只给候选元素,用户必须能编辑、删除、重新提取”,这会直接落到 FrameLightbox 和元素接口。

3. 最后说不希望发生什么

例如“点击元素不要跳页面”、“不要直接进入编排打断思路”、“不要把参考视频复刻成一样的东西”。这能约束交互和文案。

建议表达格式:我要改「功能区」;当前问题是「行为」;正确职责是「业务目的」;不要影响「已有流程」。

运行与入口

项目命令 / 入口说明
前端开发服务 cd web && pnpm dev Next.js App Router,主页面是 web/app/page.tsx,默认端口 4290。
后端开发服务 cd api && source .venv/bin/activate && uvicorn main:app --port 4291 --reload FastAPI,所有任务状态、视频、关键帧、清洗、元素、分镜保存都在 api/main.py
测试页面 http://localhost:4290/?job=c6767f3a166b URL 里可放多个 job id:?job=id1,id2,id3,前端会恢复多个任务并激活最后一个。
源码解析页 open docs/source-analysis.html 独立静态 HTML,不被 Next 构建、不影响产品工作台。

业务管线

当前产品不是“复制别人的视频”,而是拆解参考视频,提取可借鉴的镜头元素,再改造成 SKG 产品语境的视频素材。

1

输入

TK 链接或本地上传,后端下载/保存源视频。

2

镜头拆解

拆轨、抽关键帧、手动加帧,形成参考分镜池。

3

清洗水印

对关键帧做全图或区域清洗,必要时应用为当前参考图。

4

Vision 识别

识别场景和候选元素,只是候选,不应锁死。

5

元素提取

编辑/新增/删除元素,对元素反复生成提取图。

6

元素改造

把参考主体、场景、动作和 SKG 产品放入分镜结构。

7

生成视频

用分镜结构生成首帧和视频片段。当前未实现。

8

合成成品

片段、字幕、配音、转场合成最终 mp4。当前未实现。

源码结构地图

前端核心

web/app/page.tsx产品工作台主状态:jobs、activeJobId、selectedFrames、clipboard、ReactFlow 节点和边。
web/components/nodes/index.tsxDAG 节点定义:Input、Keyframe、ASR、Translate、Rewrite、Storyboard、VideoGen、Compose。
web/components/lightbox.tsx镜头拆解和元素提取的主工作面板:清洗、识别、元素编辑、区域提取、抠图。
web/components/storyboard-bar.tsx顶部已选分镜条:展示选入编排的关键帧,点击进入工作台。
web/components/storyboard-workbench.tsx全屏分镜编排工作台:4 图槽、改造目标、时长、自动保存。
web/lib/api.ts前端类型和 API client,是前后端数据契约镜像。

后端核心

api/main.pyFastAPI 单文件后端:状态模型、任务恢复、下载、抽帧、Vision、清洗、元素、分镜、文件返回。
jobs/<jobId>/state.json运行时状态文件,不在源码列表里,但刷新恢复依赖它。
jobs/<jobId>/frames关键帧 jpg。注意 frame.index 是稳定 ID,不等于数组下标。
jobs/<jobId>/cleaned清洗后待应用图片。
jobs/<jobId>/elements元素提取图,多版本命名:idx_elementId_cutoutId.jpg
jobs/<jobId>/gen关键帧生图结果。
前端主链路:
web/app/page.tsx
  -> ReactFlow 节点:web/components/nodes/index.tsx
  -> 画布内镜头拆解面板:KeyframeNode 内嵌 web/components/lightbox.tsx
  -> 顶部分镜条:web/components/storyboard-bar.tsx
  -> 分镜工作台:web/components/storyboard-workbench.tsx
  -> API 契约:web/lib/api.ts

后端主链路:
api/main.py
  -> Job / KeyFrame / KeyElement / StoryboardScene
  -> 下载 / 上传 / 抽帧 / Vision / 清洗 / 元素提取 / 分镜保存
  -> jobs/<jobId>/state.json + 图片文件落盘

界面区域到源码

你看到的区域Input 节点和视频缩略图
主要源码InputNode in web/components/nodes/index.tsx;状态处理在 page.tsx
适合怎么描述“输入/下载/视频就绪这个节点应该如何提示用户下一步”。
你看到的区域镜头拆解节点上方关键帧
主要源码KeyframeNode 内嵌 FrameLightbox;后端 /frames/describe/cleanup
适合怎么描述“关键帧详情面板在无限画布上怎么展示、缩放、跟随,以及清洗/识别/元素提取的操作顺序”。
你看到的区域元素列表和提取图
主要源码FrameLightbox;类型 KeyElement;接口 addElement/updateElement/deleteElement/cutoutElement/deleteCutout
适合怎么描述“Vision 识别出来的是候选,用户要能修正、重复提取、删除错误元素”。
你看到的区域元素改造 · Storyboard 节点
主要源码StoryboardNode;上方元素缩略图来自所有已提取 cutouts。
适合怎么描述“这里是素材入口,不是最终视频编辑器;点击是否进入工作台要不要打断当前任务”。
你看到的区域顶部分镜条
主要源码StoryboardBar;只展示 selectedFrames,不负责提取元素。
适合怎么描述“选好的分镜如何按时间序组织,以及如何进入具体分镜编排”。
你看到的区域分镜头编排工作台
主要源码StoryboardWorkbench;保存到 frame.storyboard;接口 PUT /storyboard
适合怎么描述“每个分镜需要哪些图片槽、哪些改造说明,如何为视频生成做准备”。

数据模型

Job

一个视频任务。前端维护多个 jobs[],当前激活的是 activeJobId。URL 查询参数会持久化多个 job。

Job {
  id, url, status, progress, message,
  video_url, duration, width, height,
  frames: KeyFrame[],
  transcript: TranscriptSegment[],
  storyboard_images?: StoryboardImage[]
}

KeyFrame

关键帧是整个产品的核心单位。index 是稳定 ID,手动加帧后不连续,不能用数组下标代替。

KeyFrame {
  index, timestamp, url,
  description,
  cleaned_url, cleaned_applied,
  elements: KeyElement[],
  storyboard: StoryboardScene,
  generated_images: GeneratedImage[]
}

KeyElement

从关键帧里识别或手动添加的可借鉴元素。Vision 给的是候选,用户可编辑,并可多次生成提取图。

KeyElement {
  id,
  name_zh, name_en, position,
  source: auto | manual | region,
  region,
  cutouts: string[],
  cutout_id
}

StoryboardScene

分镜编排结果,不是复刻说明。它把参考图和 SKG 改造方向绑定到一个分镜上。

StoryboardScene {
  duration,
  subject_image,
  scene_image,
  product_image,
  action_image,
  subject,
  product,
  scene,
  action
}

接口地图

功能接口前端调用说明
创建任务POST /jobscreateJob提交 TK 链接,后台开始下载,停在 downloaded 等用户点解析。
上传视频POST /jobs/uploaduploadJob保存 source.mp4,然后同样进入下载完成状态。
解析视频POST /jobs/{id}/analyzeanalyzeJob拆轨 + 抽关键帧。当前不自动跑 ASR,避免 audio 阻塞视觉管线。
手动加帧POST /jobs/{id}/frames?t=addManualFrame按视频时间戳抽一帧,index 递增但 frames 按 timestamp 排序。
Vision 识别POST /frames/{idx}/describedescribeFrame写入 frame.description,后续可从 objects 加候选元素。
清洗水印POST /frames/{idx}/cleanupcleanupFrame支持全图和区域清洗,生成 cleaned 待应用版本。
应用清洗POST /cleanup/applyapplyCleanedFrame物理覆盖 frames/{idx}.jpg,并备份原图。
元素增改删POST/PATCH/DELETE /elementsaddElement/updateElement/deleteElement让用户修正 Vision 错误,避免候选结果锁死。
元素提取POST /elements/{element_id}/cutoutcutoutElement调用图像模型生成独立白底素材图,每次累积一张 cutout。
分镜保存PUT /frames/{idx}/storyboardupdateStoryboard保存 4 图槽、时长和改造说明。
生图POST /frames/{idx}/generategenerateImage基于关键帧或已选生成图做 image-to-image,目前可用。

节点职责边界

节点当前职责不该承担改动主要文件
输入 Input 创建/上传任务,显示视频就绪,触发解析。 不要自动一路跑到 ASR 或生图;用户需要控制解析节奏。 page.tsxInputNodeapi/main.py
镜头拆解 / 元素提取 关键帧选择、清洗、Vision 候选、元素编辑、区域提取、元素 cutout。 不要把 Vision 结果当最终结论;不要点击元素就跳走。 KeyframeNodeFrameLightbox、元素接口
元素改造 Storyboard 展示可用元素素材,承接“参考元素 → SKG 画面”的入口。 不要等同于最终视频生成;不要暗示复刻原视频。 StoryboardNodeStoryboardBar
分镜工作台 每个分镜填 4 图槽和改造 brief,为后续生成首帧/视频片段做准备。 当前不负责真实调用视频模型。 StoryboardWorkbenchupdateStoryboard
ASR / Translate / Rewrite 未来的文案轨,目前部分占位或受 audio 阻塞。 不要阻断视觉素材管线。 ASRNodeTranslateNodeRewriteNode、ASR 接口
Video Gen / Compose 未来生成视频和合成成品。 当前只是占位,不要描述成已打通。 VideoGenNodeComposeNode、未来模型接口

当前已通与阻塞

已通

  • TK 链接 / 上传创建 job。
  • 视频下载或本地保存,ffmpeg 抽关键帧。
  • 手动按时间戳加关键帧。
  • 关键帧清洗水印,全图或区域清洗。
  • Vision 识别关键帧,输出 scene、objects、style、suggested_prompt。
  • 元素增改删、区域元素添加、元素多次提取图。
  • 分镜工作台 4 图槽和改造说明自动保存。
  • nano-banana-pro image-to-image 生图。

阻塞 / 占位

  • ASR:SKG 网关 audio endpoint 404 或渠道不可用。
  • Translate:本身 text 通,但产品流里依赖 ASR 段落。
  • Rewrite:需要 SKG 产品信息模板和目标脚本结构。
  • Video Gen:sora/video endpoint 未通,Seedance/Kling/Veo3 外部 key 未接。
  • Compose:还没做本地 ffmpeg 字幕/TTS 合成。

最重要的产品判断:当前视觉素材管线已经能继续推进,文案/音频/视频生成不要再反过来卡住镜头拆解和元素改造。

需求描述模板

改镜头拆解 / 元素提取

“我在关键帧 lightbox 里,Vision 识别后的元素列表应该怎么编辑/重提取/删除;点击元素不要跳转;提取图怎么预览和复制。”

改 Storyboard 节点

“我在 DAG 的元素改造节点,它上方缩略图展示什么、hover 预览什么、点击后是否进入工作台、是否自动选中对应分镜。”

改分镜工作台

“我在全屏分镜编排工作台,每个分镜需要哪些槽位、字段如何命名、保存后如何传给后续生成视频。”

改数据/接口

“这个动作需要持久化到 state.json,字段加在 Job/KeyFrame/KeyElement/StoryboardScene 哪一层,刷新后要恢复。”

改节点语义

“这个节点的业务职责要改,不只是 UI 文案;请同步更新节点标题、subtitle、说明、可点击行为、状态推导和本源码解析页。”

变更记录

这个记录不是 git log 的替代品。它记录“产品理解发生了什么变化、影响了哪些源码、你以后描述需求时该怎么说”。后续每次改功能都要补一条。

2026-05-13 · 关键帧详情从固定左侧抽屉迁到无限画布

KeyframeNode

问题:关键帧详情 / 元素提取面板固定在左侧 drawer,和 ReactFlow 无限画布割裂,也不会跟随画布缩放。

改动:移除主页面隐藏渲染的 Dashboard drawer 承载方式,新增独立 keyframePanel ReactFlow 节点来挂载 FrameLightbox

影响:web/app/page.tsxweb/components/nodes/index.tsx;点关键帧后面板默认出现在流程左侧空白画布里,不遮挡 Input / Keyframe 主节点;标题栏可拖动,跟随 ReactFlow 平移和缩放。再次点击关键帧缩略图会把面板找回到默认位置,并自动把视野拉到“关键帧 + 面板”。

2026-05-13 · 元素改造 hover 预览简化为原帧预览

StoryboardNode

问题:元素改造节点的 hover 预览虽然已改为节点内显示,但仍比关键帧节点复杂,多了“来源原帧 / 提取元素”两栏和元素名称,信息过载。

改动:改成和镜头拆解关键帧一致的简单预览:只显示来源原帧,底部显示分镜编号和时间。

影响:web/components/nodes/index.tsx;元素改造板块 hover 现在更轻,不干扰当前判断。

2026-05-13 · 元素改造 hover 预览改为节点内效果

StoryboardNode

问题:上一版把元素预览用 createPortal 挂到 body,DevTools 里会出现额外 fixed 层,交互形态和关键帧节点不一致。

改动:改成节点内 group-hover 预览,不再向 body 插入预览层。后续又简化为只展示来源原帧,见上方最新记录。

影响:web/components/nodes/index.tsx;元素改造板块的 DOM 和交互效果更接近关键帧缩略图。

2026-05-13 · 新增独立源码解析与协作地图

docs

目的:把产品功能区、源码位置、接口、数据模型、需求描述方式固定下来,减少“描述不准导致改偏”。

影响:新增 docs/source-analysis.html,不接入 Next 应用,不影响工作台运行。

以后描述:可以直接引用本页的功能区名称、节点职责和源码文件名。

2026-05-13 · Storyboard 元素缩略图 hover 预览修复

StoryboardNode

问题:元素改造节点上方小图 hover 没有像镜头拆解节点一样显示原图预览,并且首次修复时出现运行时错误。

原因:节点内部 overflow 裁剪了预览;随后 portal 预览里把变量写成了不存在的 aspectRatio

影响:web/components/nodes/index.tsx。该记录之后又改为节点内预览,见上方最新记录。

2026-05-13 · 元素识别结果不再锁死

元素提取

问题:Vision 识别可能错,但元素列表像最终结果;点击提取图会跳页面,打断用户思路。

改动:支持元素改名、改英文提示、改位置、删除元素、重复提取、删除单张提取图;提取图不再用链接跳新页。

影响:FrameLightboxweb/lib/api.tsPATCH /jobs/{job_id}/frames/{idx}/elements/{element_id}

2026-05-13 · 分镜编排入口聚焦到具体分镜

StoryboardWorkbench

问题:从 Storyboard 或顶部分镜条进入编排时,没有明确定位到用户正在看的那一帧。

改动:工作台接受 focusedFrame,点击缩略图会打开工作台并聚焦对应分镜。

影响:page.tsxStoryboardBarStoryboardWorkbenchStoryboardNode

2026-05-13 · 视觉管线不再被 ASR 阻断

Pipeline

问题:SKG 网关 audio 不通时,视觉解析也容易被标记失败。

改动:analyze 主流程强调拆轨和关键帧,声音文案轨独立处理。

影响:api/main.pypage.tsx、节点语义说明。

更新规则

以后任何改动只要影响产品理解、节点职责、界面行为、数据模型、API、运行方式或用户操作路径,都要同步更新本页的对应章节和“变更记录”。

改动类型必须更新本页哪里原因
节点文案 / 节点功能业务管线、节点职责边界、界面区域到源码、变更记录避免用户按旧节点理解描述需求。
新增 / 修改接口接口地图、数据模型、变更记录避免前后端契约不清。
新增数据字段数据模型、源码结构地图、变更记录刷新恢复和 state.json 依赖字段一致。
改交互路径界面区域到源码、需求描述模板、变更记录用户描述“点击哪里”时必须和真实路径一致。
修 bug变更记录;如果暴露新坑,也更新当前已通与阻塞让后续同类问题能快速定位。