Communitygithub.com

bigzaqui/videolabs

Erstelle ein vertontes, ca. 30-minütiges technisches Videokurs mit Remotion + ElevenLabs im Omarchy / Tokyo Night Terminal-Stil (Waybar, geteilte Fenster, oh-my-zsh Prompt, Markdown-Überschriften), bei dem jedes Element genau dann erscheint, wenn der Sprecher es nennt. Mit Satzpausen, einfachen Untertiteln, schnellem Remote-Rendering und einem kapitelbasierten Web-Player.

Was ist videolabs?

Dieses Skill ermöglicht die automatisierte Produktion professioneller technischer Videokurse im Stil einer Terminal-Demo. Es kombiniert Remotion für die Video-Erstellung mit ElevenLabs für die Sprachausgabe und erzeugt einen typischen Omarchy/Tokyo Night-Look mit Waybar, geteilten Fenstern und oh-my-zsh Prompt. Die Synchronisation von Bild und Ton erfolgt nicht zeitbasiert, sondern wortgenau: Jedes Element (Befehle, Diagramme, Notizen) erscheint genau in dem Moment, in dem der Sprecher es erwähnt. Der Workflow ist stark automatisiert: Nach Abstimmung des Skripts mit dem Nutzer führt das Skill ohne weitere Nachfrage die Schritte Text-to-Speech, Cue-Validierung, Rendering auf einem leistungsstarken Remote-Server (z.B. 24 Kerne, RTX 3090 Ti) und die Erstellung des Web-Players durch. Für praxisorientierte Themen erstellt es zuerst eine reale Laborumgebung (z.B. mit QEMU/KVM), verwendet die tatsächliche Befehlsausgabe im Video und baut die Labor-VMs nach dem Rendern wieder ab. Die Veröffentlichung auf der videolabs-Website (Cloudflare) erfolgt über das separate Skill videolabs_publish. Das Skill läuft in einem zentralen Repository (/opt/opus/videolabs) und unterstützt mehrere Kurse parallel, die sich lediglich durch ihre Konfigurationsdateien im labs/-Verzeichnis unterscheiden.

Funktioniert mit✓Claude Code✓Codex CLI✓Cursor
npx skills add https://github.com/bigzaqui/videolabs/tree/HEAD/skills/videolabs_create-video

In Ihrer bevorzugten KI fragen

Öffnet einen neuen Chat, in dem dieser Agent-Skill bereits geladen ist.

Dokumentation

videolabs: Ein Video erstellen (Terminal-Kurs-Stil)

Alles befindet sich in einem Repository, /opt/opus/videolabs (github.com/bigzaqui/videolabs, öffentlich: niemals Zugangsdaten committen; vor dem Commit scripts/check-secrets.sh ausführen). Die Quelle dieses Skills ist skills/videolabs_create-video/ in diesem Repository, verknüpft in ~/.claude/skills durch scripts/setup.sh. Die Konfigurationswerte (ElevenLabs- und Cloudflare-Schlüssel, der Render-Host) befinden sich in der git-ignorierten .env-Datei im Repository-Stammverzeichnis; siehe .env.example.

Das Repository enthält: eine generische Engine (Remotion + ElevenLabs Tooling, einmal npm ci) und einen Ordner pro Labor unter labs/. Verwendet für "kafka - in a nutshell" (26 Lektionen / 18 Min.), "ceph - first steps" (14 Lektionen / 11,6 Min.) und früher "ceph in a nutshell" (41 Lektionen / 30 Min.; dessen Skript und visuelle Elemente sind in reference/ als Beispiel für Karten, Vergleiche, Messgeräte, Bäume, Vorfälle, Zustände und Standorte erhalten). Beide aktuellen Labore sind praxisorientiert: Jeder Befehl wurde zuerst in einem echten Labor ausgeführt (siehe "Reales Labor").

/opt/opus/videolabs/
  engine/                       generische Tooling: engine/cli.mjs <lab> <command>, src/ (Remotion), scripts/
  labs/<slug>/
    lab.config.json             Katalogeintrag (Titel, Beschreibung, Tags) + Aussehen (Marke, Logo, Statusleiste, Toolnamen, Beispielausschnitt)
    script/script.md            Erzählung, eine Szene pro ###-Überschrift
    visuals.ts                  Was jede Szene zeigt + Cue-Überschreibungen
    lab/                        create-lab.sh, destroy-lab.sh, cap.sh, captures/, lab-meta.json
    audio/raw/                  ElevenLabs Ausgabe (kostenpflichtig; in git committet)
    out/ data/ public/voiceover/  generiert, git-ignoriert
  site/  scripts/publish-all.sh  state/    die Website und deren Veröffentlichung (Skill videolabs_publish)

