diff --git a/Docs/DevLogs/Day13.md b/Docs/DevLogs/Day13.md index efedf24..e397316 100644 --- a/Docs/DevLogs/Day13.md +++ b/Docs/DevLogs/Day13.md @@ -1,4 +1,4 @@ -# Day 13 - 声音克隆功能集成完成 +# Day 13 - 声音克隆功能集成 + 字幕功能 **日期**:2026-01-29 @@ -276,4 +276,156 @@ pm2 logs vigent2-qwen-tts --lines 50 - [task_complete.md](../task_complete.md) - 任务总览 - [Day12.md](./Day12.md) - iOS 兼容与 Qwen3-TTS 部署 - [QWEN3_TTS_DEPLOY.md](../QWEN3_TTS_DEPLOY.md) - Qwen3-TTS 部署指南 +- [SUBTITLE_DEPLOY.md](../SUBTITLE_DEPLOY.md) - 字幕功能部署指南 - [DEPLOY_MANUAL.md](../DEPLOY_MANUAL.md) - 完整部署手册 + +--- + +## 🎬 逐字高亮字幕 + 片头标题功能 + +### 背景 + +为提升视频质量,新增逐字高亮字幕(卡拉OK效果)和片头标题功能。 + +### 技术方案 + +| 组件 | 技术 | 说明 | +|------|------|------| +| 字幕对齐 | **faster-whisper** | 生成字级别时间戳 | +| 视频渲染 | **Remotion** | React 视频合成框架 | + +### 架构设计 + +``` +原有流程: + 文本 → EdgeTTS → 音频 → LatentSync → FFmpeg合成 → 最终视频 + +新流程: + 文本 → EdgeTTS → 音频 ─┬→ LatentSync → 唇形视频 ─┐ + └→ faster-whisper → 字幕JSON ─┴→ Remotion合成 → 最终视频 +``` + +### 后端新增服务 + +#### 1. 字幕服务 (`whisper_service.py`) + +基于 faster-whisper 生成字级别时间戳: + +```python +from faster_whisper import WhisperModel + +class WhisperService: + def __init__(self, model_size="large-v3", device="cuda"): + self.model = WhisperModel(model_size, device=device) + + async def align(self, audio_path: str, text: str, output_path: str): + segments, info = self.model.transcribe(audio_path, word_timestamps=True) + # 将词拆分成单字,时间戳线性插值 + result = {"segments": [...]} + # 保存到 JSON +``` + +**字幕拆字算法**:faster-whisper 对中文返回词级别,系统自动拆分成单字并线性插值: + +```python +# 输入: {"word": "大家好", "start": 0.0, "end": 0.9} +# 输出: +[ + {"word": "大", "start": 0.0, "end": 0.3}, + {"word": "家", "start": 0.3, "end": 0.6}, + {"word": "好", "start": 0.6, "end": 0.9} +] +``` + +#### 2. Remotion 渲染服务 (`remotion_service.py`) + +调用 Remotion 渲染字幕和标题: + +```python +class RemotionService: + async def render(self, video_path, output_path, captions_path, title, ...): + cmd = f"npx ts-node render.ts --video {video_path} --output {output_path} ..." + # 执行渲染 +``` + +### Remotion 项目结构 + +``` +remotion/ +├── package.json # Node.js 依赖 +├── render.ts # 服务端渲染脚本 +└── src/ + ├── Video.tsx # 主视频组件 + ├── components/ + │ ├── Title.tsx # 片头标题(淡入淡出) + │ ├── Subtitles.tsx # 逐字高亮字幕 + │ └── VideoLayer.tsx # 视频图层 + └── utils/ + └── captions.ts # 字幕数据类型 +``` + +### 前端 UI + +新增标题和字幕设置区块: + +| 功能 | 说明 | +|------|------| +| 片头标题输入 | 可选,在视频开头显示 3 秒 | +| 字幕开关 | 默认开启,可关闭 | + +### 遇到的问题与修复 + +#### 问题 1: `fs` 模块错误 + +**现象**:Remotion 打包失败,提示 `fs.js doesn't exist` + +**原因**:`captions.ts` 中有 `loadCaptions` 函数使用了 Node.js 的 `fs` 模块 + +**修复**:删除未使用的 `loadCaptions` 函数 + +#### 问题 2: 视频文件读取失败 + +**现象**:`file://` 协议无法读取本地视频 + +**修复**: +1. `render.ts` 使用 `publicDir` 指向视频目录 +2. `VideoLayer.tsx` 使用 `staticFile()` 加载视频 + +```typescript +// render.ts +const publicDir = path.dirname(path.resolve(options.videoPath)); +const bundleLocation = await bundle({ + entryPoint: path.resolve(__dirname, './src/index.ts'), + publicDir, // 关键配置 +}); + +// VideoLayer.tsx +const videoUrl = staticFile(videoSrc); +``` + +### 测试结果 + +- ✅ faster-whisper 字幕对齐成功(~1秒) +- ✅ Remotion 渲染成功(~10秒) +- ✅ 字幕逐字高亮效果正常 +- ✅ 片头标题淡入淡出正常 +- ✅ 降级机制正常(Remotion 失败时回退到 FFmpeg) + +--- + +## 📁 今日修改文件清单(完整) + +| 文件 | 变更类型 | 说明 | +|------|----------|------| +| `models/Qwen3-TTS/qwen_tts_server.py` | 新增 | Qwen3-TTS HTTP 推理服务 | +| `run_qwen_tts.sh` | 新增 | PM2 启动脚本 (根目录) | +| `backend/app/services/voice_clone_service.py` | 新增 | 声音克隆服务 (HTTP 调用) | +| `backend/app/services/whisper_service.py` | 新增 | 字幕对齐服务 (faster-whisper) | +| `backend/app/services/remotion_service.py` | 新增 | Remotion 渲染服务 | +| `backend/app/api/ref_audios.py` | 新增 | 参考音频管理 API | +| `backend/app/api/videos.py` | 修改 | 集成字幕和标题功能 | +| `backend/app/main.py` | 修改 | 注册 ref-audios 路由 | +| `backend/requirements.txt` | 修改 | 添加 faster-whisper 依赖 | +| `remotion/` | 新增 | Remotion 视频渲染项目 | +| `frontend/src/app/page.tsx` | 修改 | TTS 模式选择 + 标题字幕 UI | +| `Docs/SUBTITLE_DEPLOY.md` | 新增 | 字幕功能部署文档 | diff --git a/Docs/SUBTITLE_DEPLOY.md b/Docs/SUBTITLE_DEPLOY.md new file mode 100644 index 0000000..df8d5e0 --- /dev/null +++ b/Docs/SUBTITLE_DEPLOY.md @@ -0,0 +1,281 @@ +# ViGent2 字幕与标题功能部署指南 + +本文档介绍如何部署 ViGent2 的逐字高亮字幕和片头标题功能。 + +## 功能概述 + +| 功能 | 说明 | +|------|------| +| **逐字高亮字幕** | 使用 faster-whisper 生成字级别时间戳,Remotion 渲染卡拉OK效果 | +| **片头标题** | 视频开头显示标题,带淡入淡出动画,几秒后消失 | + +## 技术架构 + +``` +原有流程: + 文本 → EdgeTTS → 音频 → LatentSync → FFmpeg合成 → 最终视频 + +新流程: + 文本 → EdgeTTS → 音频 ─┬→ LatentSync → 唇形视频 ─┐ + └→ faster-whisper → 字幕JSON ─┴→ Remotion合成 → 最终视频 +``` + +## 系统要求 + +| 组件 | 要求 | +|------|------| +| Node.js | 18+ | +| Python | 3.10+ | +| GPU 显存 | faster-whisper 需要约 3-4GB VRAM | +| FFmpeg | 已安装 | + +--- + +## 部署步骤 + +### 步骤 1: 安装 faster-whisper (Python) + +```bash +cd /home/rongye/ProgramFiles/ViGent2/backend +source venv/bin/activate + +# 安装 faster-whisper +pip install faster-whisper>=1.0.0 -i https://pypi.tuna.tsinghua.edu.cn/simple +``` + +> **注意**: 首次运行时,faster-whisper 会自动下载 `large-v3` Whisper 模型 (~3GB) + +### 步骤 2: 安装 Remotion (Node.js) + +```bash +cd /home/rongye/ProgramFiles/ViGent2/remotion + +# 安装依赖 +npm install +``` + +### 步骤 3: 重启后端服务 + +```bash +pm2 restart vigent2-backend +``` + +### 步骤 4: 验证安装 + +```bash +# 检查 faster-whisper 是否安装成功 +cd /home/rongye/ProgramFiles/ViGent2/backend +source venv/bin/activate +python -c "from faster_whisper import WhisperModel; print('faster-whisper OK')" + +# 检查 Remotion 是否安装成功 +cd /home/rongye/ProgramFiles/ViGent2/remotion +npx remotion --version +``` + +--- + +## 文件结构 + +### 后端新增文件 + +| 文件 | 说明 | +|------|------| +| `backend/app/services/whisper_service.py` | 字幕对齐服务 (基于 faster-whisper) | +| `backend/app/services/remotion_service.py` | Remotion 渲染服务 | + +### Remotion 项目结构 + +``` +remotion/ +├── package.json # Node.js 依赖配置 +├── tsconfig.json # TypeScript 配置 +├── render.ts # 服务端渲染脚本 +└── src/ + ├── index.ts # Remotion 入口 + ├── Root.tsx # 根组件 + ├── Video.tsx # 主视频组件 + ├── components/ + │ ├── Title.tsx # 片头标题组件 + │ ├── Subtitles.tsx # 逐字高亮字幕组件 + │ └── VideoLayer.tsx # 视频图层组件 + ├── utils/ + │ └── captions.ts # 字幕数据处理工具 + └── fonts/ # 字体文件目录 (可选) +``` + +--- + +## API 参数 + +视频生成 API (`POST /api/videos/generate`) 新增以下参数: + +| 参数 | 类型 | 默认值 | 说明 | +|------|------|--------|------| +| `title` | string | null | 视频标题(片头显示,可选) | +| `enable_subtitles` | boolean | true | 是否启用逐字高亮字幕 | + +### 请求示例 + +```json +{ + "material_path": "https://...", + "text": "大家好,欢迎来到我的频道", + "tts_mode": "edgetts", + "voice": "zh-CN-YunxiNeural", + "title": "今日分享", + "enable_subtitles": true +} +``` + +--- + +## 视频生成流程 + +新的视频生成流程进度分配: + +| 阶段 | 进度 | 说明 | +|------|------|------| +| 下载素材 | 0% → 5% | 从 Supabase 下载输入视频 | +| TTS 语音生成 | 5% → 25% | EdgeTTS 或 Qwen3-TTS 生成音频 | +| 唇形同步 | 25% → 80% | LatentSync 推理 | +| 字幕对齐 | 80% → 85% | faster-whisper 生成字级别时间戳 | +| Remotion 渲染 | 85% → 95% | 合成字幕和标题 | +| 上传结果 | 95% → 100% | 上传到 Supabase Storage | + +--- + +## 降级处理 + +系统包含自动降级机制,确保基本功能不受影响: + +| 场景 | 处理方式 | +|------|----------| +| 字幕对齐失败 | 跳过字幕,继续生成视频 | +| Remotion 未安装 | 使用 FFmpeg 直接合成 | +| Remotion 渲染失败 | 回退到 FFmpeg 合成 | + +--- + +## 配置说明 + +### 字幕服务配置 + +字幕服务位于 `backend/app/services/whisper_service.py`,默认配置: + +| 参数 | 默认值 | 说明 | +|------|--------|------| +| `model_size` | large-v3 | Whisper 模型大小 | +| `device` | cuda | 运行设备 | +| `compute_type` | float16 | 计算精度 | + +如需修改,可编辑 `whisper_service.py` 中的 `WhisperService` 初始化参数。 + +### Remotion 配置 + +Remotion 渲染参数在 `backend/app/services/remotion_service.py` 中配置: + +| 参数 | 默认值 | 说明 | +|------|--------|------| +| `fps` | 25 | 输出帧率 | +| `title_duration` | 3.0 | 标题显示时长(秒) | + +--- + +## 故障排除 + +### faster-whisper 相关 + +**问题**: `ModuleNotFoundError: No module named 'faster_whisper'` + +```bash +cd /home/rongye/ProgramFiles/ViGent2/backend +source venv/bin/activate +pip install faster-whisper>=1.0.0 -i https://pypi.tuna.tsinghua.edu.cn/simple +``` + +**问题**: GPU 显存不足 + +修改 `whisper_service.py`,使用较小的模型: +```python +WhisperService(model_size="medium", compute_type="int8") +``` + +### Remotion 相关 + +**问题**: `node_modules not found` + +```bash +cd /home/rongye/ProgramFiles/ViGent2/remotion +npm install +``` + +**问题**: Remotion 渲染失败 - `fs` 模块错误 + +确保 `remotion/src/utils/captions.ts` 中没有使用 Node.js 的 `fs` 模块。Remotion 在浏览器环境打包,不支持 `fs`。 + +**问题**: Remotion 渲染失败 - 视频文件读取错误 (`file://` 协议) + +确保 `render.ts` 使用 `publicDir` 选项指向视频所在目录,`VideoLayer.tsx` 使用 `staticFile()` 加载视频: + +```typescript +// render.ts +const publicDir = path.dirname(path.resolve(options.videoPath)); +const bundleLocation = await bundle({ + entryPoint: path.resolve(__dirname, './src/index.ts'), + publicDir, // 关键配置 +}); + +// VideoLayer.tsx +const videoUrl = staticFile(videoSrc); // 使用 staticFile +``` + +**问题**: Remotion 渲染失败 + +查看后端日志: +```bash +pm2 logs vigent2-backend +``` + +### 查看服务健康状态 + +```bash +# 字幕服务健康检查 +cd /home/rongye/ProgramFiles/ViGent2/backend +source venv/bin/activate +python -c "from app.services.whisper_service import whisper_service; import asyncio; print(asyncio.run(whisper_service.check_health()))" + +# Remotion 健康检查 +python -c "from app.services.remotion_service import remotion_service; import asyncio; print(asyncio.run(remotion_service.check_health()))" +``` + +--- + +## 可选优化 + +### 添加中文字体 + +为获得更好的字幕渲染效果,可添加中文字体: + +```bash +# 下载 Noto Sans SC 字体 +cd /home/rongye/ProgramFiles/ViGent2/remotion/src/fonts +wget https://github.com/googlefonts/noto-cjk/raw/main/Sans/OTF/SimplifiedChinese/NotoSansSC-Regular.otf -O NotoSansSC.otf +``` + +### 使用 GPU 0 + +faster-whisper 默认使用 GPU 0,与 LatentSync (GPU 1) 分开,避免显存冲突。如需指定 GPU: + +```python +# 在 whisper_service.py 中修改 +WhisperService(device="cuda:0") # 或 "cuda:1" +``` + +--- + +## 更新日志 + +| 日期 | 版本 | 说明 | +|------|------|------| +| 2026-01-29 | 1.0.0 | 初始版本,使用 faster-whisper + Remotion 实现逐字高亮字幕和片头标题 | diff --git a/Docs/task_complete.md b/Docs/task_complete.md index 7ca70ca..fd5129f 100644 --- a/Docs/task_complete.md +++ b/Docs/task_complete.md @@ -3,7 +3,7 @@ **项目**:ViGent2 数字人口播视频生成系统 **服务器**:Dell R730 (2× RTX 3090 24GB) **更新时间**:2026-01-29 -**整体进度**:100%(Day 13 声音克隆功能集成完成) +**整体进度**:100%(Day 13 声音克隆 + 字幕功能完成) ## 📖 快速导航 @@ -177,6 +177,14 @@ - [x] **Supabase ref-audios Bucket** (参考音频存储桶 + RLS 策略) - [x] **端到端测试验证** (声音克隆完整流程测试通过) +### 阶段二十一:逐字高亮字幕 + 片头标题 (Day 13) +- [x] **faster-whisper 字幕对齐** (字级别时间戳生成) +- [x] **Remotion 视频渲染** (React 视频合成框架) +- [x] **逐字高亮字幕** (卡拉OK效果) +- [x] **片头标题** (淡入淡出动画) +- [x] **前端标题/字幕设置 UI** +- [x] **降级机制** (Remotion 失败时回退 FFmpeg) + --- ## 🛤️ 后续规划 @@ -187,6 +195,7 @@ ### 🟠 功能完善 - [x] Qwen3-TTS 集成到 ViGent2 ✅ Day 13 完成 - [x] 定时发布功能 ✅ Day 7 完成 +- [x] 逐字高亮字幕 ✅ Day 13 完成 - [ ] **后端定时发布** - 替代平台端定时,使用 APScheduler 实现任务调度 - [ ] 批量视频生成 - [ ] 字幕样式编辑器 @@ -366,11 +375,15 @@ Day 12: iOS 兼容与移动端优化 ✅ 完成 - **Qwen3-TTS 0.6B 部署** (声音克隆模型,GPU0) - **部署文档** (QWEN3_TTS_DEPLOY.md) -Day 13: 声音克隆功能集成 ✅ 完成 +Day 13: 声音克隆 + 字幕功能 ✅ 完成 - Qwen3-TTS HTTP 服务 (独立 FastAPI,端口 8009) - 声音克隆服务 (voice_clone_service.py) - 参考音频管理 API (上传/列表/删除) - 前端 TTS 模式选择 (EdgeTTS / 声音克隆) - Supabase ref-audios Bucket 配置 - 端到端测试验证通过 + - **faster-whisper 字幕对齐** (字级别时间戳) + - **Remotion 视频渲染** (逐字高亮字幕 + 片头标题) + - **前端标题/字幕设置 UI** + - **部署文档** (SUBTITLE_DEPLOY.md)