From 51f3ab67df842657e1f61b447c6cc7a574d5d325 Mon Sep 17 00:00:00 2001 From: Kevin Wong Date: Mon, 19 Jan 2026 18:22:18 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E8=A7=86=E9=A2=91=E4=B8=8A?= =?UTF-8?q?=E4=BC=A0=E7=95=8C=E9=9D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Docs/DevLogs/Day5.md | 34 +++++++++++ Docs/task_complete.md | 16 ++++- frontend/src/app/page.tsx | 124 ++++++++++++++++++++++++++++++++++---- 3 files changed, 158 insertions(+), 16 deletions(-) create mode 100644 Docs/DevLogs/Day5.md diff --git a/Docs/DevLogs/Day5.md b/Docs/DevLogs/Day5.md new file mode 100644 index 0000000..d09d0e7 --- /dev/null +++ b/Docs/DevLogs/Day5.md @@ -0,0 +1,34 @@ +# Day 5: 前端视频上传功能 + +--- + +## 🆕 Web 视频上传功能 (15:32) + +**需求**:用户需要通过 Web 界面上传原视频,而非手动放入目录 + +**实现**: +- 后端 `POST /api/materials/` 已有完整上传接口 +- 前端 `page.tsx` 新增上传 UI 组件 + +### 修改的文件 + +| 文件 | 修改内容 | +|------|----------| +| `frontend/src/app/page.tsx` | 添加上传按钮、进度条、handleUpload 函数 | + +### 功能特性 + +1. **上传按钮**:紫色渐变样式,位于素材区块标题栏 +2. **文件验证**:仅接受 MP4/MOV/AVI 格式 +3. **进度显示**:使用 XMLHttpRequest 实时追踪上传进度 +4. **自动刷新**:上传成功后自动刷新素材列表 +5. **错误处理**:显示文件类型错误、网络错误等提示 + +--- + +## ✅ Day 5 完成事项 + +- [x] 添加视频上传 UI 组件 +- [x] 实现上传进度显示 +- [x] 上传成功后自动刷新素材列表 +- [ ] 手动测试验证 diff --git a/Docs/task_complete.md b/Docs/task_complete.md index 4a8c593..c7f3651 100644 --- a/Docs/task_complete.md +++ b/Docs/task_complete.md @@ -2,8 +2,8 @@ **项目**:ViGent 数字人口播视频生成系统 **服务器**:Dell R730 (2× RTX 3090 24GB) -**更新时间**:2026-01-16 -**整体进度**:100%(MuseTalk 口型同步完整修复,端到端验证通过) +**更新时间**:2026-01-19 +**整体进度**:100%(Day 5 前端视频上传功能完成) ## 📖 快速导航 @@ -16,7 +16,7 @@ | [时间线](#-时间线) | 开发历程 | **相关文档**: -- [Day 日志](file:///d:/CodingProjects/Antigravity/ViGent/Docs/DevLogs/) (Day1-4) +- [Day 日志](file:///d:/CodingProjects/Antigravity/ViGent/Docs/DevLogs/) (Day1-5) - [部署指南](file:///d:/CodingProjects/Antigravity/ViGent/Docs/DEPLOY_MANUAL.md) --- @@ -68,6 +68,11 @@ - [x] 视频合成 MP4 生成验证 - [x] 端到端流程完整测试 +### 阶段八:前端功能增强 (Day 5) +- [x] Web 视频上传功能 +- [x] 上传进度显示 +- [x] 自动刷新素材列表 + --- ## 🛤️ 后续规划 @@ -163,5 +168,10 @@ Day 4: 口型同步完整修复 ✅ 完成 - audio_processor.py 音视频长度修复 - inference.py 错误日志增强 - MP4 视频合成验证通过 + +Day 5: 前端功能增强 ✅ 完成 + - Web 视频上传功能 + - 上传进度显示 + - 自动刷新素材列表 ``` diff --git a/frontend/src/app/page.tsx b/frontend/src/app/page.tsx index f935dd2..b464743 100644 --- a/frontend/src/app/page.tsx +++ b/frontend/src/app/page.tsx @@ -37,6 +37,9 @@ export default function Home() { const [generatedVideo, setGeneratedVideo] = useState(null); const [fetchError, setFetchError] = useState(null); const [debugData, setDebugData] = useState(""); + const [isUploading, setIsUploading] = useState(false); + const [uploadProgress, setUploadProgress] = useState(0); + const [uploadError, setUploadError] = useState(null); // 可选音色 const voices = [ @@ -83,6 +86,58 @@ export default function Home() { } }; + // 上传视频 + const handleUpload = async (e: React.ChangeEvent) => { + const file = e.target.files?.[0]; + if (!file) return; + + // 验证文件类型 + const validTypes = ['.mp4', '.mov', '.avi']; + const ext = file.name.toLowerCase().slice(file.name.lastIndexOf('.')); + if (!validTypes.includes(ext)) { + setUploadError('仅支持 MP4、MOV、AVI 格式'); + return; + } + + setIsUploading(true); + setUploadProgress(0); + setUploadError(null); + + const formData = new FormData(); + formData.append('file', file); + + // 使用 XMLHttpRequest 以获取上传进度 + const xhr = new XMLHttpRequest(); + + xhr.upload.onprogress = (event) => { + if (event.lengthComputable) { + const progress = Math.round((event.loaded / event.total) * 100); + setUploadProgress(progress); + } + }; + + xhr.onload = () => { + setIsUploading(false); + if (xhr.status >= 200 && xhr.status < 300) { + fetchMaterials(); // 刷新素材列表 + setUploadProgress(100); + } else { + setUploadError(`上传失败: ${xhr.statusText}`); + } + }; + + xhr.onerror = () => { + setIsUploading(false); + setUploadError('网络错误,上传失败'); + }; + + xhr.open('POST', `${API_BASE}/api/materials/`); + xhr.send(formData); + + // 清空 input 以便可以再次选择同一文件 + e.target.value = ''; + }; + // 生成视频 const handleGenerate = async () => { if (!selectedMaterial || !text.trim()) { @@ -162,14 +217,62 @@ export default function Home() {

📹 选择素材视频

- +
+ {/* 隐藏的文件输入 */} + + + +
+ {/* 上传进度条 */} + {isUploading && ( +
+
+ 📤 上传中... + {uploadProgress}% +
+
+
+
+
+ )} + + {/* 上传错误提示 */} + {uploadError && ( +
+ ❌ {uploadError} + +
+ )} + {fetchError ? (
获取素材失败: {fetchError} @@ -178,16 +281,11 @@ export default function Home() {
) : materials.length === 0 ? (
+
📁

暂无素材视频

- 请将视频放入 backend/uploads/materials/ 目录 + 点击上方「📤 上传视频」按钮添加素材

-
-

Debug Info:

-

Items: {materials.length}

-

Raw Response:

-

{debugData}

-
) : (