ai-chatbot/docs/video-canvas-task-repairs-2026-09-17.md

19 KiB
Raw Blame History

视频画布任务与交互修复 · 2026-09-17

承接 23f86dfc 的全面扫描。用户补充“浏览器刷新一下就好了”,本轮重点修复任务结果与页面状态脱节,同时处理 F02–F07 中已确认的入口问题。本记录是分支修复与本地验收,未部署 48 服务器,也没有把原 231 项清单改成全部通过。

前半部分保留 0d17638a 阶段记录;本轮新增修复和验证见文末“后续修复”。

修复范围

扫描项 本轮改动 验证及边界
F01 任务恢复 新增统一生成任务接口、数据库受理记录、请求 ID 去重、原子领取、心跳与结果保存;客户端提交前保存待核对请求,刷新/重开/online/focus/visibilitychange 时查询;去掉虚假进度;旧版无任务 ID 的 pending 明确提示无法恢复 主图像/视频生成、配置工具的图像/视频/分析、脚本再生成、批量分镜/视频接入。局部编辑按已有 taskId 恢复查询。真实数据库与浏览器验收见下文。专用图像后期、角度编辑、脚本弹窗资产生成/逐镜提示词仍有同步请求,未宣称全部入口具备同等恢复能力
F02 取消 排队任务通过数据库 CAS 取消;已提交供应商的任务返回明确说明,继续保存结果;删除已完成结果写入任务隐藏记录 数据库并发及浏览器排队取消通过;没有冒充支持上游中止
F03 模板 待执行模板设为 idle;参考样例标记示例;空脚本不再显示硬编码成稿 代码检查;未逐个模板做生产生成
F04 脚本 脚本入口统一 story-script;空响应/无有效镜头返回失败并保留旧稿 结果契约回归通过;脚本资产生成与单镜提示词处理不是此次持久队列接入范围
F05 批量 批量分镜和视频实际入队;按有无首帧选择兼容模式,采用模型声明的离散时长/比例/分辨率;完成任务不重复提交,失败/空节点可继续执行 模型参数和任务契约通过;没有新增真实付费批量请求
F06 素材弹窗 去掉假分页和无效图标,增加搜索、纵向滚动、自适应列、素材名称与明确数量单位 实际组件注入 100 个素材,第 100 项能选中、确认回传,搜索返回 1 项;使用当前 Tailwind 编译产物验收
F07 次级控件 文本及音频生视频提示词翻译接真实接口并预览后应用;旧脚本编辑聚焦;资源替换接上传;通知显示真实任务;模板筛选使用配置数据;退出接现有登出流程;未实现按钮明确禁用 代码与类型检查。未实际退出生产账户,未声称所有停用高级能力已实现

任务表复用既有 0091_add_canvas_capability_tasks.sql,没有新增数据库迁移。上线前须核对该既有迁移已应用。

任务一致性

  • 同一请求 ID 重试不会重复执行;同一节点已有活动任务时复用现有任务。
  • 同画布任务串行领取,多执行者通过 PostgreSQL 事务锁与状态更新竞争。
  • 刷新前画布尚未保存的已受理节点,可从任务快照补回;不会从旧任务复活已保存删除的节点。
  • 多图结果使用任务 ID 与序号组成稳定结果节点 ID,轮询不重复追加,重新生成不误用上次附图。
  • 旧请求不能覆盖新请求;画布保存落后于新任务时,根据任务时间和保存版本恢复最新结果。
  • 连线仅首次恢复时补齐,后续轮询不反复恢复用户已经删除的连线。
  • 执行进程心跳超过 120 秒未更新,任务标记待核实;不自动重新提交付费请求。若原执行稍后确实返回,仍允许保存真实结果。
  • 浏览器离开与服务端执行进程重启是不同情况:本轮解决前者的主要入口;进程中断后尚未实现供应商任务 ID 的自动续查。

