# 开源影视媒体库自动化刮削整理完整技术方案(可落地) ## 一、方案概述 本方案针对个人/NAS影视媒体库(适配 Jellyfin/Emby/Kodi),基于**全开源工具栈**搭建一套标准化、可自动化、可API对接的媒体处理流水线,覆盖:文件标准化重命名、批量字幕下载、影视元数据刮削、NFO/海报/背景图生成、程序API自动化控制。 方案区分两套核心模式: - **GUI手动精准刮削模式**:轻量化、低占用,替代TinyMediaManager - **API全自动流水线模式**:支持脚本/自研系统对接,无人值守批量处理媒体库 适用场景:本地影视库、NAS媒体库、自建影音服务、个人媒体自动化运维。 ## 二、核心工具选型对比(开源、无付费、无广告) 摒弃闭源工具,全部采用开源可商用工具,精准分工,避免单一工具短板。 |工具|核心用途|优势|短板|场景定位| |---|---|---|---|---| |MediaElch|GUI可视化刮削、生成标准NFO/海报|轻量快速、无Java依赖、中文适配、Kodi标准NFO、跨平台|无字幕下载、无API、新版无TVDB、动漫弱|手动精准刮削、替代TMM日常使用| |mnamer|批量文件标准化重命名(CLI)|开源跨平台、递归扫描、智能匹配、可脚本自动化|不生成NFO、不下载图片|媒体库前置规整,统一文件命名规范| |Subliminal|批量简体中文字幕下载(CLI)|开源批量、自动去重、适配主流视频格式|部分字幕源需网络优化|配套MediaElch补齐字幕能力| |SubtitleEdit|字幕修复、编码转换、时间轴校准|全能开源字幕工具、批量处理、解决乱码|无自动下载能力|字幕后置修复优化| |tinyMediaManager\(TMM\)|可视化刮削 \+ **完整REST API**|双源TMDB/TVDB、支持API远程控制、生态成熟、剧集识别强|Java占用高、启动慢|API自动化核心工具、老剧/剧集优先| |自建FastAPI刮削服务|自研无状态刮削API|完全自主可控、可深度定制、无程序依赖|需自行开发文件写入逻辑|自研系统对接、个性化流水线| |Radarr/Sonarr|全自动化媒体运维(下载\+刮削\+整理)|Docker友好、API完善、全自动无人值守|功能过重,单纯存量库刮削没必要|PT自动追更、全自动媒体库| ## 三、标准化媒体库目录规范(核心基础) 所有刮削工具生效的前提,统一文件夹结构,兼容所有影音服务器。 ### 3\.1 电影目录规范 ```Plain Text Media/ └── Movies/ └── 流浪地球 (2019)/ # 单电影独立文件夹 └── 流浪地球 (2019).mkv # 标准化命名 ``` ### 3\.2 剧集目录规范 ```Plain Text Media/ └── Shows/ └── 漫长的季节 (2023)/ ├── Season 01/ │ ├── S01E01.mkv │ └── S01E02.mkv ``` ### 3\.3 输出文件规范 - 电影元数据:`movie.nfo` - 剧集元数据:`tvshow.nfo` \+ `episode.nfo` - 图片资源:`poster.jpg`(海报)、`fanart.jpg`(背景) - 字幕文件:视频同目录 `.srt` 简体中文字幕 ## 四、方案一:轻量化手动刮削流水线(日常主力) **适用人群**:不想装Java、追求流畅、手动精修媒体库、存量影片整理 **工具组合**:mnamer \+ Subliminal \+ MediaElch \+ SubtitleEdit **执行顺序(固定流水线)** ### 4\.1 第一步:mnamer 文件标准化重命名 先规整杂乱文件名,为字幕匹配、元数据刮削打底。 核心配置文件 `.mnamer-v2.json`: ```Plain Text { "language": "zh-CN", "movie_api": "tmdb", "movie_format": "{name} ({year}).{extension}", "recurse": true, "extension_mask": ["mkv","mp4","mov","webm","ts","m4v"], "max_hits": 5 } ``` 执行命令(先预览后生效,规避误改): ```Plain Text # 预览模式(无修改) mnamer --test 媒体目录路径 # 正式重命名 mnamer 媒体目录路径 ``` ### 4\.2 第二步:Subliminal 批量下载中文字幕 ```Plain Text # 递归下载简体中文字幕 subliminal download -l zh 媒体目录路径 ``` ### 4\.3 第三步:MediaElch 可视化精准刮削 核心预设配置(中文兼容最优): - 数据源:TMDB,语言 `zh-CN` - 开启:标题、简介、年份、评分、演员、海报、背景图下载 - 输出:标准Kodi NFO,适配Jellyfin/Emby/Kodi - 自动清理旧冗余NFO、图片文件 ### 4\.4 第四步:SubtitleEdit 字幕修复 批量解决字幕乱码、时间轴错位、编码不统一问题,统一转为UTF\-8编码。 ## 五、方案二:API全自动无人值守流水线(进阶自动化) **适用人群**:需要脚本控制、自研系统对接、NAS自动化、批量无人值守刮库 **两套API方案可选**:TMM官方API(开箱即用)、自建FastAPI(完全自研) ### 5\.1 方案2\.1:TMM REST API 自动化流水线(推荐商用落地) #### 5\.1\.1 前置配置 - 开启TMM:设置\-系统\-API,启用服务,默认端口7878 - 获取API\-KEY,开启跨域访问 - API文档地址:`http://127.0.0.1:7878/api/docs` #### 5\.1\.2 完整Python自动化脚本 ```Plain Text import requests import time # TMM配置 TMM_HOST = "http://127.0.0.1:7878" API_KEY = "你的TMM_API_KEY" HEADERS = {"api-key": API_KEY} # 扫描媒体库 def scan_library(library_id: int): resp = requests.post(f"{TMM_HOST}/api/v1/library/scan/{library_id}", headers=HEADERS) print("库扫描完成:", resp.text) time.sleep(5) # 单影片自动刮削(写NFO+下海报) def scrape_movie(movie_id: int): payload = { "scraper": "tmdb", "language": "zh-CN", "downloadImages": True, "writeNfo": True } resp = requests.post(f"{TMM_HOST}/api/v1/movies/scrape/{movie_id}", json=payload, headers=HEADERS) print("影片刮削完成:", resp.text) # 获取库内所有影片 def get_all_movies(library_id: int): resp = requests.get(f"{TMM_HOST}/api/v1/library/{library_id}/movies", headers=HEADERS) return resp.json() if __name__ == "__main__": lib_id = 1 # 替换为你的媒体库ID scan_library(lib_id) movies = get_all_movies(lib_id) for movie in movies: scrape_movie(movie["id"]) time.sleep(2) ``` ### 5\.2 方案2\.2:自建FastAPI无状态刮削服务(自研定制) 无第三方程序依赖,纯接口服务,可自由扩展NFO生成、图片下载、自定义规则。 #### 5\.2\.1 依赖安装 ```Plain Text pip install fastapi uvicorn tmdbv3api pydantic ``` #### 5\.2\.2 完整服务代码 ```Plain Text from fastapi import FastAPI from pydantic import BaseModel from tmdbv3api import TMDb, Movie, TV import uvicorn app = FastAPI(title="自研影视刮削API服务") # TMDB配置 tmdb = TMDb() tmdb.api_key = "你的TMDB_KEY" tmdb.language = "zh-CN" movie_api = Movie() tv_api = TV() class SearchRequest(BaseModel): name: str year: int = None media_type: str # 影视搜索刮削接口 @app.post("/scrape/search") async def scrape_search(req: SearchRequest): if req.media_type == "movie": res = movie_api.search(req.name, year=req.year) elif req.media_type == "tv": res = tv_api.search(req.name, year=req.year) else: return {"error": "media_type仅支持movie/tv"} result = [] for item in res: result.append({ "id": item.id, "title": item.title if req.media_type == "movie" else item.name, "original_title": item.original_title, "overview": item.overview, "release_date": getattr(item, "release_date", getattr(item, "first_air_date", "")), "poster_path": item.poster_path, "score": item.vote_average }) return {"code":200, "data":result} # 生成标准NFO文本工具函数 def generate_movie_nfo(meta:dict) -> str: return f""" {meta['title']} {meta['original_title']} {meta['overview']} {meta['release_date'][:4]} {meta['score']} {meta['id']} """ if __name__ == "__main__": uvicorn.run("main:app", host="0.0.0.0", port=8000) ``` 服务启动后,访问 `127.0.0.1:8000/docs` 可在线调试API。 ## 六、Windows一键批量脚本(整合全流程) 双击即可完成:文件预览校验→正式重命名→批量字幕下载,全程可视化确认。 ```Plain Text @echo off chcp 65001 setlocal set "MEDIA_PATH=D:\Media\Movies" echo ========== 第一步:预览文件重命名 ========== mnamer --test "%MEDIA_PATH%" set /p "choice=确认执行重命名?Y/N: " if /i not "%choice%"=="Y" exit echo ========== 第二步:执行标准化重命名 ========== mnamer "%MEDIA_PATH%" echo ========== 第三步:批量下载中文字幕 ========== subliminal download -l zh "%MEDIA_PATH%" echo 全部任务执行完成! pause ``` ## 七、场景化选型策略(核心落地指南) ### 7\.1 日常个人媒体库(首选) mnamer \+ Subliminal \+ MediaElch,轻量无负担,中文适配最佳 ### 7\.2 大量老剧集、海外剧集 改用 TMM,支持TVDB双源,识别准确率远超MediaElch ### 7\.3 需要程序自动化、系统对接 优先 TMM API(开箱即用),深度自研选择 FastAPI自建服务 ### 7\.4 全自动PT追更媒体库(NAS) Radarr \+ Sonarr 容器化部署,全流程无人值守 ### 7\.5 大量动漫资源 补充开源工具 Mochi,支持Bangumi番剧数据源,弥补MediaElch短板 ## 八、常见问题与解决方案(踩坑汇总) - **TMDB刮削超时**:网络解析问题,优化hosts配置或合规代理 - **字幕命中率低**:必须先用mnamer标准化文件名,杂乱命名无法精准匹配 - **NFO不被Jellyfin识别**:文件统一UTF\-8编码、视频独立文件夹、禁止多层嵌套 - **MediaElch剧集匹配差**:新版无TVDB,老剧切换TMM处理 - **字幕乱码**:SubtitleEdit批量转为UTF\-8编码 ## 九、方案优势总结 1. **全开源无版权风险**:所有工具均为开源协议,无付费、无捆绑、无水印 2. **分层适配场景**:兼顾手动精修 \+ 全自动API自动化,适配个人/自研系统/NAS 3. **标准化输出**:全部生成Kodi标准NFO,100%兼容Jellyfin/Emby/Kodi主流影音服务 4. **可扩展可定制**:支持自建API、二次开发、流水线自定义改造 > (注:部分内容可能由 AI 生成)