|
@@ -99,9 +99,10 @@ |
|
|
v-for="item in AiFaceList" |
|
|
v-for="item in AiFaceList" |
|
|
:key="item.id" |
|
|
:key="item.id" |
|
|
> |
|
|
> |
|
|
<!-- <div class="img"></div> --> |
|
|
|
|
|
<img :src="item.material" alt="" /> |
|
|
|
|
|
<p>{{ item.title }}</p> |
|
|
|
|
|
|
|
|
<div class="imgBox"> |
|
|
|
|
|
<img :src="item.material" alt="" /> |
|
|
|
|
|
</div> |
|
|
|
|
|
s |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
@@ -131,7 +132,9 @@ |
|
|
<div @click="insertIcon">🕗</div> |
|
|
<div @click="insertIcon">🕗</div> |
|
|
</div> |
|
|
</div> |
|
|
<p>{{ $t("createVideo.languages") }}</p> |
|
|
<p>{{ $t("createVideo.languages") }}</p> |
|
|
|
|
|
<!-- 语言 --> |
|
|
<el-select |
|
|
<el-select |
|
|
|
|
|
@change="chooseType" |
|
|
v-model="language" |
|
|
v-model="language" |
|
|
placeholder="Select" |
|
|
placeholder="Select" |
|
|
style="width: 100%" |
|
|
style="width: 100%" |
|
@@ -139,34 +142,50 @@ |
|
|
<el-option |
|
|
<el-option |
|
|
v-for="item in languageOptions" |
|
|
v-for="item in languageOptions" |
|
|
:key="item.value" |
|
|
:key="item.value" |
|
|
:label="item.label" |
|
|
|
|
|
:value="item.value" |
|
|
|
|
|
/> |
|
|
|
|
|
|
|
|
:label="item.name" |
|
|
|
|
|
:value="item.id" |
|
|
|
|
|
> |
|
|
|
|
|
<img |
|
|
|
|
|
:src="item.img" |
|
|
|
|
|
alt="" |
|
|
|
|
|
style=" |
|
|
|
|
|
width: 20px; |
|
|
|
|
|
margin-right: 10px; |
|
|
|
|
|
vertical-align: text-top; |
|
|
|
|
|
" |
|
|
|
|
|
/> |
|
|
|
|
|
<span style="line-height: 20px">{{ item.name }}</span> |
|
|
|
|
|
</el-option> |
|
|
</el-select> |
|
|
</el-select> |
|
|
<p>{{ $t("createVideo.voices") }}</p> |
|
|
<p>{{ $t("createVideo.voices") }}</p> |
|
|
|
|
|
<!-- 声音 --> |
|
|
<el-select |
|
|
<el-select |
|
|
v-model="language" |
|
|
|
|
|
placeholder="Select" |
|
|
|
|
|
|
|
|
@change="chooseStyle" |
|
|
|
|
|
:disabled="language ? false : true" |
|
|
|
|
|
v-model="sound" |
|
|
|
|
|
:placeholder="language ? 'Select' : 'Please select language'" |
|
|
style="width: 100%" |
|
|
style="width: 100%" |
|
|
> |
|
|
> |
|
|
<el-option |
|
|
<el-option |
|
|
v-for="item in soundOptions" |
|
|
v-for="item in soundOptions" |
|
|
:key="item.value" |
|
|
:key="item.value" |
|
|
:label="item.label" |
|
|
|
|
|
:value="item.value" |
|
|
|
|
|
|
|
|
:label="item.displayName" |
|
|
|
|
|
:value="item.id" |
|
|
/> |
|
|
/> |
|
|
</el-select> |
|
|
</el-select> |
|
|
<p>{{ $t("createVideo.styles") }}</p> |
|
|
<p>{{ $t("createVideo.styles") }}</p> |
|
|
|
|
|
<!-- 风格 --> |
|
|
<el-select |
|
|
<el-select |
|
|
v-model="language" |
|
|
|
|
|
placeholder="Select" |
|
|
|
|
|
|
|
|
:disabled="soundStyleOptions ? false : true" |
|
|
|
|
|
v-model="soundStyle" |
|
|
|
|
|
:placeholder="soundStyleOptions ? 'Select' : '暂无数据'" |
|
|
style="width: 100%" |
|
|
style="width: 100%" |
|
|
> |
|
|
> |
|
|
<el-option |
|
|
<el-option |
|
|
v-for="item in soundStyleOptions" |
|
|
v-for="item in soundStyleOptions" |
|
|
:key="item.value" |
|
|
|
|
|
:label="item.label" |
|
|
|
|
|
:value="item.value" |
|
|
|
|
|
|
|
|
:key="item" |
|
|
|
|
|
:label="item" |
|
|
|
|
|
:value="item" |
|
|
/> |
|
|
/> |
|
|
</el-select> |
|
|
</el-select> |
|
|
<el-button color="#000" type="primary">{{ |
|
|
<el-button color="#000" type="primary">{{ |
|
@@ -184,8 +203,14 @@ |
|
|
</p> |
|
|
</p> |
|
|
<div class="uploadVideo"> |
|
|
<div class="uploadVideo"> |
|
|
+ |
|
|
+ |
|
|
<input type="file" ref="fileInput" @change="handleFileChange" /> |
|
|
|
|
|
|
|
|
<input |
|
|
|
|
|
type="file" |
|
|
|
|
|
ref="fileInput" |
|
|
|
|
|
@click="e.target.value = null" |
|
|
|
|
|
@change="handleFileChange" |
|
|
|
|
|
/> |
|
|
<video |
|
|
<video |
|
|
|
|
|
style="position: absolute; top: 0" |
|
|
v-if="videoSrc" |
|
|
v-if="videoSrc" |
|
|
:src="videoSrc" |
|
|
:src="videoSrc" |
|
|
ref="videoPlayer" |
|
|
ref="videoPlayer" |
|
@@ -305,6 +330,9 @@ import { |
|
|
awsImgUpload, |
|
|
awsImgUpload, |
|
|
videoUpload, |
|
|
videoUpload, |
|
|
saveImgApi, |
|
|
saveImgApi, |
|
|
|
|
|
uploadProgressApi, |
|
|
|
|
|
voiceTotalApi, |
|
|
|
|
|
chooseTypeApi, |
|
|
} from "@/apis/createVideo"; |
|
|
} from "@/apis/createVideo"; |
|
|
import Recorder from "js-audio-recorder"; //mp3插件 |
|
|
import Recorder from "js-audio-recorder"; //mp3插件 |
|
|
import imageCompression from "browser-image-compression"; //压缩图片插件 |
|
|
import imageCompression from "browser-image-compression"; //压缩图片插件 |
|
@@ -313,9 +341,9 @@ import imageCompression from "browser-image-compression"; //压缩图片插件 |
|
|
// 获取AI头像 |
|
|
// 获取AI头像 |
|
|
const AiFaceList = ref([]); |
|
|
const AiFaceList = ref([]); |
|
|
const feceItemLoading = ref(false); |
|
|
const feceItemLoading = ref(false); |
|
|
function getAiFaceList(pageNum, pageSize) { |
|
|
|
|
|
|
|
|
function getAiFaceList(pageNum, pageSize, sendType) { |
|
|
feceItemLoading.value = true; |
|
|
feceItemLoading.value = true; |
|
|
personPhotoList(pageNum, pageSize) |
|
|
|
|
|
|
|
|
personPhotoList(pageNum, pageSize, sendType) |
|
|
.then((res) => { |
|
|
.then((res) => { |
|
|
AiFaceList.value = res.data.list; |
|
|
AiFaceList.value = res.data.list; |
|
|
feceItemLoading.value = false; |
|
|
feceItemLoading.value = false; |
|
@@ -328,6 +356,12 @@ function getAiFaceList(pageNum, pageSize) { |
|
|
// 选择显示的face列表 |
|
|
// 选择显示的face列表 |
|
|
const showFace = ref("0"); |
|
|
const showFace = ref("0"); |
|
|
function ChangeShowFaceList(index) { |
|
|
function ChangeShowFaceList(index) { |
|
|
|
|
|
if (index == 0) { |
|
|
|
|
|
getAiFaceList(1, 100, 1); |
|
|
|
|
|
} |
|
|
|
|
|
if (index == 1) { |
|
|
|
|
|
getAiFaceList(1, 100, 3); |
|
|
|
|
|
} |
|
|
showFace.value = index; |
|
|
showFace.value = index; |
|
|
} |
|
|
} |
|
|
const faceItemActive = ref(); //高亮处理 |
|
|
const faceItemActive = ref(); //高亮处理 |
|
@@ -409,40 +443,39 @@ function insertIcon() { |
|
|
textarea.setSelectionRange(newCursorPos, newCursorPos); |
|
|
textarea.setSelectionRange(newCursorPos, newCursorPos); |
|
|
textarea.focus(); |
|
|
textarea.focus(); |
|
|
} |
|
|
} |
|
|
const language = ref(""); |
|
|
|
|
|
const sound = ref(""); |
|
|
|
|
|
const soundStyle = ref(""); |
|
|
|
|
|
|
|
|
|
|
|
const languageOptions = reactive([ |
|
|
|
|
|
|
|
|
const language = ref(""); //选择的语言 |
|
|
|
|
|
const sound = ref(""); // 选择的声音 |
|
|
|
|
|
const soundStyle = ref(""); //选择的风格 |
|
|
|
|
|
// 语言下拉框内容 |
|
|
|
|
|
const languageOptions = ref([ |
|
|
{ |
|
|
{ |
|
|
value: "0", |
|
|
|
|
|
label: "中文", |
|
|
|
|
|
|
|
|
id: "0", |
|
|
|
|
|
name: "中文", |
|
|
}, |
|
|
}, |
|
|
{ |
|
|
{ |
|
|
value: "1", |
|
|
|
|
|
label: "English", |
|
|
|
|
|
}, |
|
|
|
|
|
]); |
|
|
|
|
|
const soundOptions = reactive([ |
|
|
|
|
|
{ |
|
|
|
|
|
value: "0", |
|
|
|
|
|
label: "老人", |
|
|
|
|
|
}, |
|
|
|
|
|
{ |
|
|
|
|
|
value: "1", |
|
|
|
|
|
label: "小孩", |
|
|
|
|
|
}, |
|
|
|
|
|
]); |
|
|
|
|
|
const soundStyleOptions = reactive([ |
|
|
|
|
|
{ |
|
|
|
|
|
value: "0", |
|
|
|
|
|
label: "生气", |
|
|
|
|
|
}, |
|
|
|
|
|
{ |
|
|
|
|
|
value: "1", |
|
|
|
|
|
label: "抑郁", |
|
|
|
|
|
|
|
|
id: "1", |
|
|
|
|
|
name: "English", |
|
|
}, |
|
|
}, |
|
|
]); |
|
|
]); |
|
|
|
|
|
async function voiceTotal() { |
|
|
|
|
|
const res = await voiceTotalApi(); |
|
|
|
|
|
languageOptions.value = res.data; |
|
|
|
|
|
} |
|
|
|
|
|
// 声音下拉框内容 |
|
|
|
|
|
const soundOptions = ref([]); |
|
|
|
|
|
async function chooseType() { |
|
|
|
|
|
const res = await chooseTypeApi(language.value); |
|
|
|
|
|
soundOptions.value = res.data; |
|
|
|
|
|
sound.value = null; |
|
|
|
|
|
} |
|
|
|
|
|
// 风格下拉框内容 |
|
|
|
|
|
const soundStyleOptions = ref(null); |
|
|
|
|
|
async function chooseStyle() { |
|
|
|
|
|
const item = soundOptions.value.find((element) => element.id == sound.value); |
|
|
|
|
|
|
|
|
|
|
|
soundStyle.value = null; |
|
|
|
|
|
soundStyleOptions.value = item.style; |
|
|
|
|
|
} |
|
|
//#endregion |
|
|
//#endregion |
|
|
|
|
|
|
|
|
//#region 录制MP3上传语音 |
|
|
//#region 录制MP3上传语音 |
|
@@ -499,15 +532,48 @@ async function uploadAudio(params) { |
|
|
//#region 上传视频功能 |
|
|
//#region 上传视频功能 |
|
|
const fileInput = ref(null); |
|
|
const fileInput = ref(null); |
|
|
const videoSrc = ref(null); |
|
|
const videoSrc = ref(null); |
|
|
const handleFileChange = () => { |
|
|
|
|
|
|
|
|
// const videoId = ref(null); |
|
|
|
|
|
let intervalId = null; // 用于存储 setInterval 的返回值 |
|
|
|
|
|
const handleFileChange = async () => { |
|
|
const file = fileInput.value.files[0]; |
|
|
const file = fileInput.value.files[0]; |
|
|
if (file) { |
|
|
if (file) { |
|
|
const videoUrl = URL.createObjectURL(file); |
|
|
const videoUrl = URL.createObjectURL(file); |
|
|
videoSrc.value = videoUrl; |
|
|
videoSrc.value = videoUrl; |
|
|
|
|
|
|
|
|
|
|
|
let formData = new FormData(); |
|
|
|
|
|
const timestamp = Date.now(); |
|
|
|
|
|
formData.append("file", file, timestamp + ".mp3"); |
|
|
|
|
|
try { |
|
|
|
|
|
const res = await videoUpload(formData); |
|
|
|
|
|
// videoId.value = res.videoId; |
|
|
|
|
|
if (res) { |
|
|
|
|
|
ElMessage.success("上传成功!"); |
|
|
|
|
|
} else { |
|
|
|
|
|
ElMessage.error("上传失败!"); |
|
|
|
|
|
return; |
|
|
|
|
|
} |
|
|
|
|
|
// 查询进度 |
|
|
|
|
|
intervalId = setInterval(() => { |
|
|
|
|
|
uploadProgress(res.data.videoId); |
|
|
|
|
|
}, 1000); |
|
|
|
|
|
} catch (error) { |
|
|
|
|
|
ElMessage.error(error); |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
}; |
|
|
}; |
|
|
|
|
|
// 获取视频上传进度 |
|
|
|
|
|
async function uploadProgress(videoId) { |
|
|
|
|
|
const res = await uploadProgressApi(videoId); |
|
|
|
|
|
if (res.data == "complete") { |
|
|
|
|
|
clearInterval(intervalId); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
//#endregion -------------------------------------- |
|
|
//#endregion -------------------------------------- |
|
|
|
|
|
|
|
|
|
|
|
//#region 获取语言列表 |
|
|
|
|
|
|
|
|
|
|
|
//#endregion ---------------------------- |
|
|
|
|
|
|
|
|
// $t在script中的使用 |
|
|
// $t在script中的使用 |
|
|
const { |
|
|
const { |
|
|
appContext: { |
|
|
appContext: { |
|
@@ -519,7 +585,9 @@ const string = "createVideo.typeScript"; |
|
|
const t = globalProperties.$t(string); |
|
|
const t = globalProperties.$t(string); |
|
|
|
|
|
|
|
|
onMounted(() => { |
|
|
onMounted(() => { |
|
|
getAiFaceList(1, 100); |
|
|
|
|
|
|
|
|
getAiFaceList(1, 100, 1); |
|
|
|
|
|
voiceTotal(); |
|
|
|
|
|
chooseType(); |
|
|
}); |
|
|
}); |
|
|
</script> |
|
|
</script> |
|
|
|
|
|
|
|
@@ -555,7 +623,7 @@ onMounted(() => { |
|
|
position: relative; |
|
|
position: relative; |
|
|
width: 100%; |
|
|
width: 100%; |
|
|
// height: 65%; |
|
|
// height: 65%; |
|
|
height: 600px; |
|
|
|
|
|
|
|
|
height: 580px; |
|
|
|
|
|
|
|
|
.uploadBtn { |
|
|
.uploadBtn { |
|
|
position: relative; |
|
|
position: relative; |
|
@@ -683,34 +751,43 @@ onMounted(() => { |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
.faceList { |
|
|
.faceList { |
|
|
padding: 3px; |
|
|
|
|
|
|
|
|
padding: 8px; |
|
|
display: flex; |
|
|
display: flex; |
|
|
flex-wrap: wrap; |
|
|
flex-wrap: wrap; |
|
|
justify-content: flex-start; |
|
|
justify-content: flex-start; |
|
|
width: 100%; |
|
|
width: 100%; |
|
|
height: 160px; |
|
|
|
|
|
|
|
|
height: 180px; |
|
|
overflow-y: scroll; |
|
|
overflow-y: scroll; |
|
|
.faceItem { |
|
|
.faceItem { |
|
|
position: relative; |
|
|
position: relative; |
|
|
margin-right: 13px; |
|
|
|
|
|
margin-bottom: 10px; |
|
|
|
|
|
|
|
|
margin-right: 35px; |
|
|
|
|
|
margin-bottom: 35px; |
|
|
width: 150px; |
|
|
width: 150px; |
|
|
height: 150px; |
|
|
height: 150px; |
|
|
padding: 0 25px; |
|
|
|
|
|
|
|
|
// padding: 0 25px; |
|
|
line-height: 150px; |
|
|
line-height: 150px; |
|
|
text-align: center; |
|
|
text-align: center; |
|
|
border-radius: 50%; |
|
|
border-radius: 50%; |
|
|
background-color: #fbf8f8; |
|
|
background-color: #fbf8f8; |
|
|
border: 2px solid #fff; |
|
|
border: 2px solid #fff; |
|
|
box-shadow: rgba(0, 0, 0, 0.3) 0px 0px 3px 3px; |
|
|
|
|
|
overflow: hidden; |
|
|
|
|
|
input { |
|
|
|
|
|
|
|
|
box-shadow: rgba(0, 0, 0, 0.3) 0px 0px 5px 5px; |
|
|
|
|
|
// overflow: hidden; |
|
|
|
|
|
.imgBox { |
|
|
|
|
|
cursor: pointer; |
|
|
position: absolute; |
|
|
position: absolute; |
|
|
top: 0; |
|
|
top: 0; |
|
|
left: 0; |
|
|
left: 0; |
|
|
width: 100%; |
|
|
|
|
|
height: 100%; |
|
|
|
|
|
opacity: 0; |
|
|
|
|
|
|
|
|
right: 0; |
|
|
|
|
|
bottom: 0; |
|
|
|
|
|
z-index: 3; |
|
|
|
|
|
width: 150px; |
|
|
|
|
|
height: 150px; |
|
|
|
|
|
border-radius: 50%; |
|
|
|
|
|
background-color: #fbf8f8; |
|
|
|
|
|
overflow: hidden; |
|
|
|
|
|
img { |
|
|
|
|
|
width: 100%; |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
.uploadImg { |
|
|
.uploadImg { |
|
|
line-height: 145px; |
|
|
line-height: 145px; |
|
@@ -718,26 +795,25 @@ onMounted(() => { |
|
|
font-weight: 700; |
|
|
font-weight: 700; |
|
|
text-align: center; |
|
|
text-align: center; |
|
|
} |
|
|
} |
|
|
p { |
|
|
|
|
|
height: 30px; |
|
|
|
|
|
} |
|
|
|
|
|
img { |
|
|
|
|
|
width: 100%; |
|
|
|
|
|
} |
|
|
|
|
|
.img { |
|
|
|
|
|
width: 100px; |
|
|
|
|
|
height: 100px; |
|
|
|
|
|
border-radius: 50%; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
} |
|
|
.faceItemActive { |
|
|
.faceItemActive { |
|
|
background: linear-gradient( |
|
|
|
|
|
270deg, |
|
|
|
|
|
rgb(201, 113, 255) 24.97%, |
|
|
|
|
|
rgb(92, 121, 252) 100% |
|
|
|
|
|
); |
|
|
|
|
|
// border: 2px solid #fff; |
|
|
|
|
|
// box-shadow: rgba(0, 0, 0, 0.3) 0px 0px 3px 3px; |
|
|
|
|
|
|
|
|
position: relative; |
|
|
|
|
|
transition: all 0.3s; |
|
|
|
|
|
&::before { |
|
|
|
|
|
content: ""; |
|
|
|
|
|
position: absolute; |
|
|
|
|
|
top: -3px; |
|
|
|
|
|
right: -7px; |
|
|
|
|
|
left: -3px; |
|
|
|
|
|
bottom: -7px; |
|
|
|
|
|
z-index: 2; |
|
|
|
|
|
border-radius: 50%; |
|
|
|
|
|
background: linear-gradient( |
|
|
|
|
|
225deg, |
|
|
|
|
|
rgb(81 217 202 / 100%), |
|
|
|
|
|
rgb(114 100 245 / 100%) |
|
|
|
|
|
); |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
@@ -838,7 +914,6 @@ onMounted(() => { |
|
|
} |
|
|
} |
|
|
.uploadVideo { |
|
|
.uploadVideo { |
|
|
text-align: center; |
|
|
text-align: center; |
|
|
|
|
|
|
|
|
margin-bottom: 20px; |
|
|
margin-bottom: 20px; |
|
|
height: 100px; |
|
|
height: 100px; |
|
|
font-size: 50px; |
|
|
font-size: 50px; |
|
@@ -846,11 +921,17 @@ onMounted(() => { |
|
|
line-height: 100px; |
|
|
line-height: 100px; |
|
|
input { |
|
|
input { |
|
|
position: absolute; |
|
|
position: absolute; |
|
|
|
|
|
top: 0; |
|
|
|
|
|
left: 0; |
|
|
width: 100%; |
|
|
width: 100%; |
|
|
height: 100%; |
|
|
height: 100%; |
|
|
opacity: 0; |
|
|
opacity: 0; |
|
|
} |
|
|
} |
|
|
video { |
|
|
video { |
|
|
|
|
|
position: absolute; |
|
|
|
|
|
top: 0; |
|
|
|
|
|
left: 0; |
|
|
|
|
|
z-index: -1; |
|
|
width: 100%; |
|
|
width: 100%; |
|
|
height: 100%; |
|
|
height: 100%; |
|
|
} |
|
|
} |
|
|