Visual Guide Video
Analysiert das Video und erstellt eine einzige Timeline-Datei (timeline.py). Die Engine rendert alle Inszenierungen, Musik und Soundeffekte programmatisch – ohne externe Schnittprogramme oder Audiodateien.
SKILL_DIR = Ordner, in dem diese SKILL.md liegt. Skripte werden mit python "$SKILL_DIR/scripts/<name>.py" ausgeführt.
0. Vorbereitung
pip install -r "$SKILL_DIR/requirements.txt" # opencv-python imageio-ffmpeg numpy scipy pillow edge-tts
ffmpeg wird über das imageio-ffmpeg-Bundle bereitgestellt. Koreanische und Emoji-Schriftarten werden automatisch im Betriebssystem erkannt (kann mit VGUIDE_FONT_BOLD/REGULAR/EMOJI überschrieben werden).
Arbeitsordner wird neben dem Video erstellt: project/timeline.py, Ausgabe project/build/, project/output/.
1. Videotyp bestimmen → Profil wählen
python "$SKILL_DIR/scripts/analyze.py" VIDEO --out build/analysis
Betrachte die Typ-Schätzung in der Konsole und die build/analysis/sheets/*.jpg direkt als Read, um den Typ zu bestimmen. Ein PROFILE legt die Standardwerte fest; in der timeline.py angegebene Werte haben immer Vorrang.
| PROFILE | Ziel | Standardwerte | Kerninszenierung |
|---|---|---|---|
screen | Bildschirmaufnahme, Tutorial, Demo | Pop-Musik, Originalton aus, Fortschrittsbalken | SHOTS (Zooms), CLICKS, LINKS, HIGHLIGHTS, CARDS, HUD, FLOW |
game | Gameplay, Bosskampf, Highlights | Epic-Musik (leise), Originalton an, cinematic Farbkorrektur, 30fps | MAGNIFY, IMPACTS, SPEED/FREEZE, POPS, CALLOUTS (@Tracks), Balkenanalyse |
vlog | Alltag, Reise, Review | Chill-Musik, Originalton an, warme Farbkorrektur | CALLOUTS, STICKERS, SPEED (Zeitraffer bei Bewegung), Untertitel, GRADES |
anim | Animation, Figurenvideos | Cute-Musik, vivid Farbkorrektur | POPS (lustig), STICKERS, CALLOUTS, FREEZE |
promo | Werbung, PR, Reise-, Brandfilm | Epic-Musik (laut), Originalton aus, 30fps | TYPE (Werbe-Typografie, Siegel), CLEANUP (Originaltext löschen), INK-Übergang, GLOWS, LETTERBOX, saisonale Partikel, Zen-Musikbogen |
Jeder Typ hat unterschiedliche Erklärungsziele:
- screen: „Wo wurde geklickt und was hat sich geändert?” → Zoom auf Klickpunkte, Pfeile auf geänderte Panels, Statuskarten.
- game: „Was ist passiert (Angriff, Verteidigung, Treffer, Heilung, Bossmuster)” + Spaß → Trefferfeedback, Reaktions-Popups, Lupe auf entfernte Ziele, Freeze-Frames zur Erklärung, Zeitraffer für langweilige Bewegungsphasen.
- vlog: „Wo wird was gemacht” + Emotion → Stimmung vor Erklärung. Höhepunkte von Ereignissen (Geburtstag, Reise, Abschluss) mit Slow-Motion und Partikeln betonen, wackelige Bewegungsphasen im Zeitraffer, Foto-Momente mit Freeze + Polaroid, Ende mit Fotocollage-Outro.
- anim: Figurenreaktionen betonen → niedliche Popups, Sticker, Freeze bei entscheidenden Gesichtsausdrücken.
- promo: „Den Zuschauer zum Reisen oder Kaufen verleiten” → Kurze Werbe-Copy anstelle von Untertiteln (2 Zeilen Opening → Hero-Titel → Kapitel pro Szene → Endkarte), signifikante Übergänge (z. B. Tusche-Läufer) bei großen Szenenwechseln, musikalische Energie-Kurve (leise → Steigerung → Höhepunkt → Nachklang → Finale). Falls Original anderweitige Schrift enthält: löschen und durch Zielsprache ersetzen (Internationale Version).
Gemeinsame Schnittprinzipien (vom Nutzer am meisten geschätzt): Unnötige Abschnitte (Bewegung, Ladezeiten, Kamera-Verwacklung) werden im Zeitraffer abgespielt, wichtige Momente werden eingefroren (Freeze), um Erklärungen oder Dekorationen einzufügen. In der Analysephase wird jeder Abschnitt als „Kern / Verbindung / Überflüssig” kategorisiert.
2. Analyse – Wann, wo, was passiert
Ereignistypen in events.json:
- Allgemein:
cut(Szenenwechsel),flash(Blitz),loud(Lautstärke-Peak = Treffergeräusch, Explosion),motion(Bewegungs-Peak) - screen:
switch(Klick-/Tab-Wechsel-Kandidat),big-change,scroll - Balken (
--bar):bar-drop/bar-big-drop(Treffer),bar-low(Gefahr),bar-empty(Tod),bar-rise(Heilung)
Bei Spielen wird der HP-Balken immer gemessen. Treffer, Heilung und Tod werden so auf das genaue Frame genau bestimmt.
python "$SKILL_DIR/scripts/crops.py" VIDEO --t 10,30 --box 200,940,500,100 --step 25 --out build/hp.jpg # Balkenkoordinaten messen
python "$SKILL_DIR/scripts/analyze.py" VIDEO --out build/analysis --bar player:337,982,626,988 --bar boss:1015,911,1590,915
- Die Balkenbox wird als eine Zeile innerhalb des Balkens (Höhe 4–8px) gewählt. Weiße Balken verwenden
light, farbige Balken:any. - Betrachte
bar_<name>.png(Kymograf: vertikal = Zeit) als Read und prüfe die Ereignisse. Wenn der Balken beim Treffer rot aufblitzt oder das HUD durch Inszenierung verschwindet, kann es Fehldetektionen geben – Überprüfung mitgraph.pngund den Sheets. - Sheets haben einen Abstand von 2 Sekunden. In Kampfabschnitten werden Frames alle 0,3–0,6 Sekunden extrahiert, um Aktionen (Angriff/Rollen/Treffer/Verwandlung) direkt zu interpretieren.
Präzise Koordinaten: Immer mit Raster-Crops messen.
python "$SKILL_DIR/scripts/crops.py" VIDEO --t 7.4,13.5 --box 0,760,420,240 --out build/crops.jpg # Bereich, 50px-Raster
python "$SKILL_DIR/scripts/crops.py" VIDEO --t 12 --full --out build/grid.jpg # Gesamt, 100px-Raster
3. timeline.py schreiben
Starte mit einem Rezept. Kopiere das passende Rezept in timeline.py und fülle nur die [1. Auszufüllende Werte] (Zeitpunkte, Koordinaten, Texte) ein – die validierte Inszenierungsstruktur wird automatisch erzeugt. Dann passe die Liste nach Preview-Ansicht an das Video an.
| Rezept | Ziel | Auszufüllende Werte |
|---|---|---|
recipes/screen_walkthrough.py | Bildschirmaufnahme-Tutorial/-Demo | Klicks (Zeit, Koordinate, Text, geändertes Element, Karte), Hervorhebungsbereiche, Untertitel |
recipes/game_boss_fight.py | Spielekampf-Highlights | HP-Balkenpositionen, Treffer (Zeit, verbleibende HP), eigene Angriffe, Boss-Down, Heilung, Tod/Sieg, Bewegungsphasen, Kommentar-Untertitel |
recipes/event_vlog.py | Geburtstag, Jubiläum, Party-Vlog | Höhepunkts-Zeitpunkt und -Objekt, wackelige Abschnitte, Foto-Countdown/-Freeze-Frame, Gäste-Auftritte, letzte Szene |
recipes/promo_shorts.py | 30s vertikale Shorts (Werbe-Montage) | Abschnittsliste (Originalabschnitt, Ausgabelänge), Szenen-Panning, saisonale Wörter/Kapitel-Texte, Übergangsart |
recipes/promo_film.py | Werbe-, PR-, Reisefilm | Opening-Copy, Hero-/Endkarte, Szenen (Abschnitt, Geschwindigkeit, Kapiteltext, Siegel, Kamera, Partikel, Energie, Hintergrundgeräusch), Tusche-Übergangszeiten, leuchtende Objekte, zu löschender Text |
Die Standardwerte eines Rezepts sind mit echten Videos validiert – wenn sie so belassen werden, funktionieren sie wie im Beispiel (bei anderen Videos unbedingt neu messen). Fehlende Elemente können aus dem Vollschema in templates/timeline_template.py ergänzt werden. Falls kein passendes Rezept existiert, mit der Vorlage beginnen.
Die timeline.py eines bearbeiteten Videos gehört in dessen Ordner. In den Skill-Repository werden keine Timelines bestimmter Videos (Personennamen, persönliche Szenen, Arbeitsinhalte) abgelegt – verallgemeinerbare Muster werden in Rezepte und dieses Dokument übernommen.
Regel: Zeit immer als 'Originalvideo-Zeit', Koordinaten immer als 'Original-Pixel'. SPEED/FREEZE ändern die Ausgabelänge – die Engine konvertiert automatisch.
Zeiten innerhalb eines Freeze-Abschnitts werden als (Originalzeit, Ausgabe-Offset-Sekunden) geschrieben: (49.45, 1.6) = Freeze beginnt bei 49,45 s, 1,6 s später. Wird genutzt, um während des Freeze nacheinander Popups, Polaroids und Outros einzublenden.
Universelle Elemente (alle Profile)
| Element | Verwendung |
|---|---|
TRIM, SPEED, FREEZE | Abschnitt zuschneiden, Geschwindigkeit/Slow-Motion (Label-Badge, Label=None = kein Badge), Freeze-Frame (look desat=zur Erklärung / photo=nur Shutter-Blitz). Zeitraffer erzeugt automatisch Bewegungsunschärfe (SPEED_BLEND) |
TRACKS | Keyframes für sich bewegende Objekte. auto=True (OpenCV-Tracking: Menschen, Tiere) / auto="match" (Template-Matching: formstabile Objekte wie Kuchen, Schilder; verfolgt mit einem einzigen Key bis until) / follow="Elternteil" (an Eltern-Track gebundenes Objekt, z. B. Kerzenflamme auf Kuchen). Wird von anderen Elementen mit "@Name", "@Name:top" referenziert |
PARTICLES | Partikel confetti/hearts/sparkle/bokeh/notes/stars/snow/petals/leaves/fireflies (Farbangabe wie palette=[6]). Von Track oder Koordinate aus burst (einmaliger Schwall) oder rate (kontinuierlich), ganzer Bildschirm (at="screen") |
PHOTOS | Ein Frame des Originals als Polaroid einblenden (Caption, Winkel, fallendes Erscheinen). Für Freeze-Frames und Outro-Collagen |
SHOTS | Kamera: Koordinaten-Zoom / "full" / "fill" (füllt ohne Letterbox) / "@Track" (Tracking-Zoom) |
MAGNIFY | Lupenlinse: Entferntes Objekt kreisförmig vergrößern + Verbindungslinie + Label |
CALLOUTS | Auf Objekt zeigende Sprechblase (folgt dem Track) |
POPS | Popup-Text-Stile impact/danger/cool/info/funny/small/party/sweet/count (Countdown-Zahlen) |
STICKERS | Emoji-Sticker (bob/pulse) |
IMPACTS | Treffer-Feedback hit/heavy/crit/damage/block/parry: Verwacklung + Blitz + Zoom-Punch + chromatische Aberration (+ automatischer Soundeffekt) |
SHAKE, FLASH | Manuelle Verwacklung / Blitz |
GRADE, GRADES | Farbkorrektur cinematic/warm/cool/vivid/mono/sepia/danger/dream/night (Übergänge zwischen Abschnitten) |
SFX, SFX_VOLUME | Soundeffekt-Bibliothek: hit boom clang pop ding scratch sad_trombone heartbeat shutter slowmo crash whoosh riser party_horn twinkle confetti / stamp temple_bell ink gliss gliss_down / längenabhängige Hintergrundgeräusche "waves:8" "wind:6" "water:6" "birds:5" |
SOURCE_AUDIO | Originalton (bei Slow-Motion sinkt die Tonhöhe, bei Freeze stumm, bei Zeitraffer um fast_gain reduziert) |
MUSIC | style pop/epic/chill/cute/zen, arc (Zen: szenenabhängige Energie), start (Musik beginnt ab dieser Zeit), drop, end (+end_fx scratch/fade/cut), volume |
MASTER_GAIN_DB | Endmix-Gain (vor Limiter). Handy-Videos haben leisen Originalton → +3 bis 5 dB |
CUSTOM_LAYERS, CUSTOM_FRAME_FX, CUSTOM_SFX | Neu angewiesene Effekte als Funktionen in timeline.py (siehe unten) |
OUTPUT_SIZE, FPS, QUALITY | Ausgabeauflösung (z. B. 720p (1280, 720)), fps, CRF |
CANVAS, BACKDROP | Design-Canvas. Kurze vertikale Videos: CANVAS = (1080, 1920) + OUTPUT_SIZE = (1080, 1920). Querformat-Original wird mittig als Streifen eingefügt, Leerraum mit BACKDROP ("black", "blur", dict(kind="blur", tint=(r,g,b), amount=0.5)). Um den Bildschirm zu füllen, Zoom auf SHOTS ≈ 3,16 (= 1920 / 607,5) und Panning in x-Richtung |
SPEED_RAMP | Geschwindigkeitsabschnitte lückenlos aneinanderreihen (Short-Montage): Zwischen Abschnitten wird nicht auf 1× zurückgesetzt, sondern nur für diese Dauer sanft übergeblendet |
Werbe-/PR-Elemente (scripts/promo.py, für alle Profile nutzbar)
| Element | Verwendung |
|---|---|
CLEANUP | Im Original eingebrannte Schrift, Stempel, Logos löschen (t0, t1, (x0,y0,x1,y1), dict(plate=(ta, tb), ref=t)). plate = Frames ohne Schrift in derselben Szene → Hintergrund wird direkt wiederhergestellt (bei Panning/Zoom automatische Korrektur durch Phasenkorrelation). mask="box" ersetzt die gesamte Box (statischer Hintergrund); ohne Plate wird Inpainting verwendet (NS + Papierstruktur). live=True für bewegte Schrift (z. B. hereingleitendes Label, ink="light") |
TYPE | Werbe-Typografie. "line" (Wort-für-Wort aufsteigende Copy), "hero" (Groß-Titel mit einfliegenden Buchstaben + Untertitel + Siegel), "chapter" (Siegel wird gesetzt, dann Kicker, Linie, Titel tauchen auf, veil für Nebel-Schleier dahinter). Koordinaten beziehen sich auf 1920×1080 Canvas, Farbe color, Lesbarkeit halo |
GLOWS | Sonne, Mond, Licht-Lens-Flare (Streek, Ghost) – folgt Tracks |
INK | Tusche-Läufer-Übergang (t, dict(dur, at)): Bei t bedeckt die Tusche den Bildschirm maximal, dann zieht sie sich von der Mitte zurück (automatischer Soundeffekt) |
TYPE "slam" | Für Shorts: Großes Wort knallt im Takt – wird über die Tusche gezeichnet und bleibt auch sichtbar, wenn der Bildschirm bedeckt ist (over_ink). Siegel seal |
LETTERBOX | Cinema-Letterbox dict(ratio=2.39, range=(t0, t1)) – weiches Ein- und Ausblenden. Partikel werden unter dem Streifen versteckt |
Neue Effekte auf Anweisung – Custom Hooks
Schreibe Funktionen in timeline.py, ohne die Engine zu ändern. ctx enthält: t (Ausgabezeit), ts (Originalzeit), raw (Originalframe), frame (aktuelles Canvas BGR), view, cv (Overlay-Canvas), tl, gfx, fx, W, H, screen("@boss"), window(t0, t1) (Originalzeitabschnitt → (alpha, Fortschritt)).
def speed_lines(ctx): # CUSTOM_LAYERS: Overlay zeichnen (keine Rückgabe oder neues frame)
w = ctx.window(57.2, 58.4)
if w:
x, y = ctx.screen("@boss")
for k in range(12):
a = k / 12 * 6.283
ctx.fx.draw_line(ctx.cv, (x + 300 * math.cos(a), y + 300 * math.sin(a)),
(x + 700 * math.cos(a), y + 700 * math.sin(a)), (255, 255, 255), 3, w[0] * 0.6)
CUSTOM_LAYERS = [speed_lines]
def red_pulse(ctx): # CUSTOM_FRAME_FX: Frame transformieren → neues frame zurückgeben
return ctx.fx._tint(ctx.frame, (255, 0, 0), 0.15) if ctx.window(76, 78) else None
CUSTOM_FRAME_FX = [red_pulse]
def boss_roar(a): # CUSTOM_SFX: a = dict(buf, add, lib, tl, SR)
a["add"](a["buf"], a["lib"]["boom"](), a["tl"].out(14.4), 0.8)
CUSTOM_SFX = [boss_roar]
Häufig benutzte Effekte werden später in fx.py als offizielle Elemente übernommen.
Layout-Regeln (aus praktischen Problemen entstanden)
Allgemein
- Emojis werden farbig gerendert. Symbole wie
▸ ✓ ✕können kastenförmig brechen → stattdessen Emojis (✅ ✖️ 👉 ⏩ ⏸) oder• → ·verwenden. - Untertitel max. 40 Zeichen pro Zeile. Schlüsselbegriffe mit
[eckigen Klammern]hervorheben. Freeze-Frame-Erklärungs-Untertitel:(tf, tf, "...")→ Freeze-Zeit als Start=Ende, erscheint nur während des Freeze. - Nicht mehr als 3 Popups, Sprechblasen, Sticker gleichzeitig überlagern. Popup-Dauer 0,8–1,2 s ist ausreichend.
screen
- Zeitliche Trennung von Karten und Highlights (Karte → Highlight). Karte endet vor dem nächsten Klick-Zoom.
- In Zoom-Zustand: Highlight außerhalb des Bildschirms wird abgeschnitten → Zoom-Faktor 1,15–1,3.
- Label-Positionen:
"right"(Pfeil),"above-right"(Tabellenzeile),"below"(oberes Element). HUD bei Zoom ≥1,12× in Mini-Modus (linke 100px).
game
- Ultrawide (21:9) wird als Letterbox im 16:9-Canvas dargestellt. Die oberen/unteren Streifen enthalten Speed-Badges und Untertitel, ohne die Action zu verdecken. Zum Füllen
"fill"in SHOTS. - Balken-Highlight mit
"above|nodim"– Abdunkeln würde die Action unsichtbar machen. - Zoom max. 1,3–1,5×. Zu starker Zoom bei schneller Action führt dazu, dass das Objekt aus dem Bild läuft. Bei Bedarf Vergrößerung über
MAGNIFY. - Freeze 1–2 s, 3–4× pro Video reichen. Während Freeze mit CALLOUTS „wer was tut” erklären.
- Bewegungs-/Ladeabschnitte mit SPEED 2–3× verkürzen. Slow-Motion 0,3–0,4× nur bei Treffer/Entscheidungstreffer 0,5–1 s.
- Track-Keyframes setzen, wenn sich das Ziel stark bewegt; bei Szenenwechseln (Cuts) denselben Wert zweimal (direkt vor/nach) notieren, um Interpolations-Sprünge zu vermeiden. Mit
python "$SKILL_DIR/scripts/tracks.py" timeline.pyein Sheet erstellen und prüfen. - HP-Ereignisse für Treffer-Zeitpunkte nutzen und
IMPACTSframe-genau anpassen. Treffer =damage/crit, eigener Treffer =hit/heavy. - Original-Spiel-Sound erhalten, BGM leise (volume 0,3–0,45). Bei Tod:
MUSIC["end"]+end_fx="scratch"zum Musik-Abbruch, mitsad_trombone-Effekt für Lacher.
promo (Werbung, PR, Internationale Version)
- Original-Text löschen: Als Plate Frames wählen, die 0,4 s vor Auftauchen/nach Verschwinden des Texts liegen. Während Überblendungen sind noch schwache Schriftreste vorhanden → mit kontrastverstärktem Crop (Hintergrund-Blur entfernt ×4) prüfen. Nach dem Löschen mit
--previewin Originalauflösung croppen, um Nachbilder/Nähte zu sehen. - Bei ständig wechselnden Hintergründen (Nebel, Gischt) passt Plate nicht (graue Flecken) → Inpainting ohne Plate, stattdessen Kapitel-Typografie mit
veilüberlagern. - Rote Stempel-Erkennung erfasst nur tiefes Rot (Sonnenuntergang, oranger Himmel ausgeschlossen). Wenn der Himmel orange ist, sicherstellen, dass die gesamte Box ersetzt wird, ohne Farbstreifen.
- Copy kurz: Opening 2–4 Wörter × 2 Zeilen, Kapiteltitel 2–5 Wörter, Endkarte Marke + eine Zeile. Keine offiziellen Slogans von Organisationen/Marken verwenden.
- Typografie innerhalb des Letterbox (obere 140 px, untere 140 px ausschließen). Die Stelle, an der Original-Text stand, ist meist „frei gelassener Himmel” und eignet sich gut für Kapitel.
- Musik: Zen verwendet
arcfür szenenabhängige Energie. Tusche-Übergangszeit auf Taktgrenzen legen (80 BPM = 3 s), indem die Szenengeschwindigkeit angepasst wird – dann passen Übergänge, Trommeln und Siegel im Takt (tl.loadgibt out-Zeit aus → Geschwindigkeit anpassen). Schrittweise Lautstärke: calm −20 dB / peak −12 dB – der Unterschied muss groß sein, damit der Höhepunkt wirkt. - Entscheidende Szenen (sich entfaltender Wandschirm, Sonnenaufgang) 0,75–1×, langsame Landschaften 1,5–2,4×. Tusche nur bei großen Wechseln (Jahreszeit, Region); innerhalb desselben Kapitels Original-Übergänge beibehalten.
- Vertikale Shorts (30 s) (
recipes/promo_shorts.py): 96 BPM (ein Takt = 2,5 s) pro Szene. MitSEGMENTS = [(Original-Start, Ende, Ausgabelänge)]aneinanderreihen undRemapberechnet die Geschwindigkeit, sodass Übergänge genau auf den Takt fallen. Original-Übergänge (Crossfade) auf 0,2 s komprimieren und unter Tusche/Blitz verstecken.- Erste 1 s = Hook: eine Zeile Copy → Takt 1 Marken-Titel + musikalischer Einschlag. Opening/Finále im Streifen-Layout (Original mittig + Typografie oben/unten), Hauptteil im vertikalen Full-Crop + Panning auf das Motiv (Sonne, Wasserfall, Mond in der Mitte; breite Landschaften von links nach rechts).
- Im Zeitraffer-Abschnitt wird die Original-Sekunde kürzer, daher Typografie-Zeit als
(TRIM[0], Ausgabe-Sekunde)ausgabe-basiert schreiben. Kapitel erscheinen mitpace=0.55schnell. - Partikel mit
clip=Trueam Cut beenden (damit Blütenblätter nicht in die nächste Jahreszeit übergehen). Typografie innerhalb der Shorts-UI: oben 260 px, unten 420 px ausschließen.
vlog (Familie, Veranstaltungen)
- Handy-Videos haben viele Verwacklungen. Wackelige Bewegungsabschnitte 3–4× im Zeitraffer (Bewegungsunschärfe wird automatisch eingefügt, glättet), Originalton wird automatisch reduziert.
- Höhepunkte (Kerzen auspusten, Anstoßen, Zielerreichung) mit 0,4× Slow-Motion + Blitz + Confetti-Burst + Party-Horn. Musik beginnt genau in diesem Moment (
MUSIC["start"]) – davor den Originalton (Geburtstagslied, Gespräch) erhalten. - Foto-Aufnahme-Szene: Direkt nach dem Auslöser den unverwackelten Frame einfrieren (
look="photo") und Polaroid einblenden. Den Freeze-Frame unbedingt per Preview auf Schärfe prüfen (bewegte Kamera-Frames sind unscharf). - Sticker, Popups, Herzen nicht auf Gesichter setzen. Gesichtskoordinaten messen und daneben oder auf freie Fläche setzen. Gesichtsausdrücke (Zunge raus, Zwinkern) mit CALLOUTS (
ring=False) von der Seite zeigen. - Wenn Countdown auf dem Bildschirm sichtbar ist (Handy-Timer),
count-Popups 3·2·1 passend zur Zeit setzen und Pop-Soundeffekt anheften. - Outro: Auf Freeze-Frame 2–3 Polaroids in Collage + kurzer Glückwunsch-Text (mit
OUTRO’stopnach oben verschieben undstats=[]). - Ohne Untertitel oder Sprecher muss die Geschichte klar sein: Intro-Titel + kurzes Popup pro Szene reichen.
4. Preview-Schleife
python "$SKILL_DIR/scripts/build.py" timeline.py --preview 3.5,7.4,26 # Originalzeit
python "$SKILL_DIR/scripts/build.py" timeline.py --preview-out 16.6,36.2 # Ausgabezeit (Freeze/Slow-Motion-Mitte prüfen)
Betrachte build/preview/sheet*.jpg als Read und korrigiere Überlappungen, Abschneidungen, Verdeckungen, Koordinatenfehler, Zeichenfehler. Die Label src ↔ out zeigen auch die Zeitkonvertierung. Freeze-Abschnitte können nicht über die Originalzeit geprüft werden → --preview-out verwenden.
5. Audio
- Hintergrundmusik
MUSIC["style"]: pop (126 BPM Elektropop), epic (96 BPM Taiko, Staccato-Streicher, Blechbläser, Chor), chill (82 BPM Lo-Fi), cute (132 BPM Marimba, Pizzicato), zen (80 BPM Gayageum, Daegeum, Janggu, Buk, Chor, mitMUSIC["arc"] = [(Originalzeit, "calm|flow|pulse|build|peak|hush|finale")]). Alle außer Zen haben eine Intro → A → B → Build → Drop → Outro-Struktur; der Drop-Zeitpunkt ist der Höhepunkt. - Originalton: Bei game/vlog/anim standardmäßig an. Wenn ein Sprecher spricht, wird gleichzeitig gedingt (
SOURCE_AUDIO["duck"]). - Level-Prüfung: Bei Spielen ist der Originalton der Hauptakteur. RMS pro Abschnitt messen und Musik 3–5 dB leiser als Original, Soundeffekte nur im Treffermoment einblenden.
import tl, music, build; t = tl.load("timeline.py"); m = music.build_music(t)[0] * t.music["volume"]; s = build.source_audio(t, m.shape[1]) - Sprecher (optional)
NARRATION = [(t, "Satz")](fehlt er, wird Textvorschlag aus Untertiteln gelesen).--voice edge(Microsoft Neural Network, online – Sätze werden an Microsoft gesendet, bitte informieren) /--voice sapi(Windows offline). Inbuild/voice_report.jsonprüfen, ob Rate > +15 % oder Overflow → Satz kürzen (Koreanisch ≈ 7 Silben/s).
6. Finales Rendering und Validierung
python "$SKILL_DIR/scripts/build.py" timeline.py [--voice edge] [--workers 8]
Frames werden auf mehrere Prozesse verteilt parallel gerendert und dann zusammengesetzt (1 min 1080p ≈ 2–3 min, 8 workers). Im Hintergrund ausführen.
Prüfungen vor Abschluss
- Letzte Zeile
[done] ... Ns (expected Ns), N MB– Länge übereinstimmend? Kein Traceback im Log? - Einige Frames aus der Ausgabe extrahieren:
ffmpeg -ss T -i out.mp4 -frames:v 1 f.png - Musik und Soundeffekte können nicht direkt gehört werden → mit RMS über Abschnitte prüfen und den Nutzer bitten, selbst zuzuhören.
Dateistruktur
| Datei | Rolle |
|---|---|
scripts/analyze.py | Metadaten, Typ-Schätzung, Szenenwechsel, Lautstärke-Peaks, Balken-Ereignisse, Graphen, Sheets |
scripts/crops.py | Original-Koordinaten-Raster-Crops |
scripts/tracks.py | Objekt-Tracking (Keyframe-Interpolation, OpenCV), Validierungs-Sheets |
scripts/remap.py | Zeit-Remapping (TRIM·SPEED·FREEZE) |
scripts/build.py | Preview / Audio-Mix (Originalton-Remapping, Limiter) / Parallel-Render / SRT |
scripts/tl.py | Timeline.py-Loader, Profil-Standardwerte, Koordinaten-/Zeit-Konvertierung |
scripts/render.py | Kamera (Tracking, Verwacklung), Bildschirmaufnahme-Layer, Custom Hooks |
scripts/fx.py | Universelle Effekte: Farbkorrektur, Treffer-Feedback, Lupe, Sprechblasen, Popups, Sticker, Badge, ... |
(Ende der übersetzten SKILL.md)