diff --git a/packages/domain/src/release-parser/parse.ts b/packages/domain/src/release-parser/parse.ts index 5b581531..0b01f9e4 100644 --- a/packages/domain/src/release-parser/parse.ts +++ b/packages/domain/src/release-parser/parse.ts @@ -45,6 +45,8 @@ type Draft = ParsedRelease & { _fin?: boolean; _disc?: boolean; _remux?: boolean; + /** 标题里有 BDRip / BRRip(压制) */ + _rip?: boolean; /** `{[k=v;…]}` 显式身份块里的季/集/类型,finalize 时覆盖推断值 */ _explicit?: { season?: number; seasonEnd?: number; episodes?: EpisodeRange; tv?: boolean }; }; @@ -746,6 +748,7 @@ function walkTokens(tokens: string[], d: Draft): void { const cnTitle = cn.join(" ").trim(); if (enTitle) d.titleEn = enTitle; if (cnTitle) d.titleCn = cnTitle; + if (ripWord) d._rip = true; if (d._remux) d.source = "REMUX"; else if (d._disc) d.source = "BluRay-Disc"; else if (blurayWord && discCodec && !encodeCodec && !ripWord && !d.encoder && sources.size === 1) { @@ -1077,9 +1080,40 @@ export function parseRelease(input: string, opts: ParseOptions = {}): ParsedRele } } + // 14. 原盘线索:标题的编码字样不足以判定时,参考副标题 / 简介里的明确说法与无损 PCM 音轨 + refineDisc(d, s, subtitle); + return finalize(d, opts); } +/** 明确说是原盘:原盘(不含「原盘压制」)、BDMV、自购自抓 / 自抓自扫、Blu-ray Disc、DIY(原盘 DIY) */ +const DISC_CUE = + /原[盘盤](?![\s::]*(?:压|壓|rip|转|轉))|BDMV|自[购購]自抓|自抓自[扫掃]|Blu-?ray[\s.]+Disc|(? /^L?PCM\b/i.test(a)); + if (DISC_CUE.test(text)) { + d.source = "BluRay-Disc"; + d.evidence.push("source:disc_hint"); + } else if (pcm) { + d.source = "BluRay-Disc"; + d.evidence.push("source:disc_pcm"); + } +} + function applyCnMarkers(d: Draft, cm: CnMarkers, prefix: string): void { const ev = d.evidence; const note = (k: string) => { @@ -1171,7 +1205,7 @@ function finalize(d: Draft, opts: ParseOptions): ParsedRelease { d.title = d.titleCn ?? d.titleEn; d.confidence = confidenceOf(d); - const { _complete, _fin, _disc, _remux, _explicit, ...out } = d; + const { _complete, _fin, _disc, _remux, _rip, _explicit, ...out } = d; return out; } diff --git a/packages/domain/test/release-parser.test.ts b/packages/domain/test/release-parser.test.ts index 0e2d4691..670989a8 100644 --- a/packages/domain/test/release-parser.test.ts +++ b/packages/domain/test/release-parser.test.ts @@ -627,6 +627,113 @@ describe("MP 差分补迁写法", () => { }); }); +// 原盘补判(SEARCH 准确度):站点搜索「药屋少女的呢喃」的真实结果。标题写成压制字样、但副标题说「自购自抓自扫」的是原盘; +// LPCM / PCM 音轨且没有 x264 / x265 / BDRip / 压制说法的也是原盘。普通压制、WEB-DL、Remux 不受影响。 +const DISC_HINTS: Sample[] = [ + { + id: "DISC-sub-self-rip", + input: "Kusuriya no Hitorigoto 2025 S02 1080p Bluray H.264 LPCM-@U2", + subtitle: "自购自抓自扫 | Team HAYAKU | Animate特典附 | TBR35041D 药屋少女的呢喃 第二季", + expect: { source: "BluRay-Disc", isEncode: false }, + }, + { + id: "DISC-sub-bdmv", + input: "The Apothecary Diaries 2025 S02 1080p Blu-ray H.264-GRP", + subtitle: "药屋少女的呢喃 第二季 BDMV Vol.1", + expect: { source: "BluRay-Disc" }, + }, + { + id: "DISC-sub-yuanpan", + input: "Some Show S01 1080p BluRay H.264 DTS-HD MA 5.1-GRP", + subtitle: "某剧 第一季 原盘 中字", + expect: { source: "BluRay-Disc" }, + }, + { + id: "DISC-pcm", + input: "Some Movie 2020 1080p BluRay LPCM 2.0-GRP", + expect: { source: "BluRay-Disc", isEncode: false }, + }, + // 已按编码字样判成原盘的不变 + { + id: "DISC-avc-lpcm", + input: "Kusuriya no Hitorigoto S02 2025 Blu-ray 1080p AVC LPCM 2Audio-@U2", + subtitle: "Team HAYAKU | Animate全卷特典附 药屋少女的呢喃 第二季", + expect: { source: "BluRay-Disc" }, + }, + { + id: "DISC-bdmv-rip-welcome", + input: "The Apothecary Diaries Vol.3 2025 BDMV 1080p AVC LPCM 2.0-Arri-RAWS@U2", + subtitle: "U2 Exclusive, RIPs welcomed with credits | 制作RIP请注明出处 | 药屋少女的呢喃/药师少女的独语 S2", + expect: { source: "BluRay-Disc" }, + }, + // 反例:压制 + { + id: "ENC-self-encode", + input: "Kusuriya no Hitorigoto 2023 BDRip 1080p AVC FLAC@U2", + subtitle: "药师少女的呢喃/Kusuriya no Hitorigoto/薬屋のひとりごと 1080p 自压(附相关专辑) TV 01-24 Fin+SP", + expect: { source: "BluRay", isEncode: true }, + }, + { + id: "ENC-x265", + input: "The Apothecary Diaries S01 2023 1080p BluRay x265 10bit FLAC 2.0-ADE", + subtitle: "药屋少女的呢喃 / 药师少女的独语 / The Apothecary Diaries / 薬屋のひとりごと 【简日|繁日|简|繁|日字幕】", + expect: { source: "BluRay", isEncode: true }, + }, + { + id: "ENC-x264", + input: "Kusuriya no Hitorigoto S01 Complete 2023 1080p Blu-ray x264 FLAC-jsum@U2", + subtitle: "药屋少女的呢喃 / 药师少女的独语 / 薬屋のひとりごと", + expect: { source: "BluRay", isEncode: true }, + }, + { + id: "ENC-av1", + input: "Kusuriya no Hitorigoto S02 1080p BluRay AV1 OPUS 2.0-7³ACG@OurBits", + subtitle: "药师少女的独语第2季/薬屋のひとりごと 第2期 | 01-24(25-48) 日语+简繁字幕", + expect: { source: "BluRay", isEncode: true }, + }, + { id: "ENC-x264-lpcm", input: "Some Movie 2020 1080p BluRay x264 LPCM 2.0-GRP", expect: { source: "BluRay" } }, + { + id: "ENC-from-disc", + input: "Some Movie 2020 1080p BluRay H.264 FLAC-GRP", + subtitle: "基于原盘压制 简繁字幕", + expect: { source: "BluRay" }, + }, + { + id: "ENC-pcm-encode-note", + input: "Some Movie 2020 1080p BluRay H.264 LPCM-GRP", + subtitle: "自压 内封字幕", + expect: { source: "BluRay" }, + }, + // 反例:其他来源不受副标题影响 + { + id: "WEB-sub-yuanpan", + input: "Some Movie 2020 1080p WEB-DL H.264 AAC-GRP", + subtitle: "原盘 DIY 还没出,先发 WEB", + expect: { source: "WEB-DL" }, + }, + { + id: "REMUX-diy", + input: "The Apothecary Diaries S01 2023 1080p BluRay Remux AVC FLAC 2.0-ADE", + subtitle: "药屋少女的呢喃 【DIY / 双语简繁字幕】", + expect: { source: "REMUX" }, + }, + // 标题里写着 2160P 的非发布名(播放器解码信息):按字面解析,不猜 + { + id: "WEB-2160-literal", + input: + "The Apothecary Diaries 2023 S01E24 2160P TV WEB-DL MPEG-4 AVC1 - Native D3D9 DXVA Decoder VLD AAC LC -Kisssub", + subtitle: + "药屋少女的呢喃 薬屋のひとりごと (2023) 2160P TVS01 [01-24](AI增强1080P转2160P) AVC1 @5160kbps AAC @128kbps", + expect: { source: "WEB-DL", resolution: "2160p" }, + }, +]; + +describe("原盘补判(副标题线索 / PCM 音轨)", () => { + for (const s of DISC_HINTS) { + it(`${s.id} ${s.input}`, () => check(parseRelease(s.input, s.subtitle ? { subtitle: s.subtitle } : {}), s.expect)); + } +}); + describe("parseRelease 样本表", () => { it("样本数量 ≥ 60", () => { expect(TITLES.length).toBeGreaterThanOrEqual(60);