# Den Abspann im Bild finden — Entwurf Der Tonabgleich findet Vorspann und Abspann, **weil sie sich wiederholen**: dieselbe Musik in Folge 1 und Folge 2. Ein Film hat nichts, womit er sich vergleichen liesse. Sein Abspann kommt genau einmal vor. Was bleibt, ist das Bild. Dieser Entwurf sagt, was daran messbar ist, was es kostet, und wo das Verfahren danebenliegt. Kapitelmarken sind hier bewusst **nicht** der Weg: sie sind exakt, wo sie stehen, aber bei einer gemischten Sammlung stehen sie selten. --- ## 1 · Das Signal, nachgemessen Ein Abspann ist dunkel. Das ist keine Vermutung — nachgestellt mit einem erzeugten Film (90 Sekunden Bild, danach 40 Sekunden weisse Schrift auf schwarzem Grund), abgetastet mit zwei Bildern je Sekunde: | Stelle | mittlere Helligkeit (`YAVG`, 0–255) | |---|---| | 0–89,5 s (Handlung) | **125** | | ab 90,0 s (Abspann) | **18** | Der Sprung liegt auf dem Bild genau, an dem der Abspann anfängt. Kein Übergang, keine Grauzone — und das ist der Punkt: gesucht wird nicht „ein dunkles Bild", sondern **die Kante**. Dieselbe Richtung geht Jellyfins Intro Skipper. Dort heisst es „Add support for using black frames to locate ending credits"; die Suche läuft rückwärts vom Ende und hört auf, wenn der Bereich auf vier Sekunden geschrumpft ist. ## 2 · Was es kostet Das Rechnen ist umsonst, das **Dekodieren** ist der Preis. Gemessen an einer erzeugten Datei, 1080p, h264, 180 Sekunden: | Weg | Zeit | |---|---| | Jedes zweite Bild dekodieren (`fps=2`) | **2,89 s** | | Nur Schlüsselbilder (`-skip_frame nokey`) | **0,24 s** | Hochgerechnet auf die letzten 15 Minuten eines Films: der erste Weg kostet rund anderthalb Minuten je Film, der zweite ein paar Sekunden. *Das ist eine Hochrechnung, keine Messung an echtem Material.* Es geht noch billiger, und so macht es Jellyfin: **nicht am Stück abtasten, sondern zielen.** Binäre Suche mit Sonden von zwei Sekunden zwischen „sicher Handlung" und „sicher Abspann" — zehn Sonden genügen für eine Genauigkeit von vier Sekunden, und zehn mal zwei Sekunden Dekodierung sind nichts. **Vorschlag: beides.** Erst eine grobe Reihe von Schlüsselbildern über die letzten zwanzig Minuten (ein Durchlauf, wenige Sekunden) — die sagt, *ob* es überhaupt eine dunkle Strecke am Ende gibt und ungefähr wo. Dann eine binäre Suche mit kurzen Sonden auf die Kante. Der erste Schritt verhindert, dass die binäre Suche in einem Film ohne dunklen Abspann wild herumspringt; der zweite macht sie genau. ## 3 · Der Zuschnitt Dieselbe Trennung wie beim Tonabgleich: **das Schwierige rein, das Dreckige dünn.** **`Bildabtaster` (Flaro.Media)** — der einzige Teil, der ffmpeg anfasst. ``` helligkeiten(pfad, ab, bis, schritt) -> [(sekunde, helligkeit)] istDunkel(pfad, ab, dauer) -> bool ``` Beides über `signalstats` beziehungsweise `blackdetect`, als eigener Prozess wie `FfprobeRunner`. Fehlt ffmpeg oder scheitert der Lauf: leere Antwort, keine Marke, kein Abbruch. **`Abspannkante` (Flaro.Core)** — reine Rechnung, ohne Datei: ``` Suchen(messpunkte, laufzeit, regeln) -> Kante? ``` Nimmt die Reihe aus Schritt eins und gibt zurück, wo die dunkle Strecke anfängt — oder nichts. Hier liegen alle Schwellen, und hier liegen die Prüfungen. Dieselbe Rolle wie `Tonabgleich`. **`Markenerkennung`** bekommt einen zweiten Zweig: Serien über den Ton, Filme über das Bild. Die Tabelle, der Vertrag, die Knöpfe in App und Web stehen schon — ein Abspann ist ein Abspann, egal woher er kommt. Dafür braucht `Marke` eine Spalte `MovieId` neben `EpisodeId` (heute nur Folgen), und `MovieResponse` die Marken, wie `EpisodeResponse` sie schon hat. ## 4 · Die Schwellen Alles hier ist eine Setzung und gehört an **eine** Stelle, damit man sie gemeinsam verschieben kann: | Grösse | Vorschlag | Warum | |---|---|---| | Helligkeit „dunkel" | `YAVG < 35` | Gemessen: Abspann 18, Handlung 125. Fünfunddreissig liegt weit von beiden. | | Anteil dunkler Bilder in einer Sonde | 85 % | Eine Schrifttafel blitzt hell auf; eine einzelne helle Sonde darf die Strecke nicht brechen. | | Kürzester Abspann | 45 s | Darunter lohnt kein Knopf, und zufällige Dunkelheit ist häufiger. | | Längster Abspann | 12 min | Darüber ist es kein Abspann, sondern ein Fehlfund. | | Suchbereich | letzte 20 min | Bei einem Dreistünder wäre „die letzten 10 %" zu viel, bei einem Kurzfilm zu wenig. | | Genauigkeit | 4 s | Wie bei Jellyfin. Feiner zu suchen kostet Sonden und bringt niemandem etwas. | ## 5 · Wo es danebenliegt — und was dann passiert **Das muss vorher dastehen, nicht hinterher.** - **Abspann über laufendem Bild.** Marvel, Pixar, jede zweite Komödie: die Namen laufen über eine Szene. Keine dunkle Strecke, kein Fund. → Kein Knopf. Das ist die richtige Antwort; ein geratener Knopf schnitte Handlung weg. - **Dunkle Schlussszene.** Ein Film, der im Dunkeln endet, bekommt die Kante zu früh. Dagegen hilft die Mindestlänge und die Obergrenze — und dass die Kante die **früheste** dunkle Stelle einer durchgehenden Strecke bis zum Ende sein muss, nicht irgendeine. - **Schwarzblende mitten im Film.** Kommt vor, hält aber selten bis zum Ende durch. Die Forderung „bis zum Dateiende dunkel" fängt das. - **Szene nach dem Abspann.** Dann ist die Strecke unterbrochen, und der Fund fällt heraus. Lieber keiner als einer, der über die Szene springt. Grobe Erwartung, **ungemessen**: bei Serien greift das Verfahren oft, bei Kinofilmen vielleicht bei der Hälfte. Mehr lässt sich erst sagen, wenn es an echtem Material gelaufen ist — und dafür braucht es einen Weg, die Funde nachzusehen. ## 6 · Nachsehen können Ohne das wird aus dem Verfahren eine Blackbox, die manchmal recht hat. Vorschlag: auf der Detailseite steht bei einem Film mit Marke, **wo** sie liegt, mit einem Knopf „stimmt nicht" — der die Marke löscht und den Titel für weitere Läufe sperrt. Drei Zeilen Oberfläche, und man hat eine Messung statt eines Gefühls. ## 7 · Stufen | | Schritt | Prüfbar an | |---|---|---| | 1 | `Abspannkante` als reine Rechnung samt Prüfungen | erfundenen Messreihen | | 2 | `Bildabtaster` über ffmpeg | der erzeugten Prüfdatei aus Abschnitt 1 | | 3 | `Marke.MovieId`, Wanderung, Marken im Filmvertrag | Serverprüfungen | | 4 | Filme im Lauf nach dem Scan | am Bestand, im Protokoll | | 5 | „stimmt nicht" auf der Detailseite | von Hand | ## Prüfliste - **V.1** Ein Film mit schwarzem Abspann bekommt eine Marke, und sie liegt innerhalb von fünf Sekunden an der richtigen Stelle. - **V.2** Ein Film mit Abspann über laufendem Bild bekommt **keine** Marke. - **V.3** Ein Film, der im Dunkeln endet, ohne Abspann, bekommt keine Marke. - **V.4** Der Lauf über hundert Filme belastet die Platte nicht länger als der Scan selbst. - **V.5** Der Überspringen-Knopf erscheint bei einem Film genauso wie bei einer Folge. - **V.6** Mit erkanntem Abspann gilt ein Film als gesehen, sobald er anfängt — dieselbe Regel wie bei Folgen, sie steht schon. --- ## Quellen - [intro-skipper auf GitHub](https://github.com/intro-skipper/intro-skipper) - [Intro Skipper, README](https://cdn.jsdelivr.net/gh/intro-skipper/intro-skipper@10.11/README.md) - [Forenbeitrag zu Abspann-Erkennung](https://forum.jellyfin.org/t-how-to-skip-ending-credits-with-confusedpolarbear-intro-skipper)