<template>
<div class="video-editor">
<div class="card">
<h2 class="title">多功能视频编辑工具</h2>
<form class="editor-form" @submit.prevent="processVideo">
<!-- 美化视频上传区域 -->
<div class="form-group">
<label class="form-label">导入视频</label>
<div class="upload-box" @click="triggerVideoUpload">
<span v-if="!videoFile">点击上传视频文件</span>
<span v-else>{{ videoFile.name }}</span>
</div>
<input ref="videoInput" type="file" accept="video/*" @change="handleVideoUpload" hidden />
</div>
<!-- 美化音频上传区域 -->
<div class="form-group">
<label for="voiceSelect" class="form-label">选择声音:</label>
<select id="voiceSelect" class="form-select">
<option value="标准">标准</option>
<option value="Trump">Trump</option>
<option value="Trump">Leap</option>
<option value="Trump">ZFQ</option>
</select>
<input ref="audioInput" type="file" accept="audio/*" @change="handleAudioUpload" hidden />
</div>
<!-- 多选功能选择 -->
<div class="form-group">
<span class="form-label">选择处理功能</span>
<div class="checkbox-group">
<label>
<input type="checkbox" value="replaceAudio" v-model="selectedFunctions" />
替换音频
</label>
<label>
<input type="checkbox" value="addSubtitle" v-model="selectedFunctions" />
添加字幕
</label>
<label>
<input type="checkbox" value="adjustResolution" v-model="selectedFunctions" />
调整分辨率
</label>
<label>
<input type="checkbox" value="addWatermark" v-model="selectedFunctions" />
添加水印
</label>
</div>
</div>
<!-- 分辨率选择,仅当选中"调整分辨率"时显示 -->
<div class="form-group" v-if="selectedFunctions.includes('adjustResolution')">
<label class="form-label" for="resolution-select">选择输出分辨率</label>
<select id="resolution-select" v-model="selectedResolution">
<option value="" disabled>请选择分辨率</option>
<option value="480p">480p</option>
<option value="720p">720p</option>
<option value="1080p">1080p</option>
</select>
</div>
<!-- 处理按钮 -->
<div class="form-group">
<button type="submit" class="submit-btn" :disabled="processing">
{{ processing ? '处理中...' : '开始处理' }}
</button>
</div>
</form>
<!-- 假进度条显示区域 -->
<div class="progress-container" v-if="processing || progress > 0">
<div class="progress-bar" :style="{ width: progress + '%' }"></div>
<div class="progress-text">{{ progress.toFixed(0) }}%</div>
</div>
<!-- 下载按钮 -->
<div class="form-group" v-if="progress >= 100">
<button @click="downloadVideo" class="download-btn">
下载处理后的视频
</button>
</div>
</div>
</div>
</template>
<script setup>
import { ref } from 'vue'
const videoFile = ref(null)
const audioFile = ref(null)
const selectedFunctions = ref([])
const selectedResolution = ref('')
const processing = ref(false)
const progress = ref(0)
let timer = null
const videoInput = ref(null)
const audioInput = ref(null)
const triggerVideoUpload = () => {
videoInput.value.click()
}
const triggerAudioUpload = () => {
audioInput.value.click()
}
const handleVideoUpload = (event) => {
const file = event.target.files[0]
videoFile.value = file
console.log('选择的视频文件:', file)
}
const handleAudioUpload = (event) => {
const file = event.target.files[0]
audioFile.value = file
console.log('选择的音频文件:', file)
}
const processVideo = () => {
if (processing.value) return
console.log('处理视频,选中的功能:', selectedFunctions.value)
console.log('输出分辨率:', selectedResolution.value)
console.log('视频文件:', videoFile.value)
console.log('音频文件:', audioFile.value)
processing.value = true
progress.value = 0
// 模拟50秒的处理进度
const totalDuration = 5 // 秒
const increment = 99 / totalDuration // 只增加到99%
timer = setInterval(() => {
if (progress.value < 99) {
progress.value = Math.min(progress.value + increment, 99)
} else {
// 到达99%后清除定时器
clearInterval(timer)
// 设置10秒后跳到100%
setTimeout(() => {
progress.value = 100
processing.value = false
console.log('处理完成')
}, 10000) // 10秒延迟
}
}, 1000)
}
const downloadVideo = async () => {
try {
const response = await fetch('http://localhost:7860/download_video')
if (!response.ok) {
throw new Error('下载失败: ' + response.statusText)
}
// 获取Blob对象
const blob = await response.blob()
// 创建下载链接
const url = window.URL.createObjectURL(blob)
const a = document.createElement('a')
a.href = url
a.download = 'processed_video.mp4' // 设置下载文件名
document.body.appendChild(a)
a.click()
// 清理
window.URL.revokeObjectURL(url)
document.body.removeChild(a)
} catch (error) {
console.error('下载视频出错:', error)
alert('下载视频失败: ' + error.message)
}
}
</script>
<style scoped>
.video-editor {
display: flex;
justify-content: center;
padding: 40px;
background: #f2f4f8;
min-height: 87vh;
}
.card {
background: #fff;
border-radius: 8px;
padding: 30px 40px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
width: 100%;
max-width: 600px;
}
.title {
text-align: center;
color: #333;
margin-bottom: 20px;
font-size: 24px;
}
.editor-form .form-group {
margin-bottom: 20px;
}
.form-label {
display: block;
margin-bottom: 8px;
font-weight: bold;
color: #555;
}
/* 上传框样式 */
.upload-box {
border: 2px dashed #ccc;
padding: 20px;
text-align: center;
border-radius: 4px;
cursor: pointer;
transition: border-color 0.3s;
color: #888;
}
.upload-box:hover {
border-color: #1a73e8;
color: #1a73e8;
}
/* 复选框组 */
.checkbox-group {
display: flex;
flex-wrap: wrap;
gap: 20px;
}
.checkbox-group label {
font-weight: normal;
color: #555;
cursor: pointer;
}
.checkbox-group input {
margin-right: 6px;
}
/* 进度条样式 */
.progress-container {
margin-top: 30px;
position: relative;
height: 30px;
background: #e0e0e0;
border-radius: 15px;
overflow: hidden;
}
.progress-bar {
height: 100%;
background: #1a73e8;
width: 0;
transition: width 1s linear;
}
.progress-text {
position: absolute;
width: 100%;
top: 0;
left: 0;
text-align: center;
line-height: 30px;
color: #fff;
font-weight: bold;
}
/* 按钮样式 */
button.submit-btn {
width: 100%;
padding: 10px;
background: #1a73e8;
color: #fff;
border: none;
border-radius: 4px;
font-size: 16px;
cursor: pointer;
transition: background 0.3s ease;
}
button.submit-btn:hover {
background: #1665c1;
}
button.submit-btn:disabled {
background: #cccccc;
cursor: not-allowed;
}
select {
width: 100%;
padding: 8px 10px;
border: 1px solid #ccc;
border-radius: 4px;
}
/* 下载按钮样式 */
.download-btn {
width: 100%;
padding: 10px;
background: #4CAF50;
color: #fff;
border: none;
border-radius: 4px;
font-size: 16px;
cursor: pointer;
transition: background 0.3s ease;
margin-top: 20px;
}
.download-btn:hover {
background: #45a049;
}
</style>