10 KiB
Executable File
开源影视媒体库自动化刮削整理完整技术方案(可落地)
一、方案概述
本方案针对个人/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 电影目录规范
Media/
└── Movies/
└── 流浪地球 (2019)/ # 单电影独立文件夹
└── 流浪地球 (2019).mkv # 标准化命名
3.2 剧集目录规范
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:
{
"language": "zh-CN",
"movie_api": "tmdb",
"movie_format": "{name} ({year}).{extension}",
"recurse": true,
"extension_mask": ["mkv","mp4","mov","webm","ts","m4v"],
"max_hits": 5
}
执行命令(先预览后生效,规避误改):
# 预览模式(无修改)
mnamer --test 媒体目录路径
# 正式重命名
mnamer 媒体目录路径
4.2 第二步:Subliminal 批量下载中文字幕
# 递归下载简体中文字幕
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自动化脚本
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 依赖安装
pip install fastapi uvicorn tmdbv3api pydantic
5.2.2 完整服务代码
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"""<movie>
<title>{meta['title']}</title>
<originaltitle>{meta['original_title']}</originaltitle>
<plot>{meta['overview']}</plot>
<year>{meta['release_date'][:4]}</year>
<rating>{meta['score']}</rating>
<tmdbid>{meta['id']}</tmdbid>
</movie>"""
if __name__ == "__main__":
uvicorn.run("main:app", host="0.0.0.0", port=8000)
服务启动后,访问 127.0.0.1:8000/docs 可在线调试API。
六、Windows一键批量脚本(整合全流程)
双击即可完成:文件预览校验→正式重命名→批量字幕下载,全程可视化确认。
@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编码
九、方案优势总结
-
全开源无版权风险:所有工具均为开源协议,无付费、无捆绑、无水印
-
分层适配场景:兼顾手动精修 + 全自动API自动化,适配个人/自研系统/NAS
-
标准化输出:全部生成Kodi标准NFO,100%兼容Jellyfin/Emby/Kodi主流影音服务
-
可扩展可定制:支持自建API、二次开发、流水线自定义改造
(注:部分内容可能由 AI 生成)