// 5.6.1 — Commander-Fund vom 03.09.2026: Bei der Blu-ray „Digimon Adventure: // Last Evolution Kizuna" fehlten im Auswahl-Dialog die Untertitel-Chips, // obwohl die Disc drei deutsche PGS-Spuren hat. Gemessen mit // makemkvcon64 -r info auf diesem PC: MakeMKV (deutsch eingestellt) schreibt // den Stream-Typ als „Untertitel", der Parser prüfte auf „Subtitles". Der // Typ-Code im vierten Feld (6203) ist sprachunabhängig. import { describe, expect, it } from 'vitest' import { STREAM_CODE_AUDIO, STREAM_CODE_UNTERTITEL, parseStreamInfo, sprachenFuerTitel } from '../src/kern/rip/parser' // Wörtlich aus der Messung (gekürzt auf Typ, Sprache, Name, Beschreibung). const KIZUNA = [ 'SINFO:1,0,1,6201,"Video"', 'SINFO:1,0,6,0,"Mpeg4"', 'SINFO:1,1,1,6202,"Audio"', 'SINFO:1,1,3,0,"deu"', 'SINFO:1,1,4,0,"German"', 'SINFO:1,1,30,0,"DTS-HD MA Surround 5.1 German"', 'SINFO:1,2,1,6202,"Audio"', 'SINFO:1,2,3,0,"deu"', 'SINFO:1,2,4,0,"German"', 'SINFO:1,3,1,6202,"Audio"', 'SINFO:1,3,3,0,"jpn"', 'SINFO:1,3,4,0,"Japanese"', 'SINFO:1,4,1,6202,"Audio"', 'SINFO:1,4,3,0,"jpn"', 'SINFO:1,4,4,0,"Japanese"', 'SINFO:1,5,1,6203,"Untertitel"', 'SINFO:1,5,3,0,"deu"', 'SINFO:1,5,4,0,"German"', 'SINFO:1,5,30,0,"PGS German"', 'SINFO:1,6,1,6203,"Untertitel"', 'SINFO:1,6,3,0,"deu"', 'SINFO:1,6,4,0,"German"', 'SINFO:1,6,22,0,"6144"', 'SINFO:1,6,30,0,"PGS German (nur erzwungene)"', 'SINFO:1,7,1,6203,"Untertitel"', 'SINFO:1,7,3,0,"deu"', 'SINFO:1,7,4,0,"German"', ].join('\n') describe('parseStreamInfo — Stream-Typ per Code, nicht per Wort (5.6.1)', () => { it('deutsches MakeMKV schreibt „Untertitel": die drei PGS-Spuren werden erkannt', () => { const streams = parseStreamInfo(KIZUNA).get(1)! expect(streams.audio.map((s) => s.lang)).toEqual(['deu', 'deu', 'jpn', 'jpn']) expect(streams.untertitel.map((s) => s.lang)).toEqual(['deu', 'deu', 'deu']) expect(streams.untertitel[0].typCode).toBe(STREAM_CODE_UNTERTITEL) expect(streams.audio[0].typCode).toBe(STREAM_CODE_AUDIO) expect(streams.untertitel[1].beschreibung).toBe('PGS German (nur erzwungene)') }) it('für den Dialog: deu×2 Ton, jpn×2 Ton, deu×3 Untertitel', () => { const sprachen = sprachenFuerTitel(parseStreamInfo(KIZUNA).get(1)) expect(sprachen.audio).toEqual([ { lang: 'deu', sprache: 'German', spuren: 2 }, { lang: 'jpn', sprache: 'Japanese', spuren: 2 }, ]) expect(sprachen.untertitel).toEqual([{ lang: 'deu', sprache: 'German', spuren: 3 }]) }) it('jede Anzeigesprache: der Code zählt — französisch, englisch, und ohne Code das Wort als Notnagel', () => { expect(parseStreamInfo('SINFO:0,1,1,6203,"Sous-titres"\nSINFO:0,1,3,0,"fra"').get(0)!.untertitel).toHaveLength(1) expect(parseStreamInfo('SINFO:0,1,1,6203,"Subtitles"\nSINFO:0,1,3,0,"eng"').get(0)!.untertitel).toHaveLength(1) expect(parseStreamInfo('SINFO:0,1,1,0,"Subtitles"\nSINFO:0,1,3,0,"eng"').get(0)!.untertitel).toHaveLength(1) expect(parseStreamInfo('SINFO:0,1,1,0,"Untertitel"\nSINFO:0,1,3,0,"deu"').get(0)!.untertitel).toHaveLength(1) expect(parseStreamInfo('SINFO:0,1,1,0,"Audio"\nSINFO:0,1,3,0,"deu"').get(0)!.audio).toHaveLength(1) }) it('Video bleibt draußen', () => { const streams = parseStreamInfo('SINFO:0,0,1,6201,"Video"\nSINFO:0,0,3,0,"und"').get(0)! expect(streams.audio).toHaveLength(0) expect(streams.untertitel).toHaveLength(0) }) })