Browse Source

1

dev_YWQ
congzc 2 years ago
parent
commit
fa80517283
5 changed files with 235 additions and 67 deletions
  1. +2
    -1
      package.json
  2. +2
    -0
      src/types/components.d.ts
  3. +170
    -61
      src/views/createVideo/index.vue
  4. +49
    -5
      src/views/myAccount/index.vue
  5. +12
    -0
      yarn.lock

+ 2
- 1
package.json View File

@@ -18,6 +18,7 @@
"@wangeditor/editor": "^5.0.0",
"@wangeditor/editor-for-vue": "^5.1.10",
"axios": "^1.3.4",
"browser-image-compression": "^2.0.2",
"echarts": "^5.2.2",
"element-plus": "^2.3.1",
"js-audio-recorder": "^1.0.7",
@@ -72,4 +73,4 @@
"repository": "https://gitee.com/youlaiorg/vue3-element-admin.git",
"author": "有来开源组织",
"license": "MIT"
}
}

+ 2
- 0
src/types/components.d.ts View File

@@ -39,8 +39,10 @@ declare module '@vue/runtime-core' {
IEpEdit: typeof import('~icons/ep/edit')['default']
IEpGoods: typeof import('~icons/ep/goods')['default']
IEpMenu: typeof import('~icons/ep/menu')['default']
IEpMic: typeof import('~icons/ep/mic')['default']
IEpSearch: typeof import('~icons/ep/search')['default']
IEpSetting: typeof import('~icons/ep/setting')['default']
IEpVideoCamera: typeof import('~icons/ep/video-camera')['default']
IEpVideoPlay: typeof import('~icons/ep/video-play')['default']
LangSelect: typeof import('./../components/LangSelect/index.vue')['default']
MultiUpload: typeof import('./../components/Upload/MultiUpload.vue')['default']


+ 170
- 61
src/views/createVideo/index.vue View File

@@ -15,10 +15,15 @@
<el-icon class="icon-edit"><i-ep-edit /></el-icon>
</div>
<!-- 上传按钮 -->
<div class="btnBox">
<div class="btnBox" v-show="submitImgBtn">
<button class="uploadBtn">
{{ $t("createVideo.reselect") }}
<input type="file" @change="lookImg" />
<input
accept="image/*"
type="file"
@click="e.target.value = null"
@change="lookImg"
/>
</button>
<button class="uploadBtn" @click="changeFile">
{{ $t("createVideo.sureUpload") }}
@@ -39,17 +44,12 @@
</div>
<div class="upload inmiddle">
+
<input type="file" @change="lookImg" />
<!-- <el-upload
class="el-upload"
v-model="fileList"
multiple
:on-preview="handlePreview"
:on-remove="handleRemove"
:before-remove="beforeRemove"
:limit="3"
:on-exceed="handleExceed"
/> -->
<input
accept="image/*"
type="file"
@click="e.target.value = null"
@change="lookImg"
/>
</div>
<div class="falseImg inmiddle">
<div><div class="icon">×</div></div>
@@ -89,8 +89,9 @@
<my-loading :isLoading="feceItemLoading"></my-loading>
<!-- face列表 -->
<div
:class="faceItemActive == item.id ? 'faceItemActive' : ''"
class="faceItem pointer"
@click="setImgUrl(item.material)"
@click="setImgUrl(item.material, item.id)"
v-for="item in AiFaceList"
:key="item.id"
>
@@ -115,15 +116,15 @@
<el-button type="primary">
{{ $t("createVideo.confirm") }}
</el-button>
<!-- 文本域 -->
<el-input
v-model="title"
id="textInputId"
v-model="textareaContent"
:rows="15"
type="textarea"
:placeholder="$t('createVideo.aiText')"
/>
<el-icon :size="20">
<Edit />
</el-icon>
<div @click="insertIcon">🕗</div>
</div>
<p>{{ $t("createVideo.languages") }}</p>
<el-select
@@ -145,7 +146,7 @@
style="width: 100%"
>
<el-option
v-for="item in languageOptions"
v-for="item in soundOptions"
:key="item.value"
:label="item.label"
:value="item.value"
@@ -158,13 +159,13 @@
style="width: 100%"
>
<el-option
v-for="item in languageOptions"
v-for="item in soundStyleOptions"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
<el-button type="primary">{{
<el-button color="#000" type="primary">{{
$t("createVideo.generateVideo")
}}</el-button>
</div>
@@ -172,7 +173,26 @@
<!-- ------------------------ 2 -->
<el-tab-pane :label="$t('createVideo.uploadAudio')">
<div class="card2">
<!-- 上传视频 -->
<p>
<el-icon class="icon-VideoCamera"><i-ep-VideoCamera /></el-icon>
上传视频
</p>
<div class="uploadVideo">
+
<input type="file" ref="fileInput" @change="handleFileChange" />
<video
v-if="videoSrc"
:src="videoSrc"
ref="videoPlayer"
controls
></video>
</div>
<!-- 录制MP3上传语音 -->
<p>
<el-icon class="icon-Mic"><i-ep-Mic /></el-icon>
录制音频
</p>
<div
class="uploadAudio"
:class="audioUrl ? 'uploadAudioAvtion' : ''"
@@ -199,20 +219,9 @@
上传音频
</button>
</div>
<!-- 上传视频 -->
<div
class="uploadVideo"
style="text-align: center; line-height: 70px"
>
上传视频
<input type="file" ref="fileInput" @change="handleFileChange" />
<video
v-if="videoSrc"
:src="videoSrc"
ref="videoPlayer"
controls
></video>
</div>
<el-button color="#000" type="primary">{{
$t("createVideo.generateVideo")
}}</el-button>
</div>
</el-tab-pane>
<!-- ----------------------- 3 -->
@@ -287,13 +296,14 @@

<script setup>
import { getCurrentInstance } from "vue";
import Recorder from "js-audio-recorder";
import {
personPhotoList,
awsImgUpload,
videoUpload,
saveImgApi,
} from "@/apis/createVideo";
import Recorder from "js-audio-recorder"; //mp3插件
import imageCompression from "browser-image-compression"; //压缩图片插件

// 获取AI头像
const AiFaceList = ref([]);
@@ -319,14 +329,27 @@ function ChangeShowFaceList(index) {
const title = ref("");

// 上传图片
const imgUrl = ref("");
const imgData = ref("");
const showUploadBtn = ref(false);
const imgUrl = ref(""); //图片回显路径
const imgData = ref(""); // 上传图片文件
const showUploadBtn = ref(false); //上传图片+号的显示隐藏
const submitImgBtn = ref(false); //右上角俩按钮显示与隐藏

// 预览图片
function lookImg(e) {
imgUrl.value = URL.createObjectURL(e.target.files[0]);
imgData.value = e.target.files[0];
async function lookImg(e) {
// imgUrl.value = URL.createObjectURL(e.target.files[0]);
// imgData.value = e.target.files[0];
// showUploadBtn.value = false;
// submitImgBtn.value = true;
// 压缩配置
const options = {
maxSizeMB: 2, // 最大压缩大小为 1MB
useWebWorker: true, // 使用 Web Worker 进行压缩,提高性能
};
const compressedFile = await imageCompression(e.target.files[0], options);
imgUrl.value = URL.createObjectURL(compressedFile);
imgData.value = compressedFile;
showUploadBtn.value = false;
submitImgBtn.value = true;
}
// 上传图片
async function changeFile() {
@@ -346,14 +369,75 @@ async function changeFile() {
ElMessage.error(error);
}
}
const faceItemActive = ref();
// 点击aifece
function setImgUrl(url) {
function setImgUrl(url, id) {
faceItemActive.value = id;
showUploadBtn.value = false;
submitImgBtn.value = false;
imgUrl.value = url;
}

// 录制MP3上传语音
//#region card1的逻辑
const textareaContent = ref("");
function insertIcon() {
const textarea = document.getElementById("textInputId");
const icon = "🕗"; // 这里使用了一个星星作为示例图标,你可以替换为你自己的图标

// 获取光标位置
const startPos = textarea.selectionStart;
const endPos = textarea.selectionEnd;

console.log(startPos);
console.log(endPos);
// 在光标位置插入图标
textareaContent.value =
textareaContent.value.substring(0, startPos) +
icon +
textareaContent.value.substring(endPos, textareaContent.value.length);

// 设置光标位置为插入图标后的位置
const newCursorPos = startPos + icon.length;
textarea.setSelectionRange(newCursorPos, newCursorPos);
textarea.focus();
}
const language = ref("");
const sound = ref("");
const soundStyle = ref("");

const languageOptions = reactive([
{
value: "0",
label: "中文",
},
{
value: "1",
label: "English",
},
]);
const soundOptions = reactive([
{
value: "0",
label: "老人",
},
{
value: "1",
label: "小孩",
},
]);
const soundStyleOptions = reactive([
{
value: "0",
label: "生气",
},
{
value: "1",
label: "抑郁",
},
]);
//#endregion

//#region 录制MP3上传语音
const parameter = {
sampleBits: 16, // 采样位数,支持 8 或 16,默认是16
sampleRate: 8000, // 采样率,支持 11025、16000、22050、24000、44100、48000,根据浏览器默认值,我的chrome是48000
@@ -402,8 +486,9 @@ async function uploadAudio(params) {
ElMessage.error(error);
}
}
//#endregion ------------------------------------

// 上传视频功能
//#region 上传视频功能
const fileInput = ref(null);
const videoSrc = ref(null);
const handleFileChange = () => {
@@ -413,20 +498,11 @@ const handleFileChange = () => {
videoSrc.value = videoUrl;
}
};
//#endregion --------------------------------------

// card3的
let language = ref("");
//#region card3的

let languageOptions = reactive([
{
value: "Option1",
label: "Option1",
},
{
value: "Option2",
label: "Option2",
},
]);
//#endregion ---------------------------

// $t在script中的使用
const {
@@ -603,6 +679,7 @@ onMounted(() => {
}

.faceList {
padding: 3px;
display: flex;
flex-wrap: wrap;
justify-content: flex-start;
@@ -611,7 +688,7 @@ onMounted(() => {
overflow-y: scroll;
.faceItem {
position: relative;
margin-right: 10px;
margin-right: 13px;
margin-bottom: 10px;
width: 150px;
height: 150px;
@@ -619,7 +696,9 @@ onMounted(() => {
line-height: 150px;
text-align: center;
border-radius: 50%;
border: 2px solid #000;
background-color: #fbf8f8;
border: 2px solid #fff;
box-shadow: rgba(0, 0, 0, 0.3) 0px 0px 3px 3px;
overflow: hidden;
input {
position: absolute;
@@ -647,6 +726,15 @@ onMounted(() => {
border-radius: 50%;
}
}
.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;
}
}
}
}
@@ -667,7 +755,6 @@ onMounted(() => {
.text {
padding: 10px;
border: 1px solid #000;

.el-button {
float: right;
margin-top: 10px;
@@ -688,9 +775,18 @@ onMounted(() => {
height: 50px;
margin-top: 10px;
}

:deep(.el-input .is-focus) {
// box-shadow: none !important;
// box-shadow: 0 0 0 1px #000 !important;
}
}
.card2 {
padding: 10px;
.el-icon {
// color: red;
vertical-align: text-top;
}
> div {
position: relative;
margin-top: 10px;
@@ -707,6 +803,7 @@ onMounted(() => {
}
.uploadAudio {
padding: 20px;
// margin-top: 30px;
margin-bottom: 20px;
height: 70px;
.btnBox {
@@ -736,7 +833,13 @@ onMounted(() => {
height: 170px;
}
.uploadVideo {
text-align: center;

margin-bottom: 20px;
height: 100px;
font-size: 50px;
font-weight: 700;
line-height: 100px;
input {
position: absolute;
width: 100%;
@@ -748,6 +851,12 @@ onMounted(() => {
height: 100%;
}
}
> .el-button {
width: 100%;
height: 50px;
margin-top: 10px;
// background-color: #000;
}
}
.card3 {
.text {


+ 49
- 5
src/views/myAccount/index.vue View File

@@ -30,7 +30,13 @@
</div>
<!-- 邀请码 -->
<div class="left-three border flex justify-between">
<div class="codeImg"></div>
<div class="codeImg">
<img
ref="codeImgRef"
src="https://formall.oss-accelerate.aliyuncs.com/1003/dongzhanxiziguoji.png"
alt=""
/>
</div>
<div class="other">
<div v-if="currentLan == 'en'">
<span>Invite friends to get</span>
@@ -43,11 +49,19 @@
<span>邀请更多好友</span>
<span class="bigWord">免费</span>
<span>生成视频!</span>
<p>
邀请码:
<span id="InviteCodeId">qweiuqkljzxcahdouiahsd</span>
</p>
</div>

<div class="btns">
<span class="myBtn">{{ $t("account.copyCode") }}</span>
<span class="myBtn">{{ $t("account.saveCode") }}</span>
<span class="myBtn" @click="copyInviteCode">{{
$t("account.copyCode")
}}</span>
<span class="myBtn" @click="DownloadCodeImg">{{
$t("account.saveCode")
}}</span>
</div>
</div>
</div>
@@ -97,9 +111,31 @@
import { useI18n } from "vue-i18n";
import { useRouter } from "vue-router";
const { locale } = useI18n();

const currentLan = ref(locale);

//#region 二维码区域
// 点击复制邀请码
function copyInviteCode() {
const inviteCode = document.getElementById("InviteCodeId").innerText;
navigator.clipboard
.writeText(inviteCode)
.then(() => {
ElMessage.success("邀请码已复制到剪贴板");
})
.catch((error) => {
ElMessage.error("无法复制邀请码:", error);
});
}
// 下载二维码图片
const codeImgRef = ref();
function DownloadCodeImg() {
const link = document.createElement("a");
link.href = codeImgRef.value.src;
link.download = "image.jpg";
link.click();
}
//#endregion

const router = useRouter();
function routerTo(url) {
router.push(url);
@@ -183,10 +219,18 @@ function routerTo(url) {

&-three {
.codeImg {
position: relative;
width: 120px;
height: 120px;
margin-right: 10px;
background-color: red;
// background-color: red;
img {
position: absolute;
top: 50%;
transform: translateY(-50%);
width: 100%;
max-height: 100%;
}
}

.other {


+ 12
- 0
yarn.lock View File

@@ -1737,6 +1737,13 @@ braces@^3.0.2, braces@~3.0.2:
dependencies:
fill-range "^7.0.1"

browser-image-compression@^2.0.2:
version "2.0.2"
resolved "https://registry.npmmirror.com/browser-image-compression/-/browser-image-compression-2.0.2.tgz#4d5ef8882e9e471d6d923715ceb9034499d14eaa"
integrity sha512-pBLlQyUf6yB8SmmngrcOw3EoS4RpQ1BcylI3T9Yqn7+4nrQTXJD4sJDe5ODnJdrvNMaio5OicFo75rDyJD2Ucw==
dependencies:
uzip "0.20201231.0"

browserslist@^4.21.3, browserslist@^4.21.5:
version "4.21.5"
resolved "https://registry.npmmirror.com/browserslist/-/browserslist-4.21.5.tgz"
@@ -6150,6 +6157,11 @@ util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1:
resolved "https://registry.npmmirror.com/util-deprecate/-/util-deprecate-1.0.2.tgz"
integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==

uzip@0.20201231.0:
version "0.20201231.0"
resolved "https://registry.npmmirror.com/uzip/-/uzip-0.20201231.0.tgz#9e64b065b9a8ebf26eb7583fe8e77e1d9a15ed14"
integrity sha512-OZeJfZP+R0z9D6TmBgLq2LHzSSptGMGDGigGiEe0pr8UBe/7fdflgHlHBNDASTXB5jnFuxHpNaJywSg8YFeGng==

v8-compile-cache-lib@^3.0.1:
version "3.0.1"
resolved "https://registry.npmmirror.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz"


Loading…
Cancel
Save