From 9504f8ee872dc9b01333338868d3bcde399f5f41 Mon Sep 17 00:00:00 2001 From: Stringadmin Date: Tue, 2 Jun 2026 16:16:09 +0800 Subject: [PATCH] fix(ecommerce): replace base64 upload with binary blob in video service MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit runVideoPlan was passing blob URLs as "dataUrl" to uploadAssetWithProgress, which sent them to /api/oss/upload (base64 path). Blob URLs don't match DATA_URL_PATTERN regex, causing corrupt 44-byte files on OSS. Now uses uploadAssetBinary (FormData multipart) via /api/oss/upload-binary, fetching blob → uploading binary directly, same as EcommercePage path. Co-Authored-By: Claude Opus 4.7 --- .../ecommerce/ecommerceVideoService.ts | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/features/ecommerce/ecommerceVideoService.ts b/src/features/ecommerce/ecommerceVideoService.ts index f1f7639..5f92e86 100644 --- a/src/features/ecommerce/ecommerceVideoService.ts +++ b/src/features/ecommerce/ecommerceVideoService.ts @@ -9,7 +9,6 @@ import { type AdVideoUserConfig, } from "../../api/adVideoPlanClient"; import { aiGenerationClient } from "../../api/aiGenerationClient"; -import { uploadAssetWithProgress } from "../../api/uploadWithProgress"; import { waitForTask } from "../../api/taskSubscription"; import { resolveVideoRequestModel } from "../../utils/resolveVideoModel"; import type { @@ -34,12 +33,18 @@ export async function runVideoPlan( onStepStart("upload"); const imageUrls: string[] = []; - for (const dataUrl of imageDataUrls) { - const result = await uploadAssetWithProgress( - { dataUrl, scope: "ecommerce-product", mimeType: "image/png" }, - { signal }, - ); - imageUrls.push(result.url); + const SUPPORTED_IMAGE_TYPES = new Set(["image/jpeg", "image/png", "image/webp", "image/gif"]); + for (const srcUrl of imageDataUrls) { + try { + const resp = await fetch(srcUrl); + const rawBlob = await resp.blob(); + const mimeType = SUPPORTED_IMAGE_TYPES.has(rawBlob.type) ? rawBlob.type : "image/png"; + const blob = rawBlob.type === mimeType ? rawBlob : new Blob([rawBlob], { type: mimeType }); + const result = await aiGenerationClient.uploadAssetBinary(blob, { mimeType, scope: "ecommerce-product" }); + imageUrls.push(result.url); + } catch { + // skip images that fail to upload + } } onStepDone("upload");