验证记录

  1. 真实本地 PostgreSQL:scripts/qa/video-canvas-task-db.cjs 建立隔离测试库,加载实际任务表迁移和实际 store。10 次并发相同提交只创建 1 条记录;10 次并发领取仅 1 次成功;跨用户隔离、排队取消、执行中不可取消、串行队列、结果保存、结果隐藏、过期不重投、晚到结果保存全部通过。这是并发数据库调用测试,不是 10 个操作系统进程实测。
  2. 真实浏览器任务恢复:验收页使用实际 React Hook、实际任务 route/worker/store 与本地 PostgreSQL;鉴权使用固定测试用户,NextResponse/after 使用本地适配器,模型返回使用 12 秒测试桩。提交图片后立即刷新,最终出现 2 个结果且只 1 条任务;视频执行时关闭页面,再打开能恢复结果;后续分析排队任务成功取消;移除附图后刷新不复活。画布快照保存使用本地验收服务器,不是生产画布接口。
  3. 实际素材组件:100 项列表可定位选择最后一项,确认回传 测试素材 100;搜索同名只剩 1 项且保留选中状态;已有第 100 项再连续点选第 1–10 项,最终只选中 10 项,第 10 项(第 11 次选择)被正确拦截。验收期间先发现旧测试样式缓存,重新编译当前源码样式后验证通过。
  4. 自动化:最终 helpers/route 回归 437 项通过,无跳过,包含本次新增 13 项任务/批量参数测试和既有真实 FFmpeg 检查。不是 437 个生产端到端测试。
  5. 静态检查:TypeScript 无错误;git diff --check 通过。新增服务端模块与旧接口共享执行逻辑,图像计费仍走原有计费模块。

没有进行新的付费模型测试,没有重新宣称参考站像素级一致,没有覆盖操作系统休眠、真实断网、多标签冲突、生产 Next.js 进程重启或生产部署后的回归。原扫描中 79 项缺失/停用能力依然需要单独实现与验证,详见原验证矩阵。

复现

# FFmpeg / ffprobe 必须在 PATH 中,避免媒体测试跳过
pnpm exec playwright test --config=playwright.helpers.config.ts
pnpm exec tsc --noEmit --incremental false
# 隔离数据库测试依赖仅装入忽略的 .qa 目录,不改项目依赖
npm install --prefix .qa/video-task-db --no-save embedded-postgres
node scripts/qa/video-canvas-task-db.cjs

浏览器验收脚手架位于忽略目录 .qa/video-durable 和 .qa/video-repair;上述记录保留测试方法和模拟边界,不能代替后续部署验收。

后续修复:图片后期与脚本子任务(承接 0d17638a)

本轮把角度编辑(自定义参数及预设)、高清、扩图、抠图、宫格批量放大,以及脚本弹窗的资产生成、单镜/全部提示词合成接入已有持久队列。结果节点在提交时创建,完成后由任务查询更新;脚本任务另外按资产 ID、镜头 ID 回填对应字段。生成期间的修改或删除会保留,新结果继续留在独立节点,并显示冲突说明。脚本弹窗重新打开后显示服务器任务的处理中/失败状态。

高清接口的 AOS 分支可能先返回 HTTP 202 和 taskId。之前视频画布同步调用只寻找 original_url,导致将“已受理”误当失败。本轮先保存上游 taskId,再调用原有 GET 查询;查询中断或达到等待上限时标为“待核实”,保留上游标识,不重新 POST。当前仍不自动恢复服务端进程重启后的上游查询,需后续补全;浏览器刷新不影响在运行的服务端查询。

四个原 API 的执行实现抽取到 lib/canvas/operations/,原 URL 的入口继续通过 auth 验证身份;队列使用已校验的任务所有者调用共享执行函数。逐文件比较确认模型、存储、计费执行逻辑与抽取前保持一致。另修正上轮清理共享生图模块时遗漏的 getCanvasImageTaskForUser 导入,本轮完整类型检查通过。

