媒体信息与探测 - MiCat-S/Mi302 GitHub Wiki
本页说明 Mi302 如何取得视频的媒体信息(分辨率、HDR、音轨、字幕轨、章节):读取视频旁边现成的 X-mediainfo.json,或自己用 ffprobe 探测,以及探测时如何避免触发 115 的限流。
为什么需要媒体信息
播放器要知道视频的分辨率、HDR/杜比视界、音轨、内封字幕和章节,才能在列表上标出 4K、HDR,播放前让人选择音轨和字幕。strm 只是一行网址,这些信息不在里面,要另外从视频的文件头读出来。
没有媒体信息时,Mi302 返回给播放器的媒体流列表是空的。视频照样能播,只是看不到这些标示和选项。
有媒体信息的视频,Mi302 返回给播放器的内容多了这些:
- 媒体流:视频、音轨、字幕轨(含语言、标题、是否默认、是否强制)和附件。
- 容器格式、分辨率、有没有字幕、默认音轨。
- 码率、文件大小、片长:原本没有时才补上。nfo 没写片长时,也用它的片长。
- 章节。学到的片头片尾标记会加在章节后面,见片头片尾跳过。
播放方式不变:仍然 302 到 115 直链,不转码。
X-mediainfo.json
视频是 X.strm(或本地视频 X.mkv)时,Mi302 读取同一个文件夹里的 X-mediainfo.json。格式和 Emby 神医助手(StrmAssistant)的“媒体信息持久化”一样:
[{"MediaSourceInfo": {"Container": "mkv", "MediaStreams": [...]}, "Chapters": [...]}]
- 用过 Emby+神医,或用 emby-mediainfo 生成过的文件,放在 strm 旁边就能用。
- 扫描时读进来,另外在 Mi302 的数据库里存一份。json 的修改时间变了,下次扫描会重新读取。
- 反过来,Mi302 探测写出的 json,Emby+神医那边也能读。
- 神医设置了“媒体信息根目录”(json 集中放在另一个文件夹)时,Mi302 找不到,要把文件移到 strm 旁边。
- 同步时 115 上的视频改名、移动、删除,本地的
X-mediainfo.json跟着 strm 一起改名、移动、删除。 - 超过 8 MB 或格式不对的 json 会跳过,日志里有警告。
用 ffprobe 探测
没有现成 json 的视频,Mi302 可以自己用 ffprobe 探测。设置在“整理”页“媒体资讯”卡片的“设定”里。有两种方式,可以同时开启。
打开时自动探测
“打开影片时自动探测”默认开启。播放器打开某部电影或某一集(查看详情或准备播放)时,如果这一项还没有媒体信息,就排进后台队列。请求照常立即响应,不等探测;下次打开就有了。
- 只排被打开的 strm 项目。浏览列表不会触发,一次打开整季也不会把整季排进去。
- 队列最多 500 项,满了的下次打开再排。
- 探测失败或被跳过的项目,一小时内不再排。
- 遇到 115 限流、还没登录 115、找不到 ffprobe 这类后面也不会成功的错误,整个队列清空,这些项目一小时后打开再排。
不想一次提取一大批的话,开这个就够了:常看的片会慢慢有媒体信息。
挑选要提取的影片
要一次补一批时,用卡片里的“挑选要提取的影片”。先开启卡片下方“设定”里的“批次探测”(默认关闭,切换后马上储存),“开始提取”和每一部的“提取”才能点。
筛选条件,没填的不限制:
| 条件 | 说明 |
|---|---|
| 搜寻片名 | 原名、简繁体、拼音全拼、首字母都认,例如 qyn、慶餘年 都能找到“庆余年” |
| 全部媒体库 | 只看某一个媒体库 |
| 电影和剧集 | 改成“只看电影”或“只看剧集” |
| 年份从、到 | 只看这几年的,剧集看剧的年份。只填一边就是“几年以后”或“几年以前”;设了年份时,没有年份的片不列出 |
“先做哪些”决定列表和提取的顺序,同一部剧里按季、集顺序:
- 最近加入的先做(默认):最近才进媒体库的先做。
- 年份新的先做、年份旧的先做:按电影或剧的年份。
- 评分高的先做:按 nfo 里的评分。
- 照片名:中文按拼音排序。
“这次最多 N 支”限制一批做几个,默认 100,0 = 全部符合的。“先做哪些”和这个数字会保存在浏览器里。
下面的列表列出还缺媒体信息的电影和剧,一页 20 部。剧标“缺 X / Y 集”,电影标“还没有”。列表上方有一行写着:符合条件的还缺几部电影、几集,点“开始提取”会做哪几个。
- “开始提取”:按筛选和“先做哪些”,做前 N 个。
- 每一部右边的“提取”:只做那一部(剧就是它缺的集),同样最多 N 个。
同一时间只运行一批,正在提取时“开始提取”和“提取”点不了。提取中:
- 改“这次最多 N 支”会直接应用到正在运行的这一批:调高就按原来的筛选和顺序补上,调低就把还在排队的去掉。只有手动开始的批次可以改,同步后自动开始的不行。
- 进度条旁边有“停止提取”:排队的不做了;手上已经在运行 ffprobe 的做完才停,还在等待获取直链的直接放弃。结果标“已停止”,没做的不算失败,之后再点“开始提取”会接着做还缺的。
做完后列表和数字自动刷新。结果会标出这一批是怎么挑的,例如“手动・年份新的先做・最多 100 支”或“手动・「庆余年」・最多 100 支”。
同步后自动探测
“同步产生新的 strm 后自动探测”默认勾选,要开启“批次探测”才有作用。勾选时,每次同步新生成的 strm,以及 115 上换了文件的 strm(见下文),会在后台探测。探测和扫描、刮削同时进行,互不等待。
探测一项时做了什么
- 读取 strm 的内容(先套用
redirect.path_rules)。 - 是 115 的 strm 时,向 115 取一次直链,用普通浏览器的 User-Agent(115 的直链通常绑定获取时的 UA)。
- Mi302 自己用一条连接、带着同一个 UA(115 的域名再带 cookie)分段读取需要的部分,不让 ffprobe 直接读网址:ffprobe 会开好几条连接来回跳着读,115 的 CDN 经常拒绝,出现“moov atom not found”“Invalid data found”。
- 文件头 6 MB。
- mp4:按顶层 box 找到 moov(视频索引)只读那一段;moov 在文件头里就不用。
- 其他格式:文件尾 2 MB(mkv 的 Cues、ts 的最后时间戳)。 读到的内容写进和原文件一样大的稀疏临时文件(没读的地方不占空间),ffprobe 读这个本地文件,读完就删除。一个视频通常读 6~9 MB。
- strm 里是其他网址(例如 alist)时也这样读,只是不向 115 取直链、不带 cookie;服务器不支持分段读取(Range)时,才让 ffprobe 直接读网址。是本地路径、或本身就是本地视频时,读本地文件。这两种都不计入每小时上限。
- 结果写成
X-mediainfo.json放在 strm 旁边,也存进数据库。视频里有章节就用视频的;没有章节时和 Emby 一样每 5 分钟生成一个。媒体文件夹只读、写不进去时,只存在数据库里。 - 视频原本没有片长时,补上探测到的片长。
每一项最多等 mediainfo.timeout 秒(默认 300),超过算失败。
失败时的信息
“媒體資訊”卡片会列出失败的视频和原因:
| 信息 | 意思 | 怎么办 |
|---|---|---|
| 115 回的不是影片(text/html):… | 115 返回了错误网页或 JSON,后面接着它写的原因 | 按 115 写的原因处理;常见的是请求太频繁,过一阵子再提取 |
| 115 回 HTTP 403 | 直链过期或被拒绝 | 再提取一次(会重新取直链) |
| 115 回了空的內容 | 115 什么都没返回 | 再提取一次 |
| mp4 檔裡找不到 moov | mp4 缺了视频索引,多半是 115 上的文件没有传完整 | 播放器多半也放不了,重新下载或换一个文件 |
| ffprobe 失敗:…(檔頭 …) | 读到的像视频,ffprobe 却解不开,可能是文件坏了或格式不支持(例如 ISO) | 檔頭那串是文件开头几个字节,反馈问题时附上 |
| 限流 | 115 限流,触发了熔断 | 见下方“115 的限制” |
设置
| 页面上的名称 | 配置键 | 默认值 | 范围 |
|---|---|---|---|
| 打开影片时自动探测 | mediainfo.on_demand |
开 | |
| 批次探测 | mediainfo.enabled |
关 | |
| 同步产生新的 strm 后自动探测 | mediainfo.after_sync |
开 | 要开启批次探测 |
| 同时探测几项 | mediainfo.concurrency |
2 | 1–3 |
| 取直链间隔(秒) | mediainfo.interval |
1.0 | 0.5–60 |
| 每小时最多几次 | mediainfo.hourly_limit |
300 | 0–100000,0 = 不限 |
| (只在配置文件) | mediainfo.timeout |
300 | 10–3600 秒 |
| (只在配置文件) | mediainfo.ffprobe |
ffprobe |
ffprobe 的路径 |
页面上的开关切换后马上储存;数字栏位改完点卡片下方“设定”里的“储存设定”。都立即生效,不必重启。配置文件的写法见配置文件参考。
115 的限制
每一项 115 的 strm 都要向 115 取一次直链。115 对此很敏感,Mi302 这样保护账号:
- 同时几条连接:115 同时最多 3 条连接,所以“同时探测几项”最多 3,默认 2。
- 取直链间隔:两次取直链之间至少隔 0.5 秒,默认 1 秒。所有探测共用这个间隔。
- 每小时上限:默认每小时最多 300 次,0 = 不限。到了上限,就等最早的那次满一小时再继续;等待期间调高上限(或改获取直链间隔)并点“储存设定”,会马上按新设置继续。一次提取上万个视频时,会分几天慢慢补齐。
- 熔断:115 返回限流或登录失效时,探测和同步都先停下,这一批剩下的不做。限流造成的熔断 45 分钟后自动解除;登录失效要到“115 网盘”页重新“扫码登入”。中断的这一批不会自己重新运行,熔断解除后再点一次“开始提取”;熔断期间点了也会马上停下。冷却期满后的前 30 分钟,间隔变为 4 倍、每小时上限变为四分之一;再往后 30 分钟是 2 倍和一半;之后恢复正常。
打开即探测和批次探测共用间隔、每小时上限和熔断。播放不受这些限制,也不受熔断影响。熔断的原因会显示在“媒体资讯”卡片和“115 网盘”页。熔断的细节见115 网盘与同步。
115 上的文件换了
同步时如果 115 上同一个位置的文件被换掉(例如换成另一个版本),它的 pickcode 会变。pickcode 是 115 给每个文件的提取码,strm 靠它取直链。这时旧的媒体信息属于另一个文件,Mi302 会删掉 X-mediainfo.json 和数据库里的记录:
- 开启了批次探测和“同步产生新的 strm 后自动探测”时,同步完就重新探测。
- 否则等下次打开这一项时自动探测,或在“挑选要提取的影片”里提取它。
只改服务器网址(p115.strm.base_url)或 strm 网址格式而重写的 strm,pickcode 没变,媒体信息照用。
卡片上能看到什么
“媒体资讯”卡片显示:
- “N / M 支影片有媒体资讯”。
- 找不到 ffprobe 时的警告;115 熔断时的原因。
- 打开即探测的队列:排队中、完成、失败各几项。
- 这一小时向 115 取了几次直链、上限多少;熔断刚恢复时放慢几倍;到了上限时,几点后继续。
- 上次批次探测(同步后自动或手动;手动的会标出怎么挑的)的结果:要探测、成功、失败、跳过,以及前几个失败原因。
失败和跳过的原因:
- 跳过:strm 是空的;strm 里不是网址,也不是存在的文件。
- 整批停下:找不到 ffprobe、还没登录 115、115 熔断。停下后还没做的算失败。
- 单项失败:ffprobe 读不了(例如 403、超时、解码错误)、超过每一项的等待时间、没有读到任何流。错误信息里的网址会抹掉,再写进卡片和日志。
失败的视频仍然没有媒体信息,下次提取时会重试。
安装 ffmpeg
ffprobe 是 ffmpeg 的一部分。
- 一键安装脚本在安装和
mi302 update时,会用系统的包管理器(apt、dnf、yum、apk、pacman、zypper、brew)尝试安装 ffmpeg。没装成只会警告,其他功能不受影响。见安装。 - 自己安装:
sudo apt install ffmpeg # Debian/Ubuntu
brew install ffmpeg # macOS
- 装好后不必重启,Mi302 一分钟内会找到 ffprobe。
- ffprobe 不在服务的 PATH 里时,在配置文件里把
mediainfo.ffprobe填成完整路径。
没有 ffprobe 时,Mi302 仍会读取现成的 X-mediainfo.json。卡片会显示警告,“开始提取”和“提取”点不了,打开即探测和同步后探测都不做。
致谢
ffprobe 结果对应到 Emby 字段的规则、限速和熔断的做法,改写自 emby-mediainfo(MIT 许可)。原项目的许可声明保留在 embyserver/mediainfo.py。文件格式沿用 StrmAssistant。