1. 项目概述:一个现代数字资产管理者的工具箱
如果你和我一样,是个喜欢收藏电影、剧集、纪录片,或者任何形式的数字媒体内容的人,那你一定经历过这样的烦恼:硬盘里塞满了各种文件,命名混乱不堪,有的叫“S01E01.mp4”,有的叫“第一季第一集.mkv”,还有的直接是一串神秘的数字。想找一部片子,得靠记忆和运气。更别提那些从不同渠道下载来的媒体文件,元数据(比如海报、简介、演员表)要么缺失,要么错乱,整个媒体库看起来就像个杂乱无章的仓库。
这就是theMK2k/Media-Hoarder这个项目诞生的背景。它不是一个单一的软件,而是一个高度集成、可编程的自动化媒体资产管理流水线。你可以把它理解为一个为你私人媒体库服务的“超级管家”或“自动化工厂”。它的核心目标,是把那些来源不一、格式各异、信息不全的媒体文件,通过一系列自动化的处理步骤,最终整理成一个结构清晰、信息完整、赏心悦目的个人媒体库,完美适配像 Plex、Jellyfin、Emby 这类流行的媒体服务器软件。
这个项目特别适合那些拥有大量本地媒体资源,并且对整理质量和自动化程度有较高要求的用户。无论是影音爱好者、数据囤积者,还是希望搭建家庭影院系统的技术玩家,Media-Hoarder 都能显著提升你的管理效率和体验。它不关心你的媒体文件是从哪里来的,只关心如何让它们在你的硬盘上变得井然有序。
2. 核心设计思路:从“仓库”到“图书馆”的自动化流水线
Media-Hoarder 的设计哲学非常清晰:自动化、可定制、模块化。它不是一个试图用一套固定规则解决所有问题的僵化工具,而是一个提供了丰富“乐高积木”的构建平台。你可以根据自己的需求,自由组合这些积木,搭建出最适合自己工作流的自动化流水线。
2.1 流水线式处理架构
整个项目的核心是一个线性的处理管道(Pipeline)。一个原始的媒体文件(我们称之为“输入”)进入这个管道,会依次经过多个处理阶段,每个阶段都像一个“车间”,负责完成一项特定的任务,最终产出一个“成品”。
一个典型的处理流程可能包含以下车间:
- 识别车间:分析文件名,猜测它是什么电影或哪一集电视剧。
- 查询车间:根据识别结果,去互联网上的数据库(如 TMDB、TVDB)拉取详细的元数据(片名、简介、评分、演员、海报等)。
- 重命名车间:根据获取的元数据,按照你预设的漂亮格式(例如:
电影名 (年份)/电影名 (年份).mkv)重命名文件和文件夹。 - 下载车间:自动下载匹配的海报、背景图、字幕等资源文件。
- 转码/优化车间(可选):将视频转换为更通用的格式(如 H.264 MP4),或者提取/嵌入音轨、字幕。
- 输出车间:将处理好的文件和元数据,按照媒体服务器(如 Plex)要求的目录结构进行摆放。
这个流水线的强大之处在于,每个“车间”都是可插拔的。你可以跳过不需要的步骤(比如不转码),也可以调整它们的顺序,甚至可以自己编写新的“车间”来满足特殊需求。
2.2 配置即代码,一切尽在掌控
与许多带图形界面的工具不同,Media-Hoarder 主要通过一个 YAML 格式的配置文件来驱动。这听起来可能对新手有点门槛,但却是其灵活性的根源。在这个配置文件里,你可以:
- 定义流水线:明确指定要启用哪些处理步骤,以及它们的执行顺序。
- 设置规则:为不同的媒体类型(电影、电视剧、纪录片)设置不同的命名规则、存储路径和元数据来源。
- 配置连接:指定你的媒体服务器地址、API密钥,以及用于元数据查询的网站凭证。
- 设置触发器:决定 Media-Hoarder 如何运行。是定时扫描特定文件夹?还是监控下载工具的完成目录?或者是手动执行?
这种“配置即代码”的方式,使得整个处理流程变得透明、可版本控制、可重复。一旦你调教好一套配置文件,它就能稳定、可靠地处理成千上万个文件。
注意:初次接触 YAML 配置可能会觉得复杂,但 Media-Hoarder 社区提供了丰富的示例配置。我的经验是,从一个最简单的、只处理电影的例子开始,逐步添加功能,比直接修改一个复杂的全能配置要容易得多。
3. 核心组件与工具链深度解析
要玩转 Media-Hoarder,你需要对它所依赖或整合的一系列核心工具和技术有基本了解。它们就像是这个“超级管家”手下的专业团队。
3.1 识别引擎:文件名的“破译者”
这是流水线的第一步,也是最关键的一步。如果识别错了,后面所有步骤都会跑偏。Media-Hoarder 本身不直接做识别,它通常集成或调用更专业的识别库。
- guessit: 这是一个非常强大的 Python 库,专门用于从混乱的文件名中解析出信息。给它一个像
The.Matrix.1999.1080p.BluRay.x264.DTS-HD.MA.5.1-FGT.mkv这样的文件名,它能准确地告诉你:标题是“The Matrix”,年份是1999,分辨率是1080p,来源是蓝光,视频编码是x264,音频编码是DTS-HD MA 5.1,发布小组是FGT。对于剧集,它能识别出季号、集号、剧集标题等。Media-Hoarder 重度依赖 guessit 来完成初步的“猜谜”工作。 - 手动修正与交互:自动识别不可能100%准确,尤其是对于那些命名极其不规范或冷门的文件。因此,一个健壮的流程必须包含人工干预的环节。Media-Hoarder 可以通过配置,在识别置信度低时暂停并提示用户进行选择,或者生成一个待审核列表,让你批量确认。
3.2 元数据抓取:为媒体注入“灵魂”
识别出媒体是什么之后,下一步就是为它填充丰富的描述信息,也就是元数据。这相当于给一本没有封面的书配上精美的封面、作者介绍和内容摘要。
数据源:
- TMDB (The Movie Database):电影和电视剧信息的主要来源,社区活跃,数据质量高,API 免费且友好。
- TVDB (The TV Database):电视剧信息的传统权威,尤其在剧集季、集对应关系上非常准确。但近年来 API 稳定性有时会波动。
- OMDB API:另一个电影数据库,有时可以作为 TMDB 的补充或备选。 Media-Hoarder 可以配置多个数据源,并设置优先级。例如,优先使用 TMDB 查询电影,如果没找到,再尝试 OMDB。
抓取内容:一次成功的查询可以获取海量信息,包括但不限于:
- 原始标题、本地化标题(如中文名)。
- 剧情简介、标语(Tagline)。
- 演职人员表(导演、演员及角色)。
- 流派、评分、时长、上映日期。
- 最重要的:各种尺寸的海报(Poster)、背景图(Fanart)、标志(Logo)等图片资源的 URL。
3.3 文件操作与重命名:建立秩序
这是将虚拟的元数据落实到物理文件上的步骤。Media-Hoarder 会根据你的配置模板,对文件和目录进行重命名和移动。
- 命名模板:这是配置中的精华部分。你可以使用类似
{title} ({year})/{title} ({year}) {edition-{edition}}{video_format}.{ext}这样的模板。当处理《黑客帝国》(1999) 的 1080p 版本时,它就会被重命名为The Matrix (1999)/The Matrix (1999) 1080p.mkv。模板中的变量(用花括号包裹)会被替换为从 guessit 和元数据查询中获取的实际值。 - 目录结构:良好的目录结构是媒体服务器的基石。通常,电影和电视剧会分开存放:
- 电影:
根目录/电影/电影名 (年份)/电影文件 - 电视剧:
根目录/电视剧/剧集名 (年份)/Season XX/剧集文件清晰的目录结构能让 Plex、Jellyfin 等软件瞬间识别并刮削到正确的信息,几乎无需手动匹配。
- 电影:
3.4 资源下载与资产管理
元数据里包含了图片资源的链接,Media-Hoarder 会负责把它们下载下来,并以媒体服务器认可的命名方式(如poster.jpg,fanart.jpg,banner.jpg)存放在媒体文件所在的目录里。有些高级配置还能下载预告片、主题音乐等。
此外,对于多音轨、多字幕的文件,Media-Hoarder 可以整合像mkvpropedit这样的工具,将元数据(如影片标题、演员)直接写入到 MKV 文件的容器属性中,这样即使用不依赖外部 NFO 文件的播放器,也能看到一些基本信息。
3.5 与媒体服务器的集成:最后一公里
整理好的媒体库最终是要被使用的。Media-Hoarder 可以与 Plex、Jellyfin、Emby 等主流媒体服务器深度集成。
- 刷新库:在完成一批文件的处理后,Media-Hoarder 可以自动调用媒体服务器的 API,通知它“库里有新内容了,快更新一下”。这样你无需手动进入服务器管理界面点击扫描。
- 部分刷新:更高效的做法是,只刷新发生变动的目录,而不是扫描整个庞大的媒体库,这能节省大量时间。
- 元数据写入:除了依赖媒体服务器自己刮削,Media-Hoarder 还可以生成
*.nfo文件。这是一个包含所有元数据的 XML 文件,是 Kodi(以及受其影响的 Emby、Jellyfin)生态的标准元数据格式。服务器会优先读取本地的 NFO 文件,这能保证元数据的准确性和一致性,避免因网络问题或数据库变动导致信息错乱。
4. 实战部署与配置详解
理论说了这么多,我们来点实际的。下面我将以一个典型的、在 Linux 环境下(使用 Docker)部署 Media-Hoarder 的流程为例,手把手带你走一遍。即使你使用其他系统,思路也是完全相通的。
4.1 环境准备与安装
最推荐的方式是使用 Docker,它能解决所有依赖问题,保持环境干净。
安装 Docker 和 Docker Compose:确保你的系统上已经安装了 Docker 和 Docker Compose。这是基础,不再赘述。
准备目录结构:在硬盘上规划好你的目录。我建议的结构如下:
/path/to/your/media/ ├── media_home/ # Media-Hoarder 的工作目录 │ ├── config/ # 存放配置文件 │ ├── logs/ # 存放运行日志 │ └── cache/ # 缓存目录,加速后续处理 ├── media_input/ # “原料区”:存放待处理的原始文件 ├── media_movies/ # “成品区”:处理好的电影 └── media_tvshows/ # “成品区”:处理好的电视剧将
media_input,media_movies,media_tvshows通过 Docker 的卷(volume)映射给容器。获取 Docker 镜像:Media-Hoarder 提供了官方镜像。使用命令拉取:
docker pull themk2k/media-hoarder
4.2 核心配置文件剖析
在config/目录下,创建主配置文件config.yaml。这是整个系统的大脑。下面是一个高度精简但功能完整的示例,我们逐段解析:
# config.yaml # 1. 全局设置 general: min_free_space_gb: 50 # 确保磁盘有至少50GB空间时才处理,防止塞满硬盘 library_path: /media # 容器内媒体库的根路径,对应我们挂载的目录 # 2. 定义输入源(从哪里获取待处理文件) inputs: local_input: type: local path: /media/media_input # 对应宿主的 /path/to/your/media/media_input # 可以设置监控,这里我们假设手动或定时将文件放入此目录 # watch: true # 如果启用,则会监控此目录,新文件出现即自动处理 # 3. 定义输出目标(处理好的文件放到哪里) outputs: movies: type: local path: /media/media_movies # 限制只处理电影类型 content_type: movie # 定义电影的文件/目录命名规则 naming: folder: "{title} ({year})" file: "{title} ({year}) {video_format}.{ext}" tvshows: type: local path: /media/media_tvshows content_type: episode naming: folder: "{series} ({year})/Season {season:02d}" file: "{series} - S{season:02d}E{episode:02d} - {title}.{ext}" # 4. 定义处理流水线(Pipeline) # 一个 Pipeline 由一系列“插件”(步骤)组成 pipelines: # 定义一个名为“movie_pipeline”的流水线来处理电影 movie_pipeline: # 这个流水线作用于哪个输入源 input: local_input # 这个流水线的输出目标是哪个 output: movies # 定义处理步骤 steps: - step: parse_filename # 第一步:解析文件名(使用 guessit) - step: identify_movie # 第二步:识别电影(查询 TMDB/TVDB) config: sources: - tmdb - tvdb language: zh-CN # 优先获取中文元数据 - step: rename # 第三步:根据模板重命名和移动文件 - step: download_images # 第四步:下载海报、背景图等 config: types: - poster - fanart - step: generate_nfo # 第五步:生成 .nfo 元数据文件(给 Kodi/Jellyfin 用) - step: notify_plex # 第六步:通知 Plex 刷新媒体库(可选) config: base_url: http://your-plex-server-ip:32400 token: YOUR_PLEX_TOKEN # 需要在 Plex 设置中获取 section_id: 1 # 你的电影库在 Plex 中的 ID # 再定义一个处理电视剧的流水线 tv_pipeline: input: local_input output: tvshows steps: - step: parse_filename - step: identify_episode # 使用 identify_episode 插件来识别剧集 config: sources: - tmdb - tvdb language: zh-CN - step: rename - step: download_images - step: generate_nfo - step: notify_plex config: base_url: http://your-plex-server-ip:32400 token: YOUR_PLEX_TOKEN section_id: 2 # 你的电视剧库 ID关键点解析:
content_type:这是路由的关键。parse_filename步骤后,Media-Hoarder 会根据 guessit 的判断结果,给文件打上movie或episode的标签。然后系统会自动将其路由到对应content_type的输出和流水线。这样,电影和电视剧就能被分开处理,互不干扰。naming模板:{title},{year},{video_format}这些都是变量。season:02d表示季号格式化为两位数字(如 01)。你可以在这里发挥创意,定制出你最顺眼的命名风格。- 步骤顺序:逻辑必须清晰。必须先
identify(知道是什么),才能rename(根据知道的信息来命名)。download_images和generate_nfo通常放在重命名之后,因为此时文件已经在最终位置了。 - Plex Token:为了安全,Plex 需要令牌才能通过 API 访问。你可以在 Plex Web 界面中,通过
设置->常规-> 最下方高级->显示高级设置->API 令牌来获取。
4.3 运行与测试
编写 Docker Compose 文件:在项目根目录创建
docker-compose.yml,让部署更简单。version: '3.8' services: media-hoarder: image: themk2k/media-hoarder container_name: media-hoarder restart: unless-stopped volumes: - /path/to/your/media/media_input:/media/media_input:ro # 只读挂载输入目录 - /path/to/your/media/media_movies:/media/media_movies - /path/to/your/media/media_tvshows:/media/media_tvshows - /path/to/your/media/media_home/config:/config - /path/to/your/media/media_home/cache:/cache - /path/to/your/media/media_home/logs:/logs environment: - TZ=Asia/Shanghai # 设置时区 command: run --config /config/config.yaml # 启动时指定配置文件首次运行与手动触发:
cd /path/to/your/media docker-compose up -d # 后台启动容器 docker-compose logs -f media-hoarder # 查看实时日志启动后,Media-Hoarder 不会自动开始处理,除非你配置了
watch: true。我们可以手动执行一次流水线来处理media_input目录下已有的文件。docker-compose exec media-hoarder media-hoarder run --config /config/config.yaml --pipeline movie_pipeline docker-compose exec media-hoarder media-hoarder run --config /config/config.yaml --pipeline tv_pipeline观察日志,你会看到每个文件的识别、查询、重命名、下载等步骤的详细输出。
验收成果:处理完成后,去
media_movies和media_tvshows目录下查看。你会发现混乱的文件名消失了,取而代之的是整齐的目录结构,每个目录里都有媒体文件、海报图(poster.jpg)和包含完整信息的 .nfo 文件。此时打开 Plex 或 Jellyfin,添加这两个库路径,几乎可以瞬间完成刮削,所有信息都已就位。
5. 高级技巧与疑难排坑实录
经过一段时间的实际使用,我积累了一些能让 Media-Hoarder 运行得更顺畅的经验,也踩过不少坑。这里分享给你。
5.1 配置优化与最佳实践
使用缓存加速:TMDB/TVDB 的 API 有调用频率限制。Media-Hoarder 的缓存功能(
cache目录)可以存储查询结果。对于已经处理过的媒体,下次再遇到(比如不同版本)可以直接使用缓存,速度极快,且避免触及 API 限制。确保缓存目录被正确挂载且可写。处理“合集”与“特别篇”:
- 电影合集:像《指环王》三部曲,guessit 可能识别为单部电影。你需要确保 TMDB 上有该合集条目,或者更常见的做法是,让 Media-Hoarder 将它们识别为独立的电影。可以在
identify_movie步骤的配置中,设置allow_guessing: false来强制要求精确匹配,避免将《指环王1》匹配到《指环王》合集上。 - 剧集特别篇:S00EXX 的剧集(如幕后花絮、特典)常常无法从 TMDB/TVDB 获取元数据。一个变通方法是,在
identify_episode配置中,为这类剧集指定一个特殊的查询模式,或者干脆为它们创建一个单独的、跳过元数据查询的简易流水线,只做重命名。
- 电影合集:像《指环王》三部曲,guessit 可能识别为单部电影。你需要确保 TMDB 上有该合集条目,或者更常见的做法是,让 Media-Hoarder 将它们识别为独立的电影。可以在
音视频文件的预处理:有时下载的文件内封了多余的非必要音轨或字幕,或者格式不被所有设备兼容。你可以在流水线中插入一个
transcode或manipulate步骤(需要额外配置 FFmpeg)。例如,使用ffmpeg将视频流复制,并将所有音频转码为 AAC 格式,同时提取中文字幕为 SRT 外挂字幕。这能极大提升媒体文件的兼容性。- step: manipulate config: ffmpeg: input_format: guess output_format: mp4 video: codec: copy # 视频流直接复制,不重新编码(速度快,无损) audio: - codec: aac language: eng # 处理英语音轨 bitrate: 192k - codec: aac language: chi # 处理中文音轨 bitrate: 192k subtitle: - language: chi # 提取中文字幕流 codec: srt实操心得:转码非常消耗 CPU 和时间,只建议对确实有兼容性问题的文件进行。对于绝大多数情况,“视频流复制 + 音频转码 AAC”是性价比最高的方案,能在保证兼容性的前提下最大化保留原画质。
5.2 常见问题与解决方案
下面是一个我遇到过的典型问题速查表:
| 问题现象 | 可能原因 | 排查与解决思路 |
|---|---|---|
| 文件未被处理,日志无相关记录 | 1. 文件不在input定义的路径下。2. 文件类型被忽略(如 .nfo,.jpg文件)。3. content_type识别失败,无法路由到任何流水线。 | 1. 检查挂载路径和配置文件中的path是否一致。2. 检查配置中是否有 ignore规则。3. 查看 parse_filename步骤的日志,确认 guessit 识别出的类型 (movie,episode,unknown)。对于识别为unknown的,需要优化文件名或调整 guessit 配置。 |
| 识别错误(如电影A被识别为电影B) | 1. 文件名信息太少或歧义大。 2. 元数据源(TMDB)中存在相似名称的条目。 | 1. 尝试在文件名中加入年份,如Movie Name (2010).mkv。2. 查看 identify步骤的日志,看它匹配到了哪个 ID。可以手动在 TMDB 网站搜索确认。对于易混淆的,可以在输入目录下创建一个简单的.match文件来强制指定 TMDB ID。 |
| 元数据获取失败或为英文 | 1. API 密钥无效或过期。 2. 网络问题无法访问 TMDB/TVDB。 3. 配置中 language设置不正确或该语言元数据不存在。 | 1. 确认 TMDB/TVDB 的 API Key 已正确配置在环境变量或插件配置中。 2. 检查容器网络,尝试 curl测试 API 端点。3. 将 language设为zh-CN,并添加fallback_language: en作为备选。 |
| 重命名后文件消失 | 1. 重命名模板配置错误,导致目标路径非法(如包含非法字符)。 2. 权限问题,容器用户无权在输出目录写入。 | 1.极其重要:先在测试目录用小批量文件运行!检查重命名模板,避免使用 `/:*?"<> |
| Plex 未刷新或刷新慢 | 1. Plex 服务器地址、Token、Section ID 配置错误。 2. Plex 服务器正在执行其他任务(如分析内容)。 | 1. 仔细核对notify_plex步骤的配置。Plex Token 和 Section ID 最容易出错。2. 查看 Plex 服务器后台任务队列。可以尝试将通知步骤改为只刷新特定路径,而非整个库。 |
| 处理速度慢 | 1. 网络延迟高(频繁查询在线元数据)。 2. 开启了图片下载(尤其是高清背景图)。 3. 配置了视频转码。 | 1. 充分利用缓存功能。 2. 评估是否需要下载 fanart等大图,或者限制图片尺寸。3. 转码是性能瓶颈,考虑在硬件更强的机器上运行,或仅在夜间处理。 |
5.3 自动化与监控
让 Media-Hoarder 全自动运行,才是解放双手的终极目标。
定时任务:最简单的自动化是使用 Crontab (Linux) 或计划任务 (Windows) 定时执行处理命令。例如,每天凌晨3点运行一次。
# 在宿主机上编辑 crontab -e 0 3 * * * cd /path/to/your/media && docker-compose exec -T media-hoarder media-hoarder run --config /config/config.yaml > /path/to/logs/cron.log 2>&1注意使用
-T参数禁用伪终端分配,适合在后台运行。目录监控:更优雅的方式是启用配置中的
watch: true。这样,只要将文件放入media_input目录,Media-Hoarder 就会自动触发处理流程。但这需要容器持续运行并监听文件系统事件。与下载工具联动:这才是“自动化流水线”的精华。你可以将 qBittorrent、Deluge、Sonarr、Radarr 等工具的“完成下载”目录设置为
media_input。这样,一旦下载完成,文件就会被自动移动到输入目录,进而触发 Media-Hoarder 的处理。整个流程:搜索 -> 下载 -> 整理 -> 入库 -> 通知服务器,完全无需人工干预。日志与通知:务必配置日志轮转,防止日志文件过大。可以将日志目录挂载出来,方便查看。对于关键错误(如连续识别失败、磁盘空间不足),可以配置 Media-Hoarder 通过电子邮件、Apprise(支持 Telegram、Slack 等数十种服务)或 Webhook 发送通知,让你及时知晓系统状态。
最后,我想说的是,Media-Hoarder 的配置是一个持续调优的过程。没有一套配置能完美适配所有人的库。我的建议是从一个最简单的、只处理一种类型媒体(比如电影)的配置开始,确保它能稳定运行。然后,逐步添加电视剧支持、图片下载、NFO生成、Plex通知等功能。每添加一项,都用一小批测试文件验证。遇到问题,就查阅日志,对照文档和社区讨论。当你看到成百上千个杂乱的文件被自动整理得井井有条,媒体服务器里瞬间出现精美的海报墙时,那种成就感,就是折腾这一切最大的回报。这个工具真正把时间还给了你,让你可以更专注于享受内容本身。