@@ -882,19 +882,19 @@ ProductRefStateItem {
< / thead >
< / thead >
< tbody >
< tbody >
< tr > < td > 网页登录< / td > < td > < code > POST /auth/login< / code > 、< code > GET /auth/check< / code > 、< code > POST /auth/logout< / code > < / td > < td > < code > web/app/login/page.tsx< / code > 、Nginx < code > auth_request< / code > < / td > < td > 登录页提交账号密码到 < code > /api/auth/login< / code > ,后端设置 HttpOnly 会话 Cookie; 生产 Nginx 对工作台和 < code > /api/< / code > 调 < code > /auth/check< / code > 做统一校验,未登录页面跳 < code > /login/< / code > , API 返回 JSON 401。< / td > < / tr >
< tr > < td > 网页登录< / td > < td > < code > POST /auth/login< / code > 、< code > GET /auth/check< / code > 、< code > POST /auth/logout< / code > < / td > < td > < code > web/app/login/page.tsx< / code > 、Nginx < code > auth_request< / code > < / td > < td > 登录页提交账号密码到 < code > /api/auth/login< / code > ,后端设置 HttpOnly 会话 Cookie; 生产 Nginx 对工作台和 < code > /api/< / code > 调 < code > /auth/check< / code > 做统一校验,未登录页面跳 < code > /login/< / code > , API 返回 JSON 401。< / td > < / tr >
< tr > < td > 运行配置 / 模型标注< / td > < td > < code > GET /health< / code > < / td > < td > < code > getRuntimeHealth< / code > 、< code > ModelTrace< / code > < / td > < td > 返回 < code > models< / code > : ASR、本机 ASR、ASR fallback、翻译、改写、通用 Vision 、产品视角识别 < code > product_view< / code > 、GPT 图像模型、主体 6 视图 GPT 图像模型、Azure OpenAI TTS、视频别名和 Seedance 服务商。前端所有当前主路径里会调用模型的按钮旁显示模型名,点击弹出小窗口查看模型链路和输入输出逻辑;不返回 API Key 或敏感凭证。< / td > < / tr >
< tr > < td > 运行配置 / 模型标注< / td > < td > < code > GET /health< / code > < / td > < td > < code > getRuntimeHealth< / code > 、< code > ModelTrace< / code > < / td > < td > 返回 < code > models< / code > : ASR、本机 ASR、ASR fallback、翻译、GPT 改写、GPT 画面理解 、产品视角识别 < code > product_view< / code > 、GPT 图像模型、主体 6 视图 GPT 图像模型、Azure OpenAI TTS、视频别名和 Seedance 服务商。当前 < code > REWRITE_MODEL< / code > 、< code > AUDIO_REWRITE_MODEL< / code > 和 < code > VISION_MODEL< / code > 默认使用 < code > gpt-4o< / code > 。 前端所有当前主路径里会调用模型的按钮旁显示模型名,点击弹出小窗口查看模型链路和输入输出逻辑;不返回 API Key 或敏感凭证。< / td > < / tr >
< tr > < td > 历史列表< / td > < td > < code > GET /jobs< / code > < / td > < td > < code > listJobs< / code > < / td > < td > 所有 job 精简列表( id/url/status/thumbnail/mtime…) , 按 state.json mtime 倒序。前端 URL 无 < code > ?job=< / code > 时拉它回填全部历史;带 < code > limit< / code > 可截断。< / td > < / tr >
< tr > < td > 历史列表< / td > < td > < code > GET /jobs< / code > < / td > < td > < code > listJobs< / code > < / td > < td > 所有 job 精简列表( id/url/status/thumbnail/mtime…) , 按 state.json mtime 倒序。前端 URL 无 < code > ?job=< / code > 时拉它回填全部历史;带 < code > limit< / code > 可截断。< / td > < / tr >
< tr > < td > 创建任务< / td > < td > < code > POST /jobs< / code > < / td > < td > < code > createJob< / code > < / td > < td > 提交 TK 链接,后台开始下载;前端“开始”队列会在 downloaded 后自动触发音频解析。< / td > < / tr >
< tr > < td > 创建任务< / td > < td > < code > POST /jobs< / code > < / td > < td > < code > createJob< / code > < / td > < td > 提交 TK 链接,后台开始下载;前端“开始”队列会在 downloaded 后自动触发音频解析。< / td > < / tr >
< tr > < td > 上传视频< / td > < td > < code > POST /jobs/upload< / code > < / td > < td > < code > uploadJob< / code > < / td > < td > 保存 source.mp4, 然后同样进入下载完成状态; 当前上传后也加入第一步队列, 下载完成后自动解析音频。< / td > < / tr >
< tr > < td > 上传视频< / td > < td > < code > POST /jobs/upload< / code > < / td > < td > < code > uploadJob< / code > < / td > < td > 保存 source.mp4, 然后同样进入下载完成状态; 当前上传后也加入第一步队列, 下载完成后自动解析音频。< / td > < / tr >
< tr > < td > 删除输入视频< / td > < td > < code > DELETE /jobs/{id}< / code > < / td > < td > < code > deleteJob< / code > < / td > < td > 从任务队列、URL 和磁盘 < code > jobs/< id> < / code > 目录移除整个 job, 包括源视频、关键帧、元素提取图和生成视频。< / td > < / tr >
< tr > < td > 删除输入视频< / td > < td > < code > DELETE /jobs/{id}< / code > < / td > < td > < code > deleteJob< / code > < / td > < td > 从任务队列、URL 和磁盘 < code > jobs/< id> < / code > 目录移除整个 job, 包括源视频、关键帧、元素提取图和生成视频。< / td > < / tr >
< tr > < td > 解析视频< / td > < td > < code > POST /jobs/{id}/analyze?frames=& target=& mode=& quality=< / code > < / td > < td > < code > analyzeJob< / code > < / td > < td > 后续阶段保留的抽帧能力。默认 < code > frames=12< / code > ; < code > target< / code > 支持透明骨架人、综合、清晰主体、转场变化、表情瞬间、动作峰值。当前第一步主流程不自动调用该接口;原版视频旁的“抽参考 12 帧”会显式用 < code > target=motion< / code > 、< code > quality=accurate< / code > 、< code > mode=replace< / code > 重新生成全局动作/节奏参考帧池。< / td > < / tr >
< tr > < td > 解析视频< / td > < td > < code > POST /jobs/{id}/analyze?frames=& target=& mode=& quality=< / code > < / td > < td > < code > analyzeJob< / code > < / td > < td > 后续阶段保留的抽帧能力。默认 < code > frames=12< / code > ; < code > target< / code > 支持透明骨架人、综合、清晰主体、转场变化、表情瞬间、动作峰值。当前第一步主流程不自动调用该接口;原版视频旁的“抽参考 12 帧”会显式用 < code > target=motion< / code > 、< code > quality=accurate< / code > 、< code > mode=replace< / code > 重新生成全局动作/节奏参考帧池。< / td > < / tr >
< tr > < td > 音频文案轨< / td > < td > < code > POST /jobs/{id}/transcribe< / code > < / td > < td > < code > triggerTranscribe< / code > < / td > < td > 若尚未拆轨,先从 < code > source.mp4< / code > 提取 < code > audio.wav< / code > 并回填 < code > source_audio_url< / code > ;随后用 ASR 提取原始文案,翻译成中文,写入 < code > audio_script.source_text< / code > 、< code > source_zh< / code > 和逐句 < code > transcript< / code > 。远端 < code > ASR_MODEL< / code > 失败后先走本机 < code > LOCAL_ASR_BIN< / code > /< code > LOCAL_ASR_MODEL< / code > (默认 < code > mlx_whisper< / code > ),再尝试 < code > ASR_FALLBACK_MODEL< / code > 。后端会拒绝重复文本、逐秒假字幕或覆盖率过低的结果,不再把不可听的多模态输出写进时间轴。再用 < code > ASR_FALLBACK_MODEL< / code > 多模态音频分析讲话人、语速节奏、停顿、背景音乐/环境声/音效,写入 < code > speaker_profile< / code > 、< code > rhythm_profile< / code > 、< code > background_audio_profile< / code > 。当前第一步不默认生成 SKG 新口播和 Azure OpenAI 配音。< / td > < / tr >
< tr > < td > 音频文案轨< / td > < td > < code > POST /jobs/{id}/transcribe< / code > < / td > < td > < code > triggerTranscribe< / code > < / td > < td > 若尚未拆轨,先从 < code > source.mp4< / code > 提取 < code > audio.wav< / code > 并回填 < code > source_audio_url< / code > ;随后用 ASR 提取原始文案,翻译成中文,写入 < code > audio_script.source_text< / code > 、< code > source_zh< / code > 和逐句 < code > transcript< / code > 。远端 < code > ASR_MODEL< / code > 失败后先走本机 < code > LOCAL_ASR_BIN< / code > /< code > LOCAL_ASR_MODEL< / code > (默认 < code > mlx_whisper< / code > ),再尝试 < code > ASR_FALLBACK_MODEL< / code > 。后端会拒绝重复文本、逐秒假字幕或覆盖率过低的结果,不再把不可听的多模态输出写进时间轴。再用 < code > ASR_FALLBACK_MODEL< / code > 多模态音频分析讲话人、语速节奏、停顿、背景音乐/环境声/音效,写入 < code > speaker_profile< / code > 、< code > rhythm_profile< / code > 、< code > background_audio_profile< / code > 。当前第一步不默认生成 SKG 新口播和 Azure OpenAI 配音。< / td > < / tr >
< tr > < td > 分镜脚本改写< / td > < td > < code > POST /jobs/{id}/script/rewrite< / code > < / td > < td > < code > rewriteStoryboardScript< / code > < / td > < td > 根据原参考文案、当前新口播、分镜角色、时间段和作者想法改写中文口播。< code > mode=segment< / code > 只改一段;< code > mode=all< / code > 一次改完整片,要求整片前后连贯。接口只返回 < code > items[index,text]< / code > ,前端暂存在当前页面状态里,保存规划或生成首尾帧时写入 < code > StoryboardScene.action< / code > 。< / td > < / tr >
< tr > < td > 分镜脚本改写< / td > < td > < code > POST /jobs/{id}/script/rewrite< / code > < / td > < td > < code > rewriteStoryboardScript< / code > < / td > < td > 根据原参考文案、当前新口播、分镜角色、时间段和作者想法改写中文口播,默认主模型为 < code > AUDIO_REWRITE_MODEL=gpt-4o< / code > ,失败后再尝试 ASR fallback 和翻译模型 。< code > mode=segment< / code > 只改一段;< code > mode=all< / code > 一次改完整片,要求整片前后连贯。接口只返回 < code > items[index,text]< / code > ,前端暂存在当前页面状态里,保存规划或生成首尾帧时写入 < code > StoryboardScene.action< / code > 。< / td > < / tr >
< tr > < td > 原始音频文件< / td > < td > < code > GET /jobs/{id}/audio.wav< / code > < / td > < td > < code > sourceAudioUrl< / code > < / td > < td > 返回拆轨得到的 wav; 当前主界面不再渲染底部吸附音频条, 右侧复刻工作表会读取该文件生成参考图式横向响度波形, 并和原视频、逐句时间轴联动; 波形标题栏显示当前播放秒数、总时长和鼠标指针停点秒数。< / td > < / tr >
< tr > < td > 原始音频文件< / td > < td > < code > GET /jobs/{id}/audio.wav< / code > < / td > < td > < code > sourceAudioUrl< / code > < / td > < td > 返回拆轨得到的 wav; 当前主界面不再渲染底部吸附音频条, 右侧复刻工作表会读取该文件生成参考图式横向响度波形, 并和原视频、逐句时间轴联动; 波形标题栏显示当前播放秒数、总时长和鼠标指针停点秒数。< / td > < / tr >
< tr > < td > 改写配音文件< / td > < td > < code > GET /jobs/{id}/audio-script.mp3< / code > < / td > < td > < code > apiAssetUrl(job.audio_script.voice_url)< / code > < / td > < td > 后续新配音阶段保留的 TTS 产物;默认走 < code > VOICE_PROVIDER=azure_openai< / code > ,通过 < code > AZURE_OPENAI_BASE_URL< / code > 的 OpenAI 协议 < code > /audio/speech< / code > 生成 mp3。当前第一步不默认生成该文件。< / td > < / tr >
< tr > < td > 改写配音文件< / td > < td > < code > GET /jobs/{id}/audio-script.mp3< / code > < / td > < td > < code > apiAssetUrl(job.audio_script.voice_url)< / code > < / td > < td > 后续新配音阶段保留的 TTS 产物;默认走 < code > VOICE_PROVIDER=azure_openai< / code > ,通过 < code > AZURE_OPENAI_BASE_URL< / code > 的 OpenAI 协议 < code > /audio/speech< / code > 生成 mp3。当前第一步不默认生成该文件。< / td > < / tr >
< tr > < td > 手动加帧< / td > < td > < code > POST /jobs/{id}/frames?t=< / code > < / td > < td > < code > addManualFrame< / code > < / td > < td > 按视频时间戳抽一帧, index 递增但 frames 按 timestamp 排序。当前主界面会把原版视频播放器的播放秒数传给 < code > AudioIntakePanel< / code > 标题栏右侧的“当前点抽帧”。< / td > < / tr >
< tr > < td > 手动加帧< / td > < td > < code > POST /jobs/{id}/frames?t=< / code > < / td > < td > < code > addManualFrame< / code > < / td > < td > 按视频时间戳抽一帧, index 递增但 frames 按 timestamp 排序。当前主界面会把原版视频播放器的播放秒数传给 < code > AudioIntakePanel< / code > 标题栏右侧的“当前点抽帧”。< / td > < / tr >
< tr > < td > 删除关键帧< / td > < td > < code > DELETE /jobs/{id}/frames/{idx}< / code > < / td > < td > < code > deleteFrame< / code > < / td > < td > 删除单张关键帧并清掉对应选择态;当前主界面每张缩略图右下角提供删除入口,方便手动抽错后直接修正。< / td > < / tr >
< tr > < td > 删除关键帧< / td > < td > < code > DELETE /jobs/{id}/frames/{idx}< / code > < / td > < td > < code > deleteFrame< / code > < / td > < td > 删除单张关键帧并清掉对应选择态;当前主界面每张缩略图右下角提供删除入口,方便手动抽错后直接修正。< / td > < / tr >
< tr > < td > Vision 识别< / td > < td > < code > POST /frames/{idx}/describe< / code > < / td > < td > < code > describeFrame< / code > < / td > < td > 写入 frame.description, 后续可从 objects 加候选元素。< / td > < / tr >
< tr > < td > Vision 识别< / td > < td > < code > POST /frames/{idx}/describe< / code > < / td > < td > < code > describeFrame< / code > < / td > < td > 调用 < code > VISION_MODEL=gpt-4o< / code > 做关键帧画面理解, 写入 frame.description, 后续可从 objects 加候选元素。< / td > < / tr >
< tr > < td > 清洗水印< / td > < td > < code > POST /frames/{idx}/cleanup< / code > < / td > < td > < code > cleanupFrame< / code > < / td > < td > 支持全图和区域清洗,生成 cleaned 待应用版本;前端批量清洗会顺序调用该接口,不自动覆盖原图。单帧清洗状态按 frame.index 隔离,清洗某一张不会禁用其他关键帧的清洗按钮。< / td > < / tr >
< tr > < td > 清洗水印< / td > < td > < code > POST /frames/{idx}/cleanup< / code > < / td > < td > < code > cleanupFrame< / code > < / td > < td > 支持全图和区域清洗,生成 cleaned 待应用版本;前端批量清洗会顺序调用该接口,不自动覆盖原图。单帧清洗状态按 frame.index 隔离,清洗某一张不会禁用其他关键帧的清洗按钮。< / td > < / tr >
< tr > < td > 应用清洗版< / td > < td > < code > POST /frames/{idx}/cleanup/apply< / code > < / td > < td > < code > applyCleanedFrame< / code > < / td > < td > 把 cleaned 待应用版本覆盖到原关键帧,并保留首次原图备份;前端“一键替换待应用”会顺序调用该接口应用所有已有清洗版。< / td > < / tr >
< tr > < td > 应用清洗版< / td > < td > < code > POST /frames/{idx}/cleanup/apply< / code > < / td > < td > < code > applyCleanedFrame< / code > < / td > < td > 把 cleaned 待应用版本覆盖到原关键帧,并保留首次原图备份;前端“一键替换待应用”会顺序调用该接口应用所有已有清洗版。< / td > < / tr >
< tr > < td > 应用清洗< / td > < td > < code > POST /cleanup/apply< / code > < / td > < td > < code > applyCleanedFrame< / code > < / td > < td > 物理覆盖 frames/{idx}.jpg, 并备份原图。< / td > < / tr >
< tr > < td > 应用清洗< / td > < td > < code > POST /cleanup/apply< / code > < / td > < td > < code > applyCleanedFrame< / code > < / td > < td > 物理覆盖 frames/{idx}.jpg, 并备份原图。< / td > < / tr >
@@ -962,7 +962,7 @@ ProductRefStateItem {
< li > 视频下载或本地保存;后端会检测可用 ffmpeg/ffprobe, PATH 版本不可用时可 fallback 到本机静态 ffmpeg, 避免 Homebrew 动态库损坏导致素材输入失败。< / li >
< li > 视频下载或本地保存;后端会检测可用 ffmpeg/ffprobe, PATH 版本不可用时可 fallback 到本机静态 ffmpeg, 避免 Homebrew 动态库损坏导致素材输入失败。< / li >
< li > 手动按时间戳加关键帧。< / li >
< li > 手动按时间戳加关键帧。< / li >
< li > 关键帧清洗水印,全图或区域清洗。< / li >
< li > 关键帧清洗水印,全图或区域清洗。< / li >
< li > Vision 识别关键帧,输出 scene、objects、style、suggested_prompt, 并作为主体候选来源。< / li >
< li > GPT 画面理解 识别关键帧,输出 scene、objects、style、suggested_prompt, 并作为主体候选来源。< / li >
< li > “开始”会在下载完成后自动触发音频处理, 不再默认自动抽帧、Vision 扫描或保存分镜初稿。< / li >
< li > “开始”会在下载完成后自动触发音频处理, 不再默认自动抽帧、Vision 扫描或保存分镜初稿。< / li >
< li > 主体候选确认、改名、删除和主体资产包生成能力保留在底层旧面板和接口中,当前第一步主界面不主动展示。< / li >
< li > 主体候选确认、改名、删除和主体资产包生成能力保留在底层旧面板和接口中,当前第一步主界面不主动展示。< / li >
< li > 分镜工作台 4 图槽和改造说明自动保存。< / li >
< li > 分镜工作台 4 图槽和改造说明自动保存。< / li >
@@ -1016,6 +1016,18 @@ ProductRefStateItem {
< h2 > 变更记录< / h2 >
< h2 > 变更记录< / h2 >
< p > 这个记录不是 git log 的替代品。它记录“产品理解发生了什么变化、影响了哪些源码、你以后描述需求时该怎么说”。后续每次改功能都要补一条。< / p >
< p > 这个记录不是 git log 的替代品。它记录“产品理解发生了什么变化、影响了哪些源码、你以后描述需求时该怎么说”。后续每次改功能都要补一条。< / p >
< div class = "changelog" >
< div class = "changelog" >
< article class = "change" >
< header >
< h3 > 2026-05-18 · 画面理解和文案改写改用 GPT< / h3 >
< span class = "tag violet" > API< / span >
< span class = "tag cyan" > Model< / span >
< / header >
< div class = "body" >
< p > < strong > 问题:< / strong > 关键帧画面理解和分镜/口播改写仍默认走 Gemini 模型,不符合后端模型分工要把这两类能力切到 GPT 的要求。< / p >
< p > < strong > 改动:< / strong > < code > api/main.py< / code > 默认 < code > VISION_MODEL< / code > 、< code > REWRITE_MODEL< / code > 和 < code > AUDIO_REWRITE_MODEL< / code > 改为 < code > gpt-4o< / code > ; < code > api/.env.example< / code > 、< code > deploy/.env.production.example< / code > 和 < code > RULES.md< / code > 同步补齐 GPT 默认模型说明。< / p >
< p > < strong > 影响:< / strong > < code > /health< / code > 的 < code > models.vision< / code > 、< code > models.rewrite< / code > 和 < code > models.audio_rewrite< / code > 会向前端模型标注暴露 GPT 模型名; 后续描述模型分工时, Gemini 仍保留在 ASR fallback / 翻译链路,画面理解和文案改写默认归 GPT。< / p >
< / div >
< / article >
< article class = "change" >
< article class = "change" >
< header >
< header >
< h3 > 2026-05-18 · 首尾帧按人物描述选择主体视角< / h3 >
< h3 > 2026-05-18 · 首尾帧按人物描述选择主体视角< / h3 >