本轮验证:

  • helpers/route 回归 447 项通过,无跳过,其中任务专项 23 项;新增后期参数校验、202 续查只提交一次、断网/502/等待上限待核实、角度响应、空结果拒绝、脚本稳定 ID 回填与修改冲突保护。
  • 真实隔离 PostgreSQL:原并发/权限/取消检查通过;新增上游任务标识写入、待核实时保留标识、不自动重投检查通过。
  • 本地浏览器:实际 Hook/API/worker/store + PostgreSQL;鉴权、模型和后期服务使用测试桩。高清提交后刷新恢复;脚本资产提交后刷新自动回填;提示词提交后刷新自动回填 imagePrompt/motionPrompt,原对白保留;生成中修改资产的冲突保护单独检查。画布保存仍使用本地验收接口,不是生产画布 API。
  • TypeScript 与 diff 空白检查通过;没有新增付费模型调用,没有部署 48 服务器。

仍需继续的项目:视频解析故事入口尚有同步请求,后台进程中断后的上游续查、多标签同时编辑、生产部署回归,以及原矩阵中的高级功能缺口。本轮不据此宣称 231 项全部完成。

后续修复:视频故事与上游任务续查(承接 86b66172)

本节更新前面仍标为未完成的“视频解析故事”和“AOS 高清已有任务编号续查”。这两项已完成分支修复与下述本地验证,其他范围不因此自动视为已修复。

视频解析故事

  • 工具栏“解析故事”在提交时创建故事节点,进入实际持久任务队列;刷新、重新打开画布后通过任务状态恢复结果。故事节点重新运行也走视频解析,修正了原先落入通用脚本生成分支的问题。
  • 解析失败或模型返回空镜头时显示错误并保留旧稿,新节点显示 0 镜。移除前后端自动填入的开场剧情、运镜、灯光、音乐等占位内容;缺失字段显示空值。
  • 前后端共用镜头规范化逻辑,保留时间 0,不再截断成最多 8 镜;目前上限 120 镜。双击提交由本地提交锁和服务端同节点任务去重保护。

高清续查

  • AOS 受理后先持久化 taskId、操作类型与源图,再查询结果。执行进程中断后,只恢复服务器已保存且与原请求匹配的高清编号;恢复分支只 GET 原任务,不重新 POST。
  • 下一次画布任务查询发现心跳过期后标记 interrupted,再按 30 秒起、最高 5 分钟的间隔接管续查;限任务创建后 24 小时、总领取次数少于 20 次。不依赖后台永久调度器,服务重启后需要画布查询触发恢复。
  • 增加领取次数校验:旧执行者的心跳、结果、检查点与失败不能覆盖已被新执行者接管的任务。恢复窗口内对同一节点重复点击运行会复用原任务。
  • AOS 明确负数失败状态立即终止查询,修正被吞掉后长期显示 processing 的问题;每次网络查询有超时,整个短轮询按实际经过时间计时。
  • 仍未给没有持久化上游编号的其他供应商任务添加自动续查;视频模型及 VIP98K 同步调用在进程中断后的恢复不能据此视为完成。没有任务编号的请求不会自动重投。

本轮验证

  • helpers/route 454 项通过,无跳过,其中任务专项 30 项;包含既有真实 FFmpeg 验证。新增检查编号匹配、恢复时限/间隔、GET-only 恢复、执行权失效、终态失败、AOS 短轮询上限、完整镜头及空结果拒绝。
  • 真实隔离 PostgreSQL:10 个并发调用争抢续查只有 1 个成功;旧领取次数的结果/错误/检查点不能覆盖新领取;重复提交恢复中的节点不会新增任务。
  • 独立进程中断与重启:实际 worker/store + PostgreSQL,供应商使用本地桩。首次进程在受理、保存编号并开始 GET 后强制退出,第二个独立进程从库恢复并完成。调用记录严格为 POST → GET → GET,上游编号一致。这不是生产 Next.js 部署重启测试。
  • 浏览器刷新:实际故事节点组件、Hook、route、worker、store + PostgreSQL;鉴权/供应商/Next after 使用本地适配。故事任务处理中刷新后恢复为 1 个真实桩镜头;另一个空镜头响应变为失败,刷新后仍显示 0 镜与明确错误。画布快照保存仍为本地验收接口。
  • TypeScript 无错误、diff 空白检查通过。没有新增付费模型调用,没有部署 48 服务器。

