媒體資訊與探測 - MiCat-S/Mi302 GitHub Wiki

繁體中文 | 简体中文 | English

這一頁說明 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(見下方),會在背景探測。探測和掃描、刮削同時進行,互不等待。

探測一項時做了什麼

  1. 讀 strm 的內容(先套用 redirect.path_rules)。
  2. 是 115 的 strm 時,向 115 取一次直鏈,用一般瀏覽器的 User-Agent(115 的直鏈通常綁定取得時的 UA)。
  3. 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。
  4. strm 裡是其他網址(例如 alist)時也這樣讀,只是不向 115 取直鏈、不帶 cookie;伺服器不支援分段讀取(Range)時,才讓 ffprobe 直接讀網址。是本機路徑、或本身就是本機影片時,讀本機檔案。這兩種都不算進每小時上限。
  5. 結果寫成 X-mediainfo.json 放在 strm 旁邊,也存進資料庫。影片裡有章節就用影片的;沒有章節時和 Emby 一樣每 5 分鐘產生一個。媒體資料夾唯讀、寫不進去時,只存在資料庫。
  6. 影片原本沒有片長時,補上探測到的片長。

每一項最多等 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 = 不限。到了上限,就等最早的那次滿一小時再繼續;在等的時候調高上限(或改取直鏈間隔)並按「儲存設定」,會馬上照新設定繼續。一次提取上萬支影片時會分幾天慢慢補齊,也可以用「這次最多 N 支」分批做。
  • 熔斷: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。