diff --git a/remotion/.gitignore b/remotion/.gitignore index 813b922..537c5bf 100644 --- a/remotion/.gitignore +++ b/remotion/.gitignore @@ -1,3 +1,4 @@ node_modules/ out/ -public/folge02/clips +public/bibliothek/clips +public/stimmen diff --git a/remotion/ANLEITUNG_PC.md b/remotion/ANLEITUNG_PC.md new file mode 100644 index 0000000..0b402d7 --- /dev/null +++ b/remotion/ANLEITUNG_PC.md @@ -0,0 +1,53 @@ +# Remotion auf dem eigenen PC (Windows) + +Damit kannst du Folgen sofort im Browser anschauen und durchspulen, ohne zu +rendern, und schneller rendern als auf dem VPS (mehr Kerne, Grafikkarte). + +## Einmalig einrichten +1. **Node.js** (LTS, z. B. 22) installieren: https://nodejs.org – Standard- + einstellungen. **Git** installieren: https://git-scm.com +2. Repo holen (in der Eingabeaufforderung `cmd`): + ```cmd + cd %USERPROFILE% + git clone ssh://git@git.larpaso.de:2222/pascal/youtube.git + cd youtube\remotion + npm install + ``` +3. **Clips vom Server holen** (stehen nicht im Git, ca. 3 MB): + ```cmd + ssh -t deploy@larpaso.de "sudo cp -r /var/lib/docker/volumes/claude_shared/_data/youtube/figuren_bibliothek/clips_frei ~/clips_frei && sudo chown -R deploy ~/clips_frei" + scp -r deploy@larpaso.de:~/clips_frei %USERPROFILE%\youtube\remotion\public\bibliothek\clips + ``` + Ohne Clips läuft alles trotzdem, an ihrer Stelle steht dann ein Standbild. + Sobald es Sprachaufnahmen gibt, genauso `/shared/youtube/stimmen` nach + `public\stimmen` kopieren. + +## Anschauen (Studio) +```cmd +cd %USERPROFILE%\youtube\remotion +npx remotion studio +``` +Es öffnet sich der Browser (sonst http://localhost:3000). Links die +Kompositionen: `F02` ist die ganze Folge, `F02-03-…` einzelne Szenen. +Mit Leertaste abspielen, mit der Zeitleiste springen. Ändert jemand den +Code (`git pull`), aktualisiert sich die Vorschau von selbst. + +Tipp: Unten rechts die Vorschau-Qualität auf „Half“ stellen, wenn es ruckelt. + +## Rendern +```cmd +node werkzeuge\render.mjs F02 --entwurf +node werkzeuge\render.mjs F02 +node werkzeuge\render.mjs F02 --szene 3 +``` +Ergebnis: `out\F02\F02-entwurf.mp4` bzw. `out\F02\F02.mp4`. Schon +gerenderte, unveränderte Szenen werden übersprungen. Das Skript nutzt alle +Kerne bis auf einen und die Grafikkarte. + +## Aktualisieren +```cmd +cd %USERPROFILE%\youtube +git pull +cd remotion +npm install +``` diff --git a/remotion/README.md b/remotion/README.md index fe71bbc..857004e 100644 --- a/remotion/README.md +++ b/remotion/README.md @@ -61,43 +61,78 @@ 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`). -## Folge 2 „Pino ist müde“ (`Folge02`) -Komplette Folge (ca. 5:20) nur mit Code, Figuren-Bibliothek und ohne Ton: -Untertitel ersetzen vorerst die Stimmen, Mitmach-Pausen zeigen ein „?“. +## 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/folge02/Folge02.tsx` | Reihenfolge der Szenen | -| `src/folge02/szene2.tsx` … `szene7.tsx`, `lied.tsx`, `buch.tsx` | die Szenen; jede hat oben ihre Sprechzeilen (`plane([...])`) | -| `src/folge02/zeit.ts` | Zeitplan aus den Zeilen; Dauer wird aus der Textlänge geschätzt | -| `src/folge02/figur.tsx` | `Figur` (Standbilder mit Posenwechsel), `ClipFigur` (freigestellte Clips), `Kamera` | -| `src/folge02/orte.tsx` | Orte als SVG; vorberechnet nach `public/folge02/orte/` | -| `src/folge02/natur.tsx` | Blätter, Nest, Vögel, Schnee, Zzz, Funkeln, große Rufe | -| `src/folge02/posen.ts` | automatisch erzeugt von `werkzeuge/posen.py` | -| `public/folge02/figuren/` | freigestellte Standbilder (WebP, im Git) | -| `public/folge02/clips` | Link auf `/shared/youtube/folge02/clips_frei/` (WebM mit Alpha, nicht im Git) | +| `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/folge02/` | Folge 2: `Folge02.tsx` (Szenenliste), `szene2.tsx` … `szene7.tsx`, `lied.tsx`, `stimmen.json` | +| `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` und `stimmen.json` +(`{}`) aus Folge 2 kopieren und den Ordnernamen anpassen, Szenen nach dem +Muster von `szene2.tsx` schreiben (oben die Zeilen mit `plane('sX', [...])`, +darunter Posenfolgen und Kamerafahrt, die sich auf `z..start/ende` +beziehen), in `FolgeNN.tsx` auflisten und in `src/Root.tsx` eintragen. + +### Rendern +```bash +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 +``` +Das Skript rendert jede Szene einzeln nach `out/F02/` 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`. + +### Stimmen (ElevenLabs) +1. Stimmen-IDs je Sprecher in `werkzeuge/stimmen.config.json` eintragen + (`ALLE` und `NOA_LULU` verweisen auf einen anderen Sprecher). +2. `npx tsx werkzeuge/stimmen.mts F02 --probe` zeigt, welche Zeilen erzeugt + würden, und zählt die Zeichen (kostet nichts). +3. `ELEVENLABS_API_KEY=… npx tsx werkzeuge/stimmen.mts F02` erzeugt die + Aufnahmen nach `public/stimmen/folge02/` und trägt ihre Länge in + `src/folge02/stimmen.json` ein. 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 +```bash +python3 werkzeuge/freistellen.py bild1.png … # ohne Zuschneiden +python3 werkzeuge/clip_freistellen.py clip1.mp4 … +python3 werkzeuge/posen.py # 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`): -```bash -npx remotion still src/index.ts F2Ort-garten public/folge02/orte/garten.webp --image-format=webp -``` - -Rendern: -```bash -npx remotion render src/index.ts Folge02 /shared/youtube/folge02/folge02-vorschau.mp4 --gl=swangle -``` -Auf einem anderen Rechner fehlen die Clips: den Ordner -`/shared/youtube/folge02/clips_frei/` nach `public/folge02/clips/` kopieren. -Fehlt ein Clip, zeigt `ClipFigur` ein Standbild der Figur. - -**Ton nachrüsten (ElevenLabs):** Je Zeile die Audiodatei erzeugen, ihre -Länge als `dauer` in die Zeile eintragen und die Datei als `