---
name: "jav-media-sorter"
description: "JAV 视频整理：组装文件、按演员分组、刮削 nfo 元数据与封面图"
---

# JAV 媒体整理与元数据刮削技能

将 qbittorrent 下载完成的 JAV 视频（ mp4 + srt + nfo ）文件整理成 `/mnt/f/av/` 格式，按演员分类，并尝试刮削封面图。

## 目录结构规范

目标格式（参考 `/mnt/f/av/`）：

```
/mnt/f/av/
├── 演员名/
│   ├── 番号-C 演员名/        ← 如果已有番号-C 目录则保留原名
│   │   ├── 番号.mp4
│   │   ├── 番号.chs.srt
│   │   ├── 番号.nfo
│   │   ├── poster.jpg
│   │   └── fanart.jpg
│   └── ...
├── 未知演员/
│   └── ...
```

另一套目录结构（参考 `/mnt/e/01_automated/日本电影/`）：

```
/mnt/e/01_automated/日本电影/
├── 演员名/
│   ├── 番号 演员名/
│   │   ├── 番号.mp4
│   │   ├── 番号.nfo
│   │   ├── 番号-poster.jpg
│   │   └── 番号-thumb.jpg
│   └── ...
```

## 前置条件

- Clash 代理运行在 Docker（端口 7443，认证 `proxy:5gynj20J`）
- FlareSolverr 运行在 Docker（已下线，按需启动）
- Python3（用于 nfo 和整理脚本）
- Docker（FlareSolverr + Clash）

## 操作流程

### 1. 检查下载目录

```bash
ls /mnt/f/qbittorrent/failed/
```

通常结构是 `failed/` 目录下平铺所有 mp4、srt（.chs.srt）、nfo 文件。

### 2. 按演员创建目标文件夹

在 `failed/` 目录内创建 `番号-C 演员名/` 文件夹，方便手动拖到 `/mnt/f/av/` 中对应演员目录。

```bash
cd /mnt/f/qbittorrent/failed
mkdir -p "ADN-016-C 明日見未来"
# ... 以此类推
```

### 3. 按演员分组（移动目录到演员子目录）

若目录直接放在 `/mnt/f/av/` 根目录下，需要移动到对应演员子目录：

```bash
cd /mnt/f/av
mkdir -p "明日見未来"
mv "ADN-016-C 明日見未来" "明日見未来/"
# ... 以此类推
```

### 4. 读取 nfo 获取演员信息

每个作品的 nfo 文件包含元数据，用 Python 解析：

```python
import xml.etree.ElementTree as ET
tree = ET.parse('番号.nfo')
root = tree.getroot()
actors = [a.find('name').text for a in root.findall('actor')]
dvd_id = root.find('num').text
```

### 5. 封面图刮削

尝试从以下来源下载封面图：

#### 5.1 FlareSolverr + Clash 代理（首选）

```bash
FLARE="http://127.0.0.1:8191/v1"
CLASH_PROXY="http://proxy:***@host.docker.internal:7443"

# FlareSolverr API 请求格式
curl -s "$FLARE" -d '{
  "cmd":"request.get",
  "url":"https://javdb.com/search?q=番号&f=all",
  "maxTimeout":45000,
  "proxy":{"url":"'$CLASH_PROXY'"}
}' -H "Content-Type: application/json"
```

从返回的 JSON 中提取 `solution.response` 中的 HTML，解析出：

- 详情页链接 `href="/v/xxx"`
- 详情页中 `class="video-cover"` 的 `src` 属性（封面图片 URL）

然后通过 Clash 代理下载图片：

```bash
curl -x "http://proxy:***@127.0.0.1:7443" -s -L -o "poster.jpg" \
  -H "Referer: https://javdb.com/" "$POSTER_URL"
```

#### 5.2 备用：Python socks5 直连

```python
import socks, socket
socks.set_default_proxy(socks.SOCKS5, "127.0.0.1", 7443,
    username="proxy", password="***", rdns=True)
socket.socket = socks.socksocket
import urllib.request, re
req = urllib.request.Request("https://javdb.com", headers={
    "User-Agent": "Mozilla/5.0"})
```

#### 5.3 已知限制

- JavDB 有 Cloudflare 反爬，Python `requests`/`cloudscraper` 均可能被拦截
- FlareSolverr 走 HTTP 代理时可能无法完成 Cloudflare JS 挑战
- FANZA/DMM 图片 CDN 返回小图（~3KB），真实大图需 JS 渲染
- 最可靠方案：**Windows 端浏览器手动下载**

### 6. 图片命名规则

- `/mnt/f/av/` 格式： `poster.jpg` + `fanart.jpg`（两图相同）
- `/mnt/e/01_automated/日本电影/` 格式： `番号-poster.jpg` + `番号-thumb.jpg`

## 注意事项

- **WSL 操作 /mnt 文件极慢**：大量小文件操作应在 Windows 原生 Python 中执行
- **代理密码注意 shell 展开**：Clash 密码 `5gynj20J` 在 bash 中写为 `"proxy:*"`（用双引号避免 `***` 展开）
- **FlareSolverr 密码兼容性**：SOCKS5 代理认证不支持通过环境变量传递。HTTP 代理用 `proxy` 参数
- **Clash 端口**：mixed-port 7443，同时支持 HTTP 和 SOCKS5
- **删除冗余的字幕目录**：`*-中文字幕/` 目录中的 `.srt` 与 `failed/` 目录中的 `.chs.srt` 多数是重复文件（MD5 一致）

## 依赖检查

```bash
# FlareSolverr
docker ps | grep flaresolverr

# Clash
docker ps | grep clash

# Python
python3 --version
pip3 list 2>/dev/null | grep -i cloudscraper
```
