Go 语言影视文件名解析库,从文件名中提取媒体技术信息,集成 TMDB API 获取元数据,支持分类管理和自定义重命名。
✨ 中文增强版:专为中文环境优化,支持中文季集识别、动漫检测、中英标题分离。
- 🎬 全面解析:分辨率、编码、音频、HDR、字幕等 30+ 字段
- 🌏 中文优化:中文数字识别(第一季、第十二集)、动漫格式检测
- 🎯 TMDB 集成:自动匹配获取标准化元数据,内置缓存
- 📂 路径解析:多层目录信息合并,智能补充缺失字段
- 🏷️ 自动分类:基于 YAML 配置的灵活分类系统
- 📝 自定义词库:屏蔽词、替换词、集偏移、直接 ID 识别
- 🔄 模板重命名:Go template 语法,支持自定义函数
go get github.com/xifofo/movparseinfo, err := movparse.Parse("The.Matrix.1999.1080p.BluRay.x264-GROUP.mkv")
// info.Title = "The Matrix"
// info.Year = 1999
// info.Resolution = "1080p"
// info.VideoCodec = "H.264"
// info.Source = "Blu-ray"
// info.ReleaseGroup = "GROUP"
// info.PrimaryCategory = "movie"// 中英混合标题自动分离
info, _ := movparse.Parse("进击的巨人 Attack on Titan S01E01 1080p.mkv")
// info.Title = "进击的巨人"
// info.EnTitle = "Attack on Titan"
// info.Season = 1
// info.Episode = 1
// 中文季集识别
info, _ = movparse.Parse("海贼王 第一季 第十二集 1080p.mkv")
// info.Title = "海贼王"
// info.Season = 1
// info.Episode = 12
// 动漫格式检测
info, _ = movparse.Parse("【喵萌奶茶屋】【1080P】鬼灭之刃 - 01.mkv")
// info.IsAnime = true
// info.Title = "鬼灭之刃"
// info.Episode = 1info, _ := movparse.Parse("Breaking.Bad.S05E16.1080p.BluRay.x264.DTS-HD.MA.5.1-GROUP.mkv")
// info.Season = 5
// info.Episode = 16
// info.PrimaryCategory = "tv"
// info.AudioCodec = "DTS-HD MA"ParsePath 支持从完整文件路径中逐层提取信息。优先使用文件名中的信息,缺失字段从上层目录逐级补充。
// 基本用法:从目录结构中提取标题、季号
info, _ := movparse.ParsePath("海贼王/Season01/E01.mkv")
// info.Title = "海贼王" ← 来自上层目录
// info.Season = 1 ← 来自 Season01 目录
// info.Episode = 1 ← 来自文件名 E01
// info.PrimaryCategory = "tv"
// 电影路径:"标题 (年份)" 目录格式
info, _ = movparse.ParsePath("The Matrix (1999)/The.Matrix.1999.1080p.BluRay.x264-GROUP.mkv")
// info.Title = "The Matrix" ← 文件名优先
// info.Year = 1999
// 深层嵌套:逐层向上补充
info, _ = movparse.ParsePath("Netflix/动漫/进击的巨人/Season02/E05.mkv")
// info.Title = "进击的巨人" ← 来自上层目录
// info.Season = 2 ← 来自 Season02 目录
// info.Episode = 5 ← 来自文件名
// info.WebSource = "Netflix" ← 来自最上层目录信息提取优先级:文件名 > 最近的父目录 > 更上层目录
支持的目录名模式:
| 模式 | 示例 | 提取内容 |
|---|---|---|
| Season + 数字 | Season01, Season 2, S03 |
季号 |
| 标题 (年份) | The Matrix (1999), 电影 [2023] |
标题 + 年份 |
| 流媒体平台名 | Netflix, AMZN |
WebSource |
| 技术标签 | 1080p.BluRay, Remux |
分辨率/来源等 |
| 普通目录名 | 海贼王, Breaking Bad |
标题(兜底) |
弱标题检测:文件名为纯数字(如 1.mkv)、集号(如 E01.mkv)或通用词(如 movie.mkv)时,会自动从目录名补充标题。
Windows 路径:自动识别反斜杠分隔符 \。
info, _ := movparse.Parse("Movie.2024.2160p.UHD.BluRay.Remux.HDR10.HEVC.TrueHD.7.1.Atmos-GRP.mkv")
// info.HDRType = "HDR10"
// info.DynamicRange = "HDR"
// info.ResourceType = "Remux"
// info.AudioChannels = "7.1"
// info.Quality = "" (无HQ标记)支持的扩展字段:
| 字段 | 说明 | 示例值 |
|---|---|---|
| HDRType | HDR类型 | HDR10, Dolby Vision, HDR10+, HLG |
| ColorDepth | 色深 | 8bit, 10bit, 12bit |
| FrameRate | 帧率 | 24fps, 60fps, 120fps |
| DynamicRange | 动态范围 | SDR, HDR |
| AudioChannels | 音频声道 | 2.0, 5.1, 7.1, Atmos, DTS:X |
| SubtitleInfo | 字幕信息 | CHS, CHT, ENG, CHS.ENG |
| ThreeDFormat | 3D格式 | 3D, Half-SBS, Half-OU |
| Quality | 质量标签 | HQ, Proper, Repack, IMAX, Remastered |
| ResourceType | 资源类型 | Remux, BDMV, BDISO, UHD |
| WebSource | 流媒体平台 | Netflix, Amazon, Disney+ |
| ContainerFormat | 容器格式 | MKV, MP4, AVI, TS |
解析时自动用 title + year 搜索 TMDB,匹配结果填充到 MediaInfo,内置缓存机制避免重复请求。
import (
"github.com/xifofo/movparse"
"github.com/xifofo/movparse/tmdb"
)
// 创建 TMDB 客户端
client, _ := tmdb.NewClient(tmdb.ClientOption{
APIKey: "your-api-key",
})
// 创建匹配器(带缓存)
matcher, _ := movparse.NewTMDBMatcher(movparse.TMDBMatcherOption{
Client: client,
CacheTTL: 24 * time.Hour, // 缓存24小时,默认值
})
// 解析时自动匹配 TMDB
info, _ := movparse.Parse("The.Matrix.1999.1080p.BluRay.x264-GROUP.mkv", movparse.ParserOption{
TMDBMatcher: matcher,
})
// info.TMDBID = 603 ← 自动匹配
// info.IMDBID = "tt0133093" ← 从 TMDB 获取
// info.EnTitle = "The Matrix" ← 英文标题
// info.OriginalTitle = "The Matrix" ← 原始标题
// TV 自动获取集信息
info, _ = movparse.Parse("Breaking.Bad.S05E16.1080p.BluRay.mkv", movparse.ParserOption{
TMDBMatcher: matcher,
})
// info.TMDBID = 1396
// info.EpisodeTitle = "Felina" ← 自动获取集标题
// info.EpisodeDate = "2013-09-29" ← 自动获取播出日期自动匹配字段:
| 字段 | 说明 | 来源 |
|---|---|---|
| TMDBID | TMDB ID | 搜索匹配 |
| IMDBID | IMDB ID | TMDB 详情 |
| EnTitle | 英文标题 | TMDB 详情 |
| OriginalTitle | 原始语言标题 | TMDB 详情 |
| EpisodeTitle | 集标题(TV) | Season 详情 |
| EpisodeDate | 播出日期(TV) | Season 详情 |
缓存管理:
cache := matcher.Cache()
cache.Len() // 缓存条目数
cache.Cleanup() // 清理过期条目
cache.Clear() // 清空全部缓存优先级规则:文件名中已有的 TMDBID/IMDBID(如 tmdbid=123、tt1234567)不会被 TMDB 匹配结果覆盖。
import "github.com/xifofo/movparse/tmdb"
client, _ := tmdb.NewClient(tmdb.ClientOption{
APIKey: "your-api-key",
Timeout: 10 * time.Second,
})
// 搜索电影
resp, _ := client.SearchMovie(ctx, "The Matrix", 1999)
best := tmdb.BestMatch(resp, "The Matrix", 1999)
// 获取详情
detail, _ := client.GetMovieDetail(ctx, best.ID)支持两种配置格式:
movie:
动画电影:
genre_ids: "16"
华语电影:
original_language: "zh,cn,bo,za"
欧美电影:
original_language: "en,de,fr,nl,ru,es,el,da"
日韩电影:
original_language: "ja,ko"
外语电影: # 最后一个作为默认分类
tv:
动画番剧:
genre_ids: "16"
综艺节目:
genre_ids: "10764,10767"
国产剧集:
origin_country: "CN,TW,HK"
欧美剧集:
origin_country: "US,FR,GB,DE,ES,IT,NL,PT,RU,UK"
日韩剧集:
origin_country: "JP,KP,KR,TH,IN,SG"
其他剧集:movie:
- name: "动画电影"
conditions:
genre_ids: "16"
- name: "华语电影"
conditions:
original_language: "zh,cn"
production_countries: "CN,HK,TW"
- name: "外语电影"
tv:
- name: "动画"
conditions:
genre_ids: "16"
- name: "综艺"
conditions:
genre_ids: "10764,10767"
- name: "其他"分类配置支持外部传入,每个用户可以自定义自己的 category.yaml:
// 方式1:从文件加载
cfg, _ := movparse.LoadClassification("/path/to/your/category.yaml")
// 方式2:从 []byte 解析(适用于远程配置、嵌入资源等)
cfg, _ := movparse.ParseClassification(yamlBytes)
// 方式3:代码中直接构建
cfg := &movparse.ClassificationConfig{
Movie: []movparse.SubCategory{
{Name: "动画电影", Conditions: map[string]string{"genre_ids": "16"}},
{Name: "华语电影", Conditions: map[string]string{"original_language": "zh,cn"}},
{Name: "外语电影"},
},
TV: []movparse.SubCategory{
{Name: "动画番剧", Conditions: map[string]string{"genre_ids": "16"}},
{Name: "其他剧集"},
},
}将分类配置和 TMDBMatcher 一起传入 ParserOption,Parse 会自动完成 TMDB 匹配 + 分类:
cfg, _ := movparse.LoadClassification("category.yaml")
matcher, _ := movparse.NewTMDBMatcher(movparse.TMDBMatcherOption{Client: client})
info, _ := movparse.Parse("The.Matrix.1999.1080p.BluRay.mkv", movparse.ParserOption{
TMDBMatcher: matcher,
Classification: cfg,
})
// info.SecondaryCategory = "欧美电影" ← 自动分类cfg, _ := movparse.LoadClassification("category.yaml")
category := cfg.Classify(movparse.CategoryMovie, tmdbData)- 多个条件字段:AND 逻辑(全部满足)
- 单个字段多个值(逗号分隔):OR 逻辑(任一满足)
- 顺序匹配:按 YAML 中定义顺序,首个匹配即返回
- 默认分类:最后一个分类作为兜底
| 字段 | 说明 | 适用 |
|---|---|---|
| original_language | 原始语言 | movie/tv |
| production_countries | 制片国家 | movie |
| origin_country | 来源国家 | tv |
| genre_ids | 类型ID | movie/tv |
| status | 状态 | movie/tv |
Genre IDs: 16=动画, 28=动作, 12=冒险, 35=喜剧, 80=犯罪, 18=剧情, 27=恐怖, 10749=爱情, 878=科幻, 53=惊悚, 10752=战争, 10764=真人秀, 10767=脱口秀
语言代码: zh=中文, en=英语, ja=日语, ko=韩语, fr=法语, de=德语, es=西班牙语
国家代码: CN=中国, US=美国, GB=英国, JP=日本, KR=韩国, HK=中国香港, TW=中国台湾, CA=加拿大, AU=澳大利亚
# 注释行
# ============================================
# 1. 屏蔽词(直接移除)
# ============================================
[CCTV]
4K修复版
简体中文
内嵌字幕
# ============================================
# 2. 替换词(标题标准化)
# ============================================
斗罗大陆2 => 斗罗大陆 第二季
权利的游戏 => 权力的游戏
海贼王 => One Piece
进击的巨人 => Attack on Titan
# ============================================
# 3. 直接ID识别(保留原标题,设置TMDB/豆瓣ID)
# ============================================
我的阿勒泰 => {[tmdbid=253055;type=tv;s=1]}
流浪地球2 => {[tmdbid=906126;type=movie]}
鬼灭之刃 => {[doubanid=34895145;type=tv]}
# ============================================
# 4. 集偏移量(调整集数)
# ============================================
# 格式: 定位词前 <> 定位词后 >> 偏移表达式
第 <> 集 >> EP+0
海贼王 <> - >> EP-1000
# ============================================
# 5. 组合格式(替换 + 集偏移)
# ============================================
名侦探柯南2024 => 名侦探柯南 && 第 <> 话 >> EP+1143
完整的中文词库示例请参考 example/chinese_dictionary.txt,包含:
- 制作组/字幕组映射(喵萌奶茶屋、动漫国等)
- 动漫标题标准化(海贼王、火影忍者等)
- 流媒体平台中文名映射(网飞、爱奇艺等)
- 质量标签标准化(国语配音、日语原声等)
- 特殊版本标记(未删减版、导演剪辑版等)
| 表达式 | 说明 | EP=5时结果 |
|---|---|---|
| EP+N | 加N | EP+10 → 15 |
| EP-N | 减N | EP-3 → 2 |
| N*EP | 乘N | 2*EP → 10 |
| N*EP+M | 先乘后加 | 2*EP+1 → 11 |
| N*EP-M | 先乘后减 | 2*EP-1 → 9 |
dict, _ := movparse.LoadDictionary("dictionary.txt")
info, _ := movparse.Parse("文件名.mkv", movparse.ParserOption{
Dictionary: dict,
})使用 Go text/template 语法:
// 电影模板
movieTmpl := `{{.title}} ({{.year}}) - {{.videoFormat}} {{.videoCodec}}`
// 电视剧模板
tvTmpl := `{{.title}} {{.season_episode}}{{if .episode_title}} {{.episode_title}}{{end}} - {{.videoFormat}}`
result, _ := movparse.Rename(movieTmpl, info)| 变量 | 说明 |
|---|---|
| title | TMDB/豆瓣标题 |
| en_title | 英文标题 |
| original_title | 原语种标题 |
| name | 文件名识别的名称 |
| original_name | 原始文件名 |
| year | 年份 |
| videoFormat | 分辨率 |
| videoCodec | 视频编码 |
| audioCodec | 音频编码 |
| releaseGroup | 制作组 |
| tmdbid | TMDB ID |
| imdbid | IMDB ID |
| doubanid | 豆瓣ID |
| fileExt | 文件扩展名 |
| resourceType | 资源类型 |
| effect | 特效 |
| edition | 版本 |
| webSource | 流媒体平台 |
| part | 段/节 |
| customization | 自定义占位符 |
| hdrType | HDR类型 |
| colorDepth | 色深 |
| frameRate | 帧率 |
| dynamicRange | 动态范围 |
| audioChannels | 音频声道 |
| subtitleInfo | 字幕信息 |
| 3dFormat | 3D格式 |
| containerFormat | 容器格式 |
| quality | 质量标签 |
| 变量 | 说明 |
|---|---|
| season | 季号 |
| episode | 集号 |
| season_episode | 季集 (S01E05) |
| season_year | 季年份 |
| episode_title | 集标题 |
| episode_date | 集播出日期 |
| 函数 | 说明 | 示例 |
|---|---|---|
| upper | 转大写 | {{upper .title}} |
| lower | 转小写 | {{lower .title}} |
| title | 标题格式 | {{title .title}} |
| replace | 字符串替换 | {{replace " " "." .title}} |
| trim | 去除首尾空白 | {{trim .title}} |
| default | 提供默认值 | {{default "Unknown" .year}} |
info, _ := movparse.Parse("Movie.2023.1080p.BluRay.x264-GRP.mkv")
jsonBytes, _ := info.ToJSON()
restored, _ := movparse.FromJSON(jsonBytes)- Go 标准库(文件名解析、JSON、模板引擎)
gopkg.in/yaml.v3(YAML 配置解析)golang.org/x/text(Unicode 文本处理)
本项目在开发过程中学习和参考了 MoviePilot 项目的设计思路和实现方法,特此致谢。
MIT License