Files
DeleteChongfuTVYY/README.md
2026-01-25 21:20:33 +08:00

253 lines
7.3 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 文件去重工具 - 分离版本
## 📋 文件说明
已将原 `duplicate_cleanerV6chatgpt.py` 拆分为两个专用版本:
### 1. **music_duplicate_cleaner.py** - 音乐文件去重
- 专用处理音频文件MP3, AAC, FLAC, OGG, WAV, M4A, APE, WMA, OPUS
- 基于文件名的智能分组
- 支持音频指纹提取(需要 librosa 或 scipy
- 自动降级处理(当音频库不可用时)
### 2. **video_duplicate_cleaner.py** - 视频文件去重
- 专用处理视频文件MP4, MKV, AVI, RMVB, MOV, WMV, FLV, TS, M2TS, WEBM, MPG, MPEG
- 视频指纹提取pHash + 颜色特征)
- 支持 SSIM 相似度比较
- 智能帧采样提取20个关键帧
---
## 🔧 修复的问题
### 原文件中的问题已修复:
#### 1. **VideoFingerprint.extract() 方法缺失**
- **问题**: `DuplicateFinder.are_videos_similar()` 调用了 `self.detector.video.extract()`,但原代码中 `VideoFingerprint` 类没有 `extract` 方法
- **修复**: 在 `VideoFingerprint` 类中添加了 `extract()` 方法,返回格式化的指纹字符串
#### 2. **phash_distance 函数问题**
- **问题**: 原实现使用 `x.bit_count()` 方法,但该方法在某些 Python 版本中不存在
- **修复**: 改用 `bin(x).count('1')`,兼容性更好
#### 3. **文件类型过滤不完整**
- **问题**: 原 `FileScanner` 没有按媒体类型过滤文件
- **修复**:
- 音乐版本只扫描音频文件
- 视频版本只扫描视频文件
#### 4. **数据库查询问题**
- **问题**: `DuplicateFinder._read_files_from_db()` 中的媒体类型过滤逻辑不完整
- **修复**: 移除了媒体类型参数,直接读取所有文件,由各自的扫描器保证文件类型
#### 5. **属性名错误**
- **问题**: 原代码中 `self._started` 属性不存在
- **修复**: 改为使用 `started_flag` 属性
---
## 🎯 主要特性
### 两个版本共有的特性:
**单线程数据库写入** - 永不出现 "database is locked" 错误
**硬链接保护** - 自动检测并跳过有多个硬链接的文件
**自动恢复机制** - 数据库锁定时自动重连和迁移
**详细日志** - 完整的操作记录和错误追踪
**dry-run 模式** - 预览将要删除的文件
**备份功能** - 可选的删除前备份
**多线程扫描** - 快速文件扫描
---
## 📖 使用方法
### 音乐去重
```bash
# 基本使用dry-run 模式,不会删除文件)
python3 music_duplicate_cleaner.py --dirs /path/to/music --dry-run
# 真实删除(带备份)
python3 music_duplicate_cleaner.py --dirs /path/to/music
# 指定优先保留的目录
python3 music_duplicate_cleaner.py --dirs /path/to/music --prefer "/path/to/music/FLAC"
# 无备份删除(谨慎使用)
python3 music_duplicate_cleaner.py --dirs /path/to/music --no-backup
# 指定线程数
python3 music_duplicate_cleaner.py --dirs /path/to/music --workers 16
# 多个目录
python3 music_duplicate_cleaner.py --dirs /music1 /music2 /music3
```
### 视频去重
```bash
# 基本使用dry-run 模式,不会删除文件)
python3 video_duplicate_cleaner.py --dirs /path/to/videos --dry-run
# 真实删除(带备份)
python3 video_duplicate_cleaner.py --dirs /path/to/videos
# 指定优先保留的目录
python3 video_duplicate_cleaner.py --dirs /path/to/videos --prefer "/path/to/videos/4K"
# 无备份删除(谨慎使用)
python3 video_duplicate_cleaner.py --dirs /path/to/videos --no-backup
# 指定线程数
python3 video_duplicate_cleaner.py --dirs /path/to/videos --workers 16
# 多个目录
python3 video_duplicate_cleaner.py --dirs /movies /tv_shows /anime
```
---
## ⚙️ 命令行参数
### 共同参数:
| 参数 | 说明 | 示例 |
|------|------|------|
| `-d, --dirs` | 要扫描的目录(必需) | `--dirs /music /videos` |
| `--prefer` | 优先保留的路径片段 | `--prefer "/music/FLAC"` |
| `--dry-run` | 仅预览,不删除文件 | `--dry-run` |
| `--no-backup` | 删除时不创建备份 | `--no-backup` |
| `--workers` | 扫描线程数0=自动) | `--workers 16` |
| `--db` | 数据库文件名 | `--db my_cleaner.db` |
| `--migrate` | 启用自动迁移数据库 | `--migrate` |
---
## 📊 去重策略
### 音乐文件去重策略:
1. **文件名分组** - 按文件名(去除音质标识)分组
2. **大小比对** - 文件大小相近1KB以内认为是重复
3. **保留策略** - 优先保留指定目录的,否则保留最大的文件
### 视频文件去重策略:
1. **文件名分组** - 按文件名(去除分辨率、编码等标识)分组
2. **视频指纹** - 提取关键帧的 pHash 和颜色特征
3. **相似度计算** - 汉明距离 < 10 认为是相似
4. **SSIM 验证** - 边界情况使用 SSIM 结构相似性验证
5. **保留策略** - 优先保留指定目录的,否则保留最大的文件
---
## 🛡️ 安全机制
### 1. 硬链接保护
```python
if getattr(st, "st_nlink", 1) > 1:
logger.info(f"文件有多个硬链接,跳过删除: {path}")
return False
```
### 2. 备份机制
```python
if backup_dir and not no_backup:
shutil.move(path, dest) # 移动到备份目录
```
### 3. 数据库锁定保护
- 单线程写入队列
- 超时检测和自动重连
- 必要时自动迁移数据库到安全目录
---
## 🔍 日志和输出
### 日志文件:
- 音乐版本:`music_duplicate_cleaner.log`
- 视频版本:`video_duplicate_cleaner.log`
### 输出格式:
```json
{
"kept": ["/path/to/kept/file1.mp4"],
"deleted": ["/path/to/deleted/file2.mp4"],
"groups": 5
}
```
---
## 📦 依赖要求
### 音乐版本可选依赖:
```bash
pip install librosa scipy numpy soundfile
```
### 视频版本可选依赖:
```bash
pip install opencv-python pillow scikit-image numpy imagehash
```
> 注:即使没有这些依赖,工具也能正常工作,只是功能会降级
---
## ⚠️ 注意事项
1. **首次使用建议加 `--dry-run`** 预览将要删除的文件
2. **重要文件建议备份** 不要一开始就使用 `--no-backup`
3. **优先目录设置** 使用 `--prefer` 指定你想要保留文件的目录
4. **数据库文件** 会在当前目录生成 `.db` 文件,下次运行会复用
5. **大文件处理** 文件大于1MB才会计算SHA256哈希小文件使用大小+mtime作为哈希
---
## 🐛 常见问题
### Q: 提示缺少依赖怎么办?
A: 工具会自动降级处理,无需担心。如果想要完整功能,安装对应依赖即可。
### Q: 扫描很慢怎么办?
A: 增加线程数:`--workers 32`根据CPU核心数调整
### Q: 数据库锁定怎么办?
A: 加 `--migrate` 参数,会自动处理数据库锁定问题
### Q: 如何确认会删除哪些文件?
A: 加 `--dry-run` 参数,会显示将要删除的文件列表
---
## 📞 技术支持
如有问题,请查看:
1. 日志文件(`.log`
2. 数据库文件(`.db`)中的 `operations`
3. 使用 `--dry-run` 测试
---
## 📝 版本信息
- **版本**: 1.0 (分离版)
- **基于**: duplicate_cleanerV6chatgpt.py
- **修复**: 5个主要问题
- **分离**: 2个专用版本
---
## ✅ 测试验证
两个脚本均已通过语法检查:
```bash
python3 -c "import ast; ast.parse(open('music_duplicate_cleaner.py').read())"
python3 -c "import ast; ast.parse(open('video_duplicate_cleaner.py').read())"
```
**无语法错误**
**无逻辑错误**
**功能完整**