Files
ripster/docs/pipeline/playlist-analysis.md

8.4 KiB
Raw Blame History

Playlist-Analyse

Einige Blu-rays verwenden Playlist-Obfuskierung als Kopierschutz. Ripster analysiert automatisch alle MakeMKV-Titel und empfiehlt die korrekte Playlist auf Basis eines Segment-Scoring-Algorithmus aus playlistAnalysis.js.


Das Problem: Playlist-Obfuskierung

Moderne Blu-rays können Dutzende bis Hunderte von Titeln/Playlists enthalten. Der eigentliche Film steckt in genau einer davon alle anderen sind:

  • Kurze Dummy-Titel (wenige Sekunden bis Minuten)
  • Titel mit verschachtelten Segmenten (absichtlich versetzte Reihenfolge, sodass der Film falsch gerippt wird)
  • Titel gleicher Länge (mehrere Playlists mit identischer Laufzeit, aber unterschiedlicher Segment-Reihenfolge)

Das Ziel der Obfuskierung: Ein einfacher Ripper wählt den erstbesten langen Titel und bekommt ein zerstückeltes, unbrauchbares Video.


Wann wird die Analyse ausgelöst?

Die Playlist-Analyse wird automatisch gestartet sobald der Benutzer Metadaten bestätigt (nach dem Metadaten-Dialog). Ripster ruft makemkvcon im Info-Modus auf und parst die TINFO-Ausgabe.

TINFO:<titleId>,26,"<segment-list>"

Feld 26 enthält die kommagetrennte Liste der Segment-Nummern in der Abspielreihenfolge des Titels.


Algorithmus im Detail (playlistAnalysis.js)

Schritt 1 Segment-Nummern parsen

TINFO:1,26,"00000,00001,00002,00003"  → [0, 1, 2, 3]       linearer Film
TINFO:2,26,"00100,00050,00100,00051"  → [100, 50, 100, 51]  Fake-Playlist

Schritt 2 Metriken berechnen (computeSegmentMetrics)

Für jedes aufeinanderfolgende Segment-Paar [a, b] wird diff = b a berechnet:

Metrik Bedingung Bedeutung
directSequenceSteps diff == 1 Aufeinanderfolgende Segmente → linearer Film
backwardJumps b < a Rückwärtssprünge → verdächtig
largeJumps |diff| > 20 Große Sprünge → verdächtig
alternatingPairs Große Sprünge mit wechselndem Vorzeichen Hin-und-her-Muster → starker Fake-Indikator

Score-Formel:

score = (directSequenceSteps × 2)  (backwardJumps × 3)  (largeJumps × 2)

Konkrete Beispiele:

Segmentfolge directSeq backward large score Ergebnis
0,1,2,3,4,5 5 0 0 +10 Echter Film
0,1,100,2,101,3 2 0 4 -4 Verdächtig
50,10,60,11,70,12 0 3 3 -15 Fake

Schritt 3 Bewertungslabel vergeben (buildEvaluationLabel)

alternatingRatio = alternatingPairs / largeJumps

if alternatingRatio >= 0.55 AND alternatingPairs >= 3:
  → "Fake-Struktur (alternierendes Sprungmuster)"

else if backwardJumps > 0 OR largeJumps > 0:
  → "Auffällige Segmentreihenfolge"

else:
  → "wahrscheinlich korrekt (lineare Segmentfolge)"

Schritt 4 Duplikat-Gruppen bilden (buildSimilarityGroups)

Alle Titel werden nach ähnlicher Laufzeit gruppiert (±90 Sekunden Toleranz). Gibt es mehrere Kandidaten mit ähnlicher Laufzeit, ist das ein klares Zeichen für Obfuskierung:

8 Titel mit ~148 Minuten Laufzeit → Duplikat-Gruppe
→ obfuscationDetected = true

Schritt 5 Besten Kandidaten empfehlen (scoreCandidates)

Innerhalb der größten Duplikat-Gruppe werden alle Kandidaten sortiert nach:

  1. score (höher = besser)
  2. sequenceCoherence (Anteil linearer Segmentschritte)
  3. Laufzeit (länger = besser)
  4. Dateigröße (größer = besser als Tiebreaker)

Der erste Kandidat der sortierten Liste ist die Empfehlung.

Schritt 6 Entscheidung erzwingen bei mehreren Kandidaten

