fix(v5): 5.6.1 — Untertitel-Spuren wieder erkannt: Stream-Typ per Code (6203), nicht per lokalisiertem Wort

Commander-Fund 03.09.2026 (Digimon Adventure: Last Evolution Kizuna): im
Auswahl-Dialog fehlten die UNTERTITEL-Chips. Gemessen mit makemkvcon64 -r
info auf diesem PC: MakeMKV schreibt den Stream-Typ in seiner Anzeigesprache
("Untertitel"), der Parser prüfte auf "Subtitles" (Messung vom 26.07. an
einem englischen MakeMKV). "Audio" heißt zufällig gleich, deshalb fiel nur
der Untertitel-Weg aus. Jetzt entscheidet der Typ-Code im vierten Feld
(6201 Video, 6202 Audio, 6203 Untertitel); das Wort bleibt Notnagel.

Test rip-parser-561 mit den gemessenen Zeilen (deu×2/jpn×2 Ton, deu×3
Untertitel, darunter "PGS German (nur erzwungene)"); die volle Messung
liegt unter beweise/messungen/2026-09-03-makemkvcon-info-kizuna.txt.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
Hitonabi
2026-09-03 19:40:22 +02:00
co-authored by Claude Fable 5.1
parent 8f671ff160
commit 687173430c
17 changed files with 484 additions and 10 deletions
+24 -7
View File
@@ -114,9 +114,21 @@ export function parseTitelInfo(ausgabe: string): TitelInfo[] {
// ⚠️ Die Sprache steht in 3/4 — NICHT in 28/29: Die tragen auf JEDEM
// Stream „eng"/„English" (MakeMKVs Anzeigesprache). Wer 28 nimmt, hält
// jede Disc für englisch.
// ⚠️ 5.6.1 (Commander-Fund 03.09.2026, Digimon Last Evolution Kizuna): Auch
// der TEXT von Attribut 1 ist MakeMKVs Anzeigesprache — deutsch eingestellt
// schreibt es `SINFO:1,5,1,6203,"Untertitel"`, nicht „Subtitles". „Audio"
// heißt zufällig in beiden Sprachen gleich, deshalb fehlten NUR die
// Untertitel. Verlässlich ist der CODE im vierten Feld: 6201 Video,
// 6202 Audio, 6203 Untertitel (gemessen an makemkvcon64 auf diesem PC).
export const STREAM_CODE_VIDEO = 6201
export const STREAM_CODE_AUDIO = 6202
export const STREAM_CODE_UNTERTITEL = 6203
export interface StreamInfo {
nr: number
typ: string
/** Typ-Code aus Attribut 1 (6201/6202/6203), 0 wenn keiner dastand. */
typCode: number
lang: string
sprache: string
codec: string
@@ -129,7 +141,7 @@ export interface TitelStreams {
untertitel: StreamInfo[]
}
const SINFO_ZEILE = /^SINFO:(\d+),(\d+),(\d+),\d+,"(.*)"\s*$/
const SINFO_ZEILE = /^SINFO:(\d+),(\d+),(\d+),(\d+),"(.*)"\s*$/
export function parseStreamInfo(ausgabe: string): Map<number, TitelStreams> {
const titel = new Map<number, Map<number, StreamInfo>>()
@@ -139,7 +151,8 @@ export function parseStreamInfo(ausgabe: string): Map<number, TitelStreams> {
const tNr = Number(treffer[1])
const sNr = Number(treffer[2])
const attr = Number(treffer[3])
const wert = treffer[4]
const code = Number(treffer[4])
const wert = treffer[5]
let streams = titel.get(tNr)
if (streams === undefined) {
streams = new Map()
@@ -147,10 +160,13 @@ export function parseStreamInfo(ausgabe: string): Map<number, TitelStreams> {
}
let eintrag = streams.get(sNr)
if (eintrag === undefined) {
eintrag = { nr: sNr, typ: '', lang: '', sprache: '', codec: '', kanaele: '', beschreibung: '' }
eintrag = { nr: sNr, typ: '', typCode: 0, lang: '', sprache: '', codec: '', kanaele: '', beschreibung: '' }
streams.set(sNr, eintrag)
}
if (attr === 1) eintrag.typ = wert
if (attr === 1) {
eintrag.typ = wert
eintrag.typCode = code
}
else if (attr === 3) eintrag.lang = wert
else if (attr === 4) eintrag.sprache = wert
else if (attr === 6) eintrag.codec = wert
@@ -164,9 +180,10 @@ export function parseStreamInfo(ausgabe: string): Map<number, TitelStreams> {
const untertitel: StreamInfo[] = []
for (const sNr of [...streams.keys()].sort((a, b) => a - b)) {
const s = streams.get(sNr)!
// MakeMKV schreibt „Subtitles" (englisch, Plural) — gemessen.
if (s.typ === 'Audio') audio.push(s)
else if (s.typ.startsWith('Subtitle')) untertitel.push(s)
// Der Code entscheidet (5.6.1); das Wort nur als Notnagel für Ausgaben
// ohne Code („Audio", „Subtitles", „Untertitel").
if (s.typCode === STREAM_CODE_AUDIO || (s.typCode === 0 && s.typ === 'Audio')) audio.push(s)
else if (s.typCode === STREAM_CODE_UNTERTITEL || (s.typCode === 0 && (s.typ.startsWith('Subtitle') || s.typ.startsWith('Untertitel')))) untertitel.push(s)
}
ergebnis.set(tNr, { audio, untertitel })
}