后续仍需完成:其他供应商执行中断恢复、多标签编辑冲突、生产部署回归,以及原矩阵列出的高级功能缺口。本次未声称参考站 231 项全部完成或像素级一致。

后续修复:五类视频续查、多页面保存与 3D 加载(承接 69dcf9b7)

本节更新前面仍列为待办的五类视频供应商续查、多页面冲突和部分导演台能力。以下均为分支修复与本地验收;没有部署 48 服务器,没有新增付费生成,也没有声称参考站 231 项全部完成。

视频提交与恢复

  • 阿里云、VIP98K external task、火山、AtlasCloud、Agnes 五类异步视频适配器接入同一任务生命周期。上游受理后先保存 taskId、原模型和服务商身份,再查询;恢复只 GET 原编号,不重复准备参考素材或 POST 生视频。
  • 恢复沿用既有 24 小时窗口、最多 20 次领取、30 秒至 5 分钟退避及执行权校验。由画布任务查询触发,不是脱离画布的永久后台调度器。
  • 模型或服务线路发生变化时停止自动查询并保留原编号。未取得编号的网络中断显示待核实,不自动重新提交;VIP98K/火山的持久任务路径禁用不确定 POST 的自动重试。明确的图片超限拒绝仍允许火山压缩后重试。
  • 明确失败/取消结束任务;AtlasCloud 的终态错误即使含有 network 字样也不会误当临时网络故障继续等待。没有上游编号的旧任务不能凭空恢复。
  • 去掉领取恢复任务时旧的 240 条扫描截断,按恢复窗口和领取次数筛选,避免陈旧记录挡住可恢复任务。

多页面保存与草稿

  • 遇到保存版本冲突,读取最新服务器内容,对基线、本页与服务器三个版本按节点/连线稳定 ID 和字段合并。不同位置的修改自动保留,同字段、删除与编辑、相互冲突的顺序修改必须显式选择。
  • 页面展示冲突位置,可选择冲突处保留本页或服务器版;无冲突的修改继续保留。支持下载当前 JSON 草稿,不再让用户只能刷新丢掉一版修改。
  • 浏览器 sessionStorage 按画布保存当前标签页的未保存草稿,隐藏、离开和定时保存前保留;重开当前标签页时与服务器版本合并。修正初始化时旧快照覆盖刚恢复草稿的问题。
  • 移除节点序列化时每次重造的 createdAt/updatedAt,避免产生虚假冲突;服务器版本时间至少递增 1 毫秒。
  • 远端连续保存导致超过 3 次自动合并重试时,暂停并保留草稿,用户仍可手动重试,不会进入永久阻塞。当前只在保存冲突时拉取其他页面版本,没有新增实时多人协同;sessionStorage 不是跨设备备份,存储满时仍需使用草稿下载。

3D 导演台逐项记录