script.md ──cli Szenen──▶ data/scenes.json
   └─ cli tts (ElevenLabs Wortzeiten) ─▶ audio/raw ──pace──▶ public/voiceover/* + data/{durations,captions}.json
visuals.ts + engine/src/cues.ts (Einblendung = wenn das Wort gesprochen wird) ─▶ Remotion ──cli render──▶ out/<slug>.mp4
cli player ─▶ out/player/{chapters.json,lab.json} ──videolabs_publish──▶ videolabs.pages.dev

Alle Befehle: node engine/cli.mjs <lab> <scenes|tts|pace|cues|stills|typecheck|studio|sample|render|player>, plus list und new <slug> (die README.md des Repos hat die Tabelle). Der Laborordner ist das Einzige, was sich zwischen Kursen unterscheidet; niemals Engine-Code in ein Labor kopieren.

Arbeitsablauf (Stimmen Sie die Gliederung und das Skript mit dem Benutzer ab; alles danach läuft ohne Nachfrage)

Ständige Autorisierung durch den Benutzer: Sobald das Skript vereinbart ist, führen Sie die kostenpflichtigen ElevenLabs tts, die Cue-Überprüfung, das Rendern auf dem Render-Host, den Player/Poster-Schritt und den Laborabbau ohne Erlaubnis für jeden Schritt aus. Melden Sie die Ergebnisse und die neue Länge danach. Halten Sie nur an, um zu fragen, wenn etwas außerhalb dieses Arbeitsablaufs liegt (z. B. eine zerstörende Aktion an Dingen, die das Labor nicht erstellt hat, oder die Veröffentlichung auf der Website, wenn der Benutzer nicht darum gebeten hat).

  1. Praxisorientiertes Thema? Erstellen und ausführen Sie zuerst ein echtes Labor (siehe "Reales Labor" unten). Schreiben Sie niemals Befehlsausgaben aus dem Gedächtnis: Der erste Entwurf des ceph-first-steps-Skripts war an zehn Stellen falsch, als es auf einem echten Cluster lief. Schreiben Sie dann das Skript basierend auf dem, was wirklich passiert ist.
  2. Zuerst das Skript, dann das Video. Schlagen Sie eine Gliederung vor (Module → Lektionen, mit dem geplanten Diagramm pro Lektion), holen Sie die Zustimmung ein, dann schreiben Sie labs/<slug>/script/script.md. Das Ändern von Text ist weitaus billiger als das Neugenerieren von Audio. Markieren Sie mit Geschwindigkeit 1,0 mit Pausen ≈ 160 Wörter pro Minute: 1.500 Wörter ≈ 9,5 Min. inkl. Modulkarten; bei 1,08 ≈ 168 Wörter pro Minute. Überprüfen Sie die tatsächliche Länge mit der Zeile "Paced … total X min" direkt nach tts und passen Sie sie vor dem Rendern an. Für versionsspezifische Befehle überprüfen Sie die aktuelle Version (Dokumente und die Download-/Image-Tags des Projekts) zuerst. Format (geparst von engine/scripts/build-scenes.mjs):
    ## Modul 1 — Kernarchitektur
    ### S02 · RADOS
    **Visual:** Notizen für den Designer
    **Befehle:** `ceph -s` `ceph osd tree`        (optional, nur auf dem Bildschirm)
    **Erzählung:**
    Ein Absatz, geschrieben zum Sprechen. Befehle buchstabieren wie gesprochen ("ceph dash s").
    
    Beenden Sie die letzte Lektion eines Moduls mit "Modul-Takeaway: …" — das Wort takeaway löst das Takeaway-Fenster aus.
  3. node engine/cli.mjs new <slug> erstellt das Grundgerüst labs/<slug>/ (Konfiguration, ein Drei-Szenen-Skript, eine visuals.ts); füllen Sie lab.config.json (Titel, Beschreibung, Tags für den Katalog; brand, user, logo, statusbar, statusCmd, networkLabels, session, tools, sample für das Aussehen) aus und führen Sie node engine/cli.mjs <slug> scenes aus.
  4. Visuelle Elemente in labs/<slug>/visuals.ts (Typen in engine/src/types.ts, colors von @engine/theme), ein Eintrag pro Szenen-ID. Diagrammarten (engine/src/components/Diagrams.tsx):
    • topology: Hosts (Name, IP, Daemon-Chips, Festplatten/Replikate) auf einer oder zwei Netzwerkleitungen, eine optionale Statuszeile (statusCmd-Label, Standard aus der Konfiguration) und flows (Blöcke, die sich zwischen Hosts bewegen, von cue bis until). Jeder Host/Daemon/Disk/Status kann einen cue haben (erscheint, wenn gesprochen) und changes: [{cue, state, label}] (Festplatte empty|osd|leader|idle|down|destroyed|new, Host ok|spare|down|maint). Elemente ohne Cue sind von Anfang an sichtbar. Bauen Sie den Laborzustand mit Hilfsfunktionen (host(n), built(n)) auf, damit das Diagramm Lektion für Lektion wächst.
    • session: eine realistische Shell; jeder cmd tippt sich selbst ein, wenn er gesprochen wird, dann werden seine out-Zeilen gedruckt; behält die neuesten Zeilen. host setzt die gesamte Eingabeaufforderung einer Zeile (Standard session.prompt aus der Konfiguration). Optionale kompakte topology darüber. Die untere Befehlsleiste ist für Sitzungsszenen ausgeblendet. Andere Arten: title (fastfetch-Karte; user, zusätzliche rows), layers, cards, flow, tree, compare, gauge, terminal (Befehlsausgabe mit Hervorhebungen), incident (Symptom/Prüfung/Aktion), checklist, states, sites; optional takeaway und commandCues pro Szene. Verwenden Sie echte Ausgaben aus lab/captures/ für jedes out und symptom.
  5. Überprüfen Sie die visuellen Elemente, bevor Sie für Audio bezahlen: node engine/cli.mjs <slug> stills (ein Frame pro Szene bei 60%; S04,S11 --at=12.5 für einen Moment) und zu 2×2 Kontaktabzügen mit ffmpeg xstack zusammenstellen, um sie anzusehen. Überprüfen Sie auf Überlauf, Umbruch, leere Layouts.
  6. Sprache: Repository-Stamm .env mit ELEVENLABS_API_KEY / ELEVENLABS_VOICE_ID, dann node engine/cli.mjs <slug> tts (direkt ausführen, keine Genehmigung erforderlich; überspringt vorhandene; --only=S03,S04 --force nur um die Szenen zu wiederholen, deren Erzählung sich geändert hat, spart auch Guthaben). Es führt pace automatisch aus. Teilen Sie dem Benutzer die neue Länge mit, wenn das Skript gewachsen ist. Committen Sie labs/<slug>/audio/ (kostenpflichtige Ausgabe).
  7. Synchronisationsprüfung: node engine/cli.mjs <slug> cues (nach jeder Änderung an einem Befehl auch seinen commandCues-Eintrag ändern: ein Chip für dmesg, der immer noch auf "smartctl" gecued ist, ist eine stille Diskrepanz) — listet das Wort, das jedes Element und jede Befehlszeile einblendet (MISS = verteilt zwischen Nachbarn). Korrigieren Sie falsche Treffer mit Cue-Überschreibungen (unten). Wiederholen Sie den Vorgang nach jeder Änderung der Erzählung oder Stimme.
  8. Vorschau: node engine/cli.mjs <slug> sample (≈1 Min. auf dem Render-Server), stichprobenartige Überprüfung von Frames mit ffmpeg -ss <t> -frames:v 1, volumedetect für Pegel (kein Clipping: max < -1 dB).
  9. Rendern Sie den gesamten Kurs (Remote, unten), dann node engine/cli.mjs <slug> player, erstellen Sie das Poster labs/<slug>/out/spot.jpg, zerstören Sie die Labor-VMs und veröffentlichen Sie die gesamte Website mit dem videolabs_publish Skill.

Designregeln, die der Benutzer genehmigt hat

  • Aussehen: Omarchy/Hyprland Desktop, Tokyo Night Palette (src/theme.ts; semantische Namen wie rados, mon, cephfs sind nur Palettenplätze). Waybar-Leiste mit Modulen als Arbeitsbereiche 0–7, ein Status (HEALTH_WARN im Fehlerbehebungsmodul), Lektionszähler 07/41. Ein geteiltes Fenster, 2px quadratischer Rand, keine Eckenrundung/Glanz/Verlauf. Jede Lektion beginnt mit einer getippten robbyrussell-Eingabeaufforderung ➜ module-1-core-architecture git:(s03) cat the-daemons.md, dann eine # Überschrift. Notizen werden als // Kommentare dargestellt, Befehle als ❯ cmd-Zeilen, Takeaways als schwebendes Fenster cat sre-takeaway.md, Modultrenner als cd module-N-… + großer Titel, der Opener als fastfetch. Alles in JetBrains Mono; Inter nur für Untertitel. Es ersetzte ein "generisches" dunkles Verlaufs-Aussehen, das der Benutzer nicht mochte.
  • Einblendungssynchronisation: Niemals nach Zeit staffeln. Jedes Element erscheint, wenn der Sprecher zum ersten Mal seinen Namen nennt (engine/src/cues.ts: längstes sinnvolles Token, präfixstamm, vorwärts vom vorherigen Cue gesucht). Überschreibungen im visuals.ts des Labors:
    • cue: "=managers" exaktes gesprochenes Wort (Bindestriche/Interpunktion ignoriert: "=write-ahead"), cue: null = kein Wort, interpolieren.
    • pointCues (Vergleichsseiten), noteCue (Baum), linkCue (Standorte), cues (Titelabzeichen), commandCues (Befehlszeilen, pro Szene).
    • Die Label-Reihenfolge in cueLabels() muss der Index-Reihenfolge entsprechen, die der Renderer in engine/src/components/Visuals.tsx verwendet (Topologie/Sitzung verwenden schlüsselbasierte Traversierung in topologyKeys/sessionKeys).
    • Ein Vorwärtscursor läuft über alle Labels einer Szene, sodass ein späteres Label, das ein allgemeines Wort wiederverwendet ("three", "recovery", "add"), auf einem späteren Vorkommen landen kann. Bevorzugen Sie ein Wort, das einmal in der Nähe des Moments vorkommt ("=repeat", "=begins"), und lesen Sie immer die cues-Prüfung.
  • Untertitel: einfache Phrasen, getrennt an Satz-/Klauselenden, eine Zeile ≤ 64 Zeichen, keine Karaoke-Hervorhebung pro Wort ("anstrengend").
  • Atmung: engine/scripts/pace.mjs fügt 250 ms nach . ? ! und 120 ms nach : ; in das rohe ElevenLabs-Audio ein und verschiebt die Wortzeiten. Schnittpunkte kommen von ffmpeg silencedetect (streng -38 dB/40 ms, dann -30 dB/20 ms), sonst das leiseste 5-ms-Fenster, mit 8 ms Überblendungen — niemals allein von den ElevenLabs-Wortgrenzen (diese landen innerhalb von Wörtern). Passen Sie SENTENCE_PAUSE/CLAUSE_PAUSE an, führen Sie node engine/cli.mjs <slug> pace erneut aus (kostenlos; rohes Audio bleibt in audio/raw/). Die Temposteuerung hängt von der ffmpeg-Version ab (7.1.5 und 8.0.1 ergaben 17,9 und 17,8 Min. für dasselbe Kafka-Audio): Tempo dort steuern, wo Sie rendern, oder data/ und public/voiceover/ auf den Render-Host kopieren.
  • Übergänge: 15-Frame-Überblendungen via @remotion/transitions TransitionSeries; sie überlappen nur die stille Einleitung (0,4 s) / Ausleitung (0,8 s). engine/src/timeline.ts subtrahiert Überlappungen; engine/scripts/player.mjs und stills.mjs spiegeln diese Konstanten wider — halten Sie sie synchron.
  • Stimme, die der Benutzer gewählt hat: ElevenLabs "Mark" v3p1kjzUvro6S76qmYmH (Voice Library; funktioniert für TTS, obwohl GET /v1/voices/{id} 404 zurückgibt), eleven_multilingual_v2, Geschwindigkeit 1,08, with-timestamps-Endpunkt, previous_text/next_text für Kontinuität. Überprüfen Sie immer eine Stimmen-ID mit einem 1-Satz-TTS-Aufruf vor einem vollständigen Durchlauf (eine frühere ID in .env wurde abgeschnitten).

Pro-Kurs-Einstellungen (labs//lab.config.json)

Arbeitsbereiche in der Waybar und die fastfetch-Modul-/Lektionszahlen folgen automatisch den Szenen. Alles andere Kursspezifische sind Daten in der Konfiguration, niemals Code: brand (Waybar-Name), user (Eingabeaufforderung auf der Titelkarte), logo (fünf Zeilen Blockbuchstaben), statusbar (ok/warn-Text, right-Text, warnModule = das Modul, das die Warnung anzeigt), statusCmd und networkLabels (Standardeinstellungen von Topologieszenen), session.prompt/session.title (Terminal-Sitzungen), tools (Befehlswörter, die beim automatischen Cuen einer Befehlszeile übersprungen werden), sample (Szenen-IDs des Beispielausschnitts), plus title, description, tags für den Katalog. Ein neues Labor mit einem anderen Aussehen benötigt keine Engine-Änderung; eine neue Diagrammart oder einen neuen Zustand hingegen schon (engine/src/types.ts, Komponenten, cues.ts) und kommt dann jedem Labor zugute.

Angewandte Remotion-Praktiken (aus den Remotion-*-Skills)

Schriftarten via @remotion/google-fonts (niemals auf Systemschriftarten verlassen); <Audio> von @remotion/media mit from; TransitionSeries; calculateMetadata dimensioniert die Komposition aus Audiodauern; animieren mit interpolate/Easing.bezier und translate (keine CSS-Übergänge). Nicht absichtlich übernommen: Interactive.create/verbundene Kompositionen (nur nützlich für manuelle Bearbeitung im Studio), große Social-Video-Text-Minima, Meme-SFX.

Rendering

  • VIDEOLABS_RENDER_HOST (SSH-Ziel des Render- und Lab-Servers, Schlüssel bereits eingerichtet) kommt aus der .env-Datei im Repository-Stammverzeichnis: führen Sie set -a; . /opt/opus/videolabs/.env; set +a vor den untenstehenden Befehlen aus und schreiben Sie diese Variable, nicht eine wörtliche Adresse, in alles, was Sie committen. Derselbe Host betreibt die Labor-VMs.
  • TMPDIR=/var/tmp wird von der CLI gesetzt: /tmp ist ein kleiner RAM-tmpfs auf diesen Hosts und eine lange Audiomischung schlägt am Ende mit "No space left on device" fehl.
  • Lokale Box (4 vCPU) ≈ 45 Min. pro 30 Min. Video. Remote-Render-Server $VIDEOLABS_RENDER_HOST (Ubuntu 26.04, 24 Threads, 31 GB RAM, RTX 3090 Ti, KVM; Node 22, ffmpeg, rsync und die Chromium-Bibliotheken von apt) rendert den 11,6-minütigen Ceph-Kurs in 3 Min. und den 18-minütigen Kafka-Kurs in 5 Min. bei Gleichzeitigkeit 12–16. Das Repository befindet sich auf beiden Maschinen unter /opt/opus/videolabs. Ablauf:
    rsync -az --delete --exclude node_modules --exclude out --exclude .env --exclude .git --exclude site --exclude state ./ $VIDEOLABS_RENDER_HOST:/opt/opus/videolabs/   # von /opt/opus/videolabs
    ssh $VIDEOLABS_RENDER_HOST 'cd /opt/opus/videolabs/engine && npm ci && cd .. && node engine/cli.mjs <slug> scenes && node engine/cli.mjs <slug> pace && node engine/cli.mjs <slug> render --concurrency=12 --log=error'
    rsync -a $VIDEOLABS_RENDER_HOST:/opt/opus/videolabs/labs/<slug>/out/<slug>.mp4 labs/<slug>/out/ && node engine/cli.mjs <slug> player
    
    (Um die gleiche zeitliche Abstimmung wie bei der Überprüfung beizubehalten, synchronisieren Sie labs/<slug>/data und public/voiceover per rsync, anstatt scenes/pace auf dem Server auszuführen.) Kopieren Sie niemals .env dorthin. Führen Sie lange Renderings getrennt aus (nohup bash script & gestartet mit ssh -f -n) und warten Sie mit einem Monitor auf die real-Zeile von time; grep-en Sie nicht das Log nach "error" (die Befehlszeile hat --log=error). Wenn sich der Waybar-/Diagrammcode ändert, überprüfen Sie beide Labore (stills), da sie ihn gemeinsam nutzen.
  • Überprüfen einer Engine-Änderung: Rendern Sie den Beispielausschnitt mit dem alten und dem neuen Code und vergleichen Sie ffmpeg -i a.mp4 -i b.mp4 -lavfi ssim -f null -; neu generierte scenes/durations/captions.json und die cues-Prüfung müssen …

Individual skills in this repo

This repo contains 1 individual skill — each has its own dedicated page.

Verwandte Skills