Skip to main content
Glama

Local Media Manager

本地媒体库索引与整理工具:扫描视频文件 → 识别番号 → 落库 → 查询/质检/整理。

面向「文件名里带番号」的本地媒体库(数万文件量级)。核心价值是把文件名解析成 结构化编号,并围绕编号建立索引,再加一道删除门控——只有拿到已验证磁力链接的 条目才允许被清理。

它能做什么

  • 扫描识别:遍历配置目录,从文件名(回退到直接父目录名)解析编号

  • 格式白名单:只收标准视频格式,可按需追加

  • SQLite 索引:三个库分工明确(见下)

  • 增量扫描:基于 file_index 跳过未变更文件;字典变了自动全量重算

  • MCP 工具层:5 个工具,供 Agent 客户端调用

  • 质检查询:缺元数据、缺封面、重复、库统计

  • 删除门控:可删列表 = 有「已验证磁力」的编号,没磁力一律不可删

Related MCP server: plex-claude-plugin

Install

pip install -r requirements.txt

配置

编辑 config.yaml

scan_paths:
  - "X:\\"                 # 扫描根目录(多个)

video_extensions: []       # 追加格式(**追加**语义,见下)
database: "storage/library_v2.db"
index_db: "storage/file_index_v2.db"
dictionary: "data/dictionary.json"

格式白名单是「追加」不是「覆盖」

程序自带一套标准视频格式:

.mp4 .mkv .avi .mov .wmv .flv .mpg .mpeg .m4v .ts .m2ts

config.yaml 里的 video_extensions往上加,不是替换。想额外收 .webm

video_extensions:
  - ".webm"

选追加而不是覆盖,是因为覆盖语义下少写一个格式会静默漏扫整类文件;追加最坏只是多扫。

.webm 不在默认列表里。实测 2.6 万条真实语料中,.webm 占 59.4% 但可信命中率为 0 (几乎全是录屏/动画片段),而 .mp4/.mkv/.wmv/.avi 承载了全部可信命中。要收就自己加。

运行

命令行扫描

python main.py

遍历 scan_paths,识别并落库。

作为 MCP 服务

python -m agent.server      # 推荐(模块方式)
python agent/server.py      # 脚本直跑(MCP 客户端常见配置)

两种都支持。暴露的工具:

工具

副作用

说明

search_media

只读

按编号查询本地媒体

check_library_quality

只读

媒体库健康检查

add_media_file

写库

手动添加编号与文件关联

fetch_metadata

写队列

请求番号元数据同步(入队,由 worker 处理)

scan_library

写库

扫描目录并落库(不传 folder 则用 scan_paths

架构

v2 是唯一主线

v1 的扫描/解析/匹配模块已冻结,仅作为 v1 数据库的只读迁移参考,v2 链路不引用。 对应关系:

v1(冻结)

v2(主线)

core/parser.py

core/parser_v2.py

core/matcher.py

core/matcher_v2.py

core/scanner.py

core/scanner_v2.py

core/database.py

core/database_v2.py

core/cache.py

core/cache_v2.py

core/organizer.py

core/organizer_v2.py

adapters/javdb.py

adapters/javdb_adapter.py

改 bug、加规则请改 v2 那一列。

分层

main.py / agent/server.py     入口(CLI 扫描 / MCP 服务)
        │
   agent/tools_v2.py          MCP 工具层(5 个工具)
        │
   services/                  MediaService / ScanService / QualityService
        │                     MetadataService / OrganizeService
        │
   core/*_v2.py               Parser / Matcher / Scanner / Database
        │
   adapters/                  JavDB 等外部数据源适配

数据落在哪

用途

storage/library_v2.db

titles / media_files / metadata / magnets / file_index

主库:编号、文件、元数据、磁力

storage/file_index_v2.db

file_index

扫描增量索引(路径 + size + mtime + 规则指纹)

file_index 会记录规则集指纹data/dictionary.json 一改,已索引文件全部视为 变更,下次扫描自动重算——避免"改了字典但旧结果赖着不走"。

两条硬规矩

1. 编号目录不参与匹配(除一层回退)

文件名解析优先用 basename;没命中时只回退到直接父目录名,不再无条件拿整个路径参与匹配。

原因是实测踩过:ABP-999/random_clip.mp4 这类会被祖先目录的编号劫持,把无关文件误判入库。 现在只保留「编号目录/video.mp4」这一层。

2. 没有磁力就不许删

可删候选来自 deletable_titles(),它的条件是存在 verified=1 的磁力记录

  • 有已验证磁力 → 进候选

  • 只有候选磁力(verified=0)→ 不进

  • 完全没磁力 → 不进,哪怕它是真片

理由:搜索结果难免混进错条目,但错的条目拿不到磁力。所以"有没有可用的磁力" 比"文件名看着像不像"更能证明这条记录是真的、且已经能重新获取。

配套约束:本项目不含任何真实删除实现(无 os.remove / unlink / rmtree / send2trash)。deletable_titles() 只产出候选清单,删除动作尚未实现—— 将来实现时必须只消费这张表。

开发

pytest tests/ -q

测试覆盖:解析规则、格式白名单、增量索引、落库与重链、磁力门控、端到端链路。

已知缺口

  • core/cache_v2.py 扫描缓存未接线,重复扫描会重算(大库性能受影响)

  • core/scheduler.py(定时扫描)、core/watcher.py(目录监听)未接线,不随服务启动

  • v2 暂无「重命名计划(只出计划不执行)」和「按演员/标签检索」能力

详见 ARCHITECTURE-AND-ISSUES.md

License

MIT

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables Plex Media Server administration including library management, media file identification and renaming, batch processing, and automatic ingestion with folder watching.
    1
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    Provides tools for AI clients to scan, match, and scrape TMDB metadata for local media files, with safe sidecar writing or full Jellyfin-style reorganization including file renaming and NFO generation.
    MIT
  • A
    license
    B
    quality
    D
    maintenance
    Enables agents to organize messy folders into structured libraries by scanning, planning, and applying reorganization via a manifest-first, non-destructive workflow.
    16
    6 npm
    1
    MIT