This commit is contained in:
Kevin Wong
2026-01-29 17:58:07 +08:00
parent b74bacb0b5
commit cf679b34bf
3 changed files with 449 additions and 3 deletions

View File

@@ -1,4 +1,4 @@
# Day 13 - 声音克隆功能集成完成 # Day 13 - 声音克隆功能集成 + 字幕功能
**日期**2026-01-29 **日期**2026-01-29
@@ -276,4 +276,156 @@ pm2 logs vigent2-qwen-tts --lines 50
- [task_complete.md](../task_complete.md) - 任务总览 - [task_complete.md](../task_complete.md) - 任务总览
- [Day12.md](./Day12.md) - iOS 兼容与 Qwen3-TTS 部署 - [Day12.md](./Day12.md) - iOS 兼容与 Qwen3-TTS 部署
- [QWEN3_TTS_DEPLOY.md](../QWEN3_TTS_DEPLOY.md) - Qwen3-TTS 部署指南 - [QWEN3_TTS_DEPLOY.md](../QWEN3_TTS_DEPLOY.md) - Qwen3-TTS 部署指南
- [SUBTITLE_DEPLOY.md](../SUBTITLE_DEPLOY.md) - 字幕功能部署指南
- [DEPLOY_MANUAL.md](../DEPLOY_MANUAL.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` | 新增 | 字幕功能部署文档 |

281
Docs/SUBTITLE_DEPLOY.md Normal file
View File

@@ -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 实现逐字高亮字幕和片头标题 |

View File

@@ -3,7 +3,7 @@
**项目**ViGent2 数字人口播视频生成系统 **项目**ViGent2 数字人口播视频生成系统
**服务器**Dell R730 (2× RTX 3090 24GB) **服务器**Dell R730 (2× RTX 3090 24GB)
**更新时间**2026-01-29 **更新时间**2026-01-29
**整体进度**100%Day 13 声音克隆功能集成完成) **整体进度**100%Day 13 声音克隆 + 字幕功能完成)
## 📖 快速导航 ## 📖 快速导航
@@ -177,6 +177,14 @@
- [x] **Supabase ref-audios Bucket** (参考音频存储桶 + RLS 策略) - [x] **Supabase ref-audios Bucket** (参考音频存储桶 + RLS 策略)
- [x] **端到端测试验证** (声音克隆完整流程测试通过) - [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] Qwen3-TTS 集成到 ViGent2 ✅ Day 13 完成
- [x] 定时发布功能 ✅ Day 7 完成 - [x] 定时发布功能 ✅ Day 7 完成
- [x] 逐字高亮字幕 ✅ Day 13 完成
- [ ] **后端定时发布** - 替代平台端定时,使用 APScheduler 实现任务调度 - [ ] **后端定时发布** - 替代平台端定时,使用 APScheduler 实现任务调度
- [ ] 批量视频生成 - [ ] 批量视频生成
- [ ] 字幕样式编辑器 - [ ] 字幕样式编辑器
@@ -366,11 +375,15 @@ Day 12: iOS 兼容与移动端优化 ✅ 完成
- **Qwen3-TTS 0.6B 部署** (声音克隆模型GPU0) - **Qwen3-TTS 0.6B 部署** (声音克隆模型GPU0)
- **部署文档** (QWEN3_TTS_DEPLOY.md) - **部署文档** (QWEN3_TTS_DEPLOY.md)
Day 13: 声音克隆功能集成 ✅ 完成 Day 13: 声音克隆 + 字幕功能 ✅ 完成
- Qwen3-TTS HTTP 服务 (独立 FastAPI端口 8009) - Qwen3-TTS HTTP 服务 (独立 FastAPI端口 8009)
- 声音克隆服务 (voice_clone_service.py) - 声音克隆服务 (voice_clone_service.py)
- 参考音频管理 API (上传/列表/删除) - 参考音频管理 API (上传/列表/删除)
- 前端 TTS 模式选择 (EdgeTTS / 声音克隆) - 前端 TTS 模式选择 (EdgeTTS / 声音克隆)
- Supabase ref-audios Bucket 配置 - Supabase ref-audios Bucket 配置
- 端到端测试验证通过 - 端到端测试验证通过
- **faster-whisper 字幕对齐** (字级别时间戳)
- **Remotion 视频渲染** (逐字高亮字幕 + 片头标题)
- **前端标题/字幕设置 UI**
- **部署文档** (SUBTITLE_DEPLOY.md)