Slim README, move algorithm prose to docs, add stills + per-fps TC to cutter report
README: 550 -> 308 lines. The dense algorithm prose was moved verbatim to docs/ALGORITHM.md and replaced in the README with a compact "Wenn ein Match falsch wirkt" troubleshooting table and a link. The cutter-facing intro points at the new in-report stills instead of the old HTML report. Cutter report: - Per-side frame rates: trailer timecodes use the trailer file's fps (typically 25), source timecodes use the source file's fps. ffprobe is used to detect each side; falls back to edl_frame_rate if unavailable. - Side-by-side trailer/source preview stills extracted via ffmpeg, taken ~30% into the beat / match window. Stored under output/cutter_stills/ (gitignored). Re-rendered only when the underlying video is newer than the cached jpg. - Compact table at the top, detailed per-beat sections below with the stills inline so the cutter can sight-check phase agreement directly. - New --no-stills flag for fast text-only regeneration. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -30,9 +30,9 @@ Was du bekommst sind zwei Dateien, mit denen du arbeitest:
|
||||
1. Öffne `CUTTER_REPORT.md` und arbeite die Tabelle von oben nach unten ab.
|
||||
2. Importiere die FCPXML/EDL ins NLE, lade Trailer und Spielfilm dazu.
|
||||
3. Bei `OK`-Beats nur stichprobenartig sichten.
|
||||
4. Bei `?`-Beats den Vorschauclip aus dem Report-HTML (siehe unten) prüfen
|
||||
und im NLE den Source-In um wenige Frames vor/zurück verschieben, bis die
|
||||
Bewegungsphase exakt zum Trailer passt.
|
||||
4. Bei `?`-Beats die beiden Vorschau-Stills im `CUTTER_REPORT.md` direkt
|
||||
vergleichen (Trailer-Frame neben Source-Frame). Wenn die Bewegungsphase
|
||||
nicht passt, im NLE den Source-In um wenige Frames vor/zurück verschieben.
|
||||
5. Bei `MAN.`-Beats selbst die passende Stelle im Spielfilm suchen — die
|
||||
Beschreibung im Report sagt dir was du suchst.
|
||||
|
||||
@@ -139,275 +139,33 @@ python cli.py rematch --beat 5 --threshold 0.50 # Schwelle anpassen (Globaler S
|
||||
python cli.py rematch --beat 5 --refine # Cached Match per lokalem Bildinhalt-Offset nachschärfen
|
||||
```
|
||||
|
||||
Der HTML-Report regeneriert seine Preview-Clips bei jedem Lauf mit genauer
|
||||
FFmpeg-Nachsuche und synchronisiert die beiden Video-Player pro Beat. Dadurch
|
||||
ist der Report zur Frame-Prüfung geeignet und zeigt keine alten gecachten
|
||||
Preview-Clips.
|
||||
Source-Previews bekommen bei Trailer-only-Tails denselben schwarzen Tail wie der
|
||||
Export, damit der Browser nicht einen zu kurzen Source-Clip gegen den längeren
|
||||
Referenzbeat weiterspult oder loopt.
|
||||
Zur Synchronprüfung rendert der Report ein einzelnes Frame-Locked-Compare-Video
|
||||
mit Referenz und Source in demselben MP4-Stream. Dieses Compare-Video ist
|
||||
maßgeblich, weil zwei getrennte Browser-Videoelemente nie zuverlässig
|
||||
framegenau synchron bleiben.
|
||||
### Cutter-Report neu erzeugen
|
||||
|
||||
Wenn ein Trailer-Beat am Ende eine Blende, Schwarzfläche oder Textkarte enthält,
|
||||
die im Source-Film nicht als normaler Shot vorhanden ist, endet der Source-Match
|
||||
am letzten stabil passenden Frame. Exportierte Timelines behalten trotzdem die
|
||||
volle Beat-Länge und fügen danach automatisch einen schwarzen Trailer-Tail mit
|
||||
Marker für Fade/Dissolve ein.
|
||||
`CUTTER_REPORT.md` wird bei jedem `match`-Lauf automatisch geschrieben.
|
||||
Manuell neu erzeugen (z. B. nach Edit eines einzelnen Beats):
|
||||
|
||||
Gezielte Ein-Beat-Matches nutzen zusätzlich vorhandene automatische Nachbarbeats
|
||||
aus dem Cache als zeitliche Suchanker. Das hilft bei aufeinanderfolgenden Shots,
|
||||
ohne manuelle Szenen oder Timecodes zu kuratieren.
|
||||
Bei `match --beat N` wird ein alter Cache-Treffer für genau diesen Beat entfernt
|
||||
und nur ein neu gefundener automatischer Treffer wieder eingetragen. Ein
|
||||
fehlgeschlagener neuer Lauf kann dadurch keinen alten falschen Report-Treffer
|
||||
stehen lassen.
|
||||
```powershell
|
||||
python scripts/generate_cutter_report.py # mit Vorschau-Stills
|
||||
python scripts/generate_cutter_report.py --no-stills # nur die Tabelle
|
||||
```
|
||||
|
||||
Der globale Bildvergleich arbeitet auf kontrast-normalisierten Luma- und
|
||||
Kantenfeatures statt auf rohen Farb-Pixeln. Dadurch bleiben Schwarzweiß- oder
|
||||
anders gegradete Trailerbilder mit dem Source-Material vergleichbar, während
|
||||
unähnliche Farbshots schlechter ranken.
|
||||
Die Inpoint-Feinjustage bestimmt den Versatz lokal aus dem Bildinhalt: Um einen
|
||||
groben Treffer herum werden mehrere Referenzframes gegen mehrere Source-Offsets
|
||||
verglichen, und der beste gemeinsame Offset wird übernommen. Das ist schneller
|
||||
als ein erneuter globaler Scan und vermeidet pauschale Frame-Prerolls.
|
||||
Zusätzlich wird die Bewegungsphase über Frame-zu-Frame-Differenzen verglichen.
|
||||
Dadurch kann der Matcher innerhalb derselben Source-Szene unterscheiden, ob
|
||||
zwei Figuren noch sprechen, sich annähern, bereits im Kontakt sind oder sich
|
||||
wieder voneinander lösen. Ein optisch ähnlicher Standbild-Treffer reicht damit
|
||||
nicht mehr aus, wenn der Bewegungsverlauf nicht zur Referenz passt.
|
||||
Schwarze Referenzframes aus Blenden oder Titel-Tails werden für diese
|
||||
Offset-Messung ausgelassen, damit echte Bildbewegung und nicht die Blende selbst
|
||||
den Inpoint bestimmt.
|
||||
`rematch --refine` nutzt denselben lokalen FFmpeg/Pillow-Aligner und schreibt
|
||||
den korrigierten Inpoint direkt zurück in `.cache/match_results.json`.
|
||||
Stills landen unter `output/cutter_stills/` und werden nur neu gerendert,
|
||||
wenn sich das zugrundeliegende Match geändert hat.
|
||||
|
||||
### Wenn ein Match falsch wirkt
|
||||
|
||||
| Symptom | Was tun |
|
||||
|---------|---------|
|
||||
| Source-Clip zeigt richtige Szene, aber falsche Bewegungsphase | `python cli.py rematch --beat N --refine` — schiebt den Inpoint frame-genau aus dem Bildinhalt. |
|
||||
| Score zu niedrig, andere Szene wäre richtig | `python cli.py match --beat N --vision` — vollständiger Re-Match nur für diesen Beat mit Vision-Phasenprüfung. |
|
||||
| Match offensichtlich falsche Szene | `python cli.py rematch --beat N --threshold 0.50` — Schwelle absenken, neuer globaler Scan nur für diesen Beat. |
|
||||
| Beat ist Schwarzbild / Logo / Titel und sollte gar nicht matchen | nichts tun, der Status `MAN.` im `CUTTER_REPORT.md` ist korrekt. |
|
||||
|
||||
### Algorithmische Details
|
||||
|
||||
Tiefer in die Matcher-Logik (Phasen-Reparatur, segmentierte Beats,
|
||||
Vision-Seeds, Recovery-Stufe usw.) — siehe [`docs/ALGORITHM.md`](docs/ALGORITHM.md).
|
||||
|
||||
Zusätzlich werden aus den besten szenenweiten Luma/Histogramm-Kandidaten
|
||||
mehrere Inpoint-Suchanker erzeugt. Diese Scene-Seeds verwenden keine harte
|
||||
pHash-Sperre, weil pHash bei stark anders gegradeten Trailerbildern echte
|
||||
Matches zu früh ausschließen kann.
|
||||
Optional kann `python cli.py match --beat N --vision` einen Vision-Layer
|
||||
zuschalten. Dann werden pro Trailer-Beat und pro wenigen Scene-Level-Kandidaten
|
||||
je drei Frames (Anfang, Mitte, Ende) von einem visionfähigen OpenAI-kompatiblen
|
||||
Modell beschrieben. Die Beschreibungen liegen in
|
||||
`.cache/vision_descriptions.json` und werden wiederverwendet. Vision erzeugt
|
||||
nur zusätzliche Suchanker; der eigentliche Match muss weiterhin durch CV,
|
||||
Content-Reranking, Timing und Duration-Coverage bestätigt werden.
|
||||
Gecachte Szenenbeschreibungen zählen nur, wenn sie vom aktuell konfigurierten
|
||||
Vision-Modell stammen. Bei langen semantisch passenden Source-Szenen beschreibt
|
||||
der Vision-Layer zusätzlich wenige lokale Zeitfenster und cached auch diese
|
||||
Fenster, damit eine grob ähnliche Szene nicht automatisch mit dem falschen
|
||||
Bewegungs- oder Dialogmoment gleichgesetzt wird.
|
||||
Dieser lokale Fenster-Probe ist bewusst breiter als die finale Seed-Auswahl:
|
||||
Eine lange Dialogszene kann in der Gesamtbeschreibung nur als Gespräch
|
||||
erscheinen, aber an einer späteren Stelle trotzdem genau die gesuchte
|
||||
Aktionsphase enthalten.
|
||||
Für diese Probe wird deshalb die grobe Szenenähnlichkeit ohne harte
|
||||
Aktionsstrafe gerankt; die harte Aktionsprüfung greift erst auf den lokalen
|
||||
Fenstern und dem finalen Source-Zeitbereich.
|
||||
Nach dem CV-Match kann derselbe Vision-Layer den konkreten finalen Source-
|
||||
Zeitbereich nochmals gegen den Trailer-Beat prüfen. Starke Aktionsphasen wie
|
||||
Annäherung, Kuss/Stirnkontakt, Handbewegungen oder Schneiden müssen dann auch
|
||||
im Source-Fenster beschrieben sein; fehlt diese Aktionsphase, wird der Treffer
|
||||
nicht gespeichert, selbst wenn der Low-Level-CV-Score hoch ist.
|
||||
Wenn die Szene selbst plausibel ist, aber der konkrete Source-Zeitpunkt diese
|
||||
Aktionsphase verfehlt, sucht der Matcher automatisch dichter innerhalb derselben
|
||||
Source-Szene nach lokalen Vision-Fenstern mit der passenden Aktion und richtet
|
||||
den Inpoint mit der Motion-Phase-Prüfung darauf neu aus. Erst wenn auch diese
|
||||
In-Scene-Reparatur scheitert, wird der Treffer verworfen.
|
||||
Diese In-Scene-Reparatur läuft auch für semantisch gültige Treffer aus langen
|
||||
Source-Szenen. Dadurch kann ein grob passender Dialogmoment nicht bestehen
|
||||
bleiben, wenn ein anderes lokales Fenster derselben Szene die gesuchte
|
||||
Aktionsphase und Bewegung klarer trifft.
|
||||
Die Kandidatenbewertung dieser Reparatur vergleicht dabei zwei Kontexte:
|
||||
den ganzen Beat als semantischen Handlungsrahmen und das konkret sichtbare
|
||||
Beat-Segment als Phasenprüfung. Ein Source-Zeitpunkt muss also nicht nur
|
||||
"die Szene mit dem Kuss" enthalten, sondern auch zur aktuellen Bewegungsphase
|
||||
des sichtbaren Trailerabschnitts passen. Pro Kandidat fließt zusätzlich ein
|
||||
lokaler Content-/Motion-Frame-Score ein, damit cached Vision-Beschreibungen
|
||||
keinen sichtbar versetzten Bewegungsmoment überstimmen.
|
||||
Bei blendigen oder segmentierten Beats nutzt die semantische Action-Suche den
|
||||
ganzen Trailerbeat als Kontext. Die eigentliche Frame-Ausrichtung bleibt auf das
|
||||
sichtbare Segment begrenzt; der gefundene Source-Inpoint wird dabei um den
|
||||
Trailer-Offset des Segments verschoben. So geht die globale Aktionsbeschreibung
|
||||
eines Beats nicht verloren, nur weil der scorebare Teil erst nach einer Blende
|
||||
beginnt.
|
||||
Die Suche nach diesem Action-Window prüft pro Segment zwei Beschreibungen:
|
||||
zuerst die des konkret sichtbaren Segments (so trifft die Phasensuche genau die
|
||||
gerade gezeigte Bewegung), als Rückfall die des gesamten Beats. Der Beat-
|
||||
Kontext gewinnt nur, wenn er deutlich (>0.06) besser scort; sonst bleibt das
|
||||
Segment-Fenster die Wahl, weil die Beat-Beschreibung Aktionen aus Fade-Bildern
|
||||
mit aufnehmen kann, die im sichtbaren Segment nicht stattfinden.
|
||||
Der Trailer-Offset-Shift wird nur angewendet, wenn tatsächlich der Beat-Kontext
|
||||
benutzt wurde; bei segmentbasierter Wahl ist das gefundene Fenster bereits auf
|
||||
die sichtbare Aktionsphase ausgerichtet.
|
||||
Der Segment-Offset zählt dabei nur über vorherige scorebare Bildinseln, nicht
|
||||
über schwarze oder blendige Lücken. Nach dem Retiming wird die nutzbare
|
||||
Source-Dauer erneut geschätzt; läuft die Source am Ende in eine sichtbar andere
|
||||
Aktionsphase, wird der Clip gekürzt und der Rest bleibt Placeholder/Fade statt
|
||||
einen falschen Bewegungsmoment zu zeigen.
|
||||
Der gewichtete Vision-Seed-Pfad ersetzt standardmäßig keinen normalen
|
||||
FFmpeg-Vollscan. Vision-Beschreibungen sind semantische Hinweise, aber keine
|
||||
Beweise; der volle CV-Scan bleibt deshalb aktiv, damit falsch bewertete
|
||||
Vision-Szenen echte Treffer nicht verdrängen. Für schnelle Experimente kann
|
||||
`skip_coarse_scan_with_weighted_seeds = true` gesetzt werden.
|
||||
Gewichtete Vision-Seeds werden nicht zuerst durch den alten Midpoint-Template
|
||||
Refine verschoben; sie gehen direkt in die lokale Content-Alignment-Prüfung.
|
||||
Das schützt wiederholte Gesprächseinstellungen, bei denen ähnliche Momente
|
||||
mehrfach in derselben Szene vorkommen.
|
||||
Innerhalb der automatisch von Vision vorgeschlagenen Szenen läuft zusätzlich
|
||||
eine dichte lokale Bildsequenzsuche. Sie misst den Phasenversatz in kleinen
|
||||
Zeitschritten direkt am Bildinhalt und bevorzugt Kandidaten mit genügend
|
||||
Restdauer in derselben Source-Szene. Das ist kein manueller Override: Vision
|
||||
grenzt nur Suchbereiche ein, die Auswahl bleibt Content-, Timing- und
|
||||
Coverage-getrieben.
|
||||
Nach einem dichten Vision-Treffer darf der spätere lokale Aligner nur noch im
|
||||
Bereich dieses Scan-Schritts nachjustieren. So kann ein korrekt gefundener
|
||||
Bewegungsmoment nicht wieder um viele Frames in eine ähnlich aussehende Phase
|
||||
derselben Szene verschoben werden.
|
||||
Für Vision-Action-Fenster nutzt die finale Retiming-Prüfung eine gemeinsame
|
||||
Content-und-Motion-Suche pro Frame. Content und Bewegungsphase werden dabei
|
||||
nicht mehr als zwei getrennte Korrekturschritte angewendet; das verhindert,
|
||||
dass eine kurze Geste erst korrekt erkannt und anschließend in eine spätere
|
||||
ähnliche Körperhaltung verschoben wird.
|
||||
Wenn mehrere Vision-Kandidaten in derselben Source-Szene ähnlich gut scoren
|
||||
und die Beat-Dauer abdecken, bevorzugt der Matcher die frühere Phase. Das
|
||||
verhindert, dass ein späterer, minimal stärkerer Standbildtreffer die
|
||||
Bewegungsphase des Trailers sichtbar überholt.
|
||||
Enthält ein Trailerbeat selbst einen harten Umschnitt, werden Kandidaten an
|
||||
angrenzenden Source-Szenengrenzen zusätzlich als zusammenhängender Multi-Shot-
|
||||
Span geprüft. Ein Match darf dann über eine Source-Szenengrenze laufen, aber
|
||||
nur wenn die relative Source-Grenze zeitlich zu einem erkannten Trailer-Umschnitt
|
||||
passt. So kann ein Beat aus Frage/Antwort-Shots vollständig erfasst werden,
|
||||
ohne Szenen willkürlich zusammenzukleben.
|
||||
Auch der lokale Content-Aligner darf einen Inpoint nur noch übernehmen, wenn
|
||||
die feste Whole-Frame-/Spatial-Validation dadurch besser wird.
|
||||
Vor dem teuren Frame-Refine wird der gesamte Kandidatenpool mit einer schnellen
|
||||
festen Inhaltsprüfung neu sortiert. Dadurch können korrekte Treffer aus
|
||||
wiederholten Einstellungen einer Szene nach oben kommen, auch wenn ein freier
|
||||
Template-Peak an anderer Stelle numerisch stärker war. Suchanker bleiben im
|
||||
Pool erhalten, dürfen aber erst nach der Inhaltsprüfung nach oben rücken. Wenn
|
||||
ein Kandidat visuell plausibel ist, aber wegen Trailerblende oder kurzem
|
||||
Source-Span die normale Coverage knapp verfehlt, wird er als provisional Match
|
||||
behalten statt als `NO MATCH` verworfen.
|
||||
Dieses Reranking berücksichtigt zusätzlich die verbleibende Szenenlänge ab dem
|
||||
Kandidaten-Inpoint. Dadurch werden zu späte ähnliche Gesprächsphasen innerhalb
|
||||
derselben Szene nicht mehr vor frühere, tragfähigere Phasen sortiert.
|
||||
Das Inhalts-Reranking nutzt bewusst nur wenige repräsentative Referenzframes und
|
||||
eine begrenzte Kandidatenzahl. So bleiben wiederholte Szenen auffindbar, ohne
|
||||
dass der Lauf durch tausende Random-Seeks minutenlang festhängt.
|
||||
Confirmed Matches werden zusätzlich durch eine feste nahezu-Whole-Frame-Prüfung
|
||||
aus Luma, Kanten, Farbhistogramm und räumlichen 4x4-Farbhistogrammen gedeckelt.
|
||||
Dadurch kann ein freier Template-Hit mit ähnlicher Fenster-/Gesichtsstruktur
|
||||
nicht mehr als sicherer Match gelten, wenn die Gesamtkomposition oder die
|
||||
Bewegungsphase sichtbar eine andere Szene ist.
|
||||
Für gewichtete Vision-Kandidaten gibt es zusätzlich eine eigene Provisional-
|
||||
Bewertung aus Content-Score, Restdauer und Seed-Stärke. Dadurch können echte,
|
||||
aber durch Trailer-Grading/Crop numerisch schwache Treffer im Report landen,
|
||||
ohne als confirmed Match durchzugehen.
|
||||
Die Cache-Normalisierung für Report/Export verwendet dieselbe niedrigere
|
||||
Content-Untergrenze für nicht bestätigte Vision-Provisional-Treffer, damit ein
|
||||
gerade gefundener automatischer Match nicht beim Report-Aufbau wieder
|
||||
weggefiltert wird.
|
||||
Sie übernimmt auch die Multi-Shot-Coverage-Regel: gecachte Treffer, die passend
|
||||
zu internen Trailer-Umschnitten über angrenzende Source-Szenen laufen, werden
|
||||
nicht mehr auf die erste Source-Szene zurückgekürzt.
|
||||
Gezielte Einzel-Beat-Matches gewichten außerdem die automatisch aus Nachbarbeats
|
||||
abgeleiteten Continuity-Seeds. Wenn ein Beat direkt an einen bereits passenden
|
||||
Vorgänger anschließt, kann ein späterer ähnlich aussehender Moment derselben
|
||||
Dialogszene den erwarteten Anschluss nicht mehr nur wegen eines höheren
|
||||
Standbildscores verdrängen.
|
||||
Diese Continuity-Seeds sind aber nur Suchanker: in derselben Szene darf ein
|
||||
späterer Inpoint gewinnen, wenn die mehrframeige Content-Prüfung die
|
||||
Bewegungsphase klar besser trifft. Dadurch bleiben Anschlussmatches stabil,
|
||||
ohne Hand-/Kopfbewegungen auf einen falschen Zeitpunkt festzunageln.
|
||||
Continuity- und Vision-Seeds allein schalten den globalen FFmpeg-Scan
|
||||
standardmäßig nicht ab. Sie sind Suchanker, keine Beweise; der volle CV-Scan
|
||||
bleibt aktiv, damit semantisch plausible, aber falsche Vision-Treffer echte
|
||||
Bildmatches nicht verdrängen.
|
||||
Bei aktivierter Vision wird für gezielte Match-Läufe trotzdem zuerst ein
|
||||
schneller seed-basierter CV-Prepass ausgeführt. Er überspringt den vollen
|
||||
FFmpeg-Stream nur vorläufig und akzeptiert einen Treffer erst nach derselben
|
||||
Bild-/Phasenvalidierung wie der normale Matcher. Nur nicht gelöste Beats fallen
|
||||
danach auf den vollständigen Scan zurück. Die Qualitätsparameter für lokale
|
||||
Vision-Szenenscans und Refine-Kandidaten bleiben dabei erhalten; der Prepass ist
|
||||
eine Reihenfolge-Optimierung, kein Qualitätsdeckel.
|
||||
Provisional Treffer aus diesem schnellen Prepass sind nicht endgültig: wenn sie
|
||||
unterhalb der Confirmed-Schwelle bleiben, läuft zusätzlich der vollständige
|
||||
CV-Scan und darf den besseren oder bestätigten Treffer übernehmen.
|
||||
OpenRouter-/Vision-Rate-Limits werden mit progressiv längeren Pausen erneut
|
||||
versucht. Billing-, Credit- oder Token-Guthaben-Fehler werden dagegen sofort als
|
||||
echter Blocker gemeldet, weil Warten dort nicht hilft.
|
||||
Auch Netzfehler beim Lesen der Antwort (Timeouts, Verbindungsabbrüche während
|
||||
einer DSL-Trennung) werden als retrybar behandelt, nicht nur Verbindungsfehler
|
||||
beim Verbindungsaufbau. Schlägt die Vision-Verifikation während der finalen
|
||||
Filter-/Repair-Stufe trotzdem dauerhaft fehl, wird der bisherige gecachte
|
||||
Treffer für diesen Beat behalten statt verworfen — ein Netzproblem darf keinen
|
||||
schon korrekt gefundenen Match aus dem Cache löschen.
|
||||
Die Phasen-Reparatur an gefundenen Treffern läuft nicht mehr nur in „langen"
|
||||
Source-Szenen, sondern überall dort, wo die Szene mehr als nur das
|
||||
Segment-Fenster trägt. Eine korrigierte Position wird übernommen, sobald sie
|
||||
das Bildinhalt-Validate besteht UND nicht spürbar schlechter scort als das
|
||||
Original (≤ 0.02 Verlust). Bereits bestätigte Treffer in eng zugeschnittenen
|
||||
Szenen werden bewusst nicht angefasst, damit ein guter Match nicht durch eine
|
||||
nominell gleichwertige Alternative ausgetauscht wird.
|
||||
Beats, die nach dem CV-Lauf weder als Vollmatch noch als Segmentmatch landen,
|
||||
durchlaufen anschließend eine Recovery-Stufe: Vibe-Check (Histogramm/pHash)
|
||||
liefert Top-K Kandidatenszenen, die semantische Action-Window-Suche prüft
|
||||
darin die Phase des sichtbaren Trailerbeat-Anteils, und der CV-Aligner setzt
|
||||
den Inpoint frame-genau. Übernommen wird nur ein Kandidat, der dieselbe
|
||||
Vision-Phasenvalidierung wie der Hauptpfad besteht. Beats ohne sichtbares
|
||||
Bildmaterial (Logos, Titel-Karten, durchgehende Fades) werden gar nicht erst
|
||||
gesucht — sie sind bewusst kein Match.
|
||||
Lange Trailerbeats werden nicht mehr automatisch über ihre gesamte Beat-Länge
|
||||
gegen einen einzigen Source-Clip validiert. Sobald nach einem sichtbaren
|
||||
Source-Abschnitt eine anhaltende Schwarzblende oder Titel-/Credit-Insel beginnt,
|
||||
endet der matchbare Referenzbereich dort; zwei aufeinanderfolgende dunkle
|
||||
Samples reichen dafür. Spätere Text-/Creditbilder im selben Beat gehen damit
|
||||
nicht mehr in Reranking, Validation oder Span-Schätzung ein.
|
||||
Wenn nach einer Blende wieder sichtbares, matchbares Material kommt, wird der
|
||||
Beat nicht mehr als „Source + schwarzer Tail“ behandelt. Der CLI-Match speichert
|
||||
zusätzliche `MatchSegment`-Einträge für jede automatisch erkannte sichtbare
|
||||
Insel; der HTML-Report setzt diese Source-Segmente frame-lockend zusammen und
|
||||
füllt nur echte Zwischenlücken mit Schwarz. Dadurch können per Blende verbundene
|
||||
Trailer-Einstellungen innerhalb eines Beats getrennt gematcht werden, ohne die
|
||||
globale Scene Detection aggressiver oder beat-spezifisch zu kuratieren.
|
||||
Beats mit mehreren sichtbaren Inseln werden direkt segmentiert gesucht, statt
|
||||
zuerst als ein künstlich zusammenhängender Source-Clip über den ganzen Film zu
|
||||
laufen. Jede Insel nutzt dieselbe gestufte Vision-/CV-Validierung wie ein
|
||||
normaler Beat; der zusammengesetzte Report bleibt beat-synchron. Wenn der
|
||||
schnelle validierte Vision-Prepass für eine Insel keinen Treffer liefert, darf
|
||||
diese Insel weiterhin in den vollständigen Scan fallen.
|
||||
Falls ein kompletter Beat keinen belastbaren Einzelclip ergibt, versucht der
|
||||
Matcher dieselbe Segmentlogik automatisch als Fallback: sichtbare Inseln werden
|
||||
einzeln global gesucht und anschließend wieder zu einem Beat-Ergebnis
|
||||
zusammengesetzt. Sehr kurze Inseln dürfen zusätzlich in den Source-Szenen
|
||||
benachbarter bereits gematchter Beats lokal nach ihrer Bewegungsphase suchen.
|
||||
Das ist weiterhin nur ein allgemeiner Continuity-Anker, kein manueller Override
|
||||
für bestimmte Beat-Nummern oder Szenen.
|
||||
Besteht ein Beat nach automatischer Fade-/Titel-Filterung nur aus einer
|
||||
einzigen sichtbaren Insel, wird diese Insel direkt als primäres Suchziel
|
||||
verwendet. Dadurch scannt der Matcher denselben Bildinhalt nicht erst als
|
||||
vollen Beat und danach noch einmal als Segment; der Report behält trotzdem die
|
||||
korrekte Beat-Position und füllt echte Randlücken mit Schwarz.
|
||||
Gecachte segmentierte Treffer werden ebenfalls gegen die automatisch sichtbare
|
||||
Referenzdauer normalisiert, nicht gegen Schwarz-/Blendränder des gesamten Beats.
|
||||
Ein korrekt gematchter kurzer Bildinhalt wird dadurch beim Report-Aufbau nicht
|
||||
nachträglich als zu kurz verworfen.
|
||||
Zusätzlich werden sehr dunkle, kontrastarme oder noch nicht sauber
|
||||
auf-/abgeblendete Referenzframes aus Score, Inhalts-Reranking,
|
||||
Phasen-Alignment und Motion-Templates herausgenommen. Blenden sollen bestimmen,
|
||||
wie der Clip später exportiert wird, aber nicht, ob der Bildinhalt als Match
|
||||
gilt.
|
||||
Sichtbare Fade-Rampen werden nur in eine matchbare Insel hinein erweitert, wenn
|
||||
sie strukturell stark zum ersten bzw. letzten scorebaren Frame derselben
|
||||
Einstellung passen. Doppelbelichtungen aus Cross-Dissolves bleiben dadurch
|
||||
Übergangsmaterial und werden nicht als einzelner Quellclip erzwungen.
|
||||
Treffer unter `provisional_content_threshold` werden gar nicht mehr gespeichert
|
||||
oder aus alten Cache-Ergebnissen übernommen. Das verhindert, dass offensichtlich
|
||||
falsche Szenen im Report als Match-Kandidat weiterleben.
|
||||
|
||||
### Log-Level
|
||||
|
||||
|
||||
Reference in New Issue
Block a user