From 00abf9ae2ff453faac29c77ee9391696c7f0e5e6 Mon Sep 17 00:00:00 2001 From: zhishi <1951671751@qq.com> Date: Mon, 16 Mar 2026 22:53:11 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8E=BB=E9=99=A4=E4=B8=80=E4=BA=9B=E5=86=85?= =?UTF-8?q?=E5=AE=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/agents/storyboard/generateImageTool.ts | 21 +- src/agents/storyboard/index.ts | 8 +- src/lib/fixDB.ts | 163 ++++++-------- src/lib/initDB.ts | 234 ++++++++++----------- src/utils/ai/image/index.ts | 1 + src/utils/ai/image/owned/formal.ts | 2 +- src/utils/ai/image/owned/other.ts | 2 - src/utils/ai/video/owned/formal.ts | 2 +- src/utils/ai/video/owned/other2.ts | 162 -------------- src/utils/oss.ts | 3 - 10 files changed, 193 insertions(+), 405 deletions(-) delete mode 100644 src/utils/ai/video/owned/other2.ts diff --git a/src/agents/storyboard/generateImageTool.ts b/src/agents/storyboard/generateImageTool.ts index 8961b8a..6bffc70 100644 --- a/src/agents/storyboard/generateImageTool.ts +++ b/src/agents/storyboard/generateImageTool.ts @@ -175,25 +175,20 @@ async function processImages(images: ImageInfo[]): Promise { let processedBuffers: Buffer[]; if (images.length <= maxImages) { - console.log("%c Line:178 🥤 images", "background:#ffdd4d", images); - - console.log("%c Line:179 🍑", "background:#ed9ec7"); const buffers = await Promise.all(images.map((img) => u.oss.getFile(img.filePath))); - console.log("%c Line:179 🧀 buffers", "background:#ffdd4d", buffers); + processedBuffers = await Promise.all(buffers.map((buffer) => compressImage(buffer))); - console.log("%c Line:181 🍇 processedBuffers", "background:#e41a6a", processedBuffers); } else { const mergeStartIndex = maxImages - 1; - console.log("%c Line:183 🍖", "background:#6ec1c2"); const firstBuffers = await Promise.all(images.slice(0, mergeStartIndex).map((img) => u.oss.getFile(img.filePath))); - console.log("%c Line:183 🍉 firstBuffers", "background:#42b983", firstBuffers); + const compressedFirstImages = await Promise.all(firstBuffers.map((buffer) => compressImage(buffer))); - console.log("%c Line:185 🍺 compressedFirstImages", "background:#42b983", compressedFirstImages); + const imagesToMergeList = images.slice(mergeStartIndex).map((img) => img.filePath); - console.log("%c Line:187 🍿 imagesToMergeList", "background:#b03734", imagesToMergeList); + const mergedImage = await mergeImages(imagesToMergeList); - console.log("%c Line:189 🍉 mergedImage", "background:#ed9ec7", mergedImage); + processedBuffers = [...compressedFirstImages, mergedImage]; } @@ -299,10 +294,9 @@ export default async (cells: { prompt: string }[], scriptId: number, projectId: // 使用 AI 过滤相关资产 const filteredImages = await filterRelevantAssets(cellPrompts, resources, allImages); - console.log("%c Line:291 🍇 filteredImages", "background:#4fff4B", filteredImages); const resourcesMapPrompts = buildResourcesMapPrompts(filteredImages); - console.log("====润色前:", cellPrompts); + const promptsData = await generateImagePromptsTool({ prompts: cellPrompts, style: `类型:${projectInfo?.type!},风格:${projectInfo?.artStyle!}`, @@ -317,7 +311,6 @@ export default async (cells: { prompt: string }[], scriptId: number, projectId: // 注意:请严格按照提示词内容生成图片,确保人物样貌、艺术风格、色调光影一致。 // `; const prompts = promptsData.prompt; - console.log("====润色后:", prompts); const processedImages = await processImages(filteredImages); const apiConfig = await u.getPromptAi("storyboardImage"); @@ -336,8 +329,6 @@ export default async (cells: { prompt: string }[], scriptId: number, projectId: }, apiConfig, ); - console.log("%c Line:315 🍊 contentStr", "background:#ffdd4d", contentStr); - const match = contentStr.match(/base64,([A-Za-z0-9+/=]+)/); const base64Str = match?.[1] ?? contentStr; const buffer = Buffer.from(base64Str, "base64"); diff --git a/src/agents/storyboard/index.ts b/src/agents/storyboard/index.ts index b2f2c6b..ec112bb 100644 --- a/src/agents/storyboard/index.ts +++ b/src/agents/storyboard/index.ts @@ -104,7 +104,7 @@ export default class Storyboard { getScript = tool({ title: "getScript", - description: "获取剧本内容", + description: "用于获取剧本内容", inputSchema: z.object({}), execute: async () => { this.log("获取剧本", `scriptId: ${this.scriptId}`); @@ -662,7 +662,9 @@ ${task} inputSchema: z.object({ taskDescription: z.string().describe("具体的任务描述,包含章节范围、修改要求等详细信息"), }), - execute: async ({ taskDescription }) => this.invokeSubAgent(agentType, taskDescription), + execute: async ({ taskDescription }) => { + return this.invokeSubAgent(agentType, taskDescription); + }, }); } @@ -672,7 +674,7 @@ ${task} return { segmentAgent: this.createSubAgentTool( "segmentAgent", - "调用片段师。负责根据剧本生成片段,会自行调用 getScript 获取剧本内容,并调用 updateSegments 保存片段结果。", + "调用片段师。负责根据剧本生成片段,必须调用 getScript工具 获取剧本内容,并调用 updateSegments 保存片段结果。", ), shotAgent: this.createSubAgentTool( "shotAgent", diff --git a/src/lib/fixDB.ts b/src/lib/fixDB.ts index 7df507b..ebe9d38 100644 --- a/src/lib/fixDB.ts +++ b/src/lib/fixDB.ts @@ -104,110 +104,104 @@ export default async (knex: Knex): Promise => { if (needInsert.length) { await knex("t_aiModelMap").insert(needInsert); } - const checkVideoModel = await knex("t_videoModel").where("manufacturer", "formal").where("model", "Sora-2-I2V").first(); - if (!checkVideoModel) { - await knex("t_videoModel").where("manufacturer", "formal").delete(); + const viduVideototal = await knex("t_videoModel").where("manufacturer", "vidu").count({ count: "*" }); + console.log("%c Line:108 🍷 viduVideototal", "background:#fca650", viduVideototal); + const viduCount = Number(viduVideototal[0].count); + if (viduCount > 5) { + await knex("t_videoModel").where("manufacturer", "vidu").delete(); await knex("t_videoModel").insert([ { - manufacturer: "formal", - model: "Seedance-1.5-Pro-audio", - durationResolutionMap: JSON.stringify([{ duration: [4, 5, 6, 7, 8, 9, 10, 11, 12], resolution: ["480p", "720p", "1080p"] }]), - aspectRatio: JSON.stringify(["16:9", "9:16"]), - audio: 0, - type: JSON.stringify(["endFrameOptional"]), - }, - { - manufacturer: "formal", - model: "Seedance-1.5-Pro-NotAudio", - durationResolutionMap: JSON.stringify([{ duration: [4, 5, 6, 7, 8, 9, 10, 11, 12], resolution: ["480p", "720p", "1080p"] }]), - aspectRatio: JSON.stringify(["16:9", "9:16"]), - audio: 0, - type: JSON.stringify(["endFrameOptional"]), - }, - { - manufacturer: "formal", - model: "Seedance-1.0-Pro", - durationResolutionMap: JSON.stringify([{ duration: [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12], resolution: ["480p", "720p", "1080p"] }]), - aspectRatio: JSON.stringify(["16:9", "9:16"]), - audio: 0, - type: JSON.stringify(["endFrameOptional"]), - }, - { - manufacturer: "formal", - model: "ViduQ3-turbo", + manufacturer: "vidu", + model: "viduq3-pro", durationResolutionMap: JSON.stringify([ { duration: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], resolution: ["540p", "720p", "1080p"] }, ]), aspectRatio: JSON.stringify(["16:9", "9:16", "3:4", "4:3", "1:1"]), audio: 1, - type: JSON.stringify(["singleImage"]), + type: JSON.stringify(["text", "singleImage"]), }, { - manufacturer: "formal", - model: "ViduQ3-pro", - durationResolutionMap: JSON.stringify([ - { duration: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], resolution: ["540p", "720p", "1080p"] }, - ]), - aspectRatio: JSON.stringify(["16:9", "9:16", "3:4", "4:3", "1:1"]), - audio: 1, - type: JSON.stringify(["singleImage"]), - }, - { - manufacturer: "formal", - model: "ViduQ2-pro-fast", + manufacturer: "vidu", + model: "viduq2-pro-fast", durationResolutionMap: JSON.stringify([{ duration: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], resolution: ["720p", "1080p"] }]), aspectRatio: JSON.stringify([]), audio: 0, type: JSON.stringify(["singleImage", "startEndRequired"]), }, { - manufacturer: "formal", - model: "ViduQ2-pro", + manufacturer: "vidu", + model: "viduq2-pro", durationResolutionMap: JSON.stringify([{ duration: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], resolution: ["540p", "720p", "1080p"] }]), aspectRatio: JSON.stringify([]), audio: 0, + type: JSON.stringify(["singleImage", "reference", "startEndRequired", "text"]), + }, + { + manufacturer: "vidu", + model: "viduq2-turbo", + durationResolutionMap: JSON.stringify([{ duration: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], resolution: ["540p", "720p", "1080p"] }]), + aspectRatio: JSON.stringify([]), + audio: 0, + type: JSON.stringify(["singleImage", "reference", "startEndRequired", "text"]), + }, + { + manufacturer: "vidu", + model: "vidu2.0", + durationResolutionMap: JSON.stringify([ + { duration: [4], resolution: ["360p", "720p", "1080p"] }, + { duration: [8], resolution: ["720p"] }, + ]), + aspectRatio: JSON.stringify([]), + audio: 0, type: JSON.stringify(["singleImage", "reference", "startEndRequired"]), }, + ]); + } + const klingVideototal = await knex("t_videoModel").where("manufacturer", "kling").count({ count: "*" }); + console.log("%c Line:161 🍋 klingVideototal", "background:#93c0a4", klingVideototal); + const kelingcount = Number(klingVideototal[0].count); + if (kelingcount > 5) { + await knex("t_videoModel").where("manufacturer", "kling").delete(); + await knex("t_videoModel").insert([ { - manufacturer: "formal", - model: "ViduQ2-turbo", - durationResolutionMap: JSON.stringify([{ duration: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], resolution: ["540p", "720p", "1080p"] }]), - aspectRatio: JSON.stringify([]), + manufacturer: "kling", + model: "kling-v1(STD)", + durationResolutionMap: JSON.stringify([{ duration: [5, 10], resolution: ["720p"] }]), + aspectRatio: JSON.stringify(["16:9", "1:1", "9:16"]), audio: 0, - type: JSON.stringify(["singleImage", "reference", "startEndRequired"]), + type: JSON.stringify(["text", "startEndRequired"]), }, { - manufacturer: "formal", - model: "ViduQ2", - durationResolutionMap: JSON.stringify([{ duration: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], resolution: ["540p", "720p", "1080p"] }]), - aspectRatio: JSON.stringify([]), + manufacturer: "kling", + model: "kling-v1(PRO)", + durationResolutionMap: JSON.stringify([{ duration: [5, 10], resolution: ["1080p"] }]), + aspectRatio: JSON.stringify(["16:9", "1:1", "9:16"]), audio: 0, - type: JSON.stringify(["singleImage", "reference"]), + type: JSON.stringify(["text", "startEndRequired"]), }, - { - manufacturer: "formal", - model: "Sora-2-I2V", - durationResolutionMap: JSON.stringify([{ duration: [4, 8, 12], resolution: [] }]), - aspectRatio: JSON.stringify([]), + manufacturer: "kling", + model: "kling-v1-6(PRO)", + durationResolutionMap: JSON.stringify([{ duration: [5, 10], resolution: ["1080p"] }]), + aspectRatio: JSON.stringify(["16:9", "1:1", "9:16"]), audio: 0, - type: JSON.stringify(["singleImage", "reference"]), + type: JSON.stringify(["text", "startEndRequired"]), }, { - manufacturer: "formal", - model: "Wan2.6-I2V-720P", - durationResolutionMap: JSON.stringify([{ duration: [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15], resolution: ["720p"] }]), - aspectRatio: JSON.stringify([]), - audio: 1, - type: JSON.stringify(["singleImage"]), + manufacturer: "kling", + model: "kling-v2-5-turbo(PRO)", + durationResolutionMap: JSON.stringify([{ duration: [5, 10], resolution: ["1080p"] }]), + aspectRatio: JSON.stringify(["16:9", "1:1", "9:16"]), + audio: 0, + type: JSON.stringify(["text", "startEndRequired"]), }, { - manufacturer: "formal", - model: "Wan2.6-I2V-720P-1080P", - durationResolutionMap: JSON.stringify([{ duration: [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15], resolution: ["1080p"] }]), - aspectRatio: JSON.stringify([]), - audio: 1, - type: JSON.stringify(["singleImage"]), + manufacturer: "kling", + model: "kling-v2-6(PRO)", + durationResolutionMap: JSON.stringify([{ duration: [5, 10], resolution: ["1080p"] }]), + aspectRatio: JSON.stringify(["16:9", "1:1", "9:16"]), + audio: 0, + type: JSON.stringify(["text", "startEndRequired"]), }, ]); } @@ -224,29 +218,4 @@ export default async (knex: Knex): Promise => { }, ]); } - const checkImageModel = await knex("t_imageModel").where("manufacturer", "formal").where("model", "Doubao-Seedream-5.0-Lite").first(); - if (!checkImageModel) { - await knex("t_imageModel").where("manufacturer", "formal").delete(); - await knex("t_imageModel").insert([ - { manufacturer: "formal", model: "Doubao-Seedream-5.0-Lite", grid: 1, type: "ti2i" }, - { manufacturer: "formal", model: "doubao-seedream-4-5-251128", grid: 1, type: "ti2i" }, - { manufacturer: "formal", model: "doubao-seedream-4-0-250828", grid: 1, type: "ti2i" }, - ]); - } - const checkTextModel = await knex("t_imageModel").where("manufacturer", "formal").where("model", "claude-sonnet-4-6").first(); - if (!checkTextModel) { - await knex("t_textModel").where("manufacturer", "formal").delete(); - await knex("t_textModel").insert([ - { manufacturer: "formal", model: "gpt-4.1", responseFormat: "schema", image: 1, think: 0, tool: 1 }, - { manufacturer: "formal", model: "doubao-seed-2-0-pro-260215", responseFormat: "object", image: 0, think: 0, tool: 1 }, - { manufacturer: "formal", model: "doubao-seed-1-8-251215", responseFormat: "schema", image: 0, think: 0, tool: 1 }, - { manufacturer: "formal", model: "gpt-5.2", responseFormat: "schema", image: 1, think: 0, tool: 1 }, - { manufacturer: "formal", model: "gpt-5.1", responseFormat: "schema", image: 1, think: 0, tool: 1 }, - { manufacturer: "formal", model: "claude-sonnet-4-6", responseFormat: "schema", image: 0, think: 0, tool: 1 }, - { manufacturer: "formal", model: "claude-sonnet-4-5-20250929", responseFormat: "schema", image: 0, think: 0, tool: 1 }, - { manufacturer: "formal", model: "claude-opus-4-5-20251101", responseFormat: "schema", image: 0, think: 0, tool: 1 }, - { manufacturer: "formal", model: "qwen3.5-plus", responseFormat: "schema", image: 1, think: 0, tool: 1 }, - { manufacturer: "formal", model: "qwen3-max-2026-01-23", responseFormat: "schema", image: 1, think: 0, tool: 1 }, - ]); - } }; diff --git a/src/lib/initDB.ts b/src/lib/initDB.ts index d69d0cb..57f2a0c 100644 --- a/src/lib/initDB.ts +++ b/src/lib/initDB.ts @@ -613,16 +613,16 @@ export default async (knex: Knex, forceInit: boolean = false): Promise => { manufacturer: "other", model: "", responseFormat: "object", image: 1, think: 0, tool: 1 }, { manufacturer: "modelScope", model: "deepseek-ai/DeepSeek-V3.2", responseFormat: "object", image: 0, think: 0, tool: 1 }, - { manufacturer: "formal", model: "gpt-4.1", responseFormat: "schema", image: 1, think: 0, tool: 1 }, - { manufacturer: "formal", model: "doubao-seed-2-0-pro-260215", responseFormat: "object", image: 0, think: 0, tool: 1 }, - { manufacturer: "formal", model: "doubao-seed-1-8-251215", responseFormat: "schema", image: 0, think: 0, tool: 1 }, - { manufacturer: "formal", model: "gpt-5.2", responseFormat: "schema", image: 1, think: 0, tool: 1 }, - { manufacturer: "formal", model: "gpt-5.1", responseFormat: "schema", image: 1, think: 0, tool: 1 }, - { manufacturer: "formal", model: "claude-sonnet-4-6", responseFormat: "schema", image: 0, think: 0, tool: 1 }, - { manufacturer: "formal", model: "claude-sonnet-4-5-20250929", responseFormat: "schema", image: 0, think: 0, tool: 1 }, - { manufacturer: "formal", model: "claude-opus-4-5-20251101", responseFormat: "schema", image: 0, think: 0, tool: 1 }, - { manufacturer: "formal", model: "qwen3.5-plus", responseFormat: "schema", image: 1, think: 0, tool: 1 }, - { manufacturer: "formal", model: "qwen3-max-2026-01-23", responseFormat: "schema", image: 1, think: 0, tool: 1 }, + // { manufacturer: "formal", model: "gpt-4.1", responseFormat: "schema", image: 1, think: 0, tool: 1 }, + // { manufacturer: "formal", model: "doubao-seed-2-0-pro-260215", responseFormat: "object", image: 0, think: 0, tool: 1 }, + // { manufacturer: "formal", model: "doubao-seed-1-8-251215", responseFormat: "schema", image: 0, think: 0, tool: 1 }, + // { manufacturer: "formal", model: "gpt-5.2", responseFormat: "schema", image: 1, think: 0, tool: 1 }, + // { manufacturer: "formal", model: "gpt-5.1", responseFormat: "schema", image: 1, think: 0, tool: 1 }, + // { manufacturer: "formal", model: "claude-sonnet-4-6", responseFormat: "schema", image: 0, think: 0, tool: 1 }, + // { manufacturer: "formal", model: "claude-sonnet-4-5-20250929", responseFormat: "schema", image: 0, think: 0, tool: 1 }, + // { manufacturer: "formal", model: "claude-opus-4-5-20251101", responseFormat: "schema", image: 0, think: 0, tool: 1 }, + // { manufacturer: "formal", model: "qwen3.5-plus", responseFormat: "schema", image: 1, think: 0, tool: 1 }, + // { manufacturer: "formal", model: "qwen3-max-2026-01-23", responseFormat: "schema", image: 1, think: 0, tool: 1 }, ]); }, }, @@ -652,9 +652,9 @@ export default async (knex: Knex, forceInit: boolean = false): Promise => { manufacturer: "grsai", model: "nano-banana", grid: 1, type: "ti2i" }, { manufacturer: "grsai", model: "nano-banana-2", grid: 1, type: "ti2i" }, - { manufacturer: "formal", model: "Doubao-Seedream-5.0-Lite", grid: 1, type: "ti2i" }, - { manufacturer: "formal", model: "doubao-seedream-4-5-251128", grid: 1, type: "ti2i" }, - { manufacturer: "formal", model: "doubao-seedream-4-0-250828", grid: 1, type: "ti2i" }, + // { manufacturer: "formal", model: "Doubao-Seedream-5.0-Lite", grid: 1, type: "ti2i" }, + // { manufacturer: "formal", model: "doubao-seedream-4-5-251128", grid: 1, type: "ti2i" }, + // { manufacturer: "formal", model: "doubao-seedream-4-0-250828", grid: 1, type: "ti2i" }, ]); }, }, @@ -712,14 +712,6 @@ export default async (knex: Knex, forceInit: boolean = false): Promise => audio: 1, type: JSON.stringify(["endFrameOptional", "multiImage"]), }, - { - manufacturer: "volcengine", - model: "doubao-seedance-1-0-lite-t2v-250428", - durationResolutionMap: JSON.stringify([{ duration: [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12], resolution: ["480p", "720p", "1080p"] }]), - aspectRatio: JSON.stringify(["16:9", "4:3", "1:1", "3:4", "9:16", "21:9"]), - audio: 0, - type: JSON.stringify(["text"]), - }, { manufacturer: "kling", model: "kling-v1(STD)", @@ -1019,107 +1011,107 @@ export default async (knex: Knex, forceInit: boolean = false): Promise => type: JSON.stringify(["startEndRequired", "text"]), }, - { - manufacturer: "formal", - model: "Seedance-1.5-Pro-audio", - durationResolutionMap: JSON.stringify([{ duration: [4, 5, 6, 7, 8, 9, 10, 11, 12], resolution: ["480p", "720p", "1080p"] }]), - aspectRatio: JSON.stringify(["16:9", "9:16"]), - audio: 0, - type: JSON.stringify(["endFrameOptional"]), - }, - { - manufacturer: "formal", - model: "Seedance-1.5-Pro-NotAudio", - durationResolutionMap: JSON.stringify([{ duration: [4, 5, 6, 7, 8, 9, 10, 11, 12], resolution: ["480p", "720p", "1080p"] }]), - aspectRatio: JSON.stringify(["16:9", "9:16"]), - audio: 0, - type: JSON.stringify(["endFrameOptional"]), - }, - { - manufacturer: "formal", - model: "Seedance-1.0-Pro", - durationResolutionMap: JSON.stringify([{ duration: [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12], resolution: ["480p", "720p", "1080p"] }]), - aspectRatio: JSON.stringify(["16:9", "9:16"]), - audio: 0, - type: JSON.stringify(["endFrameOptional"]), - }, - { - manufacturer: "formal", - model: "ViduQ3-turbo", - durationResolutionMap: JSON.stringify([ - { duration: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], resolution: ["540p", "720p", "1080p"] }, - ]), - aspectRatio: JSON.stringify(["16:9", "9:16", "3:4", "4:3", "1:1"]), - audio: 1, - type: JSON.stringify(["singleImage"]), - }, - { - manufacturer: "formal", - model: "ViduQ3-pro", - durationResolutionMap: JSON.stringify([ - { duration: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], resolution: ["540p", "720p", "1080p"] }, - ]), - aspectRatio: JSON.stringify(["16:9", "9:16", "3:4", "4:3", "1:1"]), - audio: 1, - type: JSON.stringify(["singleImage"]), - }, - { - manufacturer: "formal", - model: "ViduQ2-pro-fast", - durationResolutionMap: JSON.stringify([{ duration: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], resolution: ["720p", "1080p"] }]), - aspectRatio: JSON.stringify([]), - audio: 0, - type: JSON.stringify(["singleImage", "startEndRequired"]), - }, - { - manufacturer: "formal", - model: "ViduQ2-pro", - durationResolutionMap: JSON.stringify([{ duration: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], resolution: ["540p", "720p", "1080p"] }]), - aspectRatio: JSON.stringify([]), - audio: 0, - type: JSON.stringify(["singleImage", "reference", "startEndRequired"]), - }, - { - manufacturer: "formal", - model: "ViduQ2-turbo", - durationResolutionMap: JSON.stringify([{ duration: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], resolution: ["540p", "720p", "1080p"] }]), - aspectRatio: JSON.stringify([]), - audio: 0, - type: JSON.stringify(["singleImage", "reference", "startEndRequired"]), - }, - { - manufacturer: "formal", - model: "ViduQ2", - durationResolutionMap: JSON.stringify([{ duration: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], resolution: ["540p", "720p", "1080p"] }]), - aspectRatio: JSON.stringify([]), - audio: 0, - type: JSON.stringify(["singleImage", "reference"]), - }, + // { + // manufacturer: "formal", + // model: "Seedance-1.5-Pro-audio", + // durationResolutionMap: JSON.stringify([{ duration: [4, 5, 6, 7, 8, 9, 10, 11, 12], resolution: ["480p", "720p", "1080p"] }]), + // aspectRatio: JSON.stringify(["16:9", "9:16"]), + // audio: 0, + // type: JSON.stringify(["endFrameOptional"]), + // }, + // { + // manufacturer: "formal", + // model: "Seedance-1.5-Pro-NotAudio", + // durationResolutionMap: JSON.stringify([{ duration: [4, 5, 6, 7, 8, 9, 10, 11, 12], resolution: ["480p", "720p", "1080p"] }]), + // aspectRatio: JSON.stringify(["16:9", "9:16"]), + // audio: 0, + // type: JSON.stringify(["endFrameOptional"]), + // }, + // { + // manufacturer: "formal", + // model: "Seedance-1.0-Pro", + // durationResolutionMap: JSON.stringify([{ duration: [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12], resolution: ["480p", "720p", "1080p"] }]), + // aspectRatio: JSON.stringify(["16:9", "9:16"]), + // audio: 0, + // type: JSON.stringify(["endFrameOptional"]), + // }, + // { + // manufacturer: "formal", + // model: "ViduQ3-turbo", + // durationResolutionMap: JSON.stringify([ + // { duration: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], resolution: ["540p", "720p", "1080p"] }, + // ]), + // aspectRatio: JSON.stringify(["16:9", "9:16", "3:4", "4:3", "1:1"]), + // audio: 1, + // type: JSON.stringify(["singleImage"]), + // }, + // { + // manufacturer: "formal", + // model: "ViduQ3-pro", + // durationResolutionMap: JSON.stringify([ + // { duration: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], resolution: ["540p", "720p", "1080p"] }, + // ]), + // aspectRatio: JSON.stringify(["16:9", "9:16", "3:4", "4:3", "1:1"]), + // audio: 1, + // type: JSON.stringify(["singleImage"]), + // }, + // { + // manufacturer: "formal", + // model: "ViduQ2-pro-fast", + // durationResolutionMap: JSON.stringify([{ duration: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], resolution: ["720p", "1080p"] }]), + // aspectRatio: JSON.stringify([]), + // audio: 0, + // type: JSON.stringify(["singleImage", "startEndRequired"]), + // }, + // { + // manufacturer: "formal", + // model: "ViduQ2-pro", + // durationResolutionMap: JSON.stringify([{ duration: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], resolution: ["540p", "720p", "1080p"] }]), + // aspectRatio: JSON.stringify([]), + // audio: 0, + // type: JSON.stringify(["singleImage", "reference", "startEndRequired"]), + // }, + // { + // manufacturer: "formal", + // model: "ViduQ2-turbo", + // durationResolutionMap: JSON.stringify([{ duration: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], resolution: ["540p", "720p", "1080p"] }]), + // aspectRatio: JSON.stringify([]), + // audio: 0, + // type: JSON.stringify(["singleImage", "reference", "startEndRequired"]), + // }, + // { + // manufacturer: "formal", + // model: "ViduQ2", + // durationResolutionMap: JSON.stringify([{ duration: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], resolution: ["540p", "720p", "1080p"] }]), + // aspectRatio: JSON.stringify([]), + // audio: 0, + // type: JSON.stringify(["singleImage", "reference"]), + // }, - { - manufacturer: "formal", - model: "Sora-2-I2V", - durationResolutionMap: JSON.stringify([{ duration: [4, 8, 12], resolution: [] }]), - aspectRatio: JSON.stringify([]), - audio: 0, - type: JSON.stringify(["singleImage", "reference"]), - }, - { - manufacturer: "formal", - model: "Wan2.6-I2V-720P", - durationResolutionMap: JSON.stringify([{ duration: [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15], resolution: ["720p"] }]), - aspectRatio: JSON.stringify([]), - audio: 1, - type: JSON.stringify(["singleImage"]), - }, - { - manufacturer: "formal", - model: "Wan2.6-I2V-720P-1080P", - durationResolutionMap: JSON.stringify([{ duration: [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15], resolution: ["1080p"] }]), - aspectRatio: JSON.stringify([]), - audio: 1, - type: JSON.stringify(["singleImage"]), - }, + // { + // manufacturer: "formal", + // model: "Sora-2-I2V", + // durationResolutionMap: JSON.stringify([{ duration: [4, 8, 12], resolution: [] }]), + // aspectRatio: JSON.stringify([]), + // audio: 0, + // type: JSON.stringify(["singleImage", "reference"]), + // }, + // { + // manufacturer: "formal", + // model: "Wan2.6-I2V-720P", + // durationResolutionMap: JSON.stringify([{ duration: [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15], resolution: ["720p"] }]), + // aspectRatio: JSON.stringify([]), + // audio: 1, + // type: JSON.stringify(["singleImage"]), + // }, + // { + // manufacturer: "formal", + // model: "Wan2.6-I2V-720P-1080P", + // durationResolutionMap: JSON.stringify([{ duration: [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15], resolution: ["1080p"] }]), + // aspectRatio: JSON.stringify([]), + // audio: 1, + // type: JSON.stringify(["singleImage"]), + // }, ]); }, }, diff --git a/src/utils/ai/image/index.ts b/src/utils/ai/image/index.ts index 3c3c6e7..b10600a 100644 --- a/src/utils/ai/image/index.ts +++ b/src/utils/ai/image/index.ts @@ -81,6 +81,7 @@ export default async (input: ImageConfig, config: AIConfig) => { } try { let imageUrl = await manufacturerFn(input, { model, apiKey, baseURL }); + if (!input.resType) input.resType = "b64"; if (input.resType === "b64" && imageUrl.startsWith("http")) imageUrl = await urlToBase64(imageUrl); // await u.db("t_myTasks").where("id", taskId).update({ diff --git a/src/utils/ai/image/owned/formal.ts b/src/utils/ai/image/owned/formal.ts index b7bba7a..003d051 100644 --- a/src/utils/ai/image/owned/formal.ts +++ b/src/utils/ai/image/owned/formal.ts @@ -17,7 +17,7 @@ export default async (input: ImageConfig, config: AIConfig): Promise => if (!config.model) throw new Error("缺少Model名称"); if (!config.apiKey) throw new Error("缺少API Key"); - const { requestUrl, queryUrl = null } = modelFn["volcengine"].buildReqUrl(config.baseURL || "https://api.toonflow.net"); + const { requestUrl, queryUrl = null } = modelFn["volcengine"].buildReqUrl(config?.baseURL); const taskBody = modelFn["volcengine"].buildReqBody(input, config); const apiKey = config.apiKey.replace("Bearer ", ""); diff --git a/src/utils/ai/image/owned/other.ts b/src/utils/ai/image/owned/other.ts index 13d4b05..c905bdb 100644 --- a/src/utils/ai/image/owned/other.ts +++ b/src/utils/ai/image/owned/other.ts @@ -111,8 +111,6 @@ export default async (input: ImageConfig, config: AIConfig): Promise => aspectRatio: input.aspectRatio as "1:1" | "3:4" | "4:3" | "9:16" | "16:9", size: sizeMap[input.size] ?? "1024x1024", }); - console.log("%c Line:106 🥚 image", "background:#e41a6a", image); - if (image.base64.startsWith("data:image/")) { return image.base64; diff --git a/src/utils/ai/video/owned/formal.ts b/src/utils/ai/video/owned/formal.ts index 12e3b21..724487f 100644 --- a/src/utils/ai/video/owned/formal.ts +++ b/src/utils/ai/video/owned/formal.ts @@ -82,7 +82,7 @@ export default async (input: VideoConfig, config: AIConfig): Promise => // 根据模型名称获取对应的适配器 const modelAdapter = getModelAdapter(config.model); - const { requestUrl, queryUrl, downLoadUrl = null } = modelAdapter.buildReqUrl(config.baseURL || "https://api.toonflow.net"); + const { requestUrl, queryUrl, downLoadUrl = null } = modelAdapter.buildReqUrl(config.baseURL); const taskBody = await modelAdapter.buildReqBody(input, config); const apiKey = config.apiKey.replace("Bearer ", ""); diff --git a/src/utils/ai/video/owned/other2.ts b/src/utils/ai/video/owned/other2.ts deleted file mode 100644 index 8814106..0000000 --- a/src/utils/ai/video/owned/other2.ts +++ /dev/null @@ -1,162 +0,0 @@ -import "../type"; -import axios from "axios"; -import sharp from "sharp"; -import FormData from "form-data"; -import fs from "fs"; -import path from "path"; -import u from "@/utils"; - -import { pollTask, validateVideoConfig } from "@/utils/ai/utils"; -function template(replaceObj: Record, url: string) { - return url.replace(/\{(\w+)\}/g, (match, varName) => { - return replaceObj.hasOwnProperty(varName) ? replaceObj[varName] : match; - }); -} -export default async (input: VideoConfig, config: AIConfig) => { - if (!config.apiKey) throw new Error("缺少API Key"); - if (!config.baseURL) throw new Error("缺少baseURL"); - // const { owned, images, hasTextType } = validateVideoConfig(input, config); - - const authorization = `Bearer ${config.apiKey}`; - const urls = config.baseURL.split("|"); - const isThreeUrlMode = urls.length === 3; - console.log("%c Line:24 🌭 isThreeUrlMode", "background:#ed9ec7", isThreeUrlMode); - - let requestUrl: string, queryUrl: string, downLoadUrl: string | undefined; - - if (isThreeUrlMode) { - [requestUrl, queryUrl, downLoadUrl] = urls; - } else { - [requestUrl, queryUrl] = urls; - } - - // 根据 aspectRatio 设置 size - const sizeMap: Record = { - "16:9": "1280x720", - "9:16": "720x1280", - }; - let resData; - let taskId = ""; - if (isThreeUrlMode) { - // 三个地址:使用 FormData 方式 - const formData = new FormData(); - formData.append("model", config.model); - formData.append("prompt", input.prompt); - formData.append("seconds", String(input.duration)); - - const size = sizeMap[input.aspectRatio] || "1280x720"; - formData.append("size", size); - - if (input.imageBase64 && input.imageBase64.length) { - const base64Data = input.imageBase64[0]!.replace(/^data:image\/\w+;base64,/, ""); - const buffer = Buffer.from(base64Data, "base64"); - - // 解析尺寸 - const [width, height] = size.split("x").map(Number); - - // 使用 sharp 调整图片尺寸 - const resizedBuffer = await sharp(buffer).resize(width, height, { fit: "cover" }).jpeg({ quality: 90 }).toBuffer(); - - formData.append("input_reference", resizedBuffer, { filename: "image.jpg", contentType: "image/jpeg" }); - } - - const response = await axios.post(requestUrl, formData, { - headers: { Authorization: authorization, ...formData.getHeaders() }, - }); - - taskId = response.data?.task_id || response.data?.id; - resData = response.data; - } else { - // 两个地址:使用 JSON 方式 - - const requestBody: any = { - model: config.model, - images: [ - "https://prod-ss-images.s3.cn-northwest-1.amazonaws.com.cn/vidu-maas/template/startend2video-1.jpeg", - "https://prod-ss-images.s3.cn-northwest-1.amazonaws.com.cn/vidu-maas/template/startend2video-2.jpeg", - ], - prompt: - "The camera zooms in on the bird, which then flies to the right. With its flight being smooth and natural, the bird soars in the sky. with a red light effect following and surrounding it from behind.", - duration: 5, - seed: 0, - resolution: "1080p", - audio: true, - off_peak: false, - }; - - if (input.imageBase64 && input.imageBase64.length) { - requestBody.images = [ - "https://prod-ss-images.s3.cn-northwest-1.amazonaws.com.cn/vidu-maas/template/startend2video-1.jpeg", - "https://prod-ss-images.s3.cn-northwest-1.amazonaws.com.cn/vidu-maas/template/startend2video-2.jpeg", - ]; - } - - console.log("%c Line:86 🍷 requestUrl", "background:#4fff4B", requestUrl); - console.log("%c Line:89 🥪 authorization", "background:#3f7cff", authorization); - - const response = await axios.post(requestUrl, JSON.stringify(requestBody), { - headers: { - Authorization: authorization, - "Content-Type": "application/json", - }, - }); - taskId = response.data.id; - resData = response.data; - console.log("%c Line:91 🍎 resData", "background:#ed9ec7", resData); - } - console.log("%c Line:87 🥒 taskId", "background:#f5ce50", taskId); - - if (!taskId) throw new Error(`任务提交失败: ${resData ? JSON.stringify(resData) : "未知错误"}`); - - return await pollTask(async () => { - // 构建查询URL,两个地址模式时使用URL参数 - const finalQueryUrl = isThreeUrlMode ? template({ id: taskId }, queryUrl) : template({ id: taskId }, queryUrl); - - const { data: queryData } = await axios.get(finalQueryUrl, { - headers: { Authorization: authorization }, - }); - console.log("%c Line:100 🥑 queryData", "background:#42b983", queryData); - - if (queryData.status === "completed") { - // 下载视频,带重试机制 - let videoRes; - let retries = 3; - let lastError; - - for (let i = 0; i < retries; i++) { - try { - // 构建下载URL - const finalDownloadUrl = - isThreeUrlMode && downLoadUrl ? template({ id: taskId }, downLoadUrl) : queryData.video_url || queryData.url || queryData.metadata.url; // 从响应中获取视频URL - - videoRes = await axios.get(finalDownloadUrl, { - headers: isThreeUrlMode ? { Authorization: authorization } : {}, - responseType: "arraybuffer", - timeout: 60 * 1000 * 10, // 60秒超时 - }); - break; // 成功则跳出循环 - } catch (error) { - lastError = error; - console.error(`视频下载失败,第 ${i + 1}/${retries} 次尝试:`, error); - if (i < retries - 1) { - // 等待后重试,使用指数退避 - await new Promise((resolve) => setTimeout(resolve, Math.pow(2, i) * 1000)); - } - } - } - - if (!videoRes) { - throw new Error(`视频下载失败,已重试 ${retries} 次: ${lastError}`); - } - - // 将视频buffer转换为base64或直接返回buffer - const savePath = input.savePath.endsWith(".mp4") ? input.savePath : path.join(input.savePath, `other_${Date.now()}.mp4`); - await u.oss.writeFile(input.savePath, videoRes.data); - - return { completed: true, url: savePath }; - } - if (queryData.status === "failed") return { completed: false, error: `任务失败: ${queryData.error || "未知错误"}` }; - // if (queryData.status === "QUEUED" || queryData.status === "RUNNING") return { completed: false }; - return { completed: false }; - }); -}; diff --git a/src/utils/oss.ts b/src/utils/oss.ts index af50603..6dad33e 100644 --- a/src/utils/oss.ts +++ b/src/utils/oss.ts @@ -66,9 +66,6 @@ class OSS { * @throws 路径不在 OSS 根目录内、文件不存在等错误 */ async getFile(userRelPath: string): Promise { - console.log("%c Line:69 🥔 userRelPath", "background:#ffdd4d", userRelPath); - console.log("%c Line:72 🥥 this.rootDir", "background:#ea7e5c", this.rootDir); - await this.ensureInit(); return fs.readFile(resolveSafeLocalPath(userRelPath, this.rootDir)); }