Musikvideo (Motion Graphics)
Du kannst den Song nicht hören. Alles Visuelle ist an gemessene Daten gekoppelt, daher ist die erste Aufgabe immer der Song-Ordner. Wenn die Song-Daten falsch sind, ist jeder Frame falsch.
Helfer befinden sich neben dieser Datei. Führe sie mit der run.py des Skill-Ordners aus (Standard-Installationspfad gezeigt; passe an, falls du anders installiert hast):
python3 ~/.claude/skills/music-video/run.py song-folder SONG.mp3 OUT_DIR [--fps 30] [--lyrics-lang en|tr] [--lyrics-text known.txt]
python3 ~/.claude/skills/music-video/run.py analyze SONG.mp3 # beats/bars/sections as JSON
python3 ~/.claude/skills/music-video/run.py dance2d SONG.mp3 --out DIR --analysis OUT_DIR/song-map.json --start 23.8 --dur 14.3 [--render]
Behaupte niemals, den Song gehört zu haben. Sage stattdessen „aus der Analyse“.
1. Song-Ordner (immer zuerst)
| Datei | Inhalt | Werkzeug |
|---|---|---|
| passage. | das Audio, byteidentische Kopie (sha256-geprüft); verwende es unverändert im finalen Mux | — |
| song-map.json / .md | bpm, Beats, Downbeats/Takte, Energieabschnitte (ruhig/aufbauend/hoch), Energie pro Beat, Drops | Beat This! → aubio CLI → eingebauter numpy-Tracker |
| stems/ | Vocals / Drums / Bass / Sonstiges (zwischengespeichert, Wiederholungen sind schnell) | demucs htdemucs (optional) |
| envelopes.json | laufbildgenaue Lautstärke des Mixes und jeder Spur (dB + 0..1) | numpy |
| hits.json | Kick / Snare / Hat-Einsätze mit Stärke 0..1 | bandspektraler Fluss auf dem Drums-Stem |
| notes.json | Melodie- und Bassnoten (optional) | basic-pitch |
| lyrics-passage.json / .md | Zeilen mit Wortzeiten | whisper.cpp whisper-cli auf dem Vocals-Stem |
| song-story.md | VORLAGE, die du ausfüllst: Thema, Stimme, Stimmungsbogen, Schlüsselbild pro Abschnitt | du, aus Texten und Karte |
| README.md | was jede Datei ist, Einheiten (Sekunden), fps | generiert |
Regeln:
- Abschnitte sind Energie-Phrasen (Zweitakt-Phrasen, geordnet nach der eigenen Energie des Songs), nicht Strophe/Refrain. Benenne sie selbst in song-story.md.
--lyrics-textmit den echten Texten (eine Zeile pro Zeile) gleicht sie mit den Wörtern von Whisper ab; Wörter, die nicht zugeordnet werden konnten, erhalten interpolierte Zeiten (matched: false). Ohne dies sind die Zeilen rohe Whisper-Ausgabe: überprüfe sie. Zeilen über einem stillen Vocals-Stem werden alssuspectmarkiert (Whisper halluziniert auf Instrumentalstücken). Instrumentale Songs überspringen Whisper.- Jeder schwere Schritt verschlechtert sich, anstatt zu scheitern: Kein Beat This! → aubio (externes CLI) → numpy-Tracker
(keine echten Downbeats, 4/4 angenommen); kein demucs → nur Mix-Envelopes und Hits; kein basic-pitch → keine
notes.json; kein whisper → keine Lyrics. Die
warningsdes Laufs sagen, was übersprungen wurde. Informiere den Nutzer. - hits.json ist gut genug für Blitze, Erschütterungen und Skalierungseffekte, nicht für eine Schlagzeugtranskription: Hats feuern auch auf Snares, Bassnoten können in das Snare-Band lecken.
- song-story.md wird bei Wiederholungen nie überschrieben. Schreibe nur, was die Texte und die Analyse hergeben; hinterlasse eine Überschrift als „unbekannt“, anstatt Bedeutung zu erfinden.
2. Kreativer Plan (vor dem Rendern zeigen)
- Ein Konzept, das aus song-story.md stammt, eine Welt, eine Palette, eine freie Schriftart (OFL) für Lyric-Typografie.
- Abschnitt → Szenentabelle: ein Abschnittswechsel = ein Szenen- oder Kameravechsel; der Refrain / der energiegeladenste Abschnitt bekommt die größte visuelle Idee, bei jedem Auftritt mit Variation wiederholt; Drops = Schnitt, Blitz oder Skalierung auf dem Downbeat.
- Lyric-Typografie nur für Schlüsselzeilen (kinetische Wörter zu ihren Wortzeiten), kein Karaoke für jede Zeile.
- Bei ruhiger Musik im Tempo von Phrase und Energie; schneide nicht hart bei jedem verfolgten Beat. Die Anzahl unterschiedlicher Treatment ist wichtiger als die Anzahl der Schnitte.
- Zeige den Plan (Tabelle + 3–4 beschriebene oder gerenderte Standbilder) und hole ein OK vor dem vollständigen Render.
- Bausteine, die es wert sind, zuerst gelesen zu werden: Das eigene
music-to-video-Skill von HyperFrames (github.com/heygen-com/hyperframes,skills/music-to-video/, Apache-2.0) hat einen Katalog von Beat-Cut-Bewegungsprimitiven (Blitzschnitt, Crash-Zoom, Whip, chromatische Teilung, Bildschirmerschütterung, kinetische Buchstaben…) und Lyric-Layouts.
3. Das eingebaute 2D-Tanzvideo
Sieh: Flachfiguren (runder dunkler Kopf, abgerundete Gliedmaßen, buntes Hemd und Schuhe), gewölbte Spiegeltüren, rotierende Sonnenburst-Hintergründe in Lila / Teal / Gold / Pink, fette kondensierte (Anton) Lyric-Wörter mit einem Akzentwort, eine Reihe gespiegelter Tänzerkopien in verschiedenen Farben, Filmstreifen, Kronen- und Schachrequisiten. Inspiriert vom „Low-Effort“-2D-Video in Devarfs YouTube-Experiment eines Musikvideos auf jedem Aufwandsniveau.
Planer (musicvideo/dance2d.py, rein und gesät):
- das Fenster rastet auf Downbeats ein; eine Posenkey pro Beat, die Pose KOMMT AUF DEM BEAT an;
- Downbeats erhalten eine große Pose (Aufbau: ArmeHoch / Zeigen / Klatschen, Hoch: Springen / ArmeHoch) und eine vollständige Kniebeuge;
- der Bewegungsablauf (eine Vierviertel-Phrase) wechselt alle Takte nach Energielevel und wiederholt sich nie zweimal hintereinander;
- Szenen wechseln an Abschnittsanfängen und alle 4 Takte (Palettenwechsel, Sonnenburst-Geschwindigkeit nach Level, Richtung wechselt; Türen in ruhig/aufbauend, Schach + 5er-Tänzerreihe in hoch, Krone auf dem Lead);
- Tänzerkopien: ruhig 1, aufbauend 3, hoch 5;
- Lyrics JSON
[{start, end, text, accent}]in Fenstersekunden → jedes Wort landet auf einem Beat.
Rig (runtime/char2d.js, window.Char2D): SVG-Gruppen mit Drehpunkten (Hüften > Beine > Schienbeine > Schuhe,
Torso > Arme > Unterarme, Kopf). Gliedmaßenwinkel sind nach außen positive Grad (0 runter, 90 Seite, 180 oben),
sodass eine Pose für beide Seiten funktioniert; eine Bodenverriegelung hält den unteren Fuß auf dem Boden (Kniebeugen
gehen von selbst nach unten), air hebt für Sprünge ab. Posen: idle, stepL/R, armsUp, swayL/R, pointL/R, clap,
jump, squat, handsOnHips (mirror(p) tauscht Seiten). poseAt(keys, t) hält und erleichtert dann die letzten
≤0,26 s mit Überschwingen bei großen Hits. runtime/dance2d.js zeichnet den Plan aus window.MV_DANCE; ein
GSAP-Tween treibt einen Proxy-Setter → draw(t), sodass jeder Frame eine reine Funktion von t ist.
Ausgabe von dance2d: DIR/plan.json und DIR/project/ (ein HyperFrames-Projekt). Mit --render
auch DIR/dance2d.mp4: 1920×1080, 30 fps, H.264 yuv420p, das eigene Audio des Songs für das Fenster (AAC,
keine Überblendungen). Musik unter CC BY benötigt den On-Screen---credit.
Rendern ist die Wahl des Nutzers. --render führt npx hyperframes render aus, das ein
headless Chrome/Chromium herunterlädt und steuert. Frage vor der Verwendung. Ohne dies funktioniert alles bis zum
Projektordner mit reinem Python. GSAP ist nicht gebündelt: lege gsap.min.js in runtime/ (oder setze
MV_GSAP), andernfalls lädt das Projekt GSAP 3.14.2 vom jsDelivr-CDN zur Renderzeit.
4. Charaktere jenseits des eingebauten Rigs (eigene mitbringen)
Dieses Skill enthält keine 3D-Modelle. Wenn der Nutzer 3D (Three.js) Charaktere möchte:
- verwende Modelle, deren Lizenz die Weiterverteilung in einem fertigen Video erlaubt, z. B. CC0-Modelle, oder Charaktere und Animationen, die der Nutzer von seinem eigenen Mixamo-Konto herunterlädt (in Ordnung innerhalb eines fertigen Videos; die Rohdateien dürfen nicht weiterverteilt oder in einem öffentlichen Repo gespeichert werden);
- kopiere niemals Beispielmodelle aus anderen Projekten, ohne deren Lizenz zu prüfen;
- oder bleibe bei prozeduralen Primitiven (Kapseln, Kugeln, Boxen auf einer einfachen Knochenkette), die überhaupt
keine Lizenzfrage haben.
Frame-Determinismus gilt weiterhin:
mixer.setTime(t * rate)pro Frame, niemalsmixer.update(dt);rate = song_bpm / clip_bpm; wechsle Clips an Taktgrenzen.
5. Rendering-Regeln (jeder Renderer)
- Alles ist eine reine Funktion von
t = frame / fps. KeinDate, keinerequestAnimationFrame-Deltas, keinMath.random()ohne Seed. - Kleine Hits (Kameraerschütterung, Lichtblitz, Skalierungseffekt) auf Kick/Snare aus hits.json; Helligkeit oder Leuchten aus envelopes.json.
- Ausgabe: 1920×1080 (oder 1080×1920 für Reels/Shorts), 30 fps, H.264 yuv420p, AAC, gleiche Länge wie der Song (oder das gewählte Fenster).
- Fotosensibilität: maximal 3 Vollbildblitze pro Sekunde.
- Budget: mehr Denkzeit führt zu besserer Bewegung, aber überprüfe in einer Sitzung. Multi-Agenten-Überprüfungsschleifen für ein einzelnes Musikvideo verbrennen schnell Tokens und neigen dazu, nach Limits neu zu starten.
6. Prüfungen vor der Auslieferung
- Spielt bis zum Ende; Dauer == Song (oder Fenster)-Dauer ±1 Frame.
- Der Audiostream ist der Originalsong (vergleiche dekodierten PCM-Hash oder einen Kreuzkorrelationspeak bei Verzögerung 0).
- Sync-Stichprobe: rendere 5 Frames auf Refrain-Downbeats und bestätige, dass die Hit-Pose / der Blitz dort landet.
- Ein Kontaktbogen pro Abschnitt (
ffmpeg -i out.mp4 -vf "fps=1,scale=480:-1,tile=4x4" sheet.jpg) und schaue ihn tatsächlich an. report.md: was du gemacht hast und warum, wie, was du geprüft hast, bei was du unsicher bist.