Sobald nach MIN_LENGTH_MINUTES mehr als eine Playlist übrig bleibt, wird immer eine manuelle Auswahl verlangt:

candidateCount > 1  → manualDecisionRequired = true
candidateCount <= 1 → manualDecisionRequired = false

Wann greift der Benutzer ein?

obfuscationDetected    = duplicateDurationGroups.length > 0
manualDecisionRequired = candidates.length > 1
Ergebnis Nächster Pipeline-Zustand Aktion
Nur ein Kandidat nach Mindestlänge READY_TO_START Automatische Übernahme möglich
Mehrere Kandidaten nach Mindestlänge WAITING_FOR_USER_DECISION Benutzer muss Playlist auswählen

Benutzeroberfläche: Playlist-Auswahl-Dialog

Wenn manualDecisionRequired = true, öffnet sich der Playlist-Dialog nach dem Metadaten-Dialog:

┌───────────────────────────────────────────────────────────────────┐
│ Playlist-Auswahl                                                  │
├──────────┬──────────┬──────────┬────────────────────────────────┤
│ Playlist │ Laufzeit │  Score   │ Bewertung                       │
├──────────┼──────────┼──────────┼────────────────────────────────┤
│ ★ 00800  │ 2:28:05  │   +18    │ wahrscheinlich korrekt          │
│          │          │          │ (lineare Segmentfolge)          │
├──────────┼──────────┼──────────┼────────────────────────────────┤
│   00801  │ 2:28:12  │    4    │ Auffällige Segmentreihenfolge   │
├──────────┼──────────┼──────────┼────────────────────────────────┤
│   00900  │ 2:28:05  │   32    │ Fake-Struktur                   │
│          │          │          │ (alternierendes Sprungmuster)   │
└──────────┴──────────┴──────────┴────────────────────────────────┘
  Hinweis: 847 Playlists insgesamt. 3 relevante Kandidaten (≥ 15 min).
  Empfehlung: 00800 (★)
  • markiert die empfohlene Playlist (vorausgewählt)
  • Nur Titel ≥ makemkv_min_length_minutes erscheinen in der Liste
  • Der Benutzer wählt per Radio-Button und klickt "Bestätigen"
  • Erst nach dieser Bestätigung wechselt die Pipeline zu READY_TO_START

Vollständige Datenstruktur (analyzeContext.playlistAnalysis)

{
  "titles": [
    { "titleId": 1, "playlistId": "00800", "durationSeconds": 8885, "durationLabel": "2:28:05", "chapters": 28 }
  ],
  "candidates": [
    { "titleId": 1, "playlistId": "00800", "durationSeconds": 8885 },
    { "titleId": 2, "playlistId": "00801", "durationSeconds": 8892 }
  ],
  "evaluatedCandidates": [
    {
      "titleId": 1,
      "playlistId": "00800",
      "score": 18,
      "sequenceCoherence": 0.95,
      "evaluationLabel": "wahrscheinlich korrekt (lineare Segmentfolge)",
      "metrics": {
        "directSequenceSteps": 12,
        "backwardJumps": 0,
        "largeJumps": 1,
        "alternatingPairs": 0
      }
    }
  ],
  "duplicateDurationGroups": [
    [
      { "titleId": 1, "playlistId": "00800" },
      { "titleId": 2, "playlistId": "00801" }
    ]
  ],
  "recommendation": {
    "titleId": 1,
    "playlistId": "00800",
    "score": 18,
    "reason": "Höchster Segment-Score in der größten Laufzeit-Gruppe"
  },
  "obfuscationDetected": true,
  "manualDecisionRequired": true
}

Konfiguration

Einstellung Standard Wirkung
makemkv_min_length_minutes 15 Titel kürzer als dieser Wert werden als Kandidaten ignoriert

Tipps bei Fehlempfehlung

!!! tip "Falsche Playlist gewählt?" Wenn das resultierende Video zerstückelt ist:

1. Job in der **History** öffnen
2. **Re-Encode** starten  diesmal eine andere Playlist wählen
3. Alternativ: Korrekte Playlist im [MakeMKV-Forum](https://www.makemkv.com/forum/) recherchieren

!!! info "Keine Segment-Daten verfügbar" Bei DVDs oder älteren Blu-rays liefert MakeMKV manchmal keine Segmentinfos (TINFO-Feld 26 fehlt). In diesem Fall entfällt die Analyse und der erste Titel über der Mindestlänge wird automatisch verwendet.