原矩阵 ID 当前实现与修复 验收及剩余边界
08-01、08-15 GLB 30 秒超时、404/解析失败提示、空几何拒绝、重试加载;WebGL 上下文丢失后可重建场景;异常中止视频导出 实际浏览器:404→重试显示橙色方块;35 秒响应在 30 秒提示超时,晚到结果不冒充成功;空模型提示无有效几何;模拟 GPU 丢失→重试恢复原对象。未覆盖所有浏览器/显卡
08-10 八个人偶体型比例预设 实际浏览器选择幼童、重开保存;回归验证持久化。这是简化人偶比例,不等同参考站八种精细角色资产
08-14 复制对象与 3×3 群众阵列,限制总数 200 实际浏览器显示 9 个人偶;回归验证数量、间距、上限。未新增自定义行列阵列编辑器
08-17、08-18 上传 2:1 全景图、20 MiB 上限、20 条背景历史、默认背景、失败/20 秒超时提示及重试 实际 TextureLoader 浏览器渲染本地全景测试图、404 错误与切回默认背景;上传调用现有服务,未做生产对象存储上传验收
09-02、09-14 各机位保存独立相机轨迹,切换不串轨 浏览器:机位 1 两帧→新机位零帧→机位 1 恢复两帧;序列化回归通过。尚不是对象、相机、灯光同时运行的完整多轨系统
09-04、09-05 yaw/pitch 旋转、持续注视所选对象;预览、截图、真实录制和发送的运镜描述共用相机解析 浏览器移动对象后注视坐标跟随,手动旋转会退出跟随;方向/距离及解析一致性回归通过。未实现相机位置跟随对象平移或物体动画轨
09-13 编辑机位时自动记录当前时间关键帧 浏览器启用后旋转相机更新当前帧;预览播放不自动写帧
09-19 整条轨迹右移 1 米、轨迹与注视方向一起转 90° 浏览器检查变换后的首帧坐标;回归验证距离不变。不是自由变换轴或铅笔/钢笔路径编辑器
09-24 MP4 不支持时回退 WebM VP9/VP8/默认编码,文件名与内容类型一致 录制测试覆盖 MP4 与 WebM 回退、切后台/取消/渲染失败清理;本轮未新增真实生产视频上传

最终本地验证

  1. helpers/route 468 项通过,无跳过,包括真实 FFmpeg 检查。新增模型恢复、合并冲突、独立轨道/跟随/体型/轨迹等回归;不是 468 个生产端到端测试。
  2. scripts/qa/video-canvas-provider-recovery.cjs 调用实际模型选择与五类供应商适配器,使用合成目录、凭证及 fetch 响应。逐一验证受理后先存编号、查询中断、GET-only 续查、原服务商身份、明确终态失败只查一次、提交网络中断只 POST 一次。脚本禁止访问测试域名以外的网络,没有付费生成。
  3. scripts/qa/video-canvas-task-db.cjs 的真实隔离 PostgreSQL 检查通过,新增视频编号持久化、重复节点去重、10 个并发调用仅一个接管;保留原高清独立进程中断恢复测试。视频本轮没有另做生产进程重启测试。
  4. 两个真实浏览器标签页使用实际持久化 Hook 和冲突组件:不同节点修改自动合并,同节点冲突可选择且保留另一节点修改;恢复预置的 sessionStorage 草稿后可保存。画布 CAS 接口为本地验收服务器,没有写生产项目。
  5. 实际导演台组件的 WebGL、独立机位、跟随、自动帧、群众阵列、全景和加载异常验收见上表。浏览器脚手架位于忽略目录 .qa/video-concurrency。
  6. TypeScript 无错误,Git diff 空白检查通过。复现供应商检查:node scripts/qa/video-canvas-provider-recovery.cjs;其余测试命令同前文。

仍未完成的范围

原矩阵是历史扫描基线,本节是增量结果,不能据此将原 79 项缺失全部改为已完成。仍缺:TTS/音乐/音色接口,多画布/故事板/Agent 与跨项目资产,部分专用视频后期和智能剪辑,精细角色/手工关节、AI 识图重建、AI 全景、对象多轨、时间轴单位缩放、自由绘制轨迹,以及参考站逐状态像素对照与上线验收。现有服务尚无通用 TTS/音乐实现,不能用仅有入口或普通模型目录代替这些能力。未接通入口继续明确标示状态。