congzc 2 роки тому
джерело
коміт
7bc825ecc5
13 змінених файлів з 7352 додано та 34 видалено
  1. +1
    -0
      package.json
  2. +22
    -0
      src/apis/createVideo.js
  3. +2
    -1
      src/lang/package/en.ts
  4. +3
    -2
      src/lang/package/zh-cn.ts
  5. +1
    -0
      src/layout/components/Sidebar/Logo.vue
  6. +1
    -1
      src/layout/components/Sidebar/index.vue
  7. +1
    -1
      src/layout/index.vue
  8. +2
    -0
      src/types/components.d.ts
  9. +510
    -0
      src/views/createVideo/index copy.vue
  10. +331
    -29
      src/views/createVideo/index.vue
  11. +3
    -0
      vite.config.ts
  12. +6470
    -0
      yarn-error.log
  13. +5
    -0
      yarn.lock

+ 1
- 0
package.json Переглянути файл

@@ -20,6 +20,7 @@
"axios": "^1.3.4",
"echarts": "^5.2.2",
"element-plus": "^2.3.1",
"js-audio-recorder": "^1.0.7",
"nprogress": "^0.2.0",
"path-browserify": "^1.0.1",
"path-to-regexp": "^6.2.0",


+ 22
- 0
src/apis/createVideo.js Переглянути файл

@@ -0,0 +1,22 @@
import request from "@/utils/request.js";

/**
* @description 上传图片
* @params ticket
* @returns data
*/
export function awsImgUpload(formData) {
return request({
url: `/api/upload/awsImgUpload`,
method: 'post',
data: formData
})
}

export function awsMp3Upload(formData) {
return request({
url: `/api/upload/awsImgUpload`,
method: 'post',
data: formData
})
}

+ 2
- 1
src/lang/package/en.ts Переглянути файл

@@ -40,7 +40,8 @@ export default {
languages: "Languages",
voices: "Voices",
styles: "Styles",
reload: "Reload",
reselect: "reselect",
sureUpload:'Confirm upload',
generateVideo: "Generate Video",
},



+ 3
- 2
src/lang/package/zh-cn.ts Переглянути файл

