403 lines
12 KiB
Markdown
403 lines
12 KiB
Markdown
# VideoConcat 项目文档
|
||
|
||
## 项目概述
|
||
|
||
VideoConcat 是一个基于 WPF 开发的视频处理应用程序,主要用于视频拼接、视频抽帧和视频元数据修改等功能。项目采用 MVVM 架构模式,使用 FFMpegCore 库进行视频处理操作。
|
||
|
||
## 技术栈
|
||
|
||
- **框架**: .NET 8.0
|
||
- **UI框架**: WPF (Windows Presentation Foundation)
|
||
- **视频处理**: FFMpegCore 5.2.0
|
||
- **日志**: log4net 3.1.0
|
||
- **UI组件库**:
|
||
- MaterialDesignThemes.Wpf
|
||
- MahApps.Metro.IconPacks
|
||
- LiveCharts.Wpf (图表库)
|
||
- **依赖注入**: Microsoft.Extensions.DependencyInjection
|
||
- **JSON处理**: Newtonsoft.Json 13.0.3
|
||
|
||
## 项目结构
|
||
|
||
```
|
||
VideoConcat/
|
||
├── Common/ # 公共模块
|
||
│ ├── Api/ # API接口
|
||
│ │ ├── Base/ # 基础API
|
||
│ │ │ ├── SystemApi.cs # 系统API(登录等)
|
||
│ │ │ └── LoginResponse.cs
|
||
│ │ └── Common/ # 通用API
|
||
│ └── Tools/ # 工具类
|
||
│ ├── Config.cs # 配置管理
|
||
│ ├── HttpUtils.cs # HTTP请求封装
|
||
│ ├── LogUtils.cs # 日志工具
|
||
│ └── VideoCombine.cs # 视频组合工具
|
||
├── Conversions/ # 转换器
|
||
│ └── EnumToBooleanConverter.cs
|
||
├── Helpers/ # 辅助类
|
||
│ └── PasswordBoxHelper.cs
|
||
├── Models/ # 数据模型
|
||
│ ├── ExtractWindowModel.cs # 抽帧窗口模型
|
||
│ ├── MainWindowModel.cs # 主窗口模型
|
||
│ └── VideoModel.cs # 视频模型
|
||
├── Services/ # 服务层
|
||
│ ├── BaseService.cs # 基础服务
|
||
│ └── Video/ # 视频服务
|
||
│ ├── VideoProcess.cs # 视频处理服务
|
||
│ └── VideoService.cs # 视频服务
|
||
├── ViewModels/ # 视图模型
|
||
│ ├── ExtractWindowViewModel.cs
|
||
│ ├── MainWindowViewModel.cs
|
||
│ └── VideoViewModel.cs
|
||
├── Views/ # 视图
|
||
│ ├── ExtractWindow.xaml # 抽帧窗口
|
||
│ ├── LoginWindow.xaml # 登录窗口
|
||
│ ├── MainWindow.xaml # 主窗口
|
||
│ └── VideoWindow.xaml # 视频窗口
|
||
├── App.xaml # 应用程序入口
|
||
├── VideoConcat.csproj # 项目文件
|
||
└── README.md # 项目说明
|
||
```
|
||
|
||
## 主要功能
|
||
|
||
### 1. 视频拼接功能
|
||
|
||
支持两种拼接模式:
|
||
|
||
#### 模式一:组合拼接(IsJoinType1Selected)
|
||
- 从多个文件夹中选择视频文件
|
||
- 生成所有可能的视频组合
|
||
- 随机选择指定数量的组合进行拼接
|
||
- 支持添加审核图片水印
|
||
|
||
#### 模式二:顺序拼接(IsJoinType2Selected)
|
||
- 按照文件夹顺序,从每个文件夹中选择对应位置的视频
|
||
- 要求所有文件夹中的视频数量相同
|
||
- 按索引顺序拼接视频
|
||
|
||
**拼接流程**:
|
||
1. 选择包含视频文件夹的目录
|
||
2. 系统自动扫描各文件夹中的 MP4 文件
|
||
3. 根据选择的模式生成视频组合
|
||
4. 将视频转换为 TS 格式(临时文件,基于 MD5 缓存)
|
||
5. 使用 FFmpeg 进行视频拼接
|
||
6. 可选:添加审核图片水印
|
||
7. 输出到 `output` 文件夹
|
||
|
||
### 2. 视频抽帧功能
|
||
|
||
- 随机删除视频中的某一帧
|
||
- 支持 HEVC 编码格式(自动转换为 H.264)
|
||
- 保持视频和音频同步
|
||
- 批量处理视频文件
|
||
|
||
**处理流程**:
|
||
1. 分析视频信息(时长、帧率等)
|
||
2. 随机选择要删除的帧(避开开头和结尾)
|
||
3. 将视频分割为两部分(删除帧前后)
|
||
4. 重新合并视频
|
||
5. 输出到 `out` 文件夹
|
||
|
||
### 3. 视频元数据修改
|
||
|
||
- 通过修改视频元数据中的注释信息改变文件 MD5
|
||
- 使用流复制模式,不重新编码视频
|
||
- 批量处理视频文件
|
||
|
||
### 4. 用户登录
|
||
|
||
- 支持用户登录验证
|
||
- 记录登录设备信息(机器名、用户名、IP地址)
|
||
- 与后端 API 交互进行身份验证
|
||
|
||
## 核心模块说明
|
||
|
||
### VideoService(视频服务)
|
||
|
||
**主要方法**:
|
||
|
||
- `ConvertVideos(string videoPath)`: 将视频文件转换为 TS 格式
|
||
- 使用 MD5 作为临时文件名,实现缓存机制
|
||
- 支持多种编码格式转换
|
||
- 失败时自动尝试备用转换方案
|
||
|
||
- `GetLargeFileMD5(string filePath)`: 计算大文件的 MD5 值
|
||
- 使用流式读取,支持大文件处理
|
||
- 8KB 缓冲区优化内存使用
|
||
|
||
- `JoinVideos(List<string> combination)`: 拼接视频列表
|
||
- 使用 FFmpeg concat 功能
|
||
- 支持音频重新编码(AAC,44.1kHz)
|
||
- 可选添加图片水印
|
||
|
||
- `Cleanup(List<string> pathList)`: 清理临时文件
|
||
|
||
### VideoProcess(视频处理)
|
||
|
||
**主要方法**:
|
||
|
||
- `RemoveFrameRandomeAsync(string inputPath, string outputPath)`: 异步删除随机帧
|
||
- 自动处理 HEVC 编码
|
||
- 保持音视频同步
|
||
|
||
- `ModifyByMetadata(string inputPath, string outputPath, string comment)`: 修改视频元数据
|
||
- 添加唯一注释信息
|
||
- 使用流复制,不重新编码
|
||
|
||
- `SubVideo(string inputPath, string outputPath, double startSec, double endSec)`: 视频裁剪
|
||
- `SubAudio(string inputPath, string outputPath, double startSec, double endSec)`: 音频裁剪
|
||
- `JoinVideo(string outPutPath, string[] videoParts)`: 视频合并
|
||
|
||
### VideoCombine(视频组合工具)
|
||
|
||
**主要方法**:
|
||
|
||
- `GenerateCombinations(List<List<string>> videoLists, int index, List<string> currentCombination, List<List<string>> result)`: 生成所有视频组合
|
||
- 递归算法生成笛卡尔积
|
||
- 支持多文件夹视频组合
|
||
|
||
- `ConvertVideos(string videoPath)`: 视频格式转换(与 VideoService 类似)
|
||
|
||
### LogUtils(日志工具)
|
||
|
||
基于 log4net 的日志封装,支持:
|
||
- Info: 信息日志
|
||
- Debug: 调试日志
|
||
- Error: 错误日志
|
||
- Warn: 警告日志
|
||
- Fatal: 致命错误日志
|
||
|
||
日志文件保存在 `bin/Debug/net8.0-windows/Log/` 目录下。
|
||
|
||
### HttpUtils(HTTP工具)
|
||
|
||
封装了 HTTP 请求功能:
|
||
- `GetAsync<T>(string url)`: GET 请求
|
||
- `PostAsync<T>(string url, object data)`: POST 请求
|
||
- 默认 BaseAddress: `https://admin.xiangbing.vip`
|
||
- 自动 JSON 序列化/反序列化
|
||
|
||
## 数据模型
|
||
|
||
### VideoModel(视频模型)
|
||
|
||
**主要属性**:
|
||
- `FolderPath`: 视频文件夹路径
|
||
- `FolderInfos`: 文件夹信息集合(包含视频文件列表)
|
||
- `ConcatVideos`: 拼接完成的视频列表
|
||
- `Num`: 需要拼接的视频数量
|
||
- `MaxNum`: 最大可拼接数量
|
||
- `AuditImagePath`: 审核图片路径
|
||
- `IsJoinType1Selected`: 组合拼接模式
|
||
- `IsJoinType2Selected`: 顺序拼接模式
|
||
- `CanStart`: 是否可以开始拼接
|
||
- `IsStart`: 是否正在处理
|
||
|
||
**FolderInfo 结构**:
|
||
```csharp
|
||
public struct FolderInfo
|
||
{
|
||
public DirectoryInfo DirectoryInfo;
|
||
public int Num; // 视频文件数量
|
||
public List<string> VideoPaths; // 视频文件路径列表
|
||
}
|
||
```
|
||
|
||
**ConcatVideo 类**:
|
||
```csharp
|
||
public class ConcatVideo
|
||
{
|
||
public int Index; // 索引
|
||
public string FileName; // 文件名
|
||
public string Size; // 文件大小
|
||
public int Seconds; // 时长(秒)
|
||
public string Status; // 状态
|
||
public string Progress; // 进度
|
||
}
|
||
```
|
||
|
||
### ExtractWindowModel(抽帧窗口模型)
|
||
|
||
**主要属性**:
|
||
- `FolderPath`: 视频文件夹路径
|
||
- `videos`: 视频文件数组
|
||
- `CanExtractFrame`: 是否可以抽帧
|
||
- `CanModify`: 是否可以修改元数据
|
||
- `IsStart`: 是否正在处理
|
||
|
||
## 配置说明
|
||
|
||
### App.config
|
||
|
||
应用程序配置文件,用于存储应用设置。
|
||
|
||
### log4net.config
|
||
|
||
日志配置文件,定义日志输出格式和存储位置。
|
||
|
||
### app.manifest
|
||
|
||
应用程序清单文件,定义应用程序的权限和特性。
|
||
|
||
## 依赖项说明
|
||
|
||
| 包名 | 版本 | 说明 |
|
||
|------|------|------|
|
||
| FFMpegCore | 5.2.0 | FFmpeg 的 .NET 封装,用于视频处理 |
|
||
| LiveCharts | 0.9.7 | 图表库,用于数据可视化 |
|
||
| LiveCharts.Wpf | 0.9.7 | WPF 图表组件 |
|
||
| log4net | 3.1.0 | 日志框架 |
|
||
| MahApps.Metro.IconPacks | 6.0.0 | Metro 风格图标包 |
|
||
| MaterialDesignThemes.Wpf | - | Material Design 主题 |
|
||
| Microsoft.Extensions.Logging | 9.0.8 | 日志扩展 |
|
||
| Newtonsoft.Json | 13.0.3 | JSON 序列化库 |
|
||
| WPFDevelopers | 0.0.0.1 | WPF 开发工具库 |
|
||
|
||
## 使用说明
|
||
|
||
### 环境要求
|
||
|
||
- Windows 操作系统
|
||
- .NET 8.0 Runtime
|
||
- FFmpeg 可执行文件(已包含在 bin 目录中)
|
||
|
||
### 运行步骤
|
||
|
||
1. **编译项目**
|
||
```bash
|
||
dotnet build
|
||
```
|
||
|
||
2. **运行程序**
|
||
```bash
|
||
dotnet run
|
||
```
|
||
或直接运行 `bin/Debug/net8.0-windows/VideoConcat.exe`
|
||
|
||
3. **使用视频拼接功能**
|
||
- 打开程序,选择"视频"标签
|
||
- 点击"选择文件夹",选择包含视频文件夹的目录
|
||
- 选择拼接模式(组合拼接或顺序拼接)
|
||
- 输入需要拼接的视频数量
|
||
- (可选)选择审核图片
|
||
- 点击"开始拼接"按钮
|
||
|
||
4. **使用视频抽帧功能**
|
||
- 选择"抽帧"标签
|
||
- 点击"选择文件夹",选择包含视频文件的目录
|
||
- 点击"开始抽帧"按钮
|
||
|
||
5. **使用元数据修改功能**
|
||
- 在"抽帧"标签中
|
||
- 选择视频文件夹
|
||
- 点击"开始修改"按钮
|
||
|
||
### 输出位置
|
||
|
||
- **拼接视频**: `{选择的文件夹}/output/`
|
||
- **抽帧视频**: `{选择的文件夹}/out/`
|
||
- **修改元数据视频**: `{选择的文件夹}/out/modify{原文件名}`
|
||
|
||
### 临时文件
|
||
|
||
- 视频转换后的 TS 文件存储在系统临时目录
|
||
- 文件名基于源文件的 MD5 值,实现缓存机制
|
||
- 处理完成后会自动清理临时文件
|
||
|
||
## 性能优化
|
||
|
||
1. **并发处理**: 使用 `SemaphoreSlim` 限制并发数量(默认10个线程)
|
||
2. **文件缓存**: 基于 MD5 的临时文件缓存,避免重复转换
|
||
3. **流式处理**: 大文件 MD5 计算使用流式读取
|
||
4. **异步处理**: 视频处理操作使用异步方法,避免 UI 阻塞
|
||
|
||
## 注意事项
|
||
|
||
1. **视频格式**: 目前主要支持 MP4 格式
|
||
2. **文件路径**: 确保视频文件路径不包含特殊字符
|
||
3. **磁盘空间**: 视频处理需要足够的临时存储空间
|
||
4. **处理时间**: 视频处理时间取决于视频大小和数量
|
||
5. **HEVC 编码**: 抽帧功能会自动将 HEVC 编码转换为 H.264
|
||
|
||
## 日志说明
|
||
|
||
日志文件保存在 `bin/Debug/net8.0-windows/Log/` 目录下,按日期命名(如 `log20251019.log`)。
|
||
|
||
日志内容包括:
|
||
- 视频处理进度
|
||
- 错误信息
|
||
- 操作记录
|
||
- 性能统计
|
||
|
||
## API 接口
|
||
|
||
### 登录接口
|
||
|
||
**端点**: `/api/base/login`
|
||
|
||
**请求参数**:
|
||
```json
|
||
{
|
||
"Username": "用户名",
|
||
"Password": "密码",
|
||
"Platform": "pc",
|
||
"PcName": "机器名",
|
||
"PcUserName": "用户名",
|
||
"Ips": "IP地址"
|
||
}
|
||
```
|
||
|
||
**响应格式**:
|
||
```json
|
||
{
|
||
"Code": 200,
|
||
"Msg": "消息",
|
||
"Data": {
|
||
// 用户信息
|
||
}
|
||
}
|
||
```
|
||
|
||
## 开发说明
|
||
|
||
### MVVM 架构
|
||
|
||
项目采用 MVVM(Model-View-ViewModel)架构模式:
|
||
|
||
- **Model**: 数据模型和业务逻辑(Models 目录)
|
||
- **View**: 用户界面(Views 目录,XAML 文件)
|
||
- **ViewModel**: 视图模型,连接 View 和 Model(ViewModels 目录)
|
||
|
||
### 命令模式
|
||
|
||
使用自定义 `Command` 类实现命令模式,绑定到 UI 控件的命令属性。
|
||
|
||
### 数据绑定
|
||
|
||
使用 WPF 数据绑定机制,实现 UI 与数据的双向绑定。
|
||
|
||
## 已知问题
|
||
|
||
1. 抽帧功能在某些情况下可能返回 false(代码中 `RemoveFrameRandomeAsync` 方法最后返回 false)
|
||
2. 顺序拼接模式要求所有文件夹视频数量相同,但错误提示信息不够明确
|
||
|
||
## 未来改进方向
|
||
|
||
1. 支持更多视频格式
|
||
2. 添加视频预览功能
|
||
3. 优化错误处理和用户提示
|
||
4. 添加进度条显示
|
||
5. 支持视频质量设置
|
||
6. 添加批量重命名功能
|
||
7. 支持视频裁剪功能(时间范围选择)
|
||
|
||
## 许可证
|
||
|
||
(待补充)
|
||
|
||
## 联系方式
|
||
|
||
(待补充)
|
||
|