本文主要从职责边界角度梳理一类自托管媒体库后端(以 Octans 扫描 / 刮削 / 重命名 / 删除子系统为例):为什么必须从物理文件出发,如何把「文件事实」升维成「逻辑身份」,以及重命名与删除为何都要 Preview-first,并和扫描前自愈拆开。重点是主链怎么切、各段做什么与不做什么,而不是任务 DTO、正则细节或某次 API 字段表。
媒体库后台一旦把「扫库、认片、改名、清理」揉进同一条黑盒流水线,最常见的后果是:误判身份后直接改盘、删一个版本误伤共享字幕、用户在磁盘上动了文件而数据库长期脏掉。下面按主链路与边界表整理,方便设计或对照现有实现做减负。
主链一览:物理优先,逻辑后组装
Octans 一类治理型媒体库通常坚持 物理优先,逻辑后组装:先承认磁盘上真实存在、且探针可信的媒体文件,再在此之上绑定外部身份、导出 NFO、规范化路径或执行删除。扫描因此不是「元数据前置步骤」,而是后续一切动作的共同前提。
物理媒体库
→ 扫描(发现 / 分类 / 占位)
→ 刮削(逻辑身份 + 元数据主干 + 图片接入)
→ 身份相对稳定
→ NFO 落盘 / 重命名规范化 / 展示与播放消费
→(并行)富化与图谱继续补全
删除不是这条升维链的「最后一步」,而是与之正交的两条清理支线:
| 支线 | 驱动方 | 目标 |
|---|---|---|
| 用户主动删除 | 显式命令 + 模式选择 | 带预演的软删 / 硬删 |
| 系统被动自愈 | 扫描周期前后等 | 让数据库重新对齐磁盘现实 |
一句话:
扫描承认现实 → 刮削赋予身份 → 重命名/NFO 规范磁盘表达
主动删除改变现实 → 被动自愈对齐现实
四段职责对照
| 模块 | 回答的核心问题 | 典型产物 | 明确不负责 |
|---|---|---|---|
| 扫描 | 库里有哪些可信文件?电影还是剧集入口? | MediaFile 与最小占位实体、路径与探针事实 | TMDB 匹配、标题终裁、NFO、命名模板、用户删除语义 |
| 刮削 | 这是哪部作品?主干元数据是否够用? | 外部身份绑定、标题/年份/简介等骨架、图片接入 | 最终命名求值、NFO 生成、删除决策、播放链路 |
| 重命名 | 在身份已稳时,如何把磁盘结构安全规范化? | 预演清单、受控改名/移动、伴生资产跟随、可回滚 | 上游识别、NFO 生成本身、删除决策 |
| 删除 | 要清到逻辑层还是物理层?范围与风险是什么? | 软删/硬删预演与执行、目录保洁、与自愈边界 | 身份识别、命名模板、NFO 生成 |
共同原则:
- 入口粒度稳定:扫描给出后续模块都能使用的物理入口;刮削升维逻辑身份,但不改写「文件是否存在」的事实。
- 危险动作 Preview-first:重命名与删除默认先让影响范围可见,再执行。
- 图谱不是可选项:伴生字幕、NFO、海报的归属与共享关系,决定改名跟随与删除解绑边界。
- 电影 / 剧集分轨:目录拓扑不同,识别与
applyScope升维方式也应分开演进,避免一套过度抽象的通用模型无限膨胀。
扫描:主链路的物理事实入口
要解决的四个基础问题
扫描阶段优先解决的不是「立刻得到完美电影页」,而是:
- 媒体库里出现了哪些真实文件。
- 这些文件是否足够健康、可信,值得进入系统。
- 更可能走电影链路还是剧集链路。
- 后续刮削、NFO、重命名、删除应从什么稳定入口继续。
因此扫描的正式职责收敛为:
- 物理文件发现
- 媒体有效性判断(探针可读出有效视频信息)
- 电影 / 剧集分轨识别
- 最小可用占位事实建立
三条原则
| 原则 | 含义 |
|---|---|
| 物理优先于展示语义 | 不因文件名「看起来像电影」就在库里宣告完整身份 |
| 先发现,再升维 | 只做发现 / 分类 / 占位;外部匹配、标题终裁、图片人物补全留给刮削与富化 |
| 与清洗解耦,但允许前置自愈 | 扫描不承担用户主动删除;进入新周期前可先被动对齐已消失宿主与遗留壳 |
电影链路更接近「单文件或少量版本围绕同一标题」;剧集链路至少涉及剧 / 季 / 集与多版本、伴生资源,更依赖目录与命名分层。分轨是为了给下游提供更稳定的上游结果,而不是实现便利。
与下游的接口心智
磁盘路径 + 探针事实 + 占位实体
↓
刮削的目标对象
↓
NFO 落盘位置 / 重命名源路径 / 删除清理边界
没有可靠物理入口,就没有可靠 sidecar 路径,也没有可信的改名与删除半径。轨清单、语言启发式与 HDR/DV 等技术事实的分层,见同系列轨与动态范围文;本文只强调:扫描负责把事实带进系统,不负责在这一层完成身份终裁。
刮削:从文件管理到媒体库管理
升维在解决什么
扫描把文件带进系统后,仍然缺少「这到底是哪部电影 / 哪部剧、该显示什么标题和海报」。刮削负责的是 物理事实 → 逻辑身份:
- 标题与年份匹配
- 电影 / 剧集 / 合集的外部元数据绑定
- 人物、简介、评分等结构化信息补全
- 图片资产获取
- 多语言、别名与地区回退
这是从「文件管理系统」迈向「媒体库管理系统」的关键一步。
人机协同,而不是全自动黑盒
现实片库常见:标题不标准、年份缺失、多版本混放、译名差异大。因此更稳妥的产品形态是:
| 链路 | 目标 | 适合场景 |
|---|---|---|
| 自动刮削 | 批量巡检、大规模补全 | 白板入库、后台例行完善 |
| 手动刮削 | 纠偏、裁定、死角兜底 | 歧义大、用户明确知道目标、自动结果不可信 |
两条链路宜共享同一后端主骨架,分别服务不同意图与规模;只做自动会持续积累误判,只做手动则失去批量能力。
主干优先,Provider 成为边界
刮削首先保证「这是谁、核心标题是什么、元数据主骨架是否稳定」;高成本、可延迟的人物 / 合集 / 附属图像可交给后续富化。Provider(搜索、详情、别名、图片的统一抽象)应是正式架构边界,避免把单一外部源写死进整条刮削体系;正式主路径可以仍以某一源(如 TMDB)为核心,但入口参数与管理边界应保留多源与回退空间。
下游消费关系
刮削结果(身份 + 主干元数据 + 图片)
├→ NFO 导出(磁盘层主权与生态交接)
├→ 重命名(模板求值依赖稳定身份)
├→ 前端详情与海报墙
└→ 图谱资产挂载与继续富化
刮削明确不负责:最终命名模板求值、NFO 文件生成、删除决策、播放链路建设,以及把所有附属元数据一次性做到最终形态。
重命名:Preview-first 的磁盘重构,不是字符串替换
为什么危险
在复杂媒体库里,重命名至少同时面对:
- 命名模板统一
- 多版本路径隔离
- 伴生资产(字幕 / NFO / 海报)跟随
- 错误操作后的可恢复性
若系统只会「把文件名换成另一个名字」,典型后果是:版本互相覆盖、sidecar 失联、旧目录垃圾残留、模板写错后无法回滚。因此应把重命名理解为 对磁盘结构的受控重构,而不是批处理改名工具。
核心语义:targetIds + applyScope
| 概念 | 含义 |
|---|---|
targetIds | 用户当前直接选中的物理文件 |
applyScope | 是否升维到更大的逻辑范围(如电影全版本、剧集整季 / 整剧) |
前端仍可从物理文件视角发起;后端在执行前统一完成升维、归组与风险判断。逻辑组与物理文件不是同一层:执行边界往往是「一部电影的多个版本」或「一部剧的整季」,而不是孤立路径字符串。
Preview-first 与回滚
预演必须先让用户看见:
- 哪些路径会变(改名 vs 移动目录)
- 哪些 sidecar 会跟随迁移或复制
- 冲突与多版本碰撞点在哪里
多版本隔离是正式边界:系统必须容忍同一逻辑内容的多个物理版本,并避免目标路径碰撞。回滚不是锦上添花,而是对危险动作的正式兜底——预演降低灾难概率,回滚建立恢复能力。
在主链中的位置
扫描 → 刮削 → 稳定逻辑实体
→ 重命名预演 → 执行 → 回滚能力保底
→(并行)NFO 落盘与资产规范化
重命名不负责上游元数据识别、NFO 生成本身或删除决策;它依赖图谱知道哪些资产独占、哪些共享、哪些应跟随、哪些应复制分叉。
删除:软删 / 硬删与被动自愈必须拆开
删除在治理什么
媒体库里的「删除」至少同时处理:
- 数据库侧移除
- 物理文件处理
- 伴生资产与空目录保洁
- 用户绕过系统直接删文件后的状态对齐
混在一起会出现:文件没了库里还留壳、记录删了磁盘上 NFO/海报/字幕残留、删版本误伤共享资产、库长期脏。
软删 vs 硬删
| 模式 | 目标 | 典型用途 |
|---|---|---|
| 软删 | 系统视角移除;清库与图谱挂载;不触碰物理媒体 | 准备重新扫描入库;先纠库状态再决定是否物理处理 |
| 硬删 | 清库 + 处理主文件、伴生资产与空目录 | 用户确认永久移除;连同 sidecar 做物理级治理 |
不显式区分时,用户无法预期删到哪一层,前端无法正确预演,后端无法区分逻辑清理与物理销毁。
预演是正式前置步骤
删除比重命名更接近不可逆,预演更关键:
- 软删重点:逻辑资产动作摘要(解绑、壳清理)
- 硬删重点:受影响路径、目录保洁风险、共享资产是否误伤
预演之后,删除才是可阅读、可确认、可审计的动作,而不是「按下按钮后后台随便做点什么」。
主动删除 vs 被动自愈
| 主动删除 | 被动自愈 | |
|---|---|---|
| 驱动 | 用户显式命令 | 系统在其他流程中触发(常与扫描协同) |
| 问题 | 要不要删、删到什么程度、波及哪些资产 | 磁盘已经变了,数据库还能否代表现实 |
| 语义 | 动作域 | 一致性修复 |
两者相关但不得合并成同一模块语义。关系可记为:
主动删除:改变磁盘和/或数据库
被动自愈:扫描前后对齐现实
扫描:把剩余有效内容重新带回主链
删除同样依赖图谱:独占资产可物理清理,共享资产往往只能解绑或清记录,不能粗暴按主文件路径连带抹掉。
端到端怎么串(与 NFO、部署的交界)
把四段放在同一张心智图上:
[磁盘] ──发现──► 扫描 ──占位──► 刮削 ──身份稳定──► ┬─ NFO 导出
├─ 重命名(预演→执行→回滚)
└─ 详情 / 播放事实消费
用户命令 ──► 删除预演 ──► 软删 / 硬删
磁盘外变 ──► 扫描前自愈 ──► 再进入扫描发现
和相邻专题的分工:
| 专题 | 本文不展开、应对照阅读的点 |
|---|---|
| NFO 导出字段标准 | 身份稳定后「写什么字段、standard/extended」;本文管「何时才有资格写、写到哪的入口从哪来」 |
| 轨识别与动态范围 | 扫描探针里轨 / HDR 事实如何分层;本文只把扫描定位为事实入口 |
| Docker 私有化部署 | 媒体卷只读/读写、数据目录与权限如何影响扫描可见性与改名写盘;本文不谈 Compose 细节 |
运维侧可记三条:
- 媒体路径不可见或权限不足 → 扫描发现失败,后面全链空转。
- 身份未稳就批量重命名 → 模板基于错误标题/年份,Preview 再漂亮也可能整库走偏。
- 只做硬删不做自愈、或只扫库不处理外删 → 库盘长期不一致。
注意事项
- 本文是 架构边界与主链心智,不是某一版本扫描器 / 刮削任务 / 重命名 API 的契约文档。
- 控制器 DTO、正则与目录排除、Provider 类结构、预演返回体字段、回滚表结构、图谱 planner 实现均属实现层,不在此展开。
- 「全自动一条龙」可以是产品快捷方式,但架构上仍建议保留:扫描与刮削解耦、危险动作预演、软硬删与自愈分语义。
- 内网路径、真实片库样本、私有 Provider 密钥与未发布接口路径不进入对外复现步骤。
小结
- 扫描是主链起点:发现、分类、占位;物理优先,先发现再升维。
- 刮削做逻辑身份与元数据主干:自动 + 手动共存,Provider 为边界,主干优先于一次做满。
- 重命名是身份稳定后的磁盘规范化:
targetIds + applyScope、多版本隔离、sidecar 跟随、Preview + 回滚。 - 删除拆软删/硬删,并与扫描协同的被动自愈分界;预演解释影响半径。
- NFO、播放、部署与轨探针各自接在主链的不同接点上,不要用单一「扫库任务」吞掉全部语义。
相关阅读
同系列还可对照:
- 媒体库 NFO 导出字段标准:Kodi 方言、兼容子集与扩展边界:身份稳定后如何把元数据落到磁盘;与本文「扫描入口 / 刮削主干」互补。
- 媒体库轨识别与动态范围:stream index、语言标题与 HDR/DV 分层探针:扫描阶段技术事实如何分层,避免与展示身份混写。
- Octans Docker 私有化部署:单镜像、Compose 叠加与健康检查:媒体卷与数据目录如何支撑扫描可见性与写盘类动作。
来源
本文综合改写自 Octans 项目文档架构层中的扫描、刮削、重命名与删除模块说明(octans-docs arch:scanner / scraper / renamer / deletion)。正文收敛为公开主链与职责边界,不展开完整 API 字段、任务载荷、控制器方法或前端批处理状态机;接口契约与运行时细节以目标环境当前实现文档为准。