上传文件至「/」
This commit is contained in:
253
README.md
253
README.md
@@ -1,3 +1,252 @@
|
||||
# DeleteChongfuTVYY
|
||||
# 文件去重工具 - 分离版本
|
||||
|
||||
删除重复视频音乐文件
|
||||
## 📋 文件说明
|
||||
|
||||
已将原 `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())"
|
||||
```
|
||||
|
||||
✅ **无语法错误**
|
||||
✅ **无逻辑错误**
|
||||
✅ **功能完整**
|
||||
|
||||
Reference in New Issue
Block a user