增加视频提示词生成

This commit is contained in:
zhishi 2026-04-01 02:21:29 +08:00
parent 24c0f3ea4e
commit f7830d862c
4 changed files with 79 additions and 21 deletions

View File

@ -536,6 +536,9 @@ description: 专注于从剧本内容中提取所使用的资产(角色、场
table.integer("videoId");
table.integer("projectId");
table.integer("scriptId");
table.text("state");
table.text("reason");
table.text("prompt");
table.primary(["id"]);
table.unique(["id"]);
},

View File

@ -72,7 +72,11 @@ export default router.post(
.db("o_storyboard")
.where("scriptId", scriptId)
.select("id", "trackId", "prompt", "duration", "state", "scriptId", "reason", "filePath");
if (!lastStoryboard || !lastStoryboard.length) return res.status(400).send(error("为查到分镜数据"));
if (!lastStoryboard || !lastStoryboard.length) return res.status(400).send(error("未查到分镜数据"));
batchGenerateVideoPrompts(
data.map((i: any) => i.id),
projectId,
);
const storyboardData = await Promise.all(
lastStoryboard.map(async (i) => {
return {
@ -91,3 +95,58 @@ export default router.post(
return res.status(200).send(success(storyboardData));
},
);
async function batchGenerateVideoPrompts(storyboardIds: number[], projectId: number) {
const lastStoryboard = await u.db("o_storyboard").whereIn("id", storyboardIds).select("id", "trackId", "prompt");
const allTrackIds = lastStoryboard.map((i) => i.trackId);
const storyboardPromptRecord: Record<number, string[]> = {};
lastStoryboard.forEach((i) => {
if (i.trackId) {
if (!storyboardPromptRecord[i.trackId]) {
storyboardPromptRecord[i.trackId] = [];
}
storyboardPromptRecord[i.trackId].push(i.prompt!);
}
});
const projectSetting = await u.db("o_project").where("id", projectId).select("artStyle").first();
const systemPrompt = u.getArtPrompt(projectSetting?.artStyle!, "art_storyboard_video");
await u
.db("o_videoTrack")
.whereIn("id", allTrackIds as number[])
.update({
state: "生成中",
});
for (const trackId in storyboardPromptRecord) {
const storboardPrompts = storyboardPromptRecord[trackId];
try {
const { text } = await u.Ai.Text("universalAi").invoke({
messages: [
{
role: "system",
content: systemPrompt,
},
{
role: "user",
content: `请根据我所提供的 ${storboardPrompts.length} 条分镜内容,为我生成一条视频提示词,请直接输出提示词内容,不做任何解释说明。
:
${storboardPrompts.map((i, index) => `${index + 1}.${i}`).join("\n")}`,
},
],
});
await u.db("o_videoTrack").where("id", trackId).update({
state: "已完成",
prompt: text,
});
console.log("%c Line:116 🍎 text", "background:#42b983", text);
} catch (e) {
console.error("生成视频提示词失败", e);
await u
.db("o_videoTrack")
.where("id", trackId)
.update({
state: "生成失败",
reason: u.error(e).message,
});
}
}
}

View File

@ -58,37 +58,23 @@ export default router.post(
}),
async (req, res) => {
const { scriptIds, projectId, groupSize = 5 } = req.body;
if (!scriptIds.length) return res.status(400).send(error("请先选择剧本"));
const scripts = await u.db("o_script").whereIn("id", scriptIds);
const intansce = u.Ai.Text("universalAi");
// 查询已有的剧本-资产关联,找出已经提取过资产的剧本
const existingScriptAssets = await u.db("o_scriptAssets").whereIn("scriptId", scriptIds).select("scriptId");
const scriptIdsWithAssets = new Set(existingScriptAssets.map((sa: any) => sa.scriptId));
// 构建 scriptId -> script 内容的映射
const scriptMap = new Map(scripts.map((s: o_script) => [s.id, s]));
// 过滤掉已成功提取过资产的剧本extractState === 1 且有关联资产)
const filteredScriptIds = scriptIds.filter((id: number) => {
const script = scriptMap.get(id);
return !(script?.extractState === 1 && scriptIdsWithAssets.has(id));
});
const skippedCount = scriptIds.length - filteredScriptIds.length;
if (!filteredScriptIds.length) {
return res.send(success("所有剧本已提取过资产,无需重复提取"));
}
await u.db("o_script").whereIn("id", filteredScriptIds).update({
await u.db("o_script").whereIn("id", scriptIds).update({
extractState: 0,
});
const errors: { scriptId: number; error: string }[] = [];
let successCount = 0;
// 将过滤后的 scriptIds 按 groupSize默认5分组每组一起发给 AI
const scriptGroups = chunkArray(filteredScriptIds, groupSize);
// 将 scriptIds 按 groupSize默认5分组每组一起发给 AI
const scriptGroups = chunkArray(scriptIds, groupSize);
/** 一组剧本提取完成后统一入库并建立关联 */
async function persistGroupResult(result: GroupResult) {
@ -257,6 +243,6 @@ export default router.post(
});
}
return res.send(success(skippedCount > 0 ? `开始提取资产,跳过 ${skippedCount} 个已提取的剧本` : "开始提取资产"));
return res.send(success("开始提取资产"));
},
);

View File

@ -1,6 +1,12 @@
// @db-hash ae0b5b1d792b614db036441010965ace
// @db-hash f82eb99171699f051830710c1f816b59
//该文件由脚本自动生成,请勿手动修改
export interface _o_videoTrack_old_20260401 {
'id'?: number;
'projectId'?: number | null;
'scriptId'?: number | null;
'videoId'?: number | null;
}
export interface memories {
'content': string;
'createTime': number;
@ -217,11 +223,15 @@ export interface o_video {
export interface o_videoTrack {
'id'?: number;
'projectId'?: number | null;
'prompt'?: string | null;
'reason'?: string | null;
'scriptId'?: number | null;
'state'?: string | null;
'videoId'?: number | null;
}
export interface DB {
"_o_videoTrack_old_20260401": _o_videoTrack_old_20260401;
"memories": memories;
"o_agentDeploy": o_agentDeploy;
"o_agentWorkData": o_agentWorkData;