Commit dde1752c by haojie

文本提交没有传时长的问题

parent 802559fd
......@@ -103,6 +103,10 @@
.file-name {
font-size: @size-16;
color: #888fa1;
max-width: 100%;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.reset-submit {
width: 200px;
......
......@@ -57,7 +57,7 @@ export default defineComponent({
default: '',
},
},
emits: ['update:modelValue', 'change', 'file'],
emits: ['update:modelValue', 'change', 'file', 'firstFrame'],
setup(props, { emit }) {
const files = ref([]);
// 文件地址
......@@ -96,6 +96,7 @@ export default defineComponent({
curfile.url = '';
curfile.status = 0;
curfile.firstFrame = '';
emit('firstFrame', null);
files.value = [];
}
};
......@@ -159,6 +160,7 @@ export default defineComponent({
const UploadSuccessCallback = async (uuid: any, url: any) => {
if (props.showFirstFrame) {
let first = await getFirstFrameOfVideo(url);
emit('firstFrame', first);
curfile.firstFrame = URL.createObjectURL(first);
}
// 关闭定时器
......
......@@ -11,6 +11,7 @@ import routerConfig from '@/router/tool';
import useConfuse from '@/hooks/useConfuse';
import { callPyjsInWindow, writeLog } from '@/utils/pyqt';
import { getTestUuid } from '@/constants/token';
import { getDurationOfAudioFile } from '@/utils/audio';
// 轮询处理文本脚本语音生成回调
export const processTextCallback = () => {
......@@ -235,19 +236,19 @@ export const processTextCallback = () => {
task_id: getTaskId(isConfuse, uuid),
});
if (res.code == 0) {
if (isDev()) {
for (let i = 0; i < 1; i++) {
let params = {
data: {
audio_address:
'http://yunyi-live.oss-cn-hangzhou.aliyuncs.com/upload/1/2023-08-16fcc74a89-d3f1-4545-a17c-d155dfa7978f.wav',
task_id: 0,
id: i,
},
};
res.data.push(params);
}
}
// if (isDev()) {
// for (let i = 0; i < 1; i++) {
// let params = {
// data: {
// audio_address:
// 'http://yunyi-live.oss-cn-hangzhou.aliyuncs.com/upload/1/2023-08-16fcc74a89-d3f1-4545-a17c-d155dfa7978f.wav',
// task_id: 0,
// id: i,
// },
// };
// res.data.push(params);
// }
// }
if (res.data.length) {
// 根据id升序排列
res.data = TableSortAsc(res.data, 'data.id');
......@@ -274,13 +275,23 @@ export const processTextCallback = () => {
let resultList = await audioStart([data.audio_address], true);
// 转一维
resultList = dimensionalConvert(resultList);
let newList = resultList.map((row: any) => {
return {
let newList = [];
// 获取音频时长
for (let $j = 0; $j < resultList.length; $j++) {
let row = resultList[$j];
let duration = await getDurationOfAudioFile(row.content);
let param: any = {
content: row.content,
movement_type: list[index].movement_type,
movement_name: list[index].movement_name,
};
});
if (typeof duration === 'number') {
param.duration = parseInt(duration + '');
} else {
param.duration = 0;
}
newList.push(param);
}
// 要提交的数组
list[index].newList = newList;
commitInfo({
......
......@@ -9,6 +9,7 @@
:config="ossConfig"
:accept="videoAccept"
:uploadInfo="videoUploadInfo"
@firstFrame="firstFrame"
></Upload>
</div>
<div class="divide">+</div>
......@@ -25,21 +26,34 @@
</div>
</div>
<div class="face-transplant-footer">
<Button theme="opacity" class="face-transplant-footer-reset" @click="onReset">重置</Button>
<Button theme="green" class="face-transplant-create" @click="openDialog">生成</Button>
<div class="footer-options">
<div class="fase-hd-switch">
<span class="label">是否开启人脸高清</span>
<Switch v-model="FaceHDSwitch"></Switch>
</div>
</div>
<div class="footer-buttons">
<Button theme="opacity" class="face-transplant-footer-reset" @click="onReset">重置</Button>
<Button theme="green" class="face-transplant-create" @click="openDialog">生成</Button>
</div>
</div>
<ConfirmDialog v-model="confirmDialogVisible" title="确定生成吗?" @confirm="confirm"></ConfirmDialog>
<OptionsDialog v-model="optionsDialogVisible" :loading="loading" @submit="onSubmit"></OptionsDialog>
</div>
</template>
<script lang="tsx" setup>
import ConfirmDialog from '@/components/ConfirmDialog.vue';
import Switch from '@/components/switch';
import Button from '@/components/Button.vue';
import Upload from '@/components/upload';
import { videoAccept, imageAccept } from '@/constants/token';
import { getUploadConfig } from '@/service/Common';
import { onMounted, ref } from 'vue';
import { show_message } from '@/utils/tool';
import { alyOssUpload, show_message } from '@/utils/tool';
import OptionsDialog from './optionsDialog.vue';
import { createChangeFaseTask } from '@/utils/api/userApi';
import { v4 } from 'uuid';
const emit = defineEmits(['restart']);
const videoUploadInfo = {
label1: '选择需要换脸的视频',
......@@ -58,18 +72,49 @@ const imageUploadInfo = {
};
const ossConfig = ref({});
// 弹窗状态
const confirmDialogVisible = ref(false);
// 选项弹窗状态
const optionsDialogVisible = ref(false);
const loading = ref(false);
// 视频文件
const videoFile = ref('');
// 视频第一帧
const videoFrame = ref();
// 上传后的视频第一帧
const uploadVideoFrame = ref('');
// 图片文件
const imageFile = ref('');
// 人脸高清
const FaceHDSwitch = ref(true);
const getConfig = async () => {
ossConfig.value = await getUploadConfig();
};
// 视频第一帧改变
const firstFrame = (file: Blob) => {
videoFrame.value = file;
};
const uploadSuccess = (name: string, url: string) => {
uploadVideoFrame.value = url;
};
// 视频第一帧上传到阿里云
const uploadImage = async () => {
try {
await getConfig();
let uuid = v4();
const res: any = await alyOssUpload(ossConfig.value, videoFrame.value, uploadSuccess, () => '', uuid);
if (res.status == 'success') {
return true;
}
return false;
} catch (e) {
console.log(e);
return false;
}
};
const openDialog = () => {
if (!videoFile.value) {
show_message('视频必传');
......@@ -79,21 +124,50 @@ const openDialog = () => {
show_message('图片必传');
return;
}
confirmDialogVisible.value = true;
optionsDialogVisible.value = true;
};
// 重置
const onReset = () => {
videoFile.value = '';
imageFile.value = '';
FaceHDSwitch.value = true;
uploadVideoFrame.value = '';
videoFrame.value = null;
};
// 确定生成
const confirm = async () => {
const onSubmit = async (params: any) => {
try {
console.log(videoFile.value);
console.log(imageFile.value);
loading.value = true;
if (videoFrame.value) {
// 视频第一帧上传到阿里云
const status = await uploadImage();
if (!status) {
show_message('上传失败');
return;
}
}
const res: any = await createChangeFaseTask({
name: params.title,
cover: uploadVideoFrame.value,
extend: {
source: imageFile.value,
target: videoFile.value,
face_enhancer: FaceHDSwitch.value,
},
});
if (res.code == 0) {
show_message('提交成功,请等待', 'success');
// 刷新记录
emit('restart');
loading.value = false;
optionsDialogVisible.value = false;
onReset();
}
loading.value = false;
} catch (e) {
loading.value = false;
console.log(e);
}
};
......@@ -153,20 +227,34 @@ onMounted(() => {
height: 60px;
border-top: 1px solid #9f9f9f;
display: flex;
justify-content: flex-end;
justify-content: space-between;
align-items: center;
padding: 0 20px;
.t-button {
font-weight: 700;
font-size: @size-14;
width: 76px;
}
.face-transplant-footer-reset {
color: #9f9f9f;
border-color: #9f9f9f;
.footer-options {
.fase-hd-switch {
display: flex;
align-items: center;
.label {
font-size: @size-16;
color: white;
font-weight: 400;
margin-right: 12px;
}
}
}
.face-transplant-create {
margin-left: 20px;
.footer-buttons {
.t-button {
font-weight: 700;
font-size: @size-14;
width: 76px;
}
.face-transplant-footer-reset {
color: #9f9f9f;
border-color: #9f9f9f;
}
.face-transplant-create {
margin-left: 20px;
}
}
}
}
......
<template>
<Dialog v-model="visible" className="face-transplant-options-dialog" @confirm="onConfirm">
<template #header> 智能换脸 </template>
<template #body>
<div>
<FormItem label="视频名称">
<Input v-model="videoName" align="left" placeholder="请输入视频名称"></Input>
</FormItem>
</div>
</template>
<ConfirmDialog
v-model="confirmDialogVisible"
:zIndex="3000"
title="确定生成吗?"
@confirm="confirmCreate"
></ConfirmDialog>
<Loading v-show="loading" :mask="true"></Loading>
</Dialog>
</template>
<script lang="ts" setup>
import { computed, ref } from 'vue';
import Dialog from '@/components/Dialog.vue';
import FormItem from '@/componentsUsiness/formItem.vue';
import Input from '@/components/input/index.vue';
import { show_message } from '@/utils/tool';
import ConfirmDialog from '@/components/ConfirmDialog.vue';
import Loading from '@/components/loading.vue';
const props = withDefaults(
defineProps<{
modelValue: boolean;
loading: boolean;
}>(),
{},
);
const emit = defineEmits(['update:modelValue', 'submit']);
// 确认弹窗状态
const confirmDialogVisible = ref(false);
const visible = computed({
get() {
return props.modelValue;
},
set(value) {
emit('update:modelValue', value);
},
});
// 视频名称
const videoName = ref('');
const onConfirm = () => {
if (!videoName.value) {
show_message('请输入视频名称');
return;
}
confirmDialogVisible.value = true;
};
// 确定生成
const confirmCreate = () => {
// 提交
emit('submit', {
title: videoName.value,
});
};
</script>
<style lang="less">
.face-transplant-options-dialog {
.t-dialog {
position: relative;
.t-dialog__body {
padding: 30px 0 !important;
.custom-usiness-form-item {
align-items: center;
}
}
}
}
</style>
......@@ -6,7 +6,7 @@
<template v-else-if="list.length">
<div class="record-items" v-for="item in list" :key="item.id">
<div class="left">
<img :src="item.cover_url" alt="" />
<img :src="item.cover" alt="" />
</div>
<div class="center">
<div class="name">
......@@ -20,17 +20,36 @@
<div class="download-box">
<Button
theme="green"
:class="['download-button', item.audit_status != 3 ? 'download-button__disabled' : '']"
:class="['download-button', item.status != 1 || !item.url ? 'download-button__disabled' : '']"
@click="onDownloadVideo(item)"
>下载</Button
>
</div>
</div>
<CustomizationStatus :status="item.audit_status">
<template #progressTip>
<div class="progress-tips">{{ tipsLabel }}</div>
<div class="customization-status-face">
<!-- 成功 -->
<template v-if="item.status == 1">
<div class="status">
<img :src="imgs.success" />
<div>{{ item.status_label }}</div>
</div>
</template>
</CustomizationStatus>
<!-- 等待 -->
<template v-else-if="item.status == 2">
<div class="status">
<img :src="imgs.underReview" />
<div>{{ item.status_label }}</div>
</div>
</template>
<!-- 进行中 -->
<template v-else-if="item.status == 3">
<div class="status">
<img :src="imgs.progress" />
<div>{{ item.status_label }}</div>
<div class="progress-tips">{{ tipsLabel }}</div>
</div>
</template>
</div>
</div>
</template>
<template v-else>
......@@ -40,7 +59,6 @@
</template>
<script lang="tsx" setup>
import CustomizationStatus from '@/components/CustomizationStatus';
import Button from '@/components/Button.vue';
import { pyDownloadVideo } from '@/utils/pyqt';
import { show_message } from '@/utils/tool';
......@@ -57,15 +75,22 @@ withDefaults(
},
);
const imgs = {
underReview: new URL('@/assets/svg/custom/underReview.svg', import.meta.url).href,
auditFailure: new URL('@/assets/svg/custom/auditFailure.svg', import.meta.url).href,
progress: new URL('@/assets/svg/custom/progress.svg', import.meta.url).href,
success: new URL('@/assets/svg/custom/success.svg', import.meta.url).href,
};
const tipsLabel = ref('该过程需要10~24小时');
// 下载视频
const onDownloadVideo = (item: any) => {
if (item.audit_status != 3) {
if (item.status != 3) {
return;
}
// 下载item的视频
let url = item.video_url;
let url = item.url;
if (!url) {
show_message('没有视频');
return;
......@@ -133,6 +158,21 @@ const onDownloadVideo = (item: any) => {
font-size: @size-16;
}
}
.customization-status-face {
.status {
font-size: @size-18;
color: #fff;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
width: 166px;
white-space: nowrap;
& > * {
margin: 4px 0;
}
}
}
.download-box {
.download-button {
height: 28px !important;
......
<template>
<Customizable class="face-transplant-izable" :video="true" :icon="getIcon()" :label="navigationLabels.faceTransplant">
<template #header>
<Header></Header>
<Header @restart="onRestart"></Header>
</template>
<CustomTabs v-model="currentTab" theme="dark2" class="custom-tabs-flex">
<CustomTabPanel name="1" label="生成记录">
......@@ -28,7 +28,7 @@ import PersonSvg from '@/assets/svg/home/faceTransplant.svg';
import { onMounted, ref, reactive } from 'vue';
import routerConfig from '@/router/tool';
import { jumpPageAddNavigation } from '@/router/jump';
import { getDigitalPeopleList } from '@/service/Common';
import { getChangeFaseRecord } from '@/utils/api/userApi';
const { addNavigation } = jumpPageAddNavigation();
......@@ -46,10 +46,17 @@ const getIcon = () => {
// 获取我的数字人列表
const getList = async () => {
loading.value = true;
let res = await getDigitalPeopleList();
personList.list = res.myList;
loading.value = false;
try {
loading.value = true;
const res: any = await getChangeFaseRecord();
if (res.code == 0) {
personList.list = res.data.data;
}
loading.value = false;
} catch (e) {
loading.value = false;
console.log(e);
}
};
onMounted(() => {
......@@ -57,6 +64,10 @@ onMounted(() => {
// 获取数字人列表
getList();
});
const onRestart = () => {
getList();
};
</script>
<style lang="less">
......
......@@ -518,3 +518,24 @@ export const randomLiveReply = () => {
},
});
};
// 创建换脸任务
export const createChangeFaseTask = (data: any) => {
const header = getHeader();
return request.post(`/api/face`, data, {
headers: {
...header,
},
});
};
// 换脸记录
export const getChangeFaseRecord = () => {
const header = getHeader();
return request.get(`/api/face`, {
params: {},
headers: {
...header,
},
});
};
......@@ -8,7 +8,7 @@ const error_messaage = '请求错误';
const getBaseUrl = async () => {
if (isDev()) {
// return 'http://156.247.11.21:93';
return 'http://156.247.11.21:93';
return '';
}
// 默认线上地址
......
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