From 4074c137332631b6b9cd7f78b8072f7d92ac3920 Mon Sep 17 00:00:00 2001 From: seaislee1209 Date: Tue, 23 Jun 2026 16:57:37 +0800 Subject: [PATCH] =?UTF-8?q?fix(video):=20=E6=8F=90=E4=BA=A4=E6=8A=A5?= =?UTF-8?q?=E9=94=99=E6=8E=A5=E4=BD=8F=E8=BF=94=20JSON=20=E4=B8=8D?= =?UTF-8?q?=E5=86=8D=E7=99=BD=E5=B1=8F=20+=20=E5=88=86=E9=95=9C=E5=9B=BE?= =?UTF-8?q?=20processing=20=E4=B9=9F=E8=B5=B0=E7=B4=A0=E6=9D=90=E5=BA=93?= =?UTF-8?q?=20asset://?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - submit-video-segment 视图接住 submit_video_segment 的异常 → 返回干净 JSON(真实火山报错文案), 不再让它变成 500 整页 HTML 报错栈 → 前端把 101KB HTML 怼进 toast 撑爆白屏 - 前端 request():非 JSON 错误体只显示状态行,绝不把整页 HTML 塞进 toast(白屏兜底) - _seedance_ref_url:只要分镜图/人物已进素材库(有 remote_id)就走 asset://,不再卡 active —— 故事板 刚重生成时分镜图还是 processing,卡 active 会回落原始直链 → 火山以「疑似真人」拒。实测 processing 的素材 asset:// 照样可引用,根治「重生成故事板后重跑视频被人脸拒」 真机验证:场4 完整提交(人物/分镜图 asset:// + 场景/商品直链)ACCEPTED 出片;后端测试通过,tsc/build 过。 Co-Authored-By: Claude Opus 4.8 (1M context) --- core/backend/apps/ai/services.py | 10 ++++++---- core/backend/apps/projects/views.py | 7 ++++++- core/frontend/src/api.ts | 3 ++- 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/core/backend/apps/ai/services.py b/core/backend/apps/ai/services.py index 9c5eb84..a6fbeaf 100644 --- a/core/backend/apps/ai/services.py +++ b/core/backend/apps/ai/services.py @@ -1516,10 +1516,12 @@ def _asset_preview_url(asset) -> str: def _seedance_ref_url(raw_url: str, review_status: str = "", review_remote_id: str = "") -> str: - """Seedance 参考图 URL:已过审(active + 有素材库 ID)的写实人脸资产 → 用 asset:// 素材库引用, - 其余 → 原始直链。火山对写实人脸的原始直链会以 InputImageSensitiveContentDetected 直接 400 拒, - 必须改用同账号素材库引用才认。人物立绘 / 分镜图(含脸)走 asset://;场景 / 商品(无脸、未送审)保持直链。""" - if review_status == "active" and review_remote_id: + """Seedance 参考图 URL:只要资产已进素材库(有 remote_id)就用 asset:// 素材库引用 —— 火山认的是 + 「在不在素材库」,与审核态无关(实测 processing 也能引用);未进库才回落原始直链。 + 火山对写实人脸的原始直链会以 InputImageSensitiveContentDetected 直接拒,必须走同账号素材库引用。 + 人物立绘 / 分镜图(含脸)进库走 asset://;场景 / 商品(无脸、未送审)保持直链。 + 注意不能只放过 active:故事板刚重生成时分镜图还是 processing,卡 active 会回落直链 → 视频被火山拒。""" + if review_remote_id: return f"asset://{review_remote_id}" return raw_url diff --git a/core/backend/apps/projects/views.py b/core/backend/apps/projects/views.py index 1140e83..21ac532 100644 --- a/core/backend/apps/projects/views.py +++ b/core/backend/apps/projects/views.py @@ -655,7 +655,12 @@ class ProjectViewSet(TeamScopedViewSetMixin, ModelViewSet): require_worker() project = self.get_object() segment = VideoSegment.objects.get(project=project, id=request.data.get("video_segment_id")) - submit_video_segment(video_segment=segment, user=request.user, prompt=request.data.get("prompt", "")) + # 火山/中转报错(如人脸需走素材库的 InputImageSensitiveContentDetected)→ 返回真实报错的 JSON, + # 前端如实显示(段已被 submit_video_segment 标 FAILED + error_message);绝不让它变 500 HTML → 前端白屏。 + try: + submit_video_segment(video_segment=segment, user=request.user, prompt=request.data.get("prompt", "")) + except Exception as exc: # noqa: BLE001 + return Response({"detail": str(exc)}, status=status.HTTP_502_BAD_GATEWAY) # worker 在线由上面的闸保证;此处入队失败只剩极小窗口(刚提交完 broker 闪断), # 任务已在 ARK,前端轮询仍可兜底取回,故不让提交 500。 try: diff --git a/core/frontend/src/api.ts b/core/frontend/src/api.ts index 4705858..10b194c 100644 --- a/core/frontend/src/api.ts +++ b/core/frontend/src/api.ts @@ -111,7 +111,8 @@ async function request(path: string, options: RequestInit = {}): Promise { if (typeof first === "string") message = first; else if (Array.isArray(first) && typeof first[0] === "string") message = first[0]; } catch { - /* 非 JSON(如网关 HTML)保持原文 */ + // 非 JSON(如 DEBUG 的整页 HTML 报错栈):绝不把整页怼进 toast(会撑爆 / 白屏),只给状态行 + message = `服务器错误 ${response.status} ${response.statusText}`.trim(); } throw new ApiError(response.status, message); }