- src/lieder/lied01: Äpfel fliegen bei jeder Zahl in den Korb, Zahl + Finger oben rechts, Äpfel leuchten beim Zählen, Lulu holt sich den obersten Apfel (Clip C9), „nur noch …?“ → 9 - Wortzeiten je Sprache mit faster-whisper gemessen (Zeilenanfang: Wortende − 0,38 s, an Lied 3 geeicht) - Komposition „Lied01“, Sprache über --props wie bei den Folgen; Gesprochenes noch ohne Aufnahmen Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> |
||
|---|---|---|
| .. | ||
| public | ||
| src | ||
| werkzeuge | ||
| .gitignore | ||
| ANLEITUNG_PC.md | ||
| package-lock.json | ||
| package.json | ||
| README.md | ||
| tsconfig.json | ||
Remotion – Szenen aus Figuren-Grafiken
Animiert die freigestellten Figuren (Pino, Noa, Lulu) per Code, ohne
Higgsfield-Clips. Erster Test: LaterneTest (14 s, Abendspaziergang mit
Noas Laterne, ohne Ton).
Aufbau
| Pfad | Inhalt |
|---|---|
public/figuren/ |
freigestellte PNGs der Figuren |
src/figuren.ts |
Bildmaße, Augenpositionen (fürs Blinzeln), Noas Hand |
src/teile/Figur.tsx |
Figur an den Füßen verankert: verschieben, drehen, stauchen, blinzeln |
src/teile/Laterne.tsx |
Laternenstab mit pendelnder Papierlaterne |
src/teile/Abendhuegel.tsx |
Hintergrund in Aquarell-Optik (SVG), Vordergrund, Papierstruktur |
src/szenen/LaterneTest.tsx |
die Testszene mit Zeitplan |
Benutzen
npm install
npx remotion studio # Vorschau im Browser
npx remotion render src/index.ts LaterneTest /shared/youtube/tests/laterne-test.mp4
Fertige Videos gehören nach /shared/youtube/, nicht ins Git.
Im VPS-Container fehlen Chrome einige Systembibliotheken. Sie liegen ohne
Root-Rechte unter ~/.local/chrome-libs (Debian-Pakete, nur entpackt) und
werden so eingebunden:
export LD_LIBRARY_PATH=$HOME/.local/chrome-libs/root/usr/lib/x86_64-linux-gnu
Fehlt der Ordner (neuer Container, kein apt-Index): Paketliste
https://deb.debian.org/debian/dists/bookworm/main/binary-amd64/Packages.xz
laden, daraus die Pfade von libnss3, libnspr4, libatk1.0-0, libatk-bridge2.0-0,
libatspi2.0-0, libxcomposite1, libxdamage1 holen, die .deb von
https://deb.debian.org/debian/<Pfad> laden und mit
dpkg-deb -x <paket>.deb ~/.local/chrome-libs/root entpacken. Welche
Bibliotheken fehlen, zeigt ldd node_modules/.remotion/chrome-headless-shell/linux64/chrome-headless-shell-linux64/chrome-headless-shell | grep "not found".
Figuren freistellen
Mit rembg (Modell isnet-general-use), danach Maske härten, nur die größte
Fläche behalten, Rand um 2 px einziehen (sonst heller Saum vor dunklem
Hintergrund). Am besten funktionieren Einzelbilder vor hellem Papier.
Körperteil-Masken (Rig)
werkzeuge/rig.py zerlegt jede Figur in Körperteile und erzeugt:
| Pfad | Inhalt |
|---|---|
public/figuren/<figur>/teile/<teil>.png |
harte Maske, genau an der Kontur |
public/figuren/<figur>/einfluss/<teil>.png |
weiche Maske für die Verformung: Teil + alles, was daran hängt, weicher Übergang am Gelenk, reicht über die Kontur hinaus |
public/figuren/<figur>/uebersicht.png |
alle Teile farbig, zum Prüfen |
src/rigs.ts |
Gelenkpunkte und Hierarchie (automatisch erzeugt) |
Teile: Lulu – kopf, hals, ohr_links/rechts, horn_links/rechts, rumpf, bein_vorne_links/rechts, bein_hinten_links/rechts, schwanz, schal_schlinge, schal_ende, schal_boden. Pino – koerper, kopf, ohr_links/rechts, bauch, arm_links/rechts, fuss_links/rechts, muetze, bommel. Noa – kopf, zopf_links/rechts, rumpf, arm_links/rechts, hand_links/rechts, bein_links/rechts, stiefel_links/rechts.
Zuordnung: Accessoires über ihre Farbe, alles andere über Kernflächen pro
Teil, die bis zur Kontur wachsen – nur innerhalb der Figur, also nie über
Lücken (Schwanz ↔ Bein). Neue Figur oder neues Bild: Skelett und Flächen in
rig.py eintragen, dann
python3 werkzeuge/rig.py # braucht numpy, scipy, pillow
und uebersicht.png prüfen. In einer Szene: gelenk('lulu', 'hals', grad)
(siehe src/szenen/VerformTest.tsx).
Folgen bauen (Baukasten)
Eine Folge besteht aus Szenen, jede Szene aus Sprechzeilen und Bewegungen,
die an diesen Zeilen hängen. Alles Wiederverwendbare liegt in
src/baukasten/, jede Folge hat einen eigenen Ordner (src/folge02/).
Untertitel stehen für die Stimmen, solange es keine Aufnahmen gibt;
Mitmach-Pausen zeigen ein „?“.
| Pfad | Inhalt |
|---|---|
src/baukasten/figur.tsx |
Figur (Standbilder mit Posenwechsel), ClipFigur (freigestellte Clips), Kamera |
src/baukasten/helfer.tsx |
Kamerafahrt, Atmen, Gehen, Hüpfen, Wackeln, Blenden, Ankerpunkte |
src/baukasten/natur.tsx |
Blätter, Nest, Vögel, Schnee, Zzz, Funkeln, große Rufe |
src/baukasten/orte.tsx |
Orte als SVG (Garten Tag/Nacht, Blick von oben, Noas Zimmer, Kalender); vorberechnet nach public/orte/ |
src/baukasten/buch.tsx |
Bilderbuch-Intro und -Outro |
src/baukasten/zeit.ts |
Zeitplan aus den Zeilen (geschätzt oder aus den Aufnahmen) |
src/baukasten/untertitel.tsx |
Untertitel, Mitmach-Pause, Stimmen abspielen |
src/baukasten/folge.tsx |
macht aus der Szenenliste die Kompositionen |
src/baukasten/posen.ts |
automatisch erzeugt von werkzeuge/posen.py |
src/baukasten/sprache.ts |
gewählte Sprache und die Wörter des Baukastens je Sprache |
src/folge02/ |
Folge 2: Folge02.tsx (Szenenliste), szene2.tsx … szene7.tsx, lied.tsx, plan.ts, texte/<sprache>.json (Sprechtexte), stimmen/<sprache>.json (Aufnahmen) |
public/bibliothek/figuren/ |
freigestellte Standbilder (WebP, im Git) |
public/bibliothek/clips/ |
freigestellte Clips (WebM mit Alpha, nicht im Git; VPS: Link auf /shared/youtube/figuren_bibliothek/clips_frei/) |
public/stimmen/ |
Sprachaufnahmen (nicht im Git; VPS: Link auf /shared/youtube/stimmen/) |
Kompositionen: F02 ist die ganze Folge, F02-01-Intro,
F02-02-Gaehnen-ueberall … jede Szene einzeln.
Neue Folge: Ordner src/folgeNN/ anlegen, plan.ts aus Folge 2 kopieren,
stimmen/de.json, es.json, fr.json mit {} anlegen, texte/<sprache>.json
mit den Sprechtexten füllen, Ordnernamen anpassen, Szenen nach dem
Muster von szene2.tsx schreiben (oben die Zeilen mit plane('sX', [...]),
darunter Posenfolgen und Kamerafahrt, die sich auf z.<zeile>.start/ende
beziehen), in FolgeNN.tsx auflisten und in src/Root.tsx eintragen.
Rendern
node werkzeuge/render.mjs F02 --entwurf # schnelle Fassung zum Begutachten
node werkzeuge/render.mjs F02 # volle Qualität
node werkzeuge/render.mjs F02 --szene 3 # nur Szene 3 neu
Mit --sprache es bzw. fr entsteht die jeweilige Fassung (siehe unten).
Das Skript rendert jede Szene einzeln nach out/F02/<sprache>/ und klebt sie
zusammen. Szenen, deren Code, Bilder oder Aufnahmen sich nicht geändert
haben, werden übersprungen. Im Entwurf stehen oben links Gesamtzeit, Szene,
Szenenzeit und Zeilen-ID – für Rückmeldungen einfach diese Angaben nennen
(z. B. „2:47, Szene 4, Zeile l1: Lulus Kopf zu weit links“).
Auf dem VPS: vorher export LD_LIBRARY_PATH=$HOME/.local/chrome-libs/root/usr/lib/x86_64-linux-gnu.
Vorschau ohne Rendern
npx remotion studio öffnet alle Kompositionen im Browser; Änderungen am
Code sind sofort zu sehen. Anleitung für einen Windows-PC: ANLEITUNG_PC.md.
Sprachen (DE, ES, FR)
Die Sprechtexte stehen nur in src/folgeNN/texte/de.json, es.json,
fr.json (Titel der Folge, Liedtitel und jede Zeile unter ihrem Schlüssel
szene/zeile, z. B. s2/e1). Die Szenendateien enthalten nur Ablauf und
Bewegung: {id: 'e1', wer: 'ERZ'} ohne Text. Wörter, die der Baukasten selbst
mitbringt (Kanalname, „Heute: …“, Sprechernamen im Untertitel, Kalendertitel,
„Hatschi!“), stehen in src/baukasten/sprache.ts.
Die Sprache wird beim Rendern gewählt; der Zeitplan richtet sich nach der Länge der Texte bzw. Aufnahmen dieser Sprache, die Bewegungen rutschen mit.
npx tsx werkzeuge/texte.mts F02 # fehlt in einer Sprache etwas?
npx tsx werkzeuge/texte.mts F02 --tabelle # alle Sprachen nebeneinander zum Gegenlesen
node werkzeuge/render.mjs F02 --sprache es # spanische Fassung → out/F02/F02-es.mp4
npx remotion studio --props='{"sprache":"fr"}'
Orte mit Schrift im Bild (bisher nur kalender) gibt es je Sprache als
public/orte/kalender_es.webp usw. (vorberechnen mit
--props='{"sprache":"es"}'). Fehlt eine Übersetzung, zeigt der Untertitel
[fehlt: s2/e1].
Stimmen (ElevenLabs)
- Stimmen-IDs je Sprecher in
werkzeuge/stimmen.config.jsoneintragen (ALLEundNOA_LULUverweisen auf einen anderen Sprecher). Andere Stimmen für eine Sprache unter"sprachen": {"es": {"stimmen": {"ERZ": "…"}}}. npx tsx werkzeuge/stimmen.mts F02 --probezeigt, welche Zeilen erzeugt würden, und zählt die Zeichen (kostet nichts).ELEVENLABS_API_KEY=… npx tsx werkzeuge/stimmen.mts F02 --sprache eserzeugt die Aufnahmen nachpublic/stimmen/folge02/es/und trägt ihre Länge insrc/folge02/stimmen/es.jsonein (ohne--sprache: Deutsch). Der Zeitplan richtet sich danach; ändert sich ein Text, wird nur diese Zeile neu erzeugt.
Untertitel ausblenden: --props='{"untertitel": false}' (bzw. in
render.mjs die props.json).
Neue Standbilder oder Clips
python3 werkzeuge/freistellen.py <zielordner> bild1.png … # ohne Zuschneiden
python3 werkzeuge/clip_freistellen.py <arbeitsordner> <clips_frei> clip1.mp4 …
python3 werkzeuge/posen.py <zielordner> <clips_frei> # Posen und Clips eintragen
Mit pip install "rembg[gpu]" nutzt rembg eine Nvidia-Grafikkarte
automatisch (auf dem VPS gibt es keine; dort ca. 3 s pro Bild).
Orte neu vorberechnen (nach Änderungen in orte.tsx bzw. am Nest in natur.tsx):
npx remotion still src/index.ts F2Ort-garten public/orte/garten.webp --image-format=webp
Bilder mit durchsichtigem Hintergrund (Zimmerwand, Tisch, Nest) als PNG
rendern (--image-format=png): Remotions WebP-Ausgabe speichert keine
Transparenz.
Was das Rendern bremst
Gemessen im Entwurf (halbe Auflösung, 4 Kerne auf dem VPS): die meisten
Szenen schaffen 3,5–5,5 Bilder/s. Teuer sind viele einzeln gezeichnete
Elemente (z. B. über 70 Blätter im Nest) und CSS-Filter oder Mischmodi über
das ganze Bild. Darum: Fertiges wie das Nest als Bild vorberechnen
(F2Nest-…), Filter nur auf die Figuren legen (filter-Prop von Figur/
ClipFigur/Nest), keine mixBlendMode-Ebenen über das ganze Bild.
Bekannte Grenzen
- Die Figuren haben nur die Pose ihres Bildes. Neue Posen brauchen ein neues Bild (z. B. aus Gemini).
- Die SVG-Filter im Hintergrund werden pro Frame neu berechnet und machen das Rendern langsam. Für lange Folgen die Hintergrund-Ebenen einmal als PNG vorberechnen.