Commit 72ce5042 authored by 周成波's avatar 周成波

update

parent b734b417
...@@ -9,6 +9,8 @@ type MyMarkType = Record<number, MyMarkInterface | string> ...@@ -9,6 +9,8 @@ type MyMarkType = Record<number, MyMarkInterface | string>
export const useManyValues = () => { export const useManyValues = () => {
const screen = "竖屏"; const screen = "竖屏";
const horizontal_img_size = {width: "960", height: "540"};
const vertical_img_size = {width: "540", height: "960"};
const if_need_subtitle = "false"; const if_need_subtitle = "false";
const sd_prompt_prefix = `(dressed:1.5),best quality,masterpiece,realistic,HDR,UHD,8K,best quality,highres,absurdres,realistic,masterpiece, const sd_prompt_prefix = `(dressed:1.5),best quality,masterpiece,realistic,HDR,UHD,8K,best quality,highres,absurdres,realistic,masterpiece,
...@@ -67,7 +69,7 @@ export const useManyValues = () => { ...@@ -67,7 +69,7 @@ export const useManyValues = () => {
const vertical_data = { const vertical_data = {
task_id: "20240220181602687", task_id: "20240220181602687",
chatgpt_prompt: `生成一个50字的科幻小故事,阿凡达系列`, chatgpt_prompt: `生成一个50字的科幻小故事,阿凡达系列`,
chatgpt_answer: `"嘿,你绝对猜不到!一只松鼠竟敢挑战国宝熊猫,就为了争夺一块蛋糕!" 在宁静的森林里,一场奇特的食物大战正在上演。一只机灵的小松鼠,眼尖地发现了一块香气扑鼻的奶油蛋糕,正惬意地躺在熊猫阿宝的竹篮里。蛋糕上的水果点缀和醇厚的奶油似乎在向小松鼠招手,它的口水都快流成一条小溪了。 而慵懒的大熊猫阿宝,本打算用这块蛋糕作为午后小憩的甜点,却没料到这位“飞檐走壁”的小贼会来挑战他的权威。只见松鼠灵活地穿梭在树枝间,伺机抢夺那块诱人的蛋糕,而熊猫阿宝则憨态可掬地试图守护这份甜蜜。 于是乎,一场别开生面的蛋糕争夺战就此展开,松鼠施展浑身解数,上蹿下跳,熊猫阿宝也不甘示弱,笨拙中透着狡黠,场面既紧张又逗趣。这场较量究竟谁能胜出?是身手矫健的小松鼠,还是憨萌可爱的熊猫阿宝?一切悬念,都围绕着那块美味的蛋糕徐徐展开……`, chatgpt_answer: `在宁静的森林里。一场奇特的食物大战正在上演。一只机灵的小松鼠。眼尖地发现了一块香气扑鼻的奶油蛋糕,正惬意地躺在熊猫阿宝的竹篮里。蛋糕上的水果点缀和醇厚的奶油似乎在向小松鼠招手,它的口水都快流成一条小溪了。`,
chatgpt_answer_roles: [], chatgpt_answer_roles: [],
adapt_result_json: [], adapt_result_json: [],
final_video: ``, final_video: ``,
...@@ -258,6 +260,8 @@ export const useManyValues = () => { ...@@ -258,6 +260,8 @@ export const useManyValues = () => {
return { return {
screen: screen, screen: screen,
horizontal_img_size: horizontal_img_size,
vertical_img_size: vertical_img_size,
sd_prompt_prefix: sd_prompt_prefix, sd_prompt_prefix: sd_prompt_prefix,
sd_negative_prompt_prefix: sd_negative_prompt_prefix, sd_negative_prompt_prefix: sd_negative_prompt_prefix,
llms: llms, llms: llms,
......
<script setup lang="ts"> <script setup lang="ts">
import { onMounted, reactive, ref, nextTick } from "vue"; import { onMounted, reactive, ref, nextTick } from "vue";
import { Sunny, UploadFilled } from "@element-plus/icons-vue"; import { Sunny, UploadFilled } from "@element-plus/icons-vue";
import { ElMessage, genFileId, import {
ElMessage, genFileId,
type UploadInstance, type UploadInstance,
type UploadProps, type UploadProps,
type UploadRawFile } from "element-plus"; type UploadRawFile
} from "element-plus";
import text2videoService from "@/api/service/text2videoService"; import text2videoService from "@/api/service/text2videoService";
import utils from "@/utils/utils"; import utils from "@/utils/utils";
import { useManyValues } from './compositions/useManyValues' import { useManyValues } from './compositions/useManyValues'
...@@ -16,6 +18,7 @@ const dialogData = ref(""); ...@@ -16,6 +18,7 @@ const dialogData = ref("");
const default_data = useManyValues(); const default_data = useManyValues();
const form = reactive({ const form = reactive({
screen: default_data.screen, screen: default_data.screen,
img_size: <Wm.ImgSize>{},
if_need_subtitle: default_data.if_need_subtitle, if_need_subtitle: default_data.if_need_subtitle,
chatgpt_prompt: "", chatgpt_prompt: "",
chatgpt_answer: "", chatgpt_answer: "",
...@@ -57,6 +60,12 @@ onMounted(() => { ...@@ -57,6 +60,12 @@ onMounted(() => {
} else { } else {
pwdCheckDialogVisible.value = true; pwdCheckDialogVisible.value = true;
} }
// 初始化宽高
if (form.screen == "横屏") {
form.img_size = default_data.horizontal_img_size;
} else {
form.img_size = default_data.vertical_img_size;
}
}); });
const delay = (ms: any) => new Promise(res => setTimeout(res, ms)); const delay = (ms: any) => new Promise(res => setTimeout(res, ms));
...@@ -364,12 +373,12 @@ const onAdaptOneSceneRoles = async (item: any) => { ...@@ -364,12 +373,12 @@ const onAdaptOneSceneRoles = async (item: any) => {
const temp_arr = item.角色.split(/[,,、]/); const temp_arr = item.角色.split(/[,,、]/);
const temp_arr_length = temp_arr.length; const temp_arr_length = temp_arr.length;
////// 如果本镜的角色大于1个,则只保留没有出现过的角色,且保证只有一个 ////// 如果本镜的角色大于1个,则只保留没有出现过的角色,且保证只有一个
if(temp_arr_length > 1) { if (temp_arr_length > 1) {
////// 获取本镜之前的所有角色 ////// 获取本镜之前的所有角色
let role_history = ""; let role_history = "";
form.adapt_result_json.forEach( scene => { form.adapt_result_json.forEach(scene => {
if (Number(scene.编号) < Number(item.编号)) { if (Number(scene.编号) < Number(item.编号)) {
role_history += scene.角色 + ","; role_history += scene.角色 + ",";
} }
}) })
role_history = role_history.replace(/,+$/, ''); role_history = role_history.replace(/,+$/, '');
...@@ -415,7 +424,7 @@ const onAdaptOneSceneRoles = async (item: any) => { ...@@ -415,7 +424,7 @@ const onAdaptOneSceneRoles = async (item: any) => {
} }
} }
// 如果找不到相同的,则模糊匹配 // 如果找不到相同的,则模糊匹配
if (! temp_role_kws) { if (!temp_role_kws) {
for (const i of form.chatgpt_answer_roles) { for (const i of form.chatgpt_answer_roles) {
if (i["角色"].includes(one_item_role.trim()) || one_item_role.includes(i["角色"].trim())) { if (i["角色"].includes(one_item_role.trim()) || one_item_role.includes(i["角色"].trim())) {
temp_role_kws = `${i["角色关键词"]}`; temp_role_kws = `${i["角色关键词"]}`;
...@@ -496,20 +505,14 @@ const onDrawOne = async (item: any) => { ...@@ -496,20 +505,14 @@ const onDrawOne = async (item: any) => {
item.画面描述词 = item.场景关键词英文 + "," + item.角色关键词英文; item.画面描述词 = item.场景关键词英文 + "," + item.角色关键词英文;
const sd_prompt = item.画面描述词 + "," + sd_prompt_prefix; 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_prompt);
// console.log(sd_negative_prompt_prefix); // console.log(sd_negative_prompt_prefix);
const sampler_index = "DPM++ SDE Karras"; const sampler_index = "DPM++ SDE Karras";
const seed = "-1"; const seed = "-1";
const steps = "6"; const steps = "6";
const cfg_scale = "2"; const cfg_scale = "2";
const sd_img = await text2videoService.submitSD(form.task_id, item.编号, sd_prompt, sd_negative_prompt_prefix, width, height, sampler_index, seed, steps, cfg_scale); const sd_img = await text2videoService.submitSD(form.task_id, item.编号, sd_prompt, sd_negative_prompt_prefix, form.img_size.width, form.img_size.height, sampler_index, seed, steps, cfg_scale);
item.本镜配图 = sd_img.domain_image_path+"?v="+utils.genDateTimeStr(); item.本镜配图 = sd_img.domain_image_path + "?v=" + utils.genDateTimeStr();
item.local_image_path = sd_img.local_image_path; item.local_image_path = sd_img.local_image_path;
} catch (error) { } catch (error) {
ElMessage({ ElMessage({
...@@ -522,7 +525,7 @@ const onDrawOne = async (item: any) => { ...@@ -522,7 +525,7 @@ const onDrawOne = async (item: any) => {
const onGenVideo = () => { const onGenVideo = () => {
if (!form.adapt_result_json || form.adapt_result_json.length == 0 ) { if (!form.adapt_result_json || form.adapt_result_json.length == 0) {
ElMessage({ ElMessage({
message: "必要信息不能为空,请重新执行", message: "必要信息不能为空,请重新执行",
type: "error", type: "error",
...@@ -550,8 +553,8 @@ const onGenVideo = () => { ...@@ -550,8 +553,8 @@ const onGenVideo = () => {
}); });
let para_rate = `${voice_rate.value}%`; let para_rate = `${voice_rate.value}%`;
let para_volume = `${voice_volume.value}%`; let para_volume = `${voice_volume.value}%`;
if(voice_rate.value >= 0){para_rate = `+${para_rate}`} if (voice_rate.value >= 0) { para_rate = `+${para_rate}` }
if(voice_volume.value >= 0){para_volume = `+${para_volume}`} if (voice_volume.value >= 0) { para_volume = `+${para_volume}` }
const video_param = { const video_param = {
task_id: form.task_id, task_id: form.task_id,
if_need_subtitle: form.if_need_subtitle, if_need_subtitle: form.if_need_subtitle,
...@@ -575,7 +578,7 @@ const onGenVideo = () => { ...@@ -575,7 +578,7 @@ const onGenVideo = () => {
.then((result: string) => { .then((result: string) => {
console.log(result); console.log(result);
form.final_video = ""; form.final_video = "";
form.final_video = result+"?v="+utils.genDateTimeStr(); form.final_video = result + "?v=" + utils.genDateTimeStr();
}) })
.catch((error: any) => { .catch((error: any) => {
// console.error(error); // console.error(error);
...@@ -639,15 +642,28 @@ const upload = ref<UploadInstance>() ...@@ -639,15 +642,28 @@ const upload = ref<UploadInstance>()
const actionUrl = ref( const actionUrl = ref(
import.meta.env.MODE === 'production' import.meta.env.MODE === 'production'
? '/file' ? '/file/upload_pic_and_modify'
: import.meta.env.VITE_APP_BASE_API + '/file' : import.meta.env.VITE_APP_BASE_API + '/file/upload_pic_and_modify'
) )
// 在分镜自定义上传图片时发现个bug
// 第一次上传没问题,但重复进行上传,会更新到最后一行上去。
// 奇怪,没找到原因。暂时先通过迂回的方法来处理。
let first_has_uploaded = false;
const handleUploadSuccess = (val: Wm.UploadResult) => { const handleUploadSuccess = (val: Wm.UploadResult) => {
if (val.code == 0){ if (val.code == 0) {
// console.log(val) console.log(val)
const id = parseInt(val.message) - 1; let id = parseInt(val.message) - 1;
form.adapt_result_json[id].本镜配图 = val.data[0].url+"?v="+utils.genDateTimeStr(); ///// 迂回解决上述bug /////
// if (id == 0) { first_has_uploaded = true; }
// if (first_has_uploaded && id == form.adapt_result_json.length - 1) {
// console.log(first_has_uploaded);
// console.log(id);
// console.log(form.adapt_result_json.length);
// id = 0;}
/////////////////////////
form.adapt_result_json[id].本镜配图 = val.data[0].url + "?v=" + utils.genDateTimeStr();
form.adapt_result_json[id].local_image_path = val.data[0].path; form.adapt_result_json[id].local_image_path = val.data[0].path;
ElMessage({ ElMessage({
message: '上传成功', message: '上传成功',
...@@ -661,7 +677,12 @@ const handleUploadSuccess = (val: Wm.UploadResult) => { ...@@ -661,7 +677,12 @@ const handleUploadSuccess = (val: Wm.UploadResult) => {
} }
} }
const handleExceed: UploadProps['onExceed'] = (files) => { const onClearOnePic = (item: any) => {
item.本镜配图 = "";
item.local_image_path = "";
};
const handleUploadExceed: UploadProps['onExceed'] = (files) => {
upload.value!.clearFiles() upload.value!.clearFiles()
const file = files[0] as UploadRawFile const file = files[0] as UploadRawFile
file.uid = genFileId() file.uid = genFileId()
...@@ -669,6 +690,13 @@ const handleExceed: UploadProps['onExceed'] = (files) => { ...@@ -669,6 +690,13 @@ const handleExceed: UploadProps['onExceed'] = (files) => {
upload.value!.submit() upload.value!.submit()
} }
const handleUploadError = (error: Error) => {
ElMessage({
message: String(error.message),
type: "error",
});
}
const onPwdCheckDialog = () => { const onPwdCheckDialog = () => {
text2videoService text2videoService
.submitPwdCheck(pwdCheckValue.value) .submitPwdCheck(pwdCheckValue.value)
...@@ -697,7 +725,7 @@ const onDeleteOne = (item: any) => { ...@@ -697,7 +725,7 @@ const onDeleteOne = (item: any) => {
form.adapt_result_json = form.adapt_result_json.filter(item => item.编号 !== delete_no); form.adapt_result_json = form.adapt_result_json.filter(item => item.编号 !== delete_no);
// 重新对记录进行编号 // 重新对记录进行编号
form.adapt_result_json = form.adapt_result_json.map((item, index) => { form.adapt_result_json = form.adapt_result_json.map((item, index) => {
return {...item, 编号: (index + 1).toString()}; return { ...item, 编号: (index + 1).toString() };
}); });
} catch (error) { } catch (error) {
ElMessage({ ElMessage({
...@@ -716,8 +744,8 @@ const onDeleteOne = (item: any) => { ...@@ -716,8 +744,8 @@ const onDeleteOne = (item: any) => {
<el-form-item> <el-form-item>
<div> <div>
<el-radio-group v-model="form.screen" @change="onChangeScreen"> <el-radio-group v-model="form.screen" @change="onChangeScreen">
<el-radio label="横屏" size="large" border/> <el-radio label="横屏" size="large" border />
<el-radio label="竖屏" size="large" border/> <el-radio label="竖屏" size="large" border />
</el-radio-group> </el-radio-group>
</div> </div>
</el-form-item> </el-form-item>
...@@ -729,15 +757,15 @@ const onDeleteOne = (item: any) => { ...@@ -729,15 +757,15 @@ const onDeleteOne = (item: any) => {
<el-input v-model="form.chatgpt_prompt" :autosize="true" type="textarea" /> <el-input v-model="form.chatgpt_prompt" :autosize="true" type="textarea" />
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-button type="primary" @click="onSubmitGpt">生成文案({{wen_an_llm.name}}</el-button> <el-button type="primary" @click="onSubmitGpt">生成文案({{ wen_an_llm.name }}</el-button>
</el-form-item> </el-form-item>
<el-form-item label="文案"> <el-form-item label="文案">
<el-input v-model="form.chatgpt_answer" :autosize="true" type="textarea" /> <el-input v-model="form.chatgpt_answer" :autosize="true" type="textarea" />
</el-form-item> </el-form-item>
<!-- 角色 --> <!-- 角色 -->
<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 }}</el-button>
<el-button type="primary" @click="onAdaptRolesKeywords">推理角色关键词({{role_keywords_llm.name}}</el-button> <el-button type="primary" @click="onAdaptRolesKeywords">推理角色关键词({{ role_keywords_llm.name }}</el-button>
<el-button plain @click="clean_roles">清空总角色列表</el-button> <el-button plain @click="clean_roles">清空总角色列表</el-button>
</el-form-item> </el-form-item>
<el-form-item label="角色"> <el-form-item label="角色">
...@@ -750,12 +778,8 @@ const onDeleteOne = (item: any) => { ...@@ -750,12 +778,8 @@ const onDeleteOne = (item: any) => {
<el-table-column prop="属性" label="属性" width="300"> <el-table-column prop="属性" label="属性" width="300">
<template v-slot="scope"> <template v-slot="scope">
<el-select v-model="scope.row.属性" filterable allow-create :reserve-keyword="false"> <el-select v-model="scope.row.属性" filterable allow-create :reserve-keyword="false">
<el-option <el-option v-for="item in default_data.role_attribute_options" :key="item.value" :label="item.label"
v-for="item in default_data.role_attribute_options" :value="item.value" />
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select> </el-select>
</template> </template>
</el-table-column> </el-table-column>
...@@ -774,8 +798,8 @@ const onDeleteOne = (item: any) => { ...@@ -774,8 +798,8 @@ const onDeleteOne = (item: any) => {
<!-- 分镜 --> <!-- 分镜 -->
<el-form-item> <el-form-item>
<el-button type="primary" @click="onAdapt">分镜</el-button> <el-button type="primary" @click="onAdapt">分镜</el-button>
<el-button type="primary" @click="onAdaptScene">推理场景({{tuili_llm.name}})</el-button> <el-button type="primary" @click="onAdaptScene">推理场景({{ tuili_llm.name }})</el-button>
<el-button type="primary" @click="onAdaptSceneRoles">推理场景中的角色({{tuili_keyword_llm.name}})</el-button> <el-button type="primary" @click="onAdaptSceneRoles">推理场景中的角色({{ tuili_keyword_llm.name }})</el-button>
<el-button type="primary" @click="onDraw">绘图</el-button> <el-button type="primary" @click="onDraw">绘图</el-button>
<el-button plain @click="clean_scenes">清空分镜列表</el-button> <el-button plain @click="clean_scenes">清空分镜列表</el-button>
</el-form-item> </el-form-item>
...@@ -791,27 +815,26 @@ const onDeleteOne = (item: any) => { ...@@ -791,27 +815,26 @@ const onDeleteOne = (item: any) => {
<template v-slot="scope"> <template v-slot="scope">
<el-text class="mx-1" size="small">{{ scope.row.场景关键词 }}</el-text> <el-text class="mx-1" size="small">{{ scope.row.场景关键词 }}</el-text>
<hr style="border: none; border-top: 1px dashed #999; margin: 5px 0;"> <hr style="border: none; border-top: 1px dashed #999; margin: 5px 0;">
<el-text class="mx-1" size="small">{{ scope.row.场景关键词英文 }}</el-text> <el-input v-model="scope.row.场景关键词英文" :autosize="true" type="textarea"></el-input>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="角色" label="角色"> <el-table-column prop="角色" label="角色">
<template v-slot="scope"> <template v-slot="scope">
<el-text class="mx-1" size="small">{{ scope.row.角色 }}<br/>{{ scope.row.info }}</el-text> <el-text class="mx-1" size="small">{{ scope.row.角色 }}<br />{{ scope.row.info }}</el-text>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="角色关键词" label="角色关键词"> <el-table-column prop="角色关键词" label="角色关键词">
<template v-slot="scope"> <template v-slot="scope">
<el-text class="mx-1" size="small">{{ scope.row.角色关键词 }}</el-text> <el-text class="mx-1" size="small">{{ scope.row.角色关键词 }}</el-text>
<hr style="border: none; border-top: 1px dashed #999; margin: 5px 0;"> <hr style="border: none; border-top: 1px dashed #999; margin: 5px 0;">
<el-text class="mx-1" size="small">{{ scope.row.角色关键词英文 }}</el-text> <el-input v-model="scope.row.角色关键词英文" :autosize="true" type="textarea"></el-input>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="本镜配图" label="本镜配图" width="300"> <el-table-column prop="本镜配图" label="本镜配图" width="300">
<template v-slot="scope"> <template v-slot="scope">
<div> <div>
<el-image :src="scope.row.本镜配图" :zoom-rate="1.2" :max-scale="1.5" :min-scale="0.5" <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" :preview-src-list="[scope.row.本镜配图]" fit="cover" :hide-on-click-modal="true" />
/>
</div> </div>
</template> </template>
</el-table-column> </el-table-column>
...@@ -825,24 +848,15 @@ const onDeleteOne = (item: any) => { ...@@ -825,24 +848,15 @@ const onDeleteOne = (item: any) => {
<div style="margin: 5px 0"><el-button type="primary" size="small" @click="onAdaptOneScene(scope.row)">推理场景</el-button></div> <div style="margin: 5px 0"><el-button type="primary" size="small" @click="onAdaptOneScene(scope.row)">推理场景</el-button></div>
<div style="margin: 5px 0"><el-button type="primary" size="small" @click="onAdaptOneSceneRoles(scope.row)">推理角色</el-button></div> <div style="margin: 5px 0"><el-button type="primary" size="small" @click="onAdaptOneSceneRoles(scope.row)">推理角色</el-button></div>
<div style="margin: 5px 0"><el-button type="primary" size="small" @click="onDrawOne(scope.row)">绘图</el-button></div> <div style="margin: 5px 0"><el-button type="primary" size="small" @click="onDrawOne(scope.row)">绘图</el-button></div>
<el-upload <el-upload class="upload-demo" ref="upload" list-type="picture" :show-file-list="false" :limit="1"
class="upload-demo" accept=".png,.PNG,.jpg,.JPG,.jpeg,.JPEG,.gif,.GIF,.bmp,.BMP"
ref="upload" :action="actionUrl" :on-success="handleUploadSuccess" :on-exceed="handleUploadExceed"
list-type="picture" :on-error="handleUploadError" :data="{ item_id: scope.row.编号, width: form.img_size.width, height: form.img_size.height }">
:show-file-list="false" <el-button type="primary" size="small" @click="console.log(scope.row.编号)">上传图片</el-button>
:limit="1"
:action="actionUrl"
:on-success="handleUploadSuccess"
:on-exceed="handleExceed"
:data="{item_id: scope.row.编号}"
>
<el-button type="primary" size="small">上传图片</el-button>
</el-upload> </el-upload>
<!-- <div style="margin: 5px 0"><el-button plain size="small" @click="onClearOnePic(scope.row)">清除图片</el-button></div> -->
<div style="margin: 5px 0"><el-button plain size="small" @click="showsdprompt(scope.row)">debug</el-button></div> <div style="margin: 5px 0"><el-button plain size="small" @click="showsdprompt(scope.row)">debug</el-button></div>
<el-dialog <el-dialog v-model=dialogVisible width="80%">
v-model=dialogVisible
width="80%"
>
<p>{{ dialogData }}</p> <p>{{ dialogData }}</p>
<template #footer> <template #footer>
<div class="dialog-footer"> <div class="dialog-footer">
...@@ -858,66 +872,56 @@ const onDeleteOne = (item: any) => { ...@@ -858,66 +872,56 @@ const onDeleteOne = (item: any) => {
<!-- 生成视频 --> <!-- 生成视频 -->
<el-form-item label="设置"> <el-form-item label="设置">
<span style="margin: 0 20px">TTS语速:</span> <span style="margin: 0 20px">TTS语速:</span>
<el-slider v-model="voice_rate" show-input :min="-50" :max="50" :marks="default_data.marks" style="width: 900px" /> <el-slider v-model="voice_rate" show-input :min="-50" :max="50" :marks="default_data.marks"
style="width: 900px" />
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<span style="margin: 0 20px">TTS音量:</span> <span style="margin: 0 20px">TTS音量:</span>
<el-slider v-model="voice_volume" show-input :min="-80" :max="80" :marks="default_data.marks" style="width: 900px" /> <el-slider v-model="voice_volume" show-input :min="-80" :max="80" :marks="default_data.marks"
style="width: 900px" />
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<span style="margin: 20px 20px 0 20px">TTS语音:</span> <span style="margin: 20px 20px 0 20px">TTS语音:</span>
<el-select v-model="voice" placeholder="Select" style="width: 400px; margin-top: 20px;"> <el-select v-model="voice" placeholder="Select" style="width: 400px; margin-top: 20px;">
<el-option <el-option v-for="item in default_data.voices" :key="item.value" :label="item.value" :value="item.value">
v-for="item in default_data.voices"
:key="item.value"
:label="item.value"
:value="item.value"
>
<span style="float: left">{{ item.value }}</span> <span style="float: left">{{ item.value }}</span>
<span <span style="
style="
float: right; float: right;
color: var(--el-text-color-secondary); color: var(--el-text-color-secondary);
font-size: 13px; font-size: 13px;
" ">{{ item.label }}</span>
>{{ item.label }}</span>
</el-option> </el-option>
</el-select> </el-select>
<audio :src="'src/assets/edge-tts-voices/' + voice + '.mp3'" controls style="height: 30px; margin: 20px 0 0 10px;"></audio> <audio :src="'src/assets/edge-tts-voices/' + voice + '.mp3'" controls
style="height: 30px; margin: 20px 0 0 10px;"></audio>
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<span style="margin: 0 20px">背景音乐:</span> <span style="margin: 0 20px">背景音乐:</span>
<el-select v-model="bgm" placeholder="无" style="width: 400px;"> <el-select v-model="bgm" placeholder="无" style="width: 400px;">
<el-option <el-option v-for="item in default_data.bgm" :key="item.value" :label="item.value" :value="item.value">
v-for="item in default_data.bgm"
:key="item.value"
:label="item.value"
:value="item.value"
>
<span style="float: left">{{ item.label }}</span> <span style="float: left">{{ item.label }}</span>
<span <span style="
style="
float: right; float: right;
color: var(--el-text-color-secondary); color: var(--el-text-color-secondary);
font-size: 13px; font-size: 13px;
" ">{{ item.value }}</span>
>{{ item.value }}</span>
</el-option> </el-option>
</el-select> </el-select>
<audio :src="'src/assets/bgm/' + bgm + '.mp3'" controls style="height: 30px; margin-left:10px;"></audio> <audio :src="'src/assets/bgm/' + bgm + '.mp3'" controls style="height: 30px; margin-left:10px;"></audio>
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<span style="margin: 0 20px">背景音量:</span> <span style="margin: 0 20px">背景音量:</span>
<el-slider v-model="bgm_volume" show-input :step="0.1" :min="0" :max="2" :marks="default_data.bgm_volume_marks" style="width: 600px" /> <el-slider v-model="bgm_volume" show-input :step="0.1" :min="0" :max="2" :marks="default_data.bgm_volume_marks"
style="width: 600px" />
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<span style="margin: 20px 20px">字幕合成:</span> <span style="margin: 20px 20px">字幕合成:</span>
<el-switch v-model="form.if_need_subtitle" active-value="true" inactive-value="false"/> <el-switch v-model="form.if_need_subtitle" active-value="true" inactive-value="false" />
<div v-if="JSON.parse(form.if_need_subtitle.toLowerCase())"> <div v-if="JSON.parse(form.if_need_subtitle.toLowerCase())">
<span style="margin-left:30px;">字体颜色:</span> <span style="margin-left:30px;">字体颜色:</span>
<el-color-picker v-model="sub_font_color"/> <el-color-picker v-model="sub_font_color" />
<span style="margin-left:30px;">字体背景:</span> <span style="margin-left:30px;">字体背景:</span>
<el-color-picker v-model="sub_bg_color"/> <el-color-picker v-model="sub_bg_color" />
<span style="margin-left:30px;">字体大小:</span> <span style="margin-left:30px;">字体大小:</span>
<el-input-number v-model="sub_font_size" :min="1" :max="50" controls-position="right" /> <el-input-number v-model="sub_font_size" :min="1" :max="50" controls-position="right" />
<span style="margin-left:30px;">在屏幕上的位置:</span> <span style="margin-left:30px;">在屏幕上的位置:</span>
...@@ -932,19 +936,15 @@ const onDeleteOne = (item: any) => { ...@@ -932,19 +936,15 @@ const onDeleteOne = (item: any) => {
</el-form-item> </el-form-item>
</el-form> </el-form>
<!-- 授权密码框 --> <!-- 授权密码框 -->
<el-dialog <el-dialog v-model=pwdCheckDialogVisible title="请输入密码" width="20%" :close-on-click-modal="false"
v-model=pwdCheckDialogVisible :close-on-press-escape="false" :show-close="false">
title="请输入密码"
width="20%"
:close-on-click-modal="false"
:close-on-press-escape="false"
:show-close="false"
>
<el-form :model="form"> <el-form :model="form">
<el-form-item label="密码"> <el-form-item label="密码">
<el-input v-model="pwdCheckValue" autocomplete="off" type="password" show-password @keyup.enter="onPwdCheckDialog()" /> <el-input v-model="pwdCheckValue" autocomplete="off" type="password" show-password
@keyup.enter="onPwdCheckDialog()" />
</el-form-item> </el-form-item>
</el-form> </el-form>
<template #footer> <template #footer>
<div class="dialog-footer"> <div class="dialog-footer">
<el-button type="primary" @click="onPwdCheckDialog()">ok</el-button> <el-button type="primary" @click="onPwdCheckDialog()">ok</el-button>
......
declare namespace Wm { declare namespace Wm {
interface ImgSize {
"width": string,
"height": string,
}
interface ScriptsItem { interface ScriptsItem {
"编号": string, "编号": string,
"场景描述": string, "场景描述": string,
......
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