This commit is contained in:
Kevin Wong
2026-01-28 17:22:31 +08:00
parent ee8cb9cfd2
commit 4a3dd2b225
46 changed files with 12739 additions and 287 deletions

View File

@@ -1,4 +1,3 @@
---
## 🔧 上传架构重构 (Direct Upload)
@@ -52,7 +51,7 @@ TO anon WITH CHECK (bucket_id = 'materials');
-**解除大小限制**:不再受限于后端服务的 `client_max_body_size`
-**用户体验提升**:上传速度更快,进度条更准确。
---
## 🔧 Supabase 部署与 RLS 配置
@@ -242,3 +241,38 @@ docker compose restart studio
| `backend/.env` | 修改 | 添加 SUPABASE_PUBLIC_URL |
| `Supabase/.env` | 修改 | SUPABASE_PUBLIC_URL |
| `frontend/src/app/page.tsx` | 修改 | 改用后端API上传 |
---
## 📅 明日任务规划 (Day 12)
### 🎯 目标:部署 Qwen3-TTS 0.6B 声音克隆系统
**任务背景**
- 当前使用 EdgeTTS微软云端 TTS音色固定无法自定义
- Qwen3-TTS 支持**零样本声音克隆**,可用少量音频克隆任意人声
**核心任务**
1. **模型部署**
- 创建独立 Conda 环境 (`qwen-tts`)
- 下载 Qwen3-TTS 0.6B 模型权重
- 配置 GPU 推理环境
2. **后端集成**
- 新增 `qwen_tts_service.py` 服务
- 支持声音克隆:上传参考音频 → 生成克隆语音
- 兼容现有 `tts_service.py` 接口
3. **前端适配**
- 添加"声音克隆"选项
- 支持上传参考音频3-10秒
- 音色预览功能
**预期成果**
- ✅ 用户可上传自己的声音样本
- ✅ 生成的口播视频使用克隆后的声音
- ✅ 保留 EdgeTTS 作为备选方案
**参考资源**
- 模型:[Qwen/Qwen3-TTS-0.6B](https://huggingface.co/Qwen/Qwen3-TTS-0.6B)
- 显存需求:~4GB (0.6B 参数量)

347
Docs/DevLogs/Day12.md Normal file
View File

@@ -0,0 +1,347 @@
# Day 12 - iOS 兼容与移动端 UI 优化
**日期**2026-01-28
---
## 🔐 Axios 全局拦截器优化
### 背景
统一处理 API 请求的认证失败场景,避免各页面重复处理 401/403 错误。
### 实现 (`frontend/src/lib/axios.ts`)
```typescript
import axios from 'axios';
// 动态获取 API 地址:服务端使用 localhost客户端使用当前域名
const API_BASE = typeof window === 'undefined'
? 'http://localhost:8006'
: '';
// 防止重复跳转
let isRedirecting = false;
const api = axios.create({
baseURL: API_BASE,
withCredentials: true, // 自动携带 HttpOnly cookie
headers: { 'Content-Type': 'application/json' },
});
// 响应拦截器 - 全局处理 401/403
api.interceptors.response.use(
(response) => response,
async (error) => {
const status = error.response?.status;
if ((status === 401 || status === 403) && !isRedirecting) {
isRedirecting = true;
// 调用 logout API 清除 HttpOnly cookie
try {
await fetch('/api/auth/logout', { method: 'POST' });
} catch (e) { /* 忽略 */ }
// 跳转登录页
if (typeof window !== 'undefined') {
window.location.replace('/login');
}
}
return Promise.reject(error);
}
);
export default api;
```
### 关键特性
-**自动携带 Cookie**: `withCredentials: true` 确保 HttpOnly JWT cookie 被发送
-**401/403 自动跳转**: 认证失败时自动清理并跳转登录页
-**防重复跳转**: `isRedirecting` 标志避免多个请求同时触发跳转
-**SSR 兼容**: 服务端渲染时使用 `localhost`,客户端使用相对路径
---
## 🔧 iOS Safari 安全区域白边修复
### 问题描述
iPhone Safari 浏览器底部和顶部显示白色区域,安卓正常。原因是 iOS Safari 有安全区域 (Safe Area),页面背景没有延伸到该区域。
### 根本原因
1. 缺少 `viewport-fit=cover` 配置
2. `min-h-screen` (100vh) 在 iOS Safari 中不包含安全区域
3. 背景渐变在页面 div 上,而非 body 上,导致安全区域显示纯色
### 解决方案
#### 1. 添加 viewport 配置 (`layout.tsx`)
```typescript
export const viewport: Viewport = {
width: 'device-width',
initialScale: 1,
viewportFit: 'cover', // 允许内容延伸到安全区域
themeColor: '#0f172a', // 顶部状态栏颜色
};
```
#### 2. 统一渐变背景到 body (`layout.tsx`)
```tsx
<html lang="en" style={{ backgroundColor: '#0f172a' }}>
<body
style={{
margin: 0,
minHeight: '100dvh',
background: 'linear-gradient(to bottom, #0f172a 0%, #0f172a 5%, #581c87 50%, #0f172a 95%, #0f172a 100%)',
}}
>
{children}
</body>
</html>
```
#### 3. CSS 安全区域支持 (`globals.css`)
```css
html {
background-color: #0f172a !important;
min-height: 100%;
}
body {
margin: 0 !important;
min-height: 100dvh;
padding-top: env(safe-area-inset-top);
padding-bottom: env(safe-area-inset-bottom);
}
```
#### 4. 移除页面独立渐变背景
各页面的根 div 移除 `bg-gradient-to-br` 类,统一使用 body 渐变:
- `page.tsx`
- `login/page.tsx`
- `publish/page.tsx`
- `admin/page.tsx`
- `register/page.tsx`
### 结果
- ✅ 顶部状态栏颜色与页面一致 (themeColor)
- ✅ 底部安全区域颜色与渐变边缘一致
- ✅ 消除分层感,背景统一
---
## 📱 移动端 Header 响应式优化
### 问题描述
移动端顶部导航按钮(视频生成、发布管理、退出)过于拥挤,文字换行显示。
### 解决方案
#### 首页 Header (`page.tsx`)
```tsx
<header className="border-b border-white/10 bg-black/20 backdrop-blur-sm">
<div className="max-w-6xl mx-auto px-4 sm:px-6 py-3 sm:py-4 flex items-center justify-between">
<Link href="/" className="text-xl sm:text-2xl font-bold ...">
<span className="text-3xl sm:text-4xl">🎬</span>
ViGent
</Link>
<div className="flex items-center gap-1 sm:gap-4">
<span className="px-2 sm:px-4 py-1 sm:py-2 text-sm sm:text-base ...">
</span>
<!-- 其他按钮同样处理 -->
</div>
</div>
</header>
```
#### 发布管理页 Header (`publish/page.tsx`)
同步应用相同的响应式类名。
### 关键改动
| 属性 | 移动端 | 桌面端 |
|------|--------|--------|
| 容器内边距 | `px-4 py-3` | `px-6 py-4` |
| 按钮间距 | `gap-1` | `gap-4` |
| 按钮内边距 | `px-2 py-1` | `px-4 py-2` |
| 字体大小 | `text-sm` | `text-base` |
| Logo 大小 | `text-xl` + `text-3xl` | `text-2xl` + `text-4xl` |
### 结果
- ✅ 移动端按钮紧凑排列,不再换行
- ✅ 桌面端保持原有宽松布局
---
## 🚀 发布页面 UI 重构
### 问题描述
原有设计将"发布时间"选项放在表单中,用户可能误选"定时发布"但忘记设置时间。
### 解决方案
将"一键发布"按钮改为两个独立按钮:
- **立即发布** (绿色,占 3/4 宽度) - 主要操作
- **定时** (占 1/4 宽度) - 点击展开时间选择器
#### 新布局 (`publish/page.tsx`)
```tsx
{/* 发布按钮区域 */}
<div className="space-y-3">
<div className="flex gap-3">
{/* 立即发布 - 占 3/4 */}
<button
onClick={() => { setScheduleMode("now"); handlePublish(); }}
className="flex-[3] py-4 rounded-xl font-bold text-lg bg-gradient-to-r from-green-600 to-teal-600 ..."
>
🚀
</button>
{/* 定时发布 - 占 1/4 */}
<button
onClick={() => setScheduleMode(scheduleMode === "scheduled" ? "now" : "scheduled")}
className="flex-1 py-4 rounded-xl font-bold text-base ..."
>
</button>
</div>
{/* 定时发布时间选择器 (展开时显示) */}
{scheduleMode === "scheduled" && (
<div className="flex gap-3 items-center">
<input type="datetime-local" ... />
<button></button>
</div>
)}
</div>
```
### 结果
- ✅ 主操作(立即发布)更醒目
- ✅ 定时发布需要二次确认,防止误触
- ✅ 从表单区域移除发布时间选项,界面更简洁
---
## 🛤️ 后续优化项
### 后端定时发布 (待实现)
**当前状态**:定时发布使用平台端定时(在各平台设置发布时间)
**优化方向**:改为后端定时任务
- 使用 APScheduler 实现任务调度
- 存储定时任务到数据库
- 到时间后端自动触发发布 API
- 支持查看/取消定时任务
**优势**
- 统一逻辑,不依赖平台定时 UI
- 更灵活,可管理定时任务
- 平台页面更新不影响功能
---
## 🤖 Qwen3-TTS 0.6B 声音克隆部署
### 背景
为实现用户自定义声音克隆功能,部署 Qwen3-TTS 0.6B-Base 模型,支持 3 秒参考音频快速克隆。
### GPU 分配
| GPU | 服务 | 模型 |
|-----|------|------|
| GPU0 | Qwen3-TTS | 0.6B-Base (声音克隆) |
| GPU1 | LatentSync | 1.6 (唇形同步) |
### 部署步骤
#### 1. 克隆仓库
```bash
cd /home/rongye/ProgramFiles/ViGent2/models
git clone https://github.com/QwenLM/Qwen3-TTS.git
```
#### 2. 创建 conda 环境
```bash
conda create -n qwen-tts python=3.10 -y
conda activate qwen-tts
```
#### 3. 安装依赖
```bash
cd Qwen3-TTS
pip install -e .
conda install -y -c conda-forge sox # 音频处理依赖
```
#### 4. 下载模型权重 (使用 ModelScope国内更快)
```bash
pip install modelscope
# Tokenizer (651MB)
modelscope download --model Qwen/Qwen3-TTS-Tokenizer-12Hz --local_dir ./checkpoints/Tokenizer
# 0.6B-Base 模型 (2.4GB)
modelscope download --model Qwen/Qwen3-TTS-12Hz-0.6B-Base --local_dir ./checkpoints/0.6B-Base
```
#### 5. 测试推理
```python
# test_inference.py
import torch
import soundfile as sf
from qwen_tts import Qwen3TTSModel
model = Qwen3TTSModel.from_pretrained(
"./checkpoints/0.6B-Base",
device_map="cuda:0",
dtype=torch.bfloat16,
)
wavs, sr = model.generate_voice_clone(
text="测试文本",
language="Chinese",
ref_audio="./examples/myvoice.wav",
ref_text="参考音频的文字内容",
)
sf.write("output.wav", wavs[0], sr)
```
### 测试结果
- ✅ 模型加载成功 (GPU0)
- ✅ 声音克隆推理成功
- ✅ 输出音频 24000Hz质量良好
### 目录结构
```
models/Qwen3-TTS/
├── checkpoints/
│ ├── Tokenizer/ # 651MB
│ └── 0.6B-Base/ # 2.4GB
├── qwen_tts/ # 源码
├── examples/
│ └── myvoice.wav # 参考音频
└── test_inference.py # 测试脚本
```
---
## 📁 今日修改文件清单
| 文件 | 变更类型 | 说明 |
|------|----------|------|
| `frontend/src/lib/axios.ts` | 修改 | Axios 全局拦截器 (401/403 自动跳转) |
| `frontend/src/app/layout.tsx` | 修改 | viewport 配置 + body 渐变背景 |
| `frontend/src/app/globals.css` | 修改 | 安全区域 CSS 支持 |
| `frontend/src/app/page.tsx` | 修改 | 移除独立渐变 + Header 响应式 |
| `frontend/src/app/login/page.tsx` | 修改 | 移除独立渐变 |
| `frontend/src/app/publish/page.tsx` | 修改 | Header 响应式 + 发布按钮重构 |
| `frontend/src/app/admin/page.tsx` | 修改 | 移除独立渐变 |
| `frontend/src/app/register/page.tsx` | 修改 | 移除独立渐变 |
| `README.md` | 修改 | 添加 "iOS/Android 移动端适配" 功能说明 |
| `Docs/FRONTEND_DEV.md` | 修改 | iOS Safari 安全区域兼容规范 + 移动端响应式规则 |
| `models/Qwen3-TTS/` | 新增 | Qwen3-TTS 声音克隆模型部署 |
| `Docs/QWEN3_TTS_DEPLOY.md` | 新增 | Qwen3-TTS 部署指南 |
---
## 🔗 相关文档
- [task_complete.md](../task_complete.md) - 任务总览
- [Day11.md](./Day11.md) - 上传架构重构
- [QWEN3_TTS_DEPLOY.md](../QWEN3_TTS_DEPLOY.md) - Qwen3-TTS 部署指南

View File

@@ -232,7 +232,7 @@ else:
| `src/app/login/page.tsx` | 登录页 | ✅ |
| `src/app/register/page.tsx` | 注册页 | ✅ |
| `src/app/admin/page.tsx` | 管理后台 | ✅ |
| `src/middleware.ts` | 路由保护 | ✅ |
| `src/proxy.ts` | 路由保护 | ✅ |
### 账号隔离集成