Files
Flaro/docs/ABSPANN-IM-BILD.md
T
ScarriffleandClaude Opus 5 9bcdd239d7 Entwurf: den Abspann eines Films im Bild finden
Der Tonabgleich kann bei Filmen grundsätzlich nichts finden — er erkennt
einen Abspann daran, dass er sich über die Folgen einer Staffel
wiederholt, und ein Film hat nichts, womit er sich vergleichen liesse.

Der Entwurf steht auf zwei Messungen statt auf Vermutungen: an einem
erzeugten Film liegt die mittlere Helligkeit in der Handlung bei 125 und
im Abspann bei 18, mit einer scharfen Kante genau am Übergang. Und das
Dekodieren der letzten Minuten kostet 2,89 Sekunden, wenn man jedes
zweite Bild nimmt, aber 0,24, wenn man sich auf Schlüsselbilder
beschränkt.

Dazu steht drin, wo das Verfahren danebenliegt: ein Abspann über
laufendem Bild hat keine dunkle Strecke und bekommt deshalb keinen Knopf.
Das ist die richtige Antwort — ein geratener Knopf schnitte Handlung weg.

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

168 lines
7.2 KiB
Markdown
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.
# 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)