- name
- media-butler-skill
- description
- Use when 用户要找片、下载影视、整理媒体库、补字幕。覆盖找片源、选种、下载电影/剧集/动漫、中文字幕获取、分类归档、库清单与缺集盘点。用户提到想看某部片、片源搜不到、下载没速度、字幕缺失、媒体库目录乱、追剧缺集、硬盘满了要清理时,都该用本 skill——哪怕没明说「下载」二字,只要意图落在「把某个影视内容弄到本地看好」或「本地影视文件乱了/缺了/占地方了」,也要主动加载它。
- version
- 0.1.0
- author
- Treasure-hub-agent
- license
- MIT
- platforms
- ["linux","macos","windows"]
- metadata
- {"hermes":{"tags":["media","download","subtitle","library","nas"],"related_skills":[]}}
# 影视管家
把「想看某部影视」变成「本地能播放的文件」,并把本地影视文件整理成可盘点、可补缺的库。
全部确定性执行(检索、解析、打分、下载调度、归档、索引)由仓库内的 CLI 完成;
本 skill 规定 agent 该怎么编排这些命令、什么时候停下来问用户。
命令入口:`python3 <repo>/scripts/media.py <子命令>`(下文简写 `media.py`)。
## 何时触发
- **找片 / 下载**:用户说想看、想看某部电影或某部剧、要下某一集或一整季、动漫新番更新了要收。
- **源头问题**:搜不到资源、搜出来全是不相关的、种子没速度、卡在 0%、下到一半停了。
- **字幕问题**:没有中文字幕、字幕对不上画面、要双语或繁中、下载后才发现是生肉。
- **整理库**:媒体库目录一团乱、想按规范重命名归档、文件散落在下载目录里。
- **盘点**:库里有几部、占了多少空间、某部剧缺第几集、《硬盘要满了想清理》。
- **口径模糊时**:用户只说出一个片名,或只说「那个片子怎么还没下好」——先加载本 skill 再澄清,不要凭印象回答。
## 铁律
1. **数值一律问 CLI**:体积、种子数、占比、路径、哈希、集号都由 CLI 输出,不要心算或凭标签猜。
为什么:这些数字直接决定选哪个片源,而模型在单位换算(GB/MB/KiB)和数量级判断上出错率不可接受。
2. **下载前先说清**:把候选清单、体积、预计占用、中字情况、来源站点讲给用户,得到确认再 `grab`。
为什么:误下一整季或几十 GB 的合集,用户要花很久才能撤销;确认是最便宜的纠错手段。
3. **中字优先**:外语内容先看有无中字版本;确定找不到时,如实告知并提供字幕补齐方案。
为什么:中文用户对「无中字的高清片」的实际可用性低于「有中字的普通片」,排序即价值判断。
4. **先预演再落地**:任何写操作(归档、移动、重命名)先 `--dry-run` 把清单给用户看,确认后执行。
为什么:归档是不可逆的整理动作,一次错误的批量移动比少做一步麻烦得多。
5. **失败照实说**:搜不到、没速度、字幕轴对不上、硬链接不可用,原样上报原因与建议,不粉饰、不假装成功。
为什么:用户后续所有判断都基于这份报告,一次谎报会让整条链路白跑。
6. **状态写家目录**:运行数据落 `~/.media-butler/`(Windows 为 `%APPDATA%\media-butler\`)。
为什么:skill 目录在多平台可能只读或被升级覆盖,写在那里会丢配置与索引。
7. **只读巡检不越权**:`doctor` 是只读体检;`doctor regrab` 只产候选清单,实际获取必须逐条得到用户确认。
为什么:自动重下会静默放大磁盘与带宽占用,且可能反复抓同一个失效源。
## 标准工作流
### A 找片下载(主流程)
1. `meta <片名>` 取标准名与检索名(中英互译、年份、总集数)。
**完成判据**:拿到至少一个可用于检索的名字(中文原名或拉丁名),并知道年份/集数是否已知。
2. `search <片名> --limit N` 多源检索,结果已按中字优先排序。
**完成判据**:有候选列表,且每条都标出体积、种子数、来源、是否带中字标记、是否合集。
3. 向用户呈报候选与推荐(含为什么推荐这条),确认后 `grab <磁力链接>`。
**完成判据**:拿到进程 id 与日志路径;或收到 `no-downloader` 状态并已把磁力链接交给用户。
4. `status` 跟进进度。
**完成判据**:给出进度百分比/已下载量/是否存在未完成分片(`.aria2`)三者之一。
5. 需要时 `subs --file <视频文件>` 补中文字幕。
**完成判据**:字幕已落地(给出路径),或明确报告「未找到匹配中文字幕 + 建议方案」。
6. `ingest <下载目录> --library <库根> --type <movie|tv|anime>` 归档入库;先 `--dry-run` 看清单。
**完成判据**:文件落在目标目录内,且库清单(`library.json` / `LIBRARY.md`)已刷新。
### B 老番/冷门单集破局
单集源常常全是死种,这时不要反复换单集磁力,改走合集路线:
检索单集 → 全为 0 种子 → 改搜整季/合集 → `grab` 取回 metadata → 按集号在文件列表里定位索引
→ `grab <磁力> --select <索引>` 只下目标集。
**完成判据**:`--select` 只选中目标集的文件(合集里其余文件不应产生有效数据),目标集真实落盘。
选集下载的索引是 1 基,与 `.torrent` 文件列表顺序一致;定位不到集号时回退整季下载前必须问用户。
### C 库内盘点与补缺
- `index list` — 库内条目全表。
- `index stats` — 条目数、总体积、带中字条目数。
- `index missing --title <片名> --season <季> --expect <总集数>` — 缺集盘点。
- `index rebuild --library <库根>` — 索引损坏或换了机器时,从磁盘结构与文件名重建。
- `doctor regrab` — 找出「库里有、但当前条件检索不到候选」的条目,只产清单。
**完成判据**:盘点结论给出具体数字(条目数/体积/缺失集号),不出现「大概」「应该差不多」。
## 命令速查
| 命令 | 用途 | 关键参数 | 输出 |
|---|---|---|---|
| `parse <文件名>` | 解析资源名(片名/年份/季集/中字标记) | — | JSON |
| `meta <片名>` | 元数据 + 可检索名 | — | `{meta, terms}` |
| `search <片名>` | 多源检索并按中字优先排序 | `--limit` | `{query, terms, count, results[]}` |
| `grab <磁力>` | 加入下载(异步返回) | `--dest` `--select` | `{status, pid, log, dest}` |
| `status` | 下载进度与日志尾部 | `--dest` `--lines` | `{download_dir, has_incomplete, tail}` |
| `subs <片名>` | 中文字幕检索/获取 | `--file` `--dest` `--dry-run` | `{status, path?, candidate?}` |
| `ingest <目录>` | 归档入库 | `--library` `--type` `--dry-run` | `{status, count/plan, log}` |
| `index <动作>` | 库清单 | `list`\|`stats`\|`export`\|`missing`\|`rebuild`;`--library` `--title` `--season` `--expect` | JSON |
| `doctor <动作>` | 只读巡检 | `sources`\|`library`\|`fs`\|`regrab`;`--library` `--src` `--dest` | JSON |
| `config` | 读/写配置 | `--set k=v`(可重复) | 当前配置 |
约定:所有子命令输出 JSON 到 stdout,出错用非 0 退出码 + `{"status": "error", "message": ...}`。
读 JSON 字段做判断,不要从自然语言日志里抠数字。
## 参数默认值
| 配置项 | 默认 | 说明 |
|---|---|---|
| `library_root` | 空 | 媒体库根目录;空则需要在 `ingest` 时用 `--library` 指定 |
| `download_root` | 空 | 下载暂存目录;空则用状态目录下的 `downloads/` |
| `subtitle_priority` | true | 中字标记加分置于首位权重 |
| `preferred_quality` | 1080p | 同条件下偏好该画质关键词 |
| `max_size_gb` | 0 | 体积上限,0 = 不限 |
| `concurrency` | 3 | 并发下载数 |
| `sources_enabled` | `["knaben"]` | 启用的源 id 列表 |
| `proxy` | 空 | 用户显式配置;空 = 直连,也代表用户要求不走代理 |
| `terms_accepted` | false | 首次使用确认标记 |
常用改法:`media.py config --set library_root=/data/media --set proxy=http://127.0.0.1:8080`。
代理只支持 HTTP 型;需要 SOCKS 时用系统级 TUN 模式,不要往 `proxy` 里塞 socks 地址。
## 相关资源
| 想查什么 | 读哪个文件 | 何时读 |
|---|---|---|
| 归档目录结构、命名格式、路径安全规则 | `references/naming.md` | 用户要改库结构、要对既有文件重新归档、`ingest` 结果路径看着不对时 |
| 源清单、自备源(PT/Jackett/Prowlarr)接入、贡献新源 | `references/sources.md` | 默认源搜不到目标、用户要接自己的源、要新增源适配器时 |
| 中字三层策略、标记词库、字幕清洗与匹配 | `references/subtitles.md` | 判断一个资源是否真的带中字、字幕找不到或轴对不上时 |
| 搜不到/没速度/字幕错位/硬链接失败等症状排查 | `references/troubleshooting.md` | 任一环节报错或结果不符合预期时,先查表再动手 |
Auf GitHub ansehen