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>
This commit is contained in:
co-authored by
Claude Opus 5
parent
fd79fb4022
commit
9bcdd239d7
@@ -0,0 +1,167 @@
|
|||||||
|
# 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)
|
||||||
Reference in New Issue
Block a user