Commit e9f12f92 authored by Administrator's avatar Administrator

小改

parent 6141f9e4
Pipeline #356 canceled with stages
<script setup lang="ts"> <script setup lang="ts">
import { RouterLink, RouterView } from 'vue-router' import { RouterLink, RouterView } from "vue-router";
import { ElConfigProvider } from 'element-plus' import { ElConfigProvider } from "element-plus";
import zhCn from 'element-plus/dist/locale/zh-cn.mjs' import zhCn from "element-plus/dist/locale/zh-cn.mjs";
const locale = zhCn const locale = zhCn;
</script> </script>
<template> <template>
...@@ -46,31 +46,4 @@ nav a { ...@@ -46,31 +46,4 @@ nav a {
nav a:first-of-type { nav a:first-of-type {
border: 0; border: 0;
} }
@media (min-width: 1024px) {
header {
display: flex;
place-items: center;
padding-right: calc(var(--section-gap) / 2);
}
.logo {
margin: 0 2rem 0 0;
}
header .wrapper {
display: flex;
place-items: flex-start;
flex-wrap: wrap;
}
nav {
text-align: left;
margin-left: -1rem;
font-size: 1rem;
padding: 1rem 0;
margin-top: 1rem;
}
}
</style> </style>
/** /**
* 视频转换相关接口 * 相关接口
*/ */
import request from '@/api/request' import request from '@/api/request'
export default { export default {
/** genScriptsByGpt(postData: any) {
* 视频转换 return request.post('/text2video/gen_scripts_by_gpt', postData)
*/
wmVideoCut(postData: any) {
return request.post('/wm_video_cut', postData)
} }
} }
...@@ -4,7 +4,8 @@ ...@@ -4,7 +4,8 @@
max-width: 1280px; max-width: 1280px;
margin: 0 auto; margin: 0 auto;
padding: 2rem; padding: 2rem;
display: flex;
justify-content: center;
font-weight: normal; font-weight: normal;
} }
...@@ -21,15 +22,3 @@ a, ...@@ -21,15 +22,3 @@ a,
} }
} }
@media (min-width: 1024px) {
body {
display: flex;
place-items: center;
}
#app {
display: grid;
grid-template-columns: 1fr 1fr;
padding: 0 2rem;
}
}
<script setup lang="ts">
import { onMounted, reactive, ref } from 'vue'
import { Sunny, UploadFilled } from '@element-plus/icons-vue'
import {
ElMessage,
genFileId,
type UploadInstance,
type UploadProps,
type UploadRawFile
} from 'element-plus'
import { useLanguage } from './compositions/index'
import videoService from '@/api/service/videoService'
import exportFile from '@/utils/exportFile'
import { whenMouse } from 'element-plus/es/utils/index.mjs'
const { languages } = useLanguage()
const step = ref(1)
const form = reactive({
language: 'en',
video: '',
timeline: <Wm.TimelineItem[]>[],
withSub: true
})
const upload = ref<UploadInstance>()
const actionUrl = ref(
import.meta.env.MODE === 'production'
? '/upload_file'
: import.meta.env.VITE_APP_BASE_API + '/upload_file'
)
onMounted(() => {})
const onSubmit = () => {
if (!form.video) {
ElMessage({
message: '请先上传视频',
type: 'error'
})
return
}
let postData: Wm.VideoCutOptions = {
instances: [
{
video: form.video,
lang: form.language,
steps: ['step'+step.value]
}
]
}
if (step.value === 2) {
let srt_json_in = form.timeline
postData.instances[0] = {
...postData.instances[0],
with_sub: form.withSub,
srt_json_in: srt_json_in
}
}
videoService
.wmVideoCut(postData)
.then((res: any) => {
console.log(res)
ElMessage({
message: '操作成功',
type: 'success'
})
const ishttps = document.location.protocol === 'https:'
// console.log(document.location)
if (res) {
if (step.value === 1) {
form.timeline = res.result
step.value = 2
} else {
let url = ''
const final_video_url = res.result
if (ishttps) {
url = final_video_url.replace('http://', 'https://')
} else {
url = final_video_url.replace('https://', 'http://')
}
url = '/download' + url.substring(1, url.length)
console.log(url)
const arr_name = final_video_url.split('/')
const file_name = arr_name[arr_name.length - 1] // 获取文件名
fetch(url)
.then((url) => url.blob())
.then((blob: any) => {
exportFile.getVideoFile(blob, file_name)
})
step.value = 1
}
}
})
.catch((err: any) => {
console.log(err)
ElMessage({
message: '操作失败' + err,
type: 'error'
})
})
}
const handleExceed: UploadProps['onExceed'] = (files) => {
upload.value!.clearFiles()
const file = files[0] as UploadRawFile
file.uid = genFileId()
upload.value!.handleStart(file)
upload.value!.submit()
}
const handleUploadSuccess = (val: Wm.UploadResult) => {
form.video = val.result.file_url
ElMessage({
message: '上传成功',
type: 'success'
})
}
const handleBeforeUpload = (file: any) => {
const isLt100M = file.size / 1024 / 1024 < 100
const fileName = file.name
const fileType = fileName.substring(fileName.lastIndexOf('.'))
console.log(fileType)
const isMp4 =
(file.type.indexOf('video') > -1 && file.type === 'video/mp4') || fileType === '.mp4'
if (!isLt100M) {
ElMessage.error('上传文件大小不能超过 100MB!')
return false
}
if (!isMp4) {
ElMessage.error('视频仅支持MP4格式!')
return false
}
return isMp4 && isLt100M
}
const handleRemove = () => {
form.video = ''
}
</script>
<template>
<main class="home-container">
<el-divider content-position="left"
>视频转换(先根据视频生成翻译,再转换视频)</el-divider
>
<el-form :model="form" label-width="114px">
<el-form-item label="选择语言">
<el-select v-model="form.language" placeholder="请选择要转换的语言">
<el-option
v-for="item in languages"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item label="上传视频">
<el-upload
class="upload-demo"
drag
ref="upload"
accept=".mp4"
:limit="1"
:action="actionUrl"
:on-success="handleUploadSuccess"
:on-exceed="handleExceed"
:on-remove="handleRemove"
:before-upload="handleBeforeUpload"
>
<el-icon class="el-icon--upload"><upload-filled /></el-icon>
<div class="el-upload__text">
将需要转换的视频文件拖到此处或 <em>点击上传</em>
</div>
<template #tip>
<div class="el-upload__tip">
<span>1、视频请上传mp4格式;</span>
<span>2、视频大小控制在100M以内</span>
</div>
</template>
</el-upload>
</el-form-item>
<el-form-item label="校对翻译" v-if="step === 2">
<!-- <el-timeline>
<el-timeline-item placement="top"
v-for="(srt, index) in form.timeline"
:key="index"
:timestamp="srt.start + ' --- ' + srt.end">
<el-input v-model="srt.content"
style="width: 500px"
:autosize="{ minRows: 1, maxRows: 3 }"
type="textarea"
/>
</el-timeline-item>
</el-timeline> -->
<div v-for="(srt, index) in form.timeline">
<el-icon v-if="srt.content != '< No Speech >'" color="#409EFC" size="10px">
<BellFilled />
</el-icon>
<span v-if="srt.content != '< No Speech >'">
{{ srt.start + " --- " + srt.end }}
</span>
<el-input
v-if="srt.content != '< No Speech >'"
v-model="srt.content"
style="width: 600px; margin: 5px 0"
:autosize="{ minRows: 1, maxRows: 3 }"
type="textarea"
/>
</div>
</el-form-item>
<el-form-item label="是否需要字幕" v-if="step === 2">
<el-select v-model="form.withSub" placeholder="是否需要字幕">
<el-option label="是" :value="true" />
<el-option label="否" :value="false" />
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="onSubmit"
>{{ step === 1 ? "翻译" : "转换" }}
</el-button>
</el-form-item>
</el-form>
</main>
</template>
<style lang="scss" scoped>
.home-container {
.upload-demo {
width: 600px;
}
.el-upload__tip {
> span {
display: flex;
line-height: 20px;
}
}
}
</style>
@/api/service/myService
\ No newline at end of file
<script setup lang="ts"> <script setup lang="ts">
import { onMounted, reactive, ref } from 'vue' import { onMounted, reactive, ref } from "vue";
import { Sunny, UploadFilled } from '@element-plus/icons-vue' import { Sunny, UploadFilled } from "@element-plus/icons-vue";
import { import { ElMessage } from "element-plus";
ElMessage, import text2videoService from "@/api/service/text2videoService";
genFileId,
type UploadInstance,
type UploadProps,
type UploadRawFile
} from 'element-plus'
import { useLanguage } from './compositions/index'
import videoService from '@/api/service/videoService'
import exportFile from '@/utils/exportFile'
import { whenMouse } from 'element-plus/es/utils/index.mjs'
const { languages } = useLanguage() const step = ref(1);
const step = ref(1)
const form = reactive({ const form = reactive({
language: 'en', chatgpt_prompt: "",
video: '', });
timeline: <Wm.TimelineItem[]>[],
withSub: true
})
const upload = ref<UploadInstance>()
const actionUrl = ref( onMounted(() => {});
import.meta.env.MODE === 'production'
? '/upload_file'
: import.meta.env.VITE_APP_BASE_API + '/upload_file'
)
onMounted(() => {})
const onSubmit = () => { const onSubmit = () => {
if (!form.video) { if (!form.chatgpt_prompt) {
ElMessage({ ElMessage({
message: '请先上传视频', message: "prompt不能为空",
type: 'error' type: "error",
}) });
return return;
} }
let postData: Wm.VideoCutOptions = { let postData = {
instances: [ source_text: form.chatgpt_prompt,
{ };
video: form.video,
lang: form.language,
steps: ['step'+step.value]
}
]
}
if (step.value === 2) {
let srt_json_in = form.timeline
postData.instances[0] = {
...postData.instances[0],
with_sub: form.withSub,
srt_json_in: srt_json_in
}
}
videoService text2videoService
.wmVideoCut(postData) .genScriptsByGpt(postData)
.then((res: any) => { .then((res: any) => {
console.log(res) console.log(res);
ElMessage({ ElMessage({
message: '操作成功', message: "操作成功",
type: 'success' type: "success",
}) });
const ishttps = document.location.protocol === 'https:' // if (res) {
// console.log(document.location)
if (res) {
if (step.value === 1) {
form.timeline = res.result
step.value = 2
} else {
let url = ''
const final_video_url = res.result
if (ishttps) {
url = final_video_url.replace('http://', 'https://')
} else {
url = final_video_url.replace('https://', 'http://')
}
url = '/download' + url.substring(1, url.length)
console.log(url)
const arr_name = final_video_url.split('/') // }
const file_name = arr_name[arr_name.length - 1] // 获取文件名
fetch(url)
.then((url) => url.blob())
.then((blob: any) => {
exportFile.getVideoFile(blob, file_name)
})
step.value = 1
}
}
}) })
.catch((err: any) => { .catch((err: any) => {
console.log(err) console.log(err);
ElMessage({ ElMessage({
message: '操作失败' + err, message: "操作失败" + err,
type: 'error' type: "error",
}) });
}) });
} };
const handleExceed: UploadProps['onExceed'] = (files) => {
upload.value!.clearFiles()
const file = files[0] as UploadRawFile
file.uid = genFileId()
upload.value!.handleStart(file)
upload.value!.submit()
}
const handleUploadSuccess = (val: Wm.UploadResult) => {
form.video = val.result.file_url
ElMessage({
message: '上传成功',
type: 'success'
})
}
const handleBeforeUpload = (file: any) => {
const isLt100M = file.size / 1024 / 1024 < 100
const fileName = file.name
const fileType = fileName.substring(fileName.lastIndexOf('.'))
console.log(fileType)
const isMp4 =
(file.type.indexOf('video') > -1 && file.type === 'video/mp4') || fileType === '.mp4'
if (!isLt100M) {
ElMessage.error('上传文件大小不能超过 100MB!')
return false
}
if (!isMp4) {
ElMessage.error('视频仅支持MP4格式!')
return false
}
return isMp4 && isLt100M
}
const handleRemove = () => {
form.video = ''
}
</script> </script>
<template> <template>
<main class="home-container"> <main class="home-container">
<el-divider content-position="left" <el-divider content-position="left">text2video</el-divider>
>视频转换(先根据视频生成翻译,再转换视频)</el-divider
>
<el-form :model="form" label-width="114px"> <el-form :model="form" label-width="114px">
<el-form-item label="选择语言"> <el-form-item label="chatgpt prompt">
<el-select v-model="form.language" placeholder="请选择要转换的语言"> <el-input
<el-option v-model="form.chatgpt_prompt"
v-for="item in languages" :autosize="{ minRows: 4, maxRows: 10 }"
:key="item.value" type="textarea"
:label="item.label" placeholder="Please input"
:value="item.value" />
/>
</el-select>
</el-form-item> </el-form-item>
<el-form-item label="上传视频"> <!-- <el-form-item label="校对" v-if="step === 2">
<el-upload
class="upload-demo"
drag
ref="upload"
accept=".mp4"
:limit="1"
:action="actionUrl"
:on-success="handleUploadSuccess"
:on-exceed="handleExceed"
:on-remove="handleRemove"
:before-upload="handleBeforeUpload"
>
<el-icon class="el-icon--upload"><upload-filled /></el-icon>
<div class="el-upload__text">
将需要转换的视频文件拖到此处或 <em>点击上传</em>
</div>
<template #tip>
<div class="el-upload__tip">
<span>1、视频请上传mp4格式;</span>
<span>2、视频大小控制在100M以内</span>
</div>
</template>
</el-upload>
</el-form-item>
<el-form-item label="校对翻译" v-if="step === 2">
<!-- <el-timeline>
<el-timeline-item placement="top"
v-for="(srt, index) in form.timeline"
:key="index"
:timestamp="srt.start + ' --- ' + srt.end">
<el-input v-model="srt.content"
style="width: 500px"
:autosize="{ minRows: 1, maxRows: 3 }"
type="textarea"
/>
</el-timeline-item>
</el-timeline> -->
<div v-for="(srt, index) in form.timeline"> <div v-for="(srt, index) in form.timeline">
<el-icon v-if="srt.content != '< No Speech >'" color="#409EFC" size="10px"> <el-icon v-if="srt.content != '< No Speech >'" color="#409EFC" size="10px">
<BellFilled /> <BellFilled />
...@@ -211,34 +75,17 @@ const handleRemove = () => { ...@@ -211,34 +75,17 @@ const handleRemove = () => {
type="textarea" type="textarea"
/> />
</div> </div>
</el-form-item> </el-form-item> -->
<el-form-item label="是否需要字幕" v-if="step === 2">
<el-select v-model="form.withSub" placeholder="是否需要字幕">
<el-option label="是" :value="true" />
<el-option label="否" :value="false" />
</el-select>
</el-form-item>
<el-form-item> <el-form-item>
<el-button type="primary" @click="onSubmit" <el-button type="primary" @click="onSubmit">确定</el-button>
>{{ step === 1 ? "翻译" : "转换" }}
</el-button>
</el-form-item> </el-form-item>
</el-form> </el-form>
</main> </main>
</template> </template>
<style lang="scss" scoped> <style lang="scss" scoped>
.home-container { .home-container {
.upload-demo { width: 1000px;
width: 600px;
}
.el-upload__tip {
> span {
display: flex;
line-height: 20px;
}
}
} }
</style> </style>
declare namespace Wm { import type internal from "stream"
interface UploadResult {
result: {
/**
* 上传后的文件地址
*/
file_url: string
}
}
interface VideoCutOptions {
instances: VideoCutOptionsInstance[]
}
interface VideoCutOptionsInstance { declare namespace Wm {
/** // chatgpt请求
* 需要转换的视频地址-通过上传接口返回的地址 interface GenScriptsByGptOptions {
*/ prompt: string
video: string
// 需要转换的语言
lang: string
// 步骤
steps: string[]
// 最终视频是否需要合并字幕
with_sub?: boolean
// 修改后的字幕
srt_json_in?: any
}
interface VideoCutResultItem {
/**
* 转换后的视频地址
*/
final_video_url: string
/**
* 转换后的字幕地址
*/
srt_url: string
} }
interface VideoCutResult { // chatgpt回复
result: VideoCutResultItem interface GenScriptsByGptResult {
result: GenScriptsByGptResultItem
} }
interface GenScriptsByGptResultItem {
interface TimelineItem { code: int
index: string data: any
start: string message: string
end: string
content: string
} }
} }
...@@ -26,7 +26,7 @@ export default defineConfig({ ...@@ -26,7 +26,7 @@ export default defineConfig({
server: { server: {
proxy: { proxy: {
'/api/': { '/api/': {
target: 'http://192.168.31.96:8080', // 后端服务实际地址 target: 'http://127.0.0.1:5000/', // 后端服务实际地址
changeOrigin: true, changeOrigin: true,
rewrite: (path: any) => path.replace(/^\/api/, '') rewrite: (path: any) => path.replace(/^\/api/, '')
} }
......
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