# 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. 支持视频裁剪功能（时间范围选择）

## 许可证

（待补充）

## 联系方式

（待补充）

