Files
UHD_Media_Tool/docs/runbook/metadata.md
T

6.0 KiB

元数据运行手册(MD-1:语言回退链 + 每集元数据 + 媒体详情)

语言回退链

  • 设置 → 元数据 → TMDB →「语言回退链」,即 settings.metadata.languages,缺省 zh-CN, zh-SG, zh-TW, zh-HK, en-US。
  • 作品标题:按链逐个语言查 TMDB translations(语言 + 地区精确匹配);该语言译名为空时查同地区、文字相符的 alternative_titles(类型为空的优先);原始语言等于链中语言时原名也算。全部落空用请求语言下的 name / 原名。对照 MP __update_tmdbinfo_cn_title(中文名 → CN 别名 → SG 译名)。
  • 中文名 titleZh:只在链里的中文语言中按顺序取(zh-CN 优先),值必须含汉字。链首改成 en-US 时标题变英文,titleZh 不变。
  • 简介 / 标语:按链取 translations 的第一个非空值。
  • 季 / 集:先按链首请求 /tv/{id}/season/{n};已播出的集缺标题(TMDB 占位名"第 N 集""Episode N")或缺简介时,按链逐个语言补拉同一端点,补齐即停;链走完仍没有标题的集保留占位名(语言记为空)。未播出的集不触发补拉。
  • 每个字段的来源值写 metadata_field,language 记实际取到的语言;同字段语言变了,旧语言的 tmdb 行删掉。
  • translations 与 alternative_titles 写 title_alias(来源 tmdb,标语言;别名只在地区与文字相符时标,如 CN + 汉字 → zh-CN)。已有同文本别名(繁简归一化后同键)不重复登记,只给语言为空的 tmdb 行补语言。

刷新

触发 拉哪些季的每集信息 新建集单元
POST /media-entities/{id}/refresh(定时追踪刷新同) 追踪中订阅的季 ∪ 库里已有集单元的季(最近 8 季) 只在追踪中的季
POST /media-entities/{id}/refresh?full=1(详情页「刷新元数据」「更新每集信息」) 全部正片季(最多 60) 是
新建档:按 TMDB 候选建作品(订阅建档、搜索 / TMDB 预览页建档、整理向导)、手动指定未登记的 TMDB 身份 同 full=1(幂等键 refreshMetadata:created:{id}) 是
  • 新建档时标题 / 简介当场按语言链取(富详情失败沿用基础详情),每集信息由随后入队的 full 刷新补齐,不用手动刷新。自动识别(RSS)新建的作品不入队 full,仍按追踪刷新。
  • 刷新是后台任务 refreshMetadata(输入 {mediaEntityId, full?}),结果里 titles 是本次取到的标题 / 语言 / 中文名,episodes[] 是各季写入统计(created 新建单元数、changedUnits 有变化的单元数)。
  • 增量:来源值和语言都没变的字段不写;只投影有变化的单元。不改编号、状态、路径绑定和资产覆盖。
  • 存量回刷(FIX-5):维护任务 metadata.backfill_languages「元数据语言回刷」在部署后首次启动即运行,对所有已确认 TMDB 身份 (active / provisional)的作品逐个跑 full 刷新。用独立的 TMDB 客户端串行请求,网络请求间隔 ≥ 500 ms(每秒最多 2 次), 请求照常走 tmdb.request PG 缓存(对照 MP @cached),中断后重跑时已取过的不再请求。进度每 5 秒写进本次运行记录的摘要, 结束写「N 部作品:刷新 / 跳过 / 失败;TMDB 请求 X 次」和前 5 条失败原因。跑完(有个别失败也算)任务自动停用; 计划页「立即执行」可再跑一次。TMDB 未配置时记为跳过、保持启用,第二天再试。只读对账模式下跳过。 代码:apps/server/src/modules/sources-identity/service/backfill-languages.ts。
  • 单部作品补齐中文名 / 每集信息:对作品跑一次 full=1。手动批量:
# 所有有 TMDB 身份的作品各跑一次(TMDB 请求走缓存;数量多时分批)
curl -s -H "Authorization: Bearer $KEY" "$BASE/api/v1/media-entities?limit=200" | jq -r '.data.items[].id' |
  while read -r id; do curl -s -X POST -H "Authorization: Bearer $KEY" "$BASE/api/v1/media-entities/$id/refresh?full=1"; done

集字段(字段级,可锁)

  • 集单元字段:name(投影到 content_unit.title)、overview、airDate(投影到 air_date)、runtime、stillPath、voteAverage、voteCount;季单元另有 posterPath。最终值在 content_unit.metadata,每个字段带来源 / 语言 / 时间 / 锁。
  • 覆盖并锁定:PUT /content-units/{id}/fields/{field} {value, lock?, reason?};取消:DELETE 同路径。锁定的字段刷新不改。界面:媒体库详情 → 季与集 → 每集行右侧铅笔。

TMDB 请求与缓存

  • 富详情一次请求:/{type}/{id}?language=链首&append_to_response=alternative_titles,credits,external_ids,translations;季详情每语言一次。都走 tmdb.request PG 缓存(TTL / 空结果短 TTL / 条数上限见设置 → 元数据 → TMDB 缓存;对照 MP @cached:成功才缓存、业务失败不缓存)。
  • 想立刻拿到 TMDB 刚改的数据:设置 → 元数据 → TMDB 缓存「清空」,再刷新。
  • 仅 TMDB 作品详情页(/console/media/tmdb/{type}/{id})的季在展开时拉 GET /api/v1/media/tmdb/tv/{id}/season/{n},不落库。

媒体详情页

  • 媒体库详情与仅 TMDB 作品详情共用 apps/web/app/components/media/media-detail.tsx:背景图(图片代理 w1280,scrim 遮罩)、海报、标题 / 原名 / 年份 / 类型 / 评分 / 状态 / 季集数、简介、外部链接,主创(导演 / 主创 + 演员前 10,头像 w185),季折叠 + 每集行(剧照 w300、集号与标题、播出日期、时长、评分、简介折叠、库内状态)。
  • 库内状态:作品有订阅时取覆盖矩阵(可切换版本目标);没有订阅时只看是否已入库。默认展开订阅的季,否则库里有文件的最新季,否则最新季。

排查

现象 看哪里
标题仍是英文原名 作品详情「字段来源与锁」里 标题 的来源与语言;是否被锁;设置里的语言链;对作品跑 full=1
某集没有中文标题 该集在 TMDB 各语言都没有译名时保留占位名 / 英文名,属正常;可在每集行手动改并锁定
季里没有集 默认刷新不为未追踪的季建集单元,点「更新每集信息」(full)