9.6 KiB
9.6 KiB
Day 14 - 模型升级 + 标题标签生成 + 前端修复
日期:2026-01-30
🚀 Qwen3-TTS 模型升级 (0.6B → 1.7B)
背景
为提升声音克隆质量,将 Qwen3-TTS 模型从 0.6B-Base 升级到 1.7B-Base。
变更内容
| 项目 | 升级前 | 升级后 |
|---|---|---|
| 模型 | 0.6B-Base | 1.7B-Base |
| 大小 | 2.4GB | 6.8GB |
| 质量 | 基础 | 更高质量 |
代码修改
文件: models/Qwen3-TTS/qwen_tts_server.py
# 升级前
MODEL_PATH = Path(__file__).parent / "checkpoints" / "0.6B-Base"
# 升级后
MODEL_PATH = Path(__file__).parent / "checkpoints" / "1.7B-Base"
模型下载
cd /home/rongye/ProgramFiles/ViGent2/models/Qwen3-TTS
# 下载 1.7B-Base 模型 (6.8GB)
modelscope download --model Qwen/Qwen3-TTS-12Hz-1.7B-Base --local_dir ./checkpoints/1.7B-Base
结果
- ✅ 模型加载正常 (GPU0, bfloat16)
- ✅ 声音克隆质量提升
- ✅ 推理速度可接受
🎨 标题和字幕显示优化
字幕组件优化 (Subtitles.tsx)
文件: remotion/src/components/Subtitles.tsx
优化内容:
- 调整高亮颜色配置
- 优化文字描边效果(多层阴影)
- 调整字间距和行高
export const Subtitles: React.FC<SubtitlesProps> = ({
captions,
highlightColor = '#FFFF00', // 高亮颜色
normalColor = '#FFFFFF', // 普通文字颜色
fontSize = 52,
}) => {
// 样式优化
const style = {
textShadow: `
2px 2px 4px rgba(0,0,0,0.8),
-2px -2px 4px rgba(0,0,0,0.8),
...
`,
letterSpacing: '2px',
lineHeight: 1.4,
maxWidth: '90%',
};
};
标题组件优化 (Title.tsx)
文件: remotion/src/components/Title.tsx
优化内容:
- 淡入淡出动画效果
- 下滑入场动画
- 可配置显示时长
interface TitleProps {
title: string;
duration?: number; // 标题显示时长(秒,默认3秒)
fadeOutStart?: number; // 开始淡出的时间(秒,默认2秒)
}
// 动画效果
// 淡入:0-0.5 秒
// 淡出:2-3 秒
// 下滑:0-0.5 秒,-20px → 0px
结果
- ✅ 字幕显示更清晰
- ✅ 标题动画更流畅
🤖 标题标签自动生成功能
功能描述
使用 AI(智谱 GLM-4-Flash)根据口播文案自动生成视频标题和标签。
后端实现
1. GLM 服务 (glm_service.py)
文件: backend/app/services/glm_service.py
class GLMService:
"""智谱 GLM AI 服务"""
async def generate_meta(self, text: str) -> dict:
"""根据文案生成标题和标签"""
prompt = """根据以下口播文案,生成一个吸引人的短视频标题和3个相关标签。
要求:
1. 标题要简洁有力,能吸引观众点击,不超过10个字
2. 标签要与内容相关,便于搜索和推荐,只要3个
返回格式:{"title": "标题", "tags": ["标签1", "标签2", "标签3"]}
"""
# 调用 GLM-4-Flash API
response = await self._call_api(prompt + text)
return self._parse_json(response)
JSON 解析容错:
- 支持直接 JSON 解析
- 支持提取 JSON 块
- 支持 ```json 代码块提取
2. API 端点 (ai.py)
文件: backend/app/api/ai.py
from pydantic import BaseModel
class GenerateMetaRequest(BaseModel):
text: str # 口播文案
class GenerateMetaResponse(BaseModel):
title: str # 生成的标题
tags: list[str] # 生成的标签列表
@router.post("/generate-meta", response_model=GenerateMetaResponse)
async def generate_meta(request: GenerateMetaRequest):
"""AI 生成标题和标签"""
result = await glm_service.generate_meta(request.text)
return result
前端实现
文件: frontend/src/app/page.tsx
UI 按钮
<button
onClick={handleGenerateMeta}
disabled={isGeneratingMeta || !text.trim()}
className="px-2 py-1 text-xs rounded transition-all whitespace-nowrap"
>
{isGeneratingMeta ? "⏳ 生成中..." : "🤖 AI生成标题标签"}
</button>
处理逻辑
const handleGenerateMeta = async () => {
if (!text.trim()) {
alert("请先输入口播文案");
return;
}
setIsGeneratingMeta(true);
try {
const { data } = await api.post('/api/ai/generate-meta', { text: text.trim() });
// 更新首页标题
setVideoTitle(data.title || "");
// 同步到发布页 localStorage
localStorage.setItem(`vigent_${storageKey}_publish_title`, data.title || "");
localStorage.setItem(`vigent_${storageKey}_publish_tags`, JSON.stringify(data.tags || []));
} catch (err: any) {
alert(`AI 生成失败: ${err.message}`);
} finally {
setIsGeneratingMeta(false);
}
};
发布页集成
文件: frontend/src/app/publish/page.tsx
从 localStorage 恢复 AI 生成的标题和标签:
// 恢复标题和标签
const savedTitle = localStorage.getItem(`vigent_${storageKey}_publish_title`);
const savedTags = localStorage.getItem(`vigent_${storageKey}_publish_tags`);
if (savedTags) {
try {
const parsed = JSON.parse(savedTags);
if (Array.isArray(parsed)) {
setTags(parsed.join(', ')); // 数组转逗号分隔字符串
} else {
setTags(savedTags);
}
} catch {
setTags(savedTags);
}
}
结果
- ✅ AI 生成标题和标签功能正常
- ✅ 数据自动同步到发布页
- ✅ 支持 JSON 数组和字符串格式兼容
🐛 前端文本保存问题修复
问题描述
现象:页面刷新后,用户输入的文案、标题等数据丢失
原因:
- 认证状态恢复失败时,
userId为null - 原代码判断
!userId后用默认值覆盖 localStorage 数据 - 导致已保存的用户数据被清空
解决方案
文件: frontend/src/app/page.tsx
1. 添加恢复完成标志
const [isRestored, setIsRestored] = useState(false);
2. 等待认证完成后恢复数据
useEffect(() => {
if (isAuthLoading) return; // 等待认证完成
// 使用 userId 或 'guest' 作为 key
const key = userId || 'guest';
// 从 localStorage 恢复数据
const savedText = localStorage.getItem(`vigent_${key}_text`);
if (savedText) setText(savedText);
// ... 恢复其他数据
setIsRestored(true); // 标记恢复完成
}, [userId, isAuthLoading]);
3. 恢复完成后才保存
useEffect(() => {
if (isRestored) {
localStorage.setItem(`vigent_${storageKey}_text`, text);
}
}, [text, storageKey, isRestored]);
用户隔离机制
const storageKey = userId || 'guest';
| 用户状态 | storageKey | 说明 |
|---|---|---|
| 已登录 | user_xxx |
数据按用户隔离 |
| 未登录/认证失败 | guest |
使用统一 key |
数据恢复流程
1. 页面加载
↓
2. 检查 isAuthLoading
├─ true: 等待认证完成
└─ false: 继续
↓
3. 确定 storageKey (userId || 'guest')
↓
4. 从 localStorage 读取数据
├─ 有保存数据: 恢复到状态
└─ 无保存数据: 使用默认值
↓
5. 设置 isRestored = true
↓
6. 后续状态变化时保存到 localStorage
保存的数据项
| Key | 说明 |
|---|---|
vigent_${key}_text |
口播文案 |
vigent_${key}_title |
视频标题 |
vigent_${key}_subtitles |
字幕开关 |
vigent_${key}_ttsMode |
TTS 模式 |
vigent_${key}_voice |
选择的音色 |
vigent_${key}_material |
选择的素材 |
vigent_${key}_publish_title |
发布标题 |
vigent_${key}_publish_tags |
发布标签 |
结果
- ✅ 页面刷新后数据正常恢复
- ✅ 认证失败时不会覆盖已保存数据
- ✅ 多用户数据隔离正常
🐛 登录页刷新循环修复
问题描述
现象:登录页未登录时不断刷新,无法停留在表单页面。
原因:
AuthProvider初始化时调用/api/auth/me- 未登录返回 401
axios全局拦截器遇到 401/403 重定向/login- 登录页本身也在 Provider 中,导致循环刷新
解决方案
文件: frontend/src/shared/api/axios.ts
在拦截器中对公开路由跳过重定向,仅在受保护页面触发登录跳转:
const PUBLIC_PATHS = new Set(['/login', '/register']);
const isPublicPath = typeof window !== 'undefined' && PUBLIC_PATHS.has(window.location.pathname);
if ((status === 401 || status === 403) && !isRedirecting && !isPublicPath) {
// ... 保持原有重定向逻辑
}
结果
- ✅ 登录页不再刷新,表单可正常输入
- ✅ 受保护页面仍会在 401/403 时跳转登录页
📁 今日修改文件清单
| 文件 | 变更类型 | 说明 |
|---|---|---|
models/Qwen3-TTS/qwen_tts_server.py |
修改 | 模型路径升级到 1.7B-Base |
Docs/QWEN3_TTS_DEPLOY.md |
修改 | 更新部署文档为 1.7B 版本 |
remotion/src/components/Subtitles.tsx |
修改 | 优化字幕显示效果 |
remotion/src/components/Title.tsx |
修改 | 优化标题动画效果 |
backend/app/services/glm_service.py |
新增 | GLM AI 服务 |
backend/app/api/ai.py |
新增 | AI 生成标题标签 API |
backend/app/main.py |
修改 | 注册 ai 路由 |
frontend/src/app/page.tsx |
修改 | AI 生成按钮 + localStorage 修复 |
frontend/src/app/publish/page.tsx |
修改 | 恢复 AI 生成的标签 |
frontend/src/shared/api/axios.ts |
修改 | 公开路由跳过 401/403 登录重定向 |
🔗 相关文档
- task_complete.md - 任务总览
- Day13.md - 声音克隆功能集成 + 字幕功能
- QWEN3_TTS_DEPLOY.md - Qwen3-TTS 1.7B 部署指南