# 配置按类目分区、特典类别外置与 Music Videos 类目 用户需求:四个配置文件(special_maps / special_keywords / skip_directories / season_offsets)"不仅需要支持当前的,还需要支持其它所有类目";特典类别判定表完全外置;并实现 Music Videos(音乐视频)类目。三项合为 v9.6。 ## 配置按类目分区 四个文件支持**两种形态**:全局单表(旧版,行为不变)与类目分区(`{"tv": {...}, "musicvideo": [...]}`)。分区判定 `is_category_partitioned`:顶层全部键 ∈ `MO_CATEGORY_KEYS`(movie/tv/music/musicvideo/video/audio/default/global)→ 分区形态;混合形态警告并按全局处理(避免类目键被当数据键)。 查询链统一:**类目/流程分区 → default 分区 → 全局表 → 内置默认**。关键决策: 1. **分区键语义因文件而异**:特典映射/词表用类目键(tv/musicvideo);跳过目录用**流程键**(video/music)——目录语义判断发生在类目确定之前(正是用词表辅助判定),无法按条目类目取值;`find_show_*`/`count_main_videos`/`detect_special` 查 video 流程分区。 2. **skip_directories 分区 = 完整语义**:分区形态**不叠加内置默认**——否则 music 流程会命中 video 侧内置词(如 "sps"),分区失去意义;通用词放 default 分区。旧全局形态保持"数组内容优先、空数组回退内置"。 3. **special_keywords 分区 = 叠加语义**:tv 分区词 + 内置默认兜底(词表是积累型,AI 持续学习)。 4. **AI 写回自动适配**:`learn_skip_dirs`/`learn_special_keywords` 检测分区形态,写 `video`/`tv` 分区(jq `.video[...]`/`.tv[...]` 路径),全局形态写顶层;内存表同步更新分区表。 5. **分区引用展开**:special_maps 分区内字符串引用同分区优先,其次全局表(`resolve_special_value_cat`)。 **考虑过的方案**:分区键用前缀(`category.tv` 等,丑且破坏旧格式兼容);分区判定用"至少一个类目键"(混合形态静默错位);skip_directories 保持全局 + 仅扩展词表(无法按流程区分,music 流程误命中 video 词)。 ## 特典类别判定表外置 `special_category_tag` 原硬编码 24 项类别(Menu/CM/PV/...)→ 外置 `mo_config/special_categories.json`:**数组保序 = 优先级**(`[{"match": "nced", "tag": "NCED"}]`)。查询链:用户表(按序子串)→ 内置默认表(保留在 `special_category_tag` 作最后兜底)→ "Special"。缺失时交互创建(`SPECIAL_CATEGORIES_TEMPLATE` 常量),自动化跳过(内置兜底)。 **考虑过的方案**:对象形态(JSON 对象无顺序,判定优先级丢失——"mini anime" 需先于 "anime");并入 special_keywords(语义不同:词表判定"是否特典",类别表判定"S00 标签",且词表被 AI 写回,类别表是用户静态维护)。 ## Music Videos 类目 识别信号 = musicvideo 判定词(special_keywords 的 `musicvideo` 分区 → default → 内置 `MUSICVIDEO_WORDS` 13 词:mv/music video/live/concert/performance/演唱会/音乐视频/音乐录影带/现场 等)。**不回退 tv 特典词表**("sp" 子串命中 "SPs" 目录 = 稳定误判,正是开发中发现的 flakiness 根因之一)。 1. **目录信号(强信号)**:目录名**精确匹配**(归一化去空格小写整名相等)musicvideo 词 → 整目录音乐视频(即使文件名含季集标记)。精确匹配避免 "Muv-Luv"/"tmp.xxx" 含词误判——开发中实测 mktemp 临时目录名(tmp.XXXXXXXX)约 3% 概率含 cm/sp/pv/mv 两字符词导致测试偶发失败,精确匹配彻底根除。 2. **文件名信号**:方括号标记子串命中 musicvideo 词。双命中歧义(标记同时在特典词表,如 [MV]/[PV])用 "**歌手 - 歌名**" 模式消解:文件名含 ` - ` → 音乐视频(歌手分隔是音乐视频命名典型结构);不含 → 保持特典路径("动画名 [MV]" 剧集 MV 特典不被误判)。两侧词表可配置完全控制。 3. **命名**:`MusicVideos/{artist}/{title}.{ext}`(`NAMING_MUSICVIDEO` 模板,Jellyfin 官方结构)。artist 链:元数据 ALBUMARTIST → ARTIST → 父目录名解析("歌手 - 歌名"取首段;无分隔符整名;源根直属不解析)→ FOLDER_UNKNOWN。 4. **不进 AI**:本地规则无网络请求,识别失败(artist 兜底 Unknown)恒成功,不消耗 AI 轮次;unknown 才交 AI(保持 AI 类型域 movie/tv 不变,零 prompt 改动)。 5. **排除在特典路径外**:musicvideo 判定置于 parse 的年份提取之后、TV/特典规则之前;`[PV]`/`[CM]` 不在 musicvideo 词表 → 特典路径不受影响。 **考虑过的方案**:目录信号子串匹配(flakiness 实证否决);musicvideo 词表回退 tv 特典词表(SPs 误判);双命中一律 musicvideo(剧集 MV 特典误判);Music Videos 走 AI 判断(需扩展 prompt 类型域,且本地规则已覆盖多数文件——CONTEXT 挂账"多数文件规则补齐"正是此意)。 ## 配套 - 新文件:`src/lib/config/maps.sh` 扩展(分区加载/查询 + 特典类别表),`src/lib/main.sh`(MUSICVIDEO_WORDS_TEMPLATE/SPECIAL_CATEGORIES_TEMPLATE 常量、分区表全局变量),`src/lib/media/filename.sh`(detect_musicvideo),`src/lib/media/identify.sh`(identify_musicvideo),`src/lib/media/ai_resolve.sh`(fallback musicvideo 分支),`src/lib/pipeline/process.sh`(分发),`src/lib/integrate/ai.sh`(写回分区感知)。 - 测试:`tests/cases/media/musicvideo.sh`(7 例)、`tests/cases/config/categories.sh`(5 例)、`tests/cases/config/partition.sh`(6 例);全量 107 通过。 - 版本 9.6(main.sh SCRIPT_VERSION + bashly.yml)。