Files
rippy/rippy-windows/src/kern/werkzeuge/spurauswahl.ts
T
HitonabiandClaude Opus 5 e7e33e9021 feat(v5): jede Spur einzeln anhaken — Codec und Kanäle je Tonspur, Untertitel genauso
WAS: Der Auswahl-Dialog zeigt je Titel jede Ton- und Untertitelspur, die
der Info-Lauf gemessen hat („German · DTS-HD MA · Surround 5.1", „German ·
DD · Stereo (Kommentar)", „German · PGS (nur erzwungene)"), vorbelegt wie
bisher (je Wunschsprache die erste Tonspur, alle Untertitel der Wunsch-
sprachen) — angehakt wird einzeln. Die Untertitel-Vorwahl je Extra ist
jetzt eine Spur. Der Parser liest dazu SINFO-Attribute 2 (Anordnung),
22 (Flags) und markiert abgeleitete Spuren (Bit 0x800, an der Kizuna-
Disc gemessen): DTS-Kerne werden nicht angeboten, „nur erzwungene"-
Untertitel schon. Die Ablage scannt die Roh-Datei und findet die
gewählten MakeMKV-Spuren gestuft wieder (Sprache + Codec-Familie +
Kanäle → … → Sprache), HandBrake bekommt `--audio 1,3 --subtitle 2,1
--subtitle-default=1`; Fehlendes wird gemeldet, scheitert der Scan,
gelten die Sprachen der gewählten Spuren als Liste. MakeMKVs Auswahl-
regel lässt Stereo-Doppel jetzt stehen (nur -sel:havecore); Rippys alte
Regel wird in der Registry ersetzt, eine fremde bleibt.
Dazu F31 (Durchsicht): `--aencoder copy` ohne `--audio-copy-mask`
verengt HandBrakeCLI 1.11.2 auf „copy:aac" — AC3/DTS/TrueHD wurden seit
5.0 in AAC umgerechnet. Beide Wege setzen die Maske jetzt ausdrücklich
(gemessen 12.09.2026: AC3 bleibt AC3, Passthru-Zeile nennt alle Codecs).
WARUM: Commander-Entscheid 12.09.2026 („Jede Spur einzeln anhaken") —
bisher ließ sich je Sprache nur „alles oder nichts" wählen, und der
Kommentar-Ton fehlte in der Roh-Datei (havemulti). Gemessen am
mitgelieferten HandBrakeCLI mit ffmpeg-gebauter Quelle
(test/messung.spuren.test.ts, RIPPY_MESSUNG=1): --audio 1,3 → jpn und
deu-Kommentar, --subtitle 2,1 --subtitle-default=1 → eng (default) vor
deu, --subtitle none → keine Spur.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-12 22:11:27 +02:00

101 lines
4.9 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// MakeMKVs Spur-Auswahlregel (5.4.0) — damit ALLE Sprachen in der
// Roh-Datei landen, die der Auswahl-Dialog anbietet.
//
// Der Befund: Der Info-Lauf zeigt jede Tonspur der Disc — aber ob sie in
// die MKV kommt, entscheidet MakeMKVs „default selection rule". Die Doku
// (forum.makemkv.com, Thema 4386, am 01.09.2026 nachgelesen — Regel D)
// nennt als Regel des Standard-Profils
//
// -sel:all,+sel:(favlang|nolang),-sel:(havemulti|havecore),=100:all,-10:favlang
//
// mit: favlang = „matches favorite languages, always matches if no
// favorite language is set" · havemulti = „track is mono/stereo and there
// is a multi-channel track in same language" · havecore = „this track is
// hd track with core audio" · +sel/-sel = wählen/abwählen · =N = Gewicht.
//
// Solange KEINE Vorzugssprache gesetzt ist, nimmt MakeMKV also alles
// (bis auf die Stereo-Doppel und die DTS-Kerne). Sobald jemand in MakeMKVs
// Einstellungen „Deutsch" wählt, fielen japanischer und englischer Ton
// STILL weg — und der Dialog böte Sprachen an, die nicht in der Datei
// sind. Rippy setzt deshalb seine eigene Regel, die sprachunabhängig
// alles behält, und zwar NUR, wenn noch keine gesetzt ist (wer eine
// eigene hat, behält sie — wie bei app_UpdateEnable in schluessel.ts).
// Abgelegt wird wie der Schlüssel in HKCU\Software\MakeMKV (Windows liest
// dort, die settings.conf ist der Linux-Weg).
//
// 5.7.0: Seit der Dialog jede Spur einzeln anbietet, dürfen auch die
// Stereo-Doppel bleiben (havemulti — „Deutsch · DD · 2.0 (Kommentar)"
// neben „Deutsch · DTS-HD MA · 5.1"): Nur die abgeleiteten DTS-Kerne
// (havecore) fallen weg, die zeigt der Dialog gar nicht erst. Stand
// Rippys ALTE Regel in der Registry, wird sie ersetzt; eine fremde bleibt.
import { spawnSync } from 'node:child_process'
export const REGISTRY_PFAD = 'HKCU\\Software\\MakeMKV'
export const REGEL_NAME = 'app_DefaultSelectionString'
/** Alles behalten, nur die Kerne weg — sprachunabhängig (5.7.0). */
export const RIPPY_REGEL = '-sel:all,+sel:all,-sel:havecore,=100:all'
/** Rippys frühere Regeln (5.4.05.6.1) — werden beim Start ersetzt. */
export const RIPPY_REGELN_ALT: readonly string[] = ['-sel:all,+sel:all,-sel:(havemulti|havecore),=100:all']
export interface SpurauswahlStand {
/** 'gesetzt' (von Rippy, jetzt) | 'eigen' (der Nutzer hat eine eigene) |
* 'rippy' (Rippys Regel steht schon) | 'fehler' */
stand: 'gesetzt' | 'eigen' | 'rippy' | 'fehler'
regel: string
text: string
}
/** Was mit einer vorgefundenen Regel geschieht (pur, testbar):
* 'rippy' = steht schon · 'ersetzen' = Rippys alte Regel · 'eigen' =
* fremd, bleibt · 'setzen' = keine da. */
export function regelUrteil(bisher: string | null): 'rippy' | 'ersetzen' | 'eigen' | 'setzen' {
if (bisher === null || bisher.length === 0) return 'setzen'
if (bisher === RIPPY_REGEL) return 'rippy'
if (RIPPY_REGELN_ALT.includes(bisher)) return 'ersetzen'
return 'eigen'
}
function reg(args: string[]): { ok: boolean; ausgabe: string } {
const ergebnis = spawnSync('reg', args, { windowsHide: true, timeout: 15_000, encoding: 'utf8' })
return { ok: ergebnis.status === 0, ausgabe: (ergebnis.stdout ?? '') + (ergebnis.stderr ?? '') }
}
/** Den Wert aus `reg query`-Ausgabe lesen (pur, testbar):
* „ app_DefaultSelectionString REG_SZ -sel:all,…" */
export function regelAusQuery(ausgabe: string): string | null {
const treffer = new RegExp(`${REGEL_NAME}\\s+REG_SZ\\s+(.*)$`, 'm').exec(ausgabe)
return treffer === null ? null : treffer[1].trim()
}
/** Sicherstellen, dass eine Regel steht, die alle Sprachen behält. */
export function spurauswahlSicherstellen(): SpurauswahlStand {
if (process.platform !== 'win32') {
return { stand: 'fehler', regel: '', text: 'Nur unter Windows (Registry).' }
}
const vorhanden = reg(['query', REGISTRY_PFAD, '/v', REGEL_NAME])
const bisher = vorhanden.ok ? regelAusQuery(vorhanden.ausgabe) : null
const urteil = regelUrteil(bisher)
if (urteil === 'rippy') {
return { stand: 'rippy', regel: bisher ?? '', text: 'MakeMKV behält alle Spuren (Rippys Auswahlregel steht).' }
}
if (urteil === 'eigen') {
return {
stand: 'eigen',
regel: bisher ?? '',
text: `MakeMKV hat eine eigene Auswahlregel („${bisher}") — Rippy lässt sie stehen. Fehlen Spuren in der Roh-Datei, liegt es daran.`,
}
}
const gesetzt = reg(['add', REGISTRY_PFAD, '/v', REGEL_NAME, '/t', 'REG_SZ', '/d', RIPPY_REGEL, '/f'])
if (!gesetzt.ok) {
return { stand: 'fehler', regel: '', text: `Auswahlregel nicht setzbar: ${gesetzt.ausgabe.trim().slice(0, 160)}` }
}
return {
stand: 'gesetzt',
regel: RIPPY_REGEL,
text:
urteil === 'ersetzen'
? 'MakeMKV-Auswahlregel erneuert: jede Spur kommt in die Roh-Datei, auch Stereo-Fassungen und Kommentare (nur DTS-Kerne nicht).'
: 'MakeMKV-Auswahlregel gesetzt: jede Spur kommt in die Roh-Datei (nur DTS-Kerne nicht).',
}
}