@@ -32,7 +32,7 @@ export default {
createVideo: {
title: "创作视频",
typeScript: "输入文案",
uploadAudio: "上传频",
uploadAudio: "上传频",
aiScript: "AI生成文本",
typeTitle: "输入标题",
confirm: "确定",
@@ -40,7 +40,8 @@ export default {
languages: "选择语言",
voices: "选择声音",
styles: "选择风格",
reload: "重新上传",
reselect: "重新选择",
sureUpload:'确认上传',
generateVideo: "生成视频",
},



+ 1
- 0
src/layout/components/Sidebar/Logo.vue Переглянути файл

@@ -55,6 +55,7 @@ const logo = ref(new URL(`../../../assets/logo.png`, import.meta.url).href);
// https://cn.vuejs.org/guide/built-ins/transition.html#the-transition-component

.left-top-box {
height: 80px;
background-color: #000;
}



+ 1
- 1
src/layout/components/Sidebar/index.vue Переглянути файл

@@ -76,7 +76,7 @@ function routerTo(url: RouteLocationRaw) {
<style lang="scss" scoped>
.myRouter {
position: relative;
height: calc(100% - 50px);
height: calc(100% - 80px);
padding: 200px 20px 0;
color: #fff;



+ 1
- 1
src/layout/index.vue Переглянути файл

@@ -18,7 +18,7 @@
<!--主页面-->
<app-main />

<!-- 设置面板 -->-
<!-- 设置面板 -->
<RightPanel v-if="showSettings">
<settings />
</RightPanel>


+ 2
- 0
src/types/components.d.ts Переглянути файл

@@ -21,6 +21,7 @@ declare module '@vue/runtime-core' {
ElIcon: typeof import('element-plus/es')['ElIcon']
ElInput: typeof import('element-plus/es')['ElInput']
ElOption: typeof import('element-plus/es')['ElOption']
ElProgress: typeof import('element-plus/es')['ElProgress']
ElRow: typeof import('element-plus/es')['ElRow']
ElScrollbar: typeof import('element-plus/es')['ElScrollbar']
ElSelect: typeof import('element-plus/es')['ElSelect']
@@ -28,6 +29,7 @@ declare module '@vue/runtime-core' {
ElTabPane: typeof import('element-plus/es')['ElTabPane']
ElTabs: typeof import('element-plus/es')['ElTabs']
ElTooltip: typeof import('element-plus/es')['ElTooltip']
ElUpload: typeof import('element-plus/es')['ElUpload']
GithubCorner: typeof import('./../components/GithubCorner/index.vue')['default']
Hamburger: typeof import('./../components/Hamburger/index.vue')['default']
IconSelect: typeof import('./../components/IconSelect/index.vue')['default']


+ 510
- 0
src/views/createVideo/index copy.vue Переглянути файл

@@ -0,0 +1,510 @@
<template>
<div class="page flex justify-around">
<!-- 左侧栏 -->
<div class="left">
<!-- 顶部 -->
<!-- 有图片时 -->
<div class="left-top" v-show="imgUrl">
<el-row class="justify-between">
<!-- title框 -->
<div class="flex justify-between" style="width: 300px">
<el-input
v-model="title"
:placeholder="$t('createVideo.typeTitle')"
/>
<el-icon class="icon-edit"><i-ep-edit /></el-icon>
</div>
<!-- 上传按钮 -->
<button class="uploadBtn">
{{ $t("createVideo.reload") }}
<input type="file" @change="changeFile" />
</button>
</el-row>
<!-- 中间展示大图 -->
<div class="bigImg inmiddle">
<img :src="imgUrl" alt="" class="inmiddle" />
</div>
</div>
<!-- 没有图片时 -->
<div class="left-top" v-show="!imgUrl">
<!-- 中间展示大图 -->
<div class="noImg">
<div class="trueImg inmiddle">
<div class="icon">✔</div>
</div>
<div class="upload inmiddle">
+
<input type="file" @change="changeFile" />
</div>
<div class="falseImg inmiddle">
<div><div class="icon">×</div></div>
<div><div class="icon">×</div></div>
<div><div class="icon">×</div></div>
</div>
</div>
</div>

<!-- 底部 -->
<div class="left-bottom">
<div class="ai">
<div class="aiAvatar"></div>
<div style="margin-left: 20px">Generate By Ai</div>
</div>
<div class="faceList scrolly">
<div class="faceItem" v-for="item in 7" :key="item">
<div class="img"></div>
<!-- <img src="" alt="" /> -->
<p>{{ item }}name</p>
</div>
</div>
</div>
</div>
<!-- 右侧栏 -->
<div class="right">
<el-tabs type="border-card" class="tabs">
<!-- ----------------------------- 1 -->
<el-tab-pane :label="$t('createVideo.typeScript')">
<div class="card1">111111111111111111</div>
</el-tab-pane>
<!-- ------------------------ 2 -->
<el-tab-pane :label="$t('createVideo.uploadAudio')">
<div class="card2">
<!-- 录制MP3上传语音 -->
<div class="uploadAudio">
<button @click="startRecording">开始录音</button>
<button @click="stopRecording">停止录音</button>
<button @click="playRecording">播放录音</button>
<audio v-if="audioUrl" controls :src="audioUrl"></audio>
<button v-if="audioUrl" @click="uploadAudio">上传音频</button>
</div>
<!-- 上传视频 -->
<div class="uploadVideo">
<input type="file" ref="fileInput" @change="handleFileChange" />
<video
v-if="videoSrc"
:src="videoSrc"
ref="videoPlayer"
controls
></video>
</div>
</div>
</el-tab-pane>
<!-- ----------------------- 3 -->
<el-tab-pane :label="$t('createVideo.aiScript')">
<div class="card3">
<div class="text">
<el-input
v-model="title"
:placeholder="$t('createVideo.typeTitle')"
/>
<el-button type="primary">
{{ $t("createVideo.confirm") }}
</el-button>
<el-input
v-model="title"
:rows="15"
type="textarea"
:placeholder="$t('createVideo.aiText')"
/>
<el-icon :size="20">
<Edit />
</el-icon>
</div>
<p>{{ $t("createVideo.languages") }}</p>
<el-select
v-model="language"
placeholder="Select"
style="width: 100%"
>
<el-option
v-for="item in languageOptions"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
<p>{{ $t("createVideo.voices") }}</p>
<el-select
v-model="language"
placeholder="Select"
style="width: 100%"
>
<el-option
v-for="item in languageOptions"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
<p>{{ $t("createVideo.styles") }}</p>
<el-select
v-model="language"
placeholder="Select"
style="width: 100%"
>
<el-option
v-for="item in languageOptions"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
<el-button type="primary">{{
$t("createVideo.generateVideo")
}}</el-button>
</div>
</el-tab-pane>
</el-tabs>
</div>
</div>
</template>
<script setup>
import { ref } from "vue";
import { getCurrentInstance } from "vue";
import Recorder from "js-audio-recorder";
// 标题
let title = ref("");
// 上传图片
let imgUrl = ref("");
function changeFile(e) {
imgUrl.value = URL.createObjectURL(e.target.files[0]);
}

// $t在script中的使用

const {
appContext: {
config: { globalProperties },
},
} = getCurrentInstance();

const string = "createVideo.typeScript";
const t = globalProperties.$t(string);
// 录制MP3上传语音

const parameter = {
sampleBits: 16, // 采样位数,支持 8 或 16,默认是16
sampleRate: 8000, // 采样率,支持 11025、16000、22050、24000、44100、48000,根据浏览器默认值,我的chrome是48000
numChannels: 1, // 声道,支持 1 或 2, 默认是1
};
const recorder = new Recorder(parameter);
const isRecording = ref(false);
const audioUrl = ref(null);

const startRecording = async () => {
if (!isRecording.value) {
try {
await recorder.start();
console.log("Recording started");
isRecording.value = true;
} catch (error) {
console.error(error);
}
}
};

const stopRecording = async () => {
if (isRecording.value) {
try {
const recording = await recorder.stop();
audioUrl.value = URL.createObjectURL(recorder.getWAVBlob());
isRecording.value = false;
} catch (error) {
console.error(error);
}
}
};

const playRecording = () => {
if (audioUrl.value) {
const audio = new Audio(audioUrl.value);
audio.play();
}
};
const uploadAudio = () => {};

// 上传视频功能
const fileInput = ref(null);
const videoSrc = ref(null);
const handleFileChange = () => {
const file = fileInput.value.files[0];
if (file) {
const videoUrl = URL.createObjectURL(file);
videoSrc.value = videoUrl;
}
};

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

let languageOptions = reactive([
{
value: "Option1",
label: "Option1",
},
{
value: "Option2",
label: "Option2",
},
]);
</script>

<style lang="scss" scoped>
.page {
// height: calc(100vh - 84px);
height: 887px;
padding: 20px 0 0 40px;
background-color: #fff;
border-radius: 25px 0 0;
}

.left {
width: 70%;
height: 100%;

:deep(.el-input__wrapper) {
border: none;
border-bottom: 2px solid #000;
border-radius: 0;
box-shadow: none;
}

.el-icon.icon-edit {
width: 35px;
height: 35px;
font-size: 35px;
color: #8c939d;
text-align: center;
}

&-top {
position: relative;
width: 100%;
height: 65%;

.uploadBtn {
position: relative;
}

.bigImg {
display: flex;
align-items: center;
justify-content: space-between;
width: 80%;
height: 88%;
margin-top: 20px;

img {
max-width: 100%;
max-height: 100%;
}
}

.noImg {
position: relative;
width: 100%;
height: 100%;
border: 1px solid #000;

.trueImg {
top: 60px;
width: 100px;
height: 100px;
background-color: green;
border-radius: 50%;
}

.upload {
top: 200px;
width: 100px;
height: 100px;
font-size: 50px;
line-height: 100px;
text-align: center;
background-color: pink;
border-radius: 50%;
}

.falseImg {
top: 350px;
// background-color: #795562;
display: flex;
justify-content: space-evenly;
width: 500px;
height: 100px;

> div {
position: relative;
width: 100px;
height: 100px;
background-color: #ccc;
border-radius: 50%;
}
}
}

// 公共类名
input {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
opacity: 0;
}

.icon {
position: absolute;
right: 2px;
width: 30px;
height: 30px;
font-size: 20px;
font-weight: 700;
line-height: 26px;
text-align: center;
border: 2px solid #000;
border-radius: 50%;
}
}

&-bottom {
width: 100%;
height: 32%;
margin-top: 10px;

.ai {
width: 100%;

.aiAvatar {
width: 100px;
height: 100px;
margin-left: 25px;
background-color: pink;
border-radius: 50%;
}
}

.faceList {
display: flex;
flex-wrap: wrap;
justify-content: flex-start;
width: 100%;
height: 130px;

.faceItem {
width: 150px;
height: 150px;
padding: 0 25px;
line-height: 30px;
text-align: center;

p {
height: 30px;
}

.img {
width: 100px;
height: 100px;
background-color: green;
border-radius: 50%;
}
}
}
}
}

.right {
width: 25%;
height: 100%;
background-color: green;

:deep(.el-tabs--border-card) {
font-size: 20px;
border: none;
}

.tabs {
height: 100%;
.card2 {
padding: 10px;
> div {
position: relative;
margin-top: 10px;
width: 100%;
height: 100px;
border-radius: 10px;
background-color: red;
overflow: hidden;
transition: all 0.3s;
&:hover {
transform: translateY(-10px);
box-shadow: #00000026 2px 2px 2px 2px;
}
}
.uploadAudio {
margin-bottom: 20px;
}
.uploadVideo {
input {
position: absolute;
width: 100%;
height: 100%;
opacity: 0;
}
video {
width: 100%;
height: 100%;
}
}
}
.card3 {
.text {
padding: 10px;
border: 1px solid #000;

.el-button {
float: right;
margin-top: 10px;
}

:deep(.el-textarea__inner) {
resize: none;
box-shadow: none;
}
}

p {
margin: 10px 0;
}

> .el-button {
width: 100%;
height: 50px;
margin-top: 10px;
}
}

:deep(.el-tabs__item.is-active) {
color: #909393;
background-color: #000;
}

:deep(.el-tabs__nav) {
width: 100%;
}

:deep(.el-tabs__item) {
width: 34%;
}

:deep(.el-tabs__item:hover) {
color: #909393;
}

:deep(.el-tabs__content) {
height: calc(100% - 60px);
padding: 0;
}
}
}
</style>

+ 331
- 29
src/views/createVideo/index.vue Переглянути файл

@@ -15,10 +15,15 @@
<el-icon class="icon-edit"><i-ep-edit /></el-icon>
</div>
<!-- 上传按钮 -->
<button class="uploadBtn">
{{ $t("createVideo.reload") }}
<input type="file" @change="changeFile" />
</button>
<div class="btnBox">
<button class="uploadBtn">
{{ $t("createVideo.reselect") }}
<input type="file" @change="lookImg" />
</button>
<button class="uploadBtn" @click="changeFile">
{{ $t("createVideo.sureUpload") }}
</button>
</div>
</el-row>
<!-- 中间展示大图 -->
<div class="bigImg inmiddle">
@@ -34,7 +39,17 @@
</div>
<div class="upload inmiddle">
+
<input type="file" @change="changeFile" />
<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"
/> -->
</div>
<div class="falseImg inmiddle">
<div><div class="icon">×</div></div>
@@ -51,10 +66,15 @@
<div style="margin-left: 20px">Generate By Ai</div>
</div>
<div class="faceList scrolly">
<div class="faceItem" v-for="item in 7" :key="item">
<div class="img"></div>
<!-- <img src="" alt="" /> -->
<p>{{ item }}name</p>
<div
class="faceItem pointer"
@click="setImgUrl(item.material)"
v-for="item in AiFace"
:key="item.id"
>
<!-- <div class="img"></div> -->
<img :src="item.material" alt="" />
<p>{{ item.title }}</p>
</div>
</div>
</div>
@@ -64,19 +84,117 @@
<el-tabs type="border-card" class="tabs">
<!-- ----------------------------- 1 -->
<el-tab-pane :label="$t('createVideo.typeScript')">
<div class="card1">111111111111111111</div>
<div class="card1">
<div class="text">
<el-input
v-model="title"
:placeholder="$t('createVideo.typeTitle')"
/>
<el-button type="primary">
{{ $t("createVideo.confirm") }}
</el-button>
<el-input
v-model="title"
:rows="15"
type="textarea"
:placeholder="$t('createVideo.aiText')"
/>
<el-icon :size="20">
<Edit />
</el-icon>
</div>
<p>{{ $t("createVideo.languages") }}</p>
<el-select
v-model="language"
placeholder="Select"
style="width: 100%"
>
<el-option
v-for="item in languageOptions"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
<p>{{ $t("createVideo.voices") }}</p>
<el-select
v-model="language"
placeholder="Select"
style="width: 100%"
>
<el-option
v-for="item in languageOptions"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
<p>{{ $t("createVideo.styles") }}</p>
<el-select
v-model="language"
placeholder="Select"
style="width: 100%"
>
<el-option
v-for="item in languageOptions"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
<el-button type="primary">{{
$t("createVideo.generateVideo")
}}</el-button>
</div>
</el-tab-pane>
<!-- ------------------------ 2 -->
<el-tab-pane :label="$t('createVideo.uploadAudio')">
<div class="card2">
<div class="uploadVideo">
<!-- 录制MP3上传语音 -->
<div
class="uploadAudio"
:class="audioUrl ? 'uploadAudioAvtion' : ''"
>
<div class="btnBox">
<button
class="pointer"
:disabled="!isRecording"
@click="startRecording"
>
开始录音
</button>
<button
class="pointer"
@click="stopRecording"
:disabled="isRecording"
>
停止录音
</button>
</div>
<!-- <button @click="playRecording">播放录音</button> -->
<audio v-if="audioUrl" controls :src="audioUrl"></audio>
<button v-if="audioUrl" @click="uploadAudio" class="pointer">
上传音频
</button>
</div>
<!-- 上传视频 -->
<div
class="uploadVideo"
style="text-align: center; line-height: 70px"
>
上传视频
<input type="file" ref="fileInput" @change="handleFileChange" />
<video ref="videoPlayer" controls></video>
<video
v-if="videoSrc"
:src="videoSrc"
ref="videoPlayer"
controls
></video>
</div>
</div>
</el-tab-pane>
<!-- ----------------------- 3 -->
<el-tab-pane :label="$t('createVideo.aiScript')">
<el-tab-pane v-if="false" :label="$t('createVideo.aiScript')">
<div class="card3">
<div class="text">
<el-input
@@ -147,27 +265,115 @@
<script setup>
import { ref } from "vue";
import { getCurrentInstance } from "vue";
import Recorder from "js-audio-recorder";
import axios from "axios";
import { awsImgUpload, awsMp3Upload } from "@/apis/createVideo";
import { ElMessage } from "element-plus";
// 获取AI头像
const AiFace = ref([]);
function getAiFace() {
axios({
url: "https://photo.metavatar.cc/C//api/personPhoto/list?pageNum=1&pageSize=1",
method: "get",
}).then((res) => {
AiFace.value = res.data.data.list;
console.log(res.data.data.list);
});
}
getAiFace();

// 标题
let title = ref("");
// 上传图片
let imgUrl = ref("");
function changeFile(e) {
const imgData = ref("");
// 预览图片
function lookImg(e) {
imgUrl.value = URL.createObjectURL(e.target.files[0]);
imgData.value = e.target.files[0];
}
// 上传图片
async function changeFile() {
imgUrl.value = URL.createObjectURL(imgData.value);
let formData = new FormData();
const timestamp = Date.now();
formData.append("file", imgData.value, timestamp + ".png");
try {
const res = await awsImgUpload(formData);
ElMessage.success("上传成功!");
} catch (error) {
ElMessage.error(error);
}
}

// $t在script中的使用
// 点击aifece
function setImgUrl(url) {
imgUrl.value = url;
}

const {
appContext: {
config: { globalProperties },
},
} = getCurrentInstance();
// 录制MP3上传语音
const parameter = {
sampleBits: 16, // 采样位数,支持 8 或 16,默认是16
sampleRate: 8000, // 采样率,支持 11025、16000、22050、24000、44100、48000,根据浏览器默认值,我的chrome是48000
numChannels: 1, // 声道,支持 1 或 2, 默认是1
};
const recorder = new Recorder(parameter);
const isRecording = ref(true);
const audioUrl = ref(null);
const audioData = ref("");

const startRecording = async () => {
try {
await recorder.start();
console.log("Recording started");
isRecording.value = false;
} catch (error) {
console.error(error);
}
};

const stopRecording = async () => {
try {
const recording = await recorder.stop();
audioUrl.value = URL.createObjectURL(recorder.getWAVBlob());
audioData.value = recorder.getWAVBlob();
isRecording.value = true;
} catch (error) {
console.error(error);
}
};

const string = "createVideo.typeScript";
const t = globalProperties.$t(string);
const playRecording = () => {
if (audioUrl.value) {
const audio = new Audio(audioUrl.value);
audio.play();
}
};
async function uploadAudio(params) {
let formData = new FormData();
const timestamp = Date.now();
formData.append("file", audioData.value, timestamp + ".mp3");
try {
const res = await awsMp3Upload(formData);
ElMessage.success("上传成功!");
} catch (error) {
ElMessage.error(error);
}
}

// 上传视频功能
const fileInput = ref(null);
const videoSrc = ref(null);
const handleFileChange = () => {
const file = fileInput.value.files[0];
if (file) {
const videoUrl = URL.createObjectURL(file);
videoSrc.value = videoUrl;
}
};

// card3的
let language = reactive("");
let language = ref("");

let languageOptions = reactive([
{
@@ -179,6 +385,16 @@ let languageOptions = reactive([
label: "Option2",
},
]);

// $t在script中的使用
const {
appContext: {
config: { globalProperties },
},
} = getCurrentInstance();

const string = "createVideo.typeScript";
const t = globalProperties.$t(string);
</script>

<style lang="scss" scoped>
@@ -216,6 +432,14 @@ let languageOptions = reactive([

.uploadBtn {
position: relative;
padding: 5px 10px;
margin-left: 10px;
border-radius: 5px;
transition: all 0.3s;
&:hover {
background-color: #000;
color: #fff;
}
}

.bigImg {
@@ -245,7 +469,14 @@ let languageOptions = reactive([
background-color: green;
border-radius: 50%;
}

.el-upload {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
opacity: 0;
}
.upload {
top: 200px;
width: 100px;
@@ -333,11 +564,13 @@ let languageOptions = reactive([
p {
height: 30px;
}

img {
width: 100%;
}
.img {
width: 100px;
height: 100px;
background-color: green;
// background-color: green;
border-radius: 50%;
}
}
@@ -357,21 +590,90 @@ let languageOptions = reactive([

.tabs {
height: 100%;
.card1 {
.text {
padding: 10px;
border: 1px solid #000;

.el-button {
float: right;
margin-top: 10px;
}

:deep(.el-textarea__inner) {
resize: none;
box-shadow: none;
}
}

p {
margin: 10px 0;
}

> .el-button {
width: 100%;
height: 50px;
margin-top: 10px;
}
}
.card2 {
padding: 10px;
.uploadVideo {
> div {
position: relative;
margin-top: 10px;
width: 100%;
height: 100px;
border: #000 1px solid;
border-radius: 10px;
background-color: red;

overflow: hidden;
transition: all 0.3s;
box-shadow: #00000026 2px 2px 2px 2px;
&:hover {
transform: translateY(-10px);
}
}
.uploadAudio {
padding: 20px;
margin-bottom: 20px;
height: 70px;
.btnBox {
display: flex;
justify-content: space-between;
margin-bottom: 10px;
}
audio {
height: 50px;
width: 100%;
}
button {
border-radius: 10px;
height: 30px;
line-height: 22px;
padding: 5px 10px;
background-color: #fff;
transition: all 0.3s;
&:hover {
background-color: #000;

color: #fff;
}
}
}
.uploadAudioAvtion {
height: 170px;
}
.uploadVideo {
height: 100px;
input {
position: absolute;
width: 100%;
height: 100%;
opacity: 0;
}
video {
width: 100%;
height: 100%;
}
}
}
.card3 {


+ 3
- 0
vite.config.ts Переглянути файл

@@ -96,5 +96,8 @@ export default defineConfig(({ mode }: ConfigEnv): UserConfig => {
symbolId: "icon-[dir]-[name]",
}),
],
define: {
global:{}
}
};
});

+ 6470
- 0
yarn-error.log
Різницю між файлами не показано, бо вона завелика
Переглянути файл


+ 5
- 0
yarn.lock Переглянути файл

@@ -3722,6 +3722,11 @@ jiti@^1.16.0, jiti@^1.18.2:
resolved "https://registry.npmmirror.com/jiti/-/jiti-1.18.2.tgz"
integrity sha512-QAdOptna2NYiSSpv0O/BwoHBSmz4YhpzJHyi+fnMRTXFjp7B8i/YG5Z8IfusxB1ufjcD2Sre1F3R+nX3fvy7gg==

js-audio-recorder@^1.0.7:
version "1.0.7"
resolved "https://registry.yarnpkg.com/js-audio-recorder/-/js-audio-recorder-1.0.7.tgz#01501cb9eb143d57994b42bd5ae97974fda18908"
integrity sha512-JiDODCElVHGrFyjGYwYyNi7zCbKk9va9C77w+zCPMmi4C6ix7zsX2h3ddHugmo4dOTOTCym9++b/wVW9nC0IaA==

js-base64@^2.1.9:
version "2.6.4"
resolved "https://registry.npmmirror.com/js-base64/-/js-base64-2.6.4.tgz"


Завантаження…
Відмінити
Зберегти