Commit 2db83afd authored by 周成波's avatar 周成波

拆分成简单任务

parent f6a8833c
......@@ -173,20 +173,9 @@ export const useManyValues = () => {
const vertical_data = {
task_id: "20240220181602687",
chatgpt_prompt: ``,
chatgpt_answer: `从前,有一个叫花果王的猴王,身手敏捷,机智过人。他生活在一片美丽的猴子园里,那里有无数的猴子,它们和谐相处,过着无忧无虑的生活。花果王是这片猴子园的领袖,他深受猴子的尊敬和喜爱。 有一天,花果王听说附近的人类村庄正在遭受一场大灾难。原来,是一只凶猛的妖邪之作正在祸害人类。花果王决定带领猴群去解救人类,拯救村子。他组织了一支强大的猴军,他们勇敢地踏上了征程。 经过艰苦的跋涉,猴军终于来到了人类村庄。他们看到村民们惊恐失措,生活在水深火热之中。于是,花果王毫不犹豫地挥舞金箍棒,击败了妖邪之作。人类村民们见状,纷纷拜谢猴王,将他们视为救世主。 从此,花果王和猴军的名声远扬,他们继续在人类与猴子之间传播友谊与和谐,成为了永恒的传说。`,
chatgpt_answer_roles: [{"角色": "花果王",
"角色关键词": "性别:雄性, 年龄:成年, 肤色:棕色(猴毛颜色), 衣服:无(自然皮毛), 发型:蓬松猴鬃, 发色:金色(象征其力量与地位的金箍棒颜色), 脸色:生动活泼的猴脸, 五官特点:炯炯有神的眼睛,机敏狡黠的表情, 领导力强, 勇敢且富有智慧"},
{"角色": "猴群",
"角色关键词": "性别各异, 年龄各异, 肤色:多种(根据自然猴种不同), 衣服:无(自然皮毛), 发型:自然猴毛发型各异, 发色:各自品种特征色, 脸色:生动活泼的猴脸, 五官特点:机灵好奇, 忠诚团结"},
{"角色": "人类村民",
"角色关键词": "性别各异, 年龄各异, 肤色:黄种人肤色, 衣服:传统农耕服饰, 发型:古代农夫、妇女常见发型, 发色:黑发, 脸色:因灾难而显得苍白恐慌, 五官特点:感激涕零, 对救星充满敬仰"},
{"角色": "妖邪之作",
"角色关键词": "性别:不明, 年龄:不明, 肤色:暗黑或异色, 衣服:可能为神秘或恐怖风格的装饰, 发型:怪异扭曲, 发色:可能是深红、墨黑或其他邪恶象征的颜色, 脸色:阴森可怖, 五官特点:狰狞可怕, 充满恶意和破坏力"}]
,
chatgpt_prompt: `生成一个100字的科幻小故事,阿凡达系列`,
chatgpt_answer: ``,
chatgpt_answer_roles: [],
adapt_result_json: [
],
final_video: ``,
......
<script setup lang="ts">
import { onMounted, reactive, ref } from "vue";
import { Sunny, UploadFilled } from "@element-plus/icons-vue";
import { ElMessage, genFileId,
type UploadInstance,
type UploadProps,
type UploadRawFile } from "element-plus";
import text2videoService from "@/api/service/text2videoService";
import utils from "@/utils/utils";
import { useManyValues } from './compositions/useManyValues'
const debug = ref(import.meta.env.MODE === 'production' ? false : true);
const loading = ref(false);
const dialogVisible = ref(false);
const dialogData = ref("");
const default_data = useManyValues();
const form = reactive({
screen: default_data.screen,
if_need_subtitle: default_data.if_need_subtitle,
chatgpt_prompt: "",
chatgpt_answer: "",
chatgpt_answer_roles: <Wm.RolesItem[]>[],
adapt_result_json: <Wm.ScriptsItem[]>[],
task_id: "",
final_video: "",
});
const sd_prompt_prefix = default_data.sd_prompt_prefix;
const sd_negative_prompt_prefix = default_data.sd_negative_prompt_prefix;
const wenan_llm = "tyqw"
const wenan_llm_name = "通义千问"
const role_llm = "tyqw"
const role_llm_name = "通义千问"
const tuili_llm = "langchain"
const tuili_llm_name = "baichuan2-7b"
const fanyi_llm = "langchain"
const fanyi_llm_name = "baichuan2-7b"
onMounted(() => {
// 初始化示例数据
onChangeScreen(form.screen);
});
const onSubmitGpt = () => {
text2videoService
.submitGpt(form.chatgpt_prompt, wenan_llm)
.then((result: string) => {
console.log(form.chatgpt_prompt);
console.log(result);
form.chatgpt_answer = result;
})
.catch((error: any) => {
// console.error(error);
ElMessage({
message: error,
type: "error",
});
});
};
const onAdaptRoles = async () => {
if (!form.chatgpt_answer || form.chatgpt_answer.length == 0) {
ElMessage({
message: "文案不能为空",
type: "error",
});
return;
}
loading.value = true;
// 推理角色
try {
const adapt_restrict = `
指令:
请理解这个故事,给出这个故事的所有角色、角色关键词(性别(可以发挥想象进行补充,但一定要明确),年龄(可以发挥想象进行补充,但一定要明确),
肤色(可以发挥想象进行补充,但一定要明确),衣服(可以发挥想象进行补充,但一定要明确),发型(可以发挥想象进行补充,但一定要明确),发色(可以发挥想象进行补充,但一定要明确),
脸色(可以发挥想象进行补充,但一定要明确),五官特点(可以发挥想象进行补充,但一定要明确))。\n
要求:
角色和角色关键词要对应。
严格以如下格式返回:[{"角色":"","角色关键词":""}]`;
const keywords = await text2videoService.submitGpt(form.chatgpt_answer + "\n" + adapt_restrict, role_llm);
console.log(keywords)
const keywords_obj = utils.formatJsonObj(keywords.replace(/```json/g, '').replace(/```/g, ''))
console.log(keywords_obj)
form.chatgpt_answer_roles = []
if ('error' in keywords_obj) {
ElMessage({
message: "未解析到角色",
type: "error",
});
} else {
for (let item of keywords_obj) {
let newObjItem = {
"角色": JSON.stringify(item["角色"]).replace(/"/g, ''),
"角色关键词": JSON.stringify(item["角色关键词"]).replace(/"/g, '')
};
form.chatgpt_answer_roles.push(newObjItem);
}
console.log(form.chatgpt_answer_roles)
}
} catch (error) {
ElMessage({
message: String(error),
type: "error",
});
} finally {
// 最终关闭loading(无论成功或失败)
loading.value = false;
}
};
const onAdapt = async () => {
if (!form.chatgpt_answer || form.chatgpt_answer.length == 0) {
ElMessage({
message: "文案不能为空",
type: "error",
});
return;
}
loading.value = true;
form.task_id = utils.genDateTimeStr();
console.log(form.task_id)
// 按标点拆分成分镜
const sentences = utils.splitText(form.chatgpt_answer);
console.log(sentences.length)
// 分镜
form.adapt_result_json = []
for (let i = 0; i < sentences.length; i++) {
form.adapt_result_json.push({
"编号": (i + 1).toString(),
"场景描述": sentences[i].trim(),
"场景关键词": "",
"角色": "",
"角色关键词": "",
"画面描述词": "",
"本镜配图": "",
"local_image_path": "",
});
}
console.log(form.adapt_result_json)
const delay = (ms: any) => new Promise(res => setTimeout(res, ms));
async function processScenes() {
for (const item of form.adapt_result_json) {
await onAdaptOne(item);
await delay(100);
await onDrawOne(item);
}
}
try {
await processScenes();
ElMessage({
message: "all scene ok",
type: "success"
});
console.log(form.adapt_result_json);
} catch (error) {
ElMessage({
message: String(error),
type: "error"
});
} finally {
loading.value = false; // 最终关闭loading(无论成功或失败)
}
};
const onAdaptOne = async (item: any) => {
if (!item.场景描述) {
ElMessage({
message: "分镜场景描述不能为空",
type: "error",
});
return;
}
// 推理关键词
try {
const adapt_restrict = `
指令:
请理解这个故事,针对其中的这个场景:“${item.场景描述}”,给出这个场景的:
场景关键词(年代,空间,时间段,地理环境,天气,物品,人物,镜头角度)、
角色(从所有角色中选择本场景的角色)。
要求:
角色和角色关键词要对应。
严格以如下格式返回:[{"场景关键词":"(多个词以逗号分隔)","角色":"(角色以逗号分隔)"}]
除了按格式返回的内容之外,不要添加其他的任何说明。`;
const keywords = await text2videoService.submitGpt("故事:\n" + form.chatgpt_answer + "\n所有角色:\n"+ JSON.stringify(form.chatgpt_answer_roles)+"\n" + adapt_restrict, tuili_llm);
// console.log(keywords)
const keywords_obj = utils.formatJsonObj(keywords.replace(/```json/g, '').replace(/```/g, ''))
// console.log(keywords_obj)
if ('error' in keywords_obj) {
ElMessage({
message: `分镜 ${item.编号} 推理关键词失败,请重试`,
type: "error",
});
} else {
item.场景关键词 = JSON.stringify(keywords_obj[0].场景关键词).replace(/"/g, '');
if (form.chatgpt_answer_roles.length === 0) {
// 总角色为空
item.角色 = '';
item.角色关键词 = '';
} else {
// 总角色不为空
// item.角色 = JSON.stringify(keywords_obj[0].角色).replace(/"/g, '');
// item.角色关键词 = JSON.stringify(keywords_obj[0].角色关键词).replace(/"/g, '');
const item_roles = JSON.stringify(keywords_obj[0].角色).replace(/"/g, '');
item.角色 = item_roles;
let role_kws = ""
const item_roles_arr = item_roles.split(/[,,]/);
item_roles_arr.forEach( one_item_role => {
// 人工指定角色关键词,包含则取
form.chatgpt_answer_roles.forEach(i => {
if (i["角色"].includes(one_item_role.trim()) || one_item_role.includes(i["角色"].trim())) {
role_kws = `${role_kws}${i["角色"]}${i["角色关键词"]}】`
}
})
})
item.角色关键词 = role_kws;
}
}
} catch (error) {
ElMessage({
message: String(error),
type: "error",
});
}
};
const onDrawOne = async (item: any) => {
if (!item.场景描述 && !item.场景关键词) {
ElMessage({
message: "场景描述和场景关键词不能都为空",
type: "error",
});
return;
}
// 翻译+画图
if (!form.task_id) {
form.task_id = utils.genDateTimeStr();
console.log(form.task_id)
}
try {
let temp_prompt = ""
if (item.场景描述) {temp_prompt = temp_prompt + `场景描述为:${item.场景描述}\n`};
if (item.场景关键词) {temp_prompt = temp_prompt + `场景关键词为:${item.场景关键词}\n`};
if (item.角色) {temp_prompt = temp_prompt + `场景中的角色有:${item.角色}\n`};
if (item.角色关键词) {temp_prompt = temp_prompt + `角色关键词为:${item.角色关键词}\n`};
const sd_describe = await text2videoService.submitGpt(
`${temp_prompt}
指令:
请理解以上内容,并返回一段英文的描述。`, fanyi_llm
);
item.画面描述词 = sd_describe;
const sd_prompt = item.画面描述词 + "," + sd_prompt_prefix;
let width = "960";
let height = "540";
if (form.screen == "竖屏") {
width = "540";
height = "960";
}
// console.log(sd_prompt);
// console.log(sd_negative_prompt_prefix);
const sd_img = await text2videoService.submitSD(form.task_id, item.编号, sd_prompt, sd_negative_prompt_prefix, width, height);
item.本镜配图 = sd_img.domain_image_path+"?v="+utils.genDateTimeStr();
item.local_image_path = sd_img.local_image_path;
} catch (error) {
ElMessage({
message: String(error),
type: "error",
});
}
};
const onGenVideo = () => {
if (!form.adapt_result_json || form.adapt_result_json.length == 0 ) {
ElMessage({
message: "必要信息不能为空,请重新执行",
type: "error",
});
return;
}
let is_all_ok = true;
form.adapt_result_json.map(item => {
if (item.编号 == "" || item.场景描述 == "" || item.local_image_path == "") {
ElMessage({
message: `分镜 ${item.编号} 的必要信息为空,请重新执行`,
type: "error",
});
is_all_ok = false;
}
});
if (!is_all_ok) return;
console.log(form.adapt_result_json);
const video_param_detail = form.adapt_result_json.map(item => {
return {
idx: item.编号,
text: item.场景描述,
img_path: item.local_image_path
};
});
const video_param = {
task_id: form.task_id,
if_need_subtitle: form.if_need_subtitle,
task_info: video_param_detail,
}
text2videoService
.submitGenVideo(video_param)
.then((result: string) => {
console.log(result);
form.final_video = "";
form.final_video = result+"?v="+utils.genDateTimeStr();
})
.catch((error: any) => {
// console.error(error);
ElMessage({
message: error,
type: "error",
});
});
};
const clean_demo = () => {
form.chatgpt_prompt = "";
form.chatgpt_answer = "";
form.chatgpt_answer_roles = <Wm.RolesItem[]>[];
form.adapt_result_json = <Wm.ScriptsItem[]>[];
form.task_id = "";
form.final_video = "";
}
const clean_roles = () => {
form.chatgpt_answer_roles = <Wm.RolesItem[]>[];
}
const onChangeScreen = (val: string) => {
if (debug.value == true) {
if (val == "横屏") {
form.task_id = default_data.horizontal_data.task_id;
form.chatgpt_prompt = default_data.horizontal_data.chatgpt_prompt;
form.chatgpt_answer = default_data.horizontal_data.chatgpt_answer;
form.chatgpt_answer_roles = default_data.horizontal_data.chatgpt_answer_roles;
form.adapt_result_json = default_data.horizontal_data.adapt_result_json;
form.final_video = default_data.horizontal_data.final_video;
} else {
form.task_id = default_data.vertical_data.task_id;
form.chatgpt_prompt = default_data.vertical_data.chatgpt_prompt;
form.chatgpt_answer = default_data.vertical_data.chatgpt_answer;
form.chatgpt_answer_roles = default_data.vertical_data.chatgpt_answer_roles;
form.adapt_result_json = default_data.vertical_data.adapt_result_json;
form.final_video = default_data.vertical_data.final_video;
}
}
}
const showsdprompt = (item: any) => {
// alert(item.画面描述词)
dialogData.value = item.画面描述词+ "," +sd_prompt_prefix+'===== negative ====='+sd_negative_prompt_prefix;
dialogVisible.value = true; // 打开对话框
}
const upload = ref<UploadInstance>()
const actionUrl = ref(
import.meta.env.MODE === 'production'
? '/file'
: import.meta.env.VITE_APP_BASE_API + '/file'
)
const handleUploadSuccess = (val: Wm.UploadResult) => {
if (val.code == 0){
// console.log(val)
const id = parseInt(val.message) - 1;
form.adapt_result_json[id].本镜配图 = val.data[0].url+"?v="+utils.genDateTimeStr();
form.adapt_result_json[id].local_image_path = val.data[0].path;
ElMessage({
message: '上传成功',
type: 'success'
})
} else {
ElMessage({
message: '上传失败',
type: 'error'
})
}
}
const handleExceed: UploadProps['onExceed'] = (files) => {
upload.value!.clearFiles()
const file = files[0] as UploadRawFile
file.uid = genFileId()
upload.value!.handleStart(file)
upload.value!.submit()
}
</script>
<template>
<main class="home-container">
<!-- 标题 -->
<el-divider content-position="left">text2video</el-divider>
<el-form :model="form" label-width="114px" v-loading="loading">
<el-form-item>
<div>
<el-radio-group v-model="form.screen" @change="onChangeScreen">
<el-radio label="横屏" size="large" border/>
<el-radio label="竖屏" size="large" border/>
</el-radio-group>
</div>
</el-form-item>
<el-form-item>
<el-button type="success" @click="clean_demo">清除所有数据</el-button>
</el-form-item>
<!-- Prompt到文案 -->
<el-form-item label="Prompt">
<el-input v-model="form.chatgpt_prompt" :autosize="true" type="textarea" />
</el-form-item>
<el-form-item>
<el-button type="primary" @click="onSubmitGpt">生成文案({{wenan_llm_name}}</el-button>
</el-form-item>
<el-form-item label="文案">
<el-input v-model="form.chatgpt_answer" :autosize="true" type="textarea" />
</el-form-item>
<!-- 角色 -->
<el-form-item>
<el-button type="primary" @click="onAdaptRoles">推理所有角色({{role_llm_name}}</el-button>
<el-button plain @click="clean_roles">清空总角色列表</el-button>
</el-form-item>
<el-form-item label="角色">
<el-table :data="form.chatgpt_answer_roles" border style="width: 100%; z-index: calc(var(--el-table-index) -1)">
<el-table-column prop="角色" label="角色">
<template v-slot="scope">
<el-input v-model="scope.row.角色" :autosize="true" type="textarea"></el-input>
</template>
</el-table-column>
<el-table-column prop="角色关键词" label="角色关键词">
<template v-slot="scope">
<el-input v-model="scope.row.角色关键词" :autosize="true" type="textarea"></el-input>
</template>
</el-table-column>
</el-table>
</el-form-item>
<!-- 分镜 -->
<el-form-item>
<el-button type="primary" @click="onAdapt">分镜、推理关键词({{tuili_llm_name}})、翻译({{fanyi_llm_name}})、绘图</el-button>
</el-form-item>
<el-form-item label="分镜">
<el-table :data="form.adapt_result_json" border style="width: 100%; z-index: calc(var(--el-table-index) -1)">
<el-table-column prop="编号" label="编号" width="60" />
<el-table-column prop="场景描述" label="场景描述">
<template v-slot="scope">
<el-input v-model="scope.row.场景描述" :autosize="true" type="textarea"></el-input>
</template>
</el-table-column>
<el-table-column prop="场景关键词" label="场景关键词">
<template v-slot="scope">
<el-input v-model="scope.row.场景关键词" :autosize="true" type="textarea"></el-input>
</template>
</el-table-column>
<el-table-column prop="角色" label="角色">
<template v-slot="scope">
<el-input v-model="scope.row.角色" :autosize="true" type="textarea"></el-input>
</template>
</el-table-column>
<el-table-column prop="角色关键词" label="角色关键词">
<template v-slot="scope">
<el-input v-model="scope.row.角色关键词" :autosize="true" type="textarea"></el-input>
</template>
</el-table-column>
<el-table-column prop="本镜配图" label="本镜配图" width="300">
<template v-slot="scope">
<div>
<el-image :src="scope.row.本镜配图" :zoom-rate="1.2" :max-scale="1.5" :min-scale="0.5"
:preview-src-list="[scope.row.本镜配图]" fit="cover" :hide-on-click-modal="true"
/>
</div>
</template>
</el-table-column>
<el-table-column width="120" label="操作" align="center">
<!--
<template v-slot:header>
<el-button type="danger" size="default" @click="">批量绘制所有图片</el-button>
</template>
-->
<template v-slot="scope">
<div style="margin: 10px 0"><el-button type="primary" size="default" @click="onAdaptOne(scope.row)">推理关键词</el-button></div>
<div style="margin: 10px 0"><el-button type="primary" size="default" @click="onDrawOne(scope.row)">翻译、绘图</el-button></div>
<el-upload
class="upload-demo"
ref="upload"
list-type="picture"
:show-file-list="false"
:limit="1"
:action="actionUrl"
:on-success="handleUploadSuccess"
:on-exceed="handleExceed"
:data="{item_id: scope.row.编号}"
>
<el-button type="primary">上传图片</el-button>
</el-upload>
<div style="margin: 10px 0"><el-button plain @click="showsdprompt(scope.row)">debug</el-button></div>
<el-dialog
v-model=dialogVisible
width="80%"
>
<p>{{ dialogData }}</p>
<template #footer>
<div class="dialog-footer">
<el-button type="primary" @click="dialogVisible = false">ok</el-button>
</div>
</template>
</el-dialog>
</template>
</el-table-column>
</el-table>
</el-form-item>
<!-- 生成视频 -->
<el-form-item>
<el-button type="primary" @click="onGenVideo">生成视频</el-button>
</el-form-item>
<el-form-item>
<video :src="form.final_video" controls></video>
</el-form-item>
</el-form>
</main>
</template>
<style lang="scss" scoped>
.home-container {
width: 100%;
}
</style>
<style lang="scss">
.home-container {
.el-table .el-table__cell {
z-index: calc(var(--el-table-index) -1);
}
}
</style>
......@@ -27,14 +27,20 @@ const form = reactive({
const sd_prompt_prefix = default_data.sd_prompt_prefix;
const sd_negative_prompt_prefix = default_data.sd_negative_prompt_prefix;
const wenan_llm = "langchain"
const wenan_llm_name = "baichuan2-7b"
const role_llm = "langchain"
const role_llm_name = "baichuan2-7b"
const tuili_llm = "langchain"
const tuili_llm_name = "baichuan2-7b"
const fanyi_llm = "langchain"
const fanyi_llm_name = "baichuan2-7b"
const tyqw = {'api': 'tyqw', 'name':'通义千问'};
const baichuan = {'api': 'langchain', 'name':'baichuan2-7b'};
const qwen = {'api': 'langchain', 'name':'Qwen-7B-Chat'};
const wenan_llm = qwen.api
const wenan_llm_name = qwen.name
const role_llm = tyqw.api
const role_llm_name = tyqw.name
const role_keywords_llm = qwen.api
const role_keywords_llm_name = qwen.name
const tuili_llm = qwen.api
const tuili_llm_name = qwen.name
const fanyi_llm = qwen.api
const fanyi_llm_name = qwen.name
onMounted(() => {
......@@ -42,6 +48,8 @@ onMounted(() => {
onChangeScreen(form.screen);
});
const delay = (ms: any) => new Promise(res => setTimeout(res, ms));
const onSubmitGpt = () => {
text2videoService
.submitGpt(form.chatgpt_prompt, wenan_llm)
......@@ -69,34 +77,46 @@ const onAdaptRoles = async () => {
}
loading.value = true;
// 推理角色
form.chatgpt_answer_roles = [];
try {
const adapt_restrict = `
指令:
请理解这个故事,给出这个故事的所有角色、角色关键词(性别(可以发挥想象进行补充,但一定要明确),年龄(可以发挥想象进行补充,但一定要明确),
肤色(可以发挥想象进行补充,但一定要明确),衣服(可以发挥想象进行补充,但一定要明确),发型(可以发挥想象进行补充,但一定要明确),发色(可以发挥想象进行补充,但一定要明确),
脸色(可以发挥想象进行补充,但一定要明确),五官特点(可以发挥想象进行补充,但一定要明确))。\n
要求:
角色和角色关键词要对应。
严格以如下格式返回:[{"角色":"","角色关键词":""}]`;
const keywords = await text2videoService.submitGpt(form.chatgpt_answer + "\n" + adapt_restrict, role_llm);
console.log(keywords)
const keywords_obj = utils.formatJsonObj(keywords.replace(/```json/g, '').replace(/```/g, ''))
console.log(keywords_obj)
form.chatgpt_answer_roles = []
if ('error' in keywords_obj) {
ElMessage({
message: "未解析到角色",
type: "error",
});
} else {
for (let item of keywords_obj) {
let newObjItem = {
"角色": JSON.stringify(item["角色"]).replace(/"/g, ''),
"角色关键词": JSON.stringify(item["角色关键词"]).replace(/"/g, '')
};
form.chatgpt_answer_roles.push(newObjItem);
请理解这个故事,给出这个故事中的所有角色,多个角色以逗号分隔`;
let roles = await text2videoService.submitGpt("故事:\n" + form.chatgpt_answer + "\n" + adapt_restrict, role_llm);
roles = roles.replace(/。/g, '').replace(/、/g, ',')
console.log(roles)
const roles_arr = roles.split(/[,,]/);
console.log(roles_arr)
async function processRoles() {
for (const one_role of roles_arr) {
await delay(100);
const adapt_keyword_restrict = `
指令:
请理解这个故事,给出这个角色“${one_role.trim()}”的关键词(性别(可以发挥想象进行补充,但一定要有),年龄(可以发挥想象进行补充,但一定要有),
肤色(可以发挥想象进行补充,但一定要有),衣服(可以发挥想象进行补充,但一定要有),发型(可以发挥想象进行补充,但一定要有),
发色(可以发挥想象进行补充,但一定要有),脸色(可以发挥想象进行补充,但一定要有),五官特点(可以发挥想象进行补充,但一定要有))。
要求:
关键词以逗号分隔。
只要返回关键词,不需要其他的说明文字。`;
let keywords = await text2videoService.submitGpt(form.chatgpt_answer + "\n" + adapt_keyword_restrict, role_keywords_llm);
keywords = keywords.replace(/。/g, '').replace(/、/g, ',')
form.chatgpt_answer_roles.push({
"角色": one_role.trim(),
"角色关键词": keywords.trim()
});
}
}
try {
await processRoles();
console.log(form.chatgpt_answer_roles)
} catch (error) {
ElMessage({
message: String(error),
type: "error"
});
} finally {
loading.value = false; // 最终关闭loading(无论成功或失败)
}
} catch (error) {
ElMessage({
......@@ -139,8 +159,6 @@ const onAdapt = async () => {
}
console.log(form.adapt_result_json)
const delay = (ms: any) => new Promise(res => setTimeout(res, ms));
async function processScenes() {
for (const item of form.adapt_result_json) {
await onAdaptOne(item);
......@@ -179,46 +197,39 @@ const onAdaptOne = async (item: any) => {
try {
const adapt_restrict = `
指令:
请理解这个故事,针对其中的这个场景:“${item.场景描述}”,给出这个场景的:
场景关键词(年代,空间,时间段,地理环境,天气,物品,人物,镜头角度)、
角色(从所有角色中选择本场景的角色)
请理解这个故事,给出这个场景“${item.场景描述}”的关键词(年代(可以发挥想象进行补充,但一定要有),空间(可以发挥想象进行补充,但一定要有),
时间段(可以发挥想象进行补充,但一定要有),地理环境(可以发挥想象进行补充,但一定要有),天气(可以发挥想象进行补充,但一定要有),
物品(可以发挥想象进行补充,但一定要有),人物(可以发挥想象进行补充,但一定要有),镜头角度(可以发挥想象进行补充,但一定要有))
要求:
角色和角色关键词要对应。
严格以如下格式返回:[{"场景关键词":"(多个词以逗号分隔)","角色":"(角色以逗号分隔)"}]
除了按格式返回的内容之外,不要添加其他的任何说明。`;
const keywords = await text2videoService.submitGpt("故事:\n" + form.chatgpt_answer + "\n所有角色:\n"+ JSON.stringify(form.chatgpt_answer_roles)+"\n" + adapt_restrict, tuili_llm);
关键词以逗号分隔。
只要返回关键词,不需要其他的说明文字。`;
const keywords = await text2videoService.submitGpt("故事:\n" + form.chatgpt_answer + "\n" + adapt_restrict, tuili_llm);
// console.log(keywords)
const keywords_obj = utils.formatJsonObj(keywords.replace(/```json/g, '').replace(/```/g, ''))
// console.log(keywords_obj)
if ('error' in keywords_obj) {
ElMessage({
message: `分镜 ${item.编号} 推理关键词失败,请重试`,
type: "error",
});
item.场景关键词 = keywords;
const adapt_role_restrict = `
指令:
请理解这个故事,针对其中的这个场景:“${item.场景描述}”,从所有角色中选择本场景的角色,多个角色以逗号分隔。`;
const item_roles = await text2videoService.submitGpt("故事:\n" + form.chatgpt_answer + "\n所有角色:\n"+ JSON.stringify(form.chatgpt_answer_roles)+"\n" + adapt_role_restrict, tuili_llm);
// console.log(role_keywords)
if (form.chatgpt_answer_roles.length === 0) {
// 总角色为空
item.角色 = '';
item.角色关键词 = '';
} else {
item.场景关键词 = JSON.stringify(keywords_obj[0].场景关键词).replace(/"/g, '');
if (form.chatgpt_answer_roles.length === 0) {
// 总角色为空
item.角色 = '';
item.角色关键词 = '';
} else {
// 总角色不为空
// item.角色 = JSON.stringify(keywords_obj[0].角色).replace(/"/g, '');
// item.角色关键词 = JSON.stringify(keywords_obj[0].角色关键词).replace(/"/g, '');
const item_roles = JSON.stringify(keywords_obj[0].角色).replace(/"/g, '');
item.角色 = item_roles;
let role_kws = ""
const item_roles_arr = item_roles.split(/[,,]/);
item_roles_arr.forEach( one_item_role => {
// 人工指定角色关键词,包含则取
form.chatgpt_answer_roles.forEach(i => {
if (i["角色"].includes(one_item_role.trim()) || one_item_role.includes(i["角色"].trim())) {
role_kws = `${role_kws}${i["角色"]}${i["角色关键词"]}】`
}
})
// 总角色不为空
item.角色 = item_roles;
let role_kws = ""
const item_roles_arr = item_roles.split(/[,,]/);
item_roles_arr.forEach( one_item_role => {
// 人工指定角色关键词,包含则取
form.chatgpt_answer_roles.forEach(i => {
if (i["角色"].includes(one_item_role.trim()) || one_item_role.includes(i["角色"].trim())) {
role_kws = `${role_kws}${i["角色"]}${i["角色关键词"]}】`
}
})
item.角色关键词 = role_kws;
}
})
item.角色关键词 = role_kws;
}
} catch (error) {
ElMessage({
......@@ -423,7 +434,7 @@ const handleExceed: UploadProps['onExceed'] = (files) => {
</el-form-item>
<!-- 角色 -->
<el-form-item>
<el-button type="primary" @click="onAdaptRoles">推理所有角色({{role_llm_name}}</el-button>
<el-button type="primary" @click="onAdaptRoles">推理角色({{role_llm_name}})、推理角色关键词({{role_keywords_llm_name}}</el-button>
<el-button plain @click="clean_roles">清空总角色列表</el-button>
</el-form-item>
<el-form-item label="角色">
......@@ -442,7 +453,7 @@ const handleExceed: UploadProps['onExceed'] = (files) => {
</el-form-item>
<!-- 分镜 -->
<el-form-item>
<el-button type="primary" @click="onAdapt">分镜、推理关键词({{tuili_llm_name}})、翻译({{fanyi_llm_name}})、绘图</el-button>
<el-button type="primary" @click="onAdapt">分镜、推理场景关键词({{tuili_llm_name}})、英文描述({{fanyi_llm_name}})、绘图</el-button>
</el-form-item>
<el-form-item label="分镜">
<el-table :data="form.adapt_result_json" border style="width: 100%; z-index: calc(var(--el-table-index) -1)">
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment