CommunityCodierung & Entwicklunggithub.com

splitbrain/ndemo

Erstellen Sie kommentierte Bildschirmaufnahme-Demo-Videos von Webanwendungen.

Was ist ndemo?

ndemo ist ein Toolkit zur Erstellung professioneller, kommentierter Bildschirmaufnahme-Demo-Videos von Webanwendungen. Es automatisiert den gesamten Workflow von der Definition von Interaktionssegmenten über die Aufnahme von Browseraktionen bis hin zur finalen Ausgabe als MP4-Datei mit TTS-Sprachausgabe. Entwickler definieren ein „Playbook“ (YAML-Datei), das URL, Anmeldeaktionen, Navigationsschritte und Erzähltexte beschreibt. ndemo spielt dann die Schritte im Browser ab, nimmt sie auf und fügt Audio hinzu. Das Tool unterstützt bedingte Aktionen und flexible Selektoren (Rolle, Name, Test-ID, CSS, etc.), sodass Demos auch bei dynamischen UI-Zuständen stabil bleiben. Es eignet sich besonders für die Erstellung von Dokumentationen, Produkt-Demos oder Anleitungen, die reproduzierbar und jederzeit neu generiert werden können.

Funktioniert mit✓Claude Code✓Codex CLI~Cursor
npx skills add https://github.com/splitbrain/ndemo/tree/main

Installed? Explore more Codierung & Entwicklung skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

In Ihrer bevorzugten KI fragen

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

Dokumentation

Was macht ndemo?

Erstellen Sie kommentierte Bildschirmaufnahme-Demo-Videos von Webanwendungen.

Einrichtung

Bei der ersten Verwendung MÜSSEN Sie das Toolkit erstellen, bevor Sie einen Befehl ausführen. Überprüfen Sie, ob ${CLAUDE_SKILL_DIR}/dist/cli.js existiert. Wenn nicht, führen Sie Folgendes aus:

cd ${CLAUDE_SKILL_DIR} && npm install && npm run build

Installieren Sie dann ggf. den Playwright-Browser:

cd ${CLAUDE_SKILL_DIR} && npx playwright install chromium

Überprüfen Sie die Einrichtung:

${CLAUDE_SKILL_DIR}/ndemo doctor

Befehle

Alle Befehle werden über ${CLAUDE_SKILL_DIR}/ndemo ausgeführt:

BefehlFunktion
${CLAUDE_SKILL_DIR}/ndemo open <playbook>Browser-Daemon starten, zur App navigieren
${CLAUDE_SKILL_DIR}/ndemo closeBrowser-Daemon herunterfahren
${CLAUDE_SKILL_DIR}/ndemo resetZur App-URL zurücknavigieren (frischer Zustand)
${CLAUDE_SKILL_DIR}/ndemo page-stateBarrierefreiheitsbaum der aktuellen Seite ausgeben
${CLAUDE_SKILL_DIR}/ndemo page-state --screenshotGleicher Befehl + Screenshot speichern unter .ndemo/screenshot.png
${CLAUDE_SKILL_DIR}/ndemo play <playbook>Alle Segmente abspielen
${CLAUDE_SKILL_DIR}/ndemo play <playbook> --segment <id>Ein Segment abspielen (spult zuerst zurück)
${CLAUDE_SKILL_DIR}/ndemo play <playbook> --from <id>Ab Segment bis zum Ende abspielen
${CLAUDE_SKILL_DIR}/ndemo play <playbook> --to <id>Nach diesem Segment anhalten
${CLAUDE_SKILL_DIR}/ndemo play <playbook> --audioMit TTS-Sprachausgabe abspielen
${CLAUDE_SKILL_DIR}/ndemo render <playbook>Vollständige Pipeline: TTS → Wiedergabe → Zusammenführung → mp4
${CLAUDE_SKILL_DIR}/ndemo render <playbook> --output <pfad>In eine bestimmte Ausgabedatei rendern
${CLAUDE_SKILL_DIR}/ndemo doctorAbhängigkeiten überprüfen

Arbeitsablauf

Schritt 1 — Playbook erstellen

Jedes Playbook lebt in einem eigenen Verzeichnis unter demo/ im Projekt des Benutzers. Der Verzeichnisname entspricht dem Playbook-Namen.

demo/
  my-feature/
    my-feature.yaml    ← Playbook
    fixtures/          ← Dateien, die während der Einrichtung wiederhergestellt werden
    audio/             ← Generierte TTS-Dateien (automatisch)
    video-raw/         ← Rohaufnahme (automatisch)
    demo.mp4           ← Endausgabe (automatisch)

Überlegen Sie vor dem Schreiben des Playbooks, in welchem Zustand sich die App für die Demo befinden muss, damit sie zuverlässig und wiederholbar funktioniert:

  • Muss der Benutzer angemeldet sein? → fügen Sie bedingte Anmeldeschritte hinzu
  • Ändert die Demo Dateien/Daten, die wiederhergestellt werden müssen? → kopieren Sie Originale in das fixtures/-Verzeichnis des Playbooks, damit die Einrichtung sie wiederherstellen kann
  • Hängt die Demo von bestimmten vorhandenen Inhalten ab? → erstellen Sie sie in fixtures oder über Shell-Befehle in der Einrichtung

Kopieren Sie alle Dateien, die während der Demo geändert werden, in das fixtures/-Unterverzeichnis des Playbook-Verzeichnisses. Einrichtungsschritte stellen sie vor jedem Durchlauf wieder her, sodass die Demo immer von einem sauberen Zustand startet.

Erstellen Sie das Verzeichnis und die YAML-Datei. Das vollständige Playbook-Schema unterstützt diese Abschnitte der obersten Ebene:

# demo/edit-page/edit-page.yaml
app:
  url: http://localhost:8080/wiki
  viewport:                          # optional, Standard 1920x1080
    width: 1920
    height: 1080
  scale: 2                           # Geräte-Skalierungsfaktor (Standard 2)
  zoom: 1.25                         # CSS-Zoomstufe (Standard 1.25)
  colorScheme: light                 # "light" oder "dark" (Standard "light")
  setup:
    # Während der Demo geänderte Dateien wiederherstellen
    - run: cp demo/edit-page/fixtures/page.txt data/pages/page.txt
    # Artefakte vorheriger Durchläufe bereinigen
    - run: rm -f data/cache/*.tmp
    # Bei Bedarf anmelden (bedingt – wird übersprungen, wenn bereits angemeldet)
    - type: click
      target: { role: link, name: "Anmelden" }
      if:
        hidden: ".user-info"
    - type: type
      target: { role: textbox, name: "Benutzername" }
      text: admin
      if:
        visible: ".login-form"
    - type: type
      target: { role: textbox, name: "Passwort" }
      text: passwort
      if:
        visible: ".login-form"
    - type: click
      target: { role: button, name: "Anmelden" }
      if:
        visible: ".login-form"
      done:
        visible: ".user-info"

titleCard:                               # optionaler Titelbildschirm (wird als erstes Bild gezeigt)
  title: "Eine Wiki-Seite bearbeiten"     # prominent angezeigt
  subtitle: "Ein kurzer Rundgang durch den Editor" # optionaler Untertitel
  duration: 3000                         # Millisekunden Anzeigedauer (Standard 3000)

tts:                                   # optionale TTS-Konfiguration
  provider: openai                     # "openai" (Standard) oder "elevenlabs"
  voice: alloy                         # TTS-Stimmenname (Standard "alloy")
  speed: 1.0                           # Sprachgeschwindigkeitsmultiplikator (Standard 1.0)

recording:                             # optionale Aufnahmeeinstellungen
  outputDir: "."                       # Ausgabeverzeichnis relativ zum Playbook (Standard ".")
  fps: 30                              # Bildrate des Videos (Standard 30)

segments:
  - id: intro
    narration: "Willkommen in unserem Wiki. Lassen Sie uns eine Seite bearbeiten."
    intent: "Zeige die Wiki-Startseite"
    timing: after                      # "after" (Standard) oder "parallel"
    actions:
      - type: wait
        duration: 2000

  - id: open-editor
    narration: "Klicken Sie auf die Schaltfläche 'Bearbeiten', um den Editor zu öffnen."
    intent: "Klicke auf die Bearbeiten-Schaltfläche"
    actions: []

Segment-Timing steuert, wann Aktionen relativ zur Erzählung ausgeführt werden:

  • after (Standard) — Die Erzählung wird zuerst abgespielt, dann werden die Aktionen ausgeführt
  • parallel — Aktionen werden ausgeführt, während die Erzählung läuft

Schreiben Sie zuerst alle Segmente mit Erzählung und Absicht. Lassen Sie Aktionen als leere Arrays. Verwenden Sie absolute Pfade, wenn Sie Playbook-Pfade an ndemo-Befehle übergeben.

Schritt 2 — Browser öffnen

${CLAUDE_SKILL_DIR}/ndemo open /absoluter/Pfad/zu/demo/my-demo/my-demo.yaml

Schritt 3 — Jedes Segment erstellen

Für jedes Segment mit leeren Aktionen:

  1. Lesen Sie den aktuellen Seitenstatus:
${CLAUDE_SKILL_DIR}/ndemo page-state
  1. Betrachten Sie die Ausgabe des Barrierefreiheitsbaums. Finden Sie die Elemente, auf die in der Absicht des Segments verwiesen wird. Schreiben Sie Aktionen in das Playbook-YAML, indem Sie Elemente aus dem Baum verwenden.

So schreiben Sie Ziele – verwenden Sie Informationen aus der page-state-Ausgabe:

Wenn page-state [button "Einstellungen"] anzeigt:

target: { role: button, name: "Einstellungen" }

Wenn page-state [searchbox "Berichte suchen" value=""] anzeigt:

target: { role: searchbox, name: "Berichte suchen" }

Andere Zielfelder – verwenden Sie, was das Element am besten identifiziert:

target: { selector: "#my-element" }        # CSS-Selektor
  target: { testId: "submit-btn" }           # data-testid-Attribut
  target: { label: "E-Mail" }                 # aria-label
  target: { placeholder: "Suchen..." }       # Platzhaltertext
  target: { text: "Klick mich" }              # sichtbarer Textinhalt

Mindestens ein Zielfeld ist erforderlich. Mehrere Felder können kombiniert werden, um die Übereinstimmung einzugrenzen.

Tipp: Der Quellcode der Webanwendung ist im Projekt-Repository verfügbar. Sehen Sie sich die Komponentenquelle nach data-testid-Attributen, Klassennamen oder IDs an, wenn der Barrierefreiheitsbaum nicht ausreicht.

So schreiben Sie Abschlussbedingungen:

done:
  visible: ".settings-panel"        # Element erscheint
  hidden: ".loading-spinner"        # Element verschwindet
  networkIdle: true                 # Keine ausstehenden Anfragen
  stable: 500                       # DOM für 500 ms unverändert
  url: "**/settings"                # URL geändert
  text:                             # Element enthält Text
    selector: ".results"
    has: "Q3-Umsatz"
  attribute:                        # Element hat Attribut
    selector: html
    name: data-theme
    value: dark
  timeout: 10000                    # Standard-Timeout überschreiben (ms)

Jede Aktion, die die Seite ändert, MUSS eine Abschlussbedingung haben. Ohne eine solche kann die nächste Aktion ausgeführt werden, bevor die Seite bereit ist.

Fügen Sie wait-Aktionen nach sichtbaren Änderungen ein, damit der Betrachter sehen kann, was passiert ist:

- type: wait
  duration: 2000    # 2 Sekunden
  1. Testen Sie das Segment:
${CLAUDE_SKILL_DIR}/ndemo play /absoluter/Pfad/zu/demo/my-demo/my-demo.yaml --segment <id>
  1. Wenn es fehlschlägt, führen Sie ${CLAUDE_SKILL_DIR}/ndemo page-state aus, um zu sehen, was jetzt auf dem Bildschirm angezeigt wird, passen Sie die Aktionen an und wiederholen Sie den Vorgang.

  2. Nachdem das Segment funktioniert hat, lesen Sie den Seitenstatus erneut, bevor Sie das nächste Segment erstellen – die Seite hat sich geändert.

Schritt 4 — Überprüfung

${CLAUDE_SKILL_DIR}/ndemo play /absoluter/Pfad/zu/demo/my-demo/my-demo.yaml

Sehen Sie sich die vollständige Sequenz im Browser an. Fragen Sie den Benutzer, ob es richtig aussieht.

Zur Überprüfung mit TTS-Erzählung (erfordert OPENAI_API_KEY und ffplay):

${CLAUDE_SKILL_DIR}/ndemo play /absoluter/Pfad/zu/demo/my-demo/my-demo.yaml --audio

Dies generiert TTS-Audio für jedes Segment (zwischengespeichert nach Inhalts-Hash), spielt das Audio zusammen mit den Browseraktionen ab und polstert das Timing so, dass Aktionen der Erzähldauer entsprechen. Wenn sich der Erzählungstext ändert, wird das Audio automatisch neu generiert und die alte Datei gelöscht.

Schritt 5 — Iterieren

Der Benutzer kann Änderungen wünschen. Häufige Muster:

Benutzer sagtWas zu tun ist
"Falscher Button"page-state ausführen, richtiges Element finden, Ziel aktualisieren
"Zu schnell" / "zu langsam"Wartezeiten anpassen, mit --audio wiederholen, um Timing zu prüfen
"Ändere die Erzählung zu ..."Erzählungsfeld bearbeiten
"Füge einen Schritt hinzu, der X zeigt"Neues Segment einfügen, seine Aktionen erstellen
"Entferne diesen Schritt"Segment aus YAML löschen
"Ab Segment X wiederholen"${CLAUDE_SKILL_DIR}/ndemo play --from <id>
"Von vorne beginnen"${CLAUDE_SKILL_DIR}/ndemo reset dann erneut abspielen

Überprüfen Sie nach jeder Änderung die betroffenen Segmente erneut.

Schritt 6 — Rendern

Wenn der Benutzer zustimmt:

${CLAUDE_SKILL_DIR}/ndemo render /absoluter/Pfad/zu/demo/my-demo/my-demo.yaml

Dies erzeugt die endgültige mp4-Datei mit TTS-Erzählung.

Referenz der Einrichtungsschritte

Einrichtungsschritte werden vor Beginn der Demo ausgeführt (bei open, reset, play und render). Dies können Shell-Befehle oder Browseraktionen sein.

Shell-Befehle werden relativ zum Projektarbeitsverzeichnis ausgeführt (dem Verzeichnis, aus dem ndemo aufgerufen wurde). Alle Pfade in run-Befehlen sollten relativ zum Projektstammverzeichnis sein.

Shell-Befehle – verwenden Sie run für Dateioperationen:

setup:
  - run: cp demo/my-feature/fixtures/original.txt data/page.txt
  - run: rm -f data/cache/*.tmp
  - run: ./scripts/reset-db.sh

Browser-Aktionen – gleiche Syntax wie Segment-Aktionen:

setup:
  - type: click
    target: { role: button, name: "Anmelden" }
  - type: type
    target: { role: textbox, name: "Benutzername" }
    text: admin

Bedingte Schritte – fügen Sie if hinzu, um zu überspringen, wenn die Bedingung nicht erfüllt ist:

setup:
  # Nur anmelden, wenn noch nicht angemeldet
  - type: click
    target: { role: link, name: "Anmelden" }
    if:
      hidden: ".user-menu"      # überspringen, wenn das Benutzermenü sichtbar ist
  # Nur auf einer bestimmten Seite ausführen
  - type: click
    target: { role: button, name: "Zurücksetzen" }
    if:
      url: "**/admin/settings"  # überspringen, wenn nicht auf dieser Seite

Bedingungsfelder:

  • visible: "<selektor>" – Schritt wird nur ausgeführt, wenn der Selektor sichtbare Elemente findet
  • hidden: "<selektor>" – Schritt wird nur ausgeführt, wenn der Selektor keine sichtbaren Elemente findet
  • url: "<muster>" – Schritt wird nur ausgeführt, wenn die aktuelle URL übereinstimmt (** = beliebiger Pfad)

Referenz der Aktionstypen

TypErforderliche FelderHinweise
clicktarget
typetarget, textOptional delay in ms zwischen Tastendrücken (Standard 80)
hovertarget
scrolltargetScrollt das Element in den sichtbaren Bereich
waitduration (ms)Pause für den Betrachter (Standard 1000ms)
presskeyTastaturtaste, z.B. "Enter", "Escape"
selecttarget, optionDropdown-Auswahl

Segment-ID-Regeln

  • Kleinbuchstaben alphanumerisch mit Bindestrichen: open-settings, toggle-dark
  • Muss innerhalb des Playbooks eindeutig sein
  • Wird als Dateiname für Audio/Video verwendet, daher kurz halten

Fehlerbehebung

  • Browser antwortet nicht: ${CLAUDE_SKILL_DIR}/ndemo close, dann open erneut. Überprüfen Sie .ndemo/daemon.log auf Browser-Daemon-Ausgabe.
  • Element nicht gefunden: Führen Sie ${CLAUDE_SKILL_DIR}/ndemo page-state aus, um zu sehen, was auf dem Bildschirm angezeigt wird, und passen Sie die Selektoren entsprechend an.
  • Playwright-Installationsfehler: Überprüfen Sie die Systemanforderungen unter https://playwright.dev/docs/library#system-requirements und führen Sie dann ${CLAUDE_SKILL_DIR}/ndemo doctor aus.
  • TTS fehlgeschlagen: Stellen Sie sicher, dass OPENAI_API_KEY oder ELEVENLABS_API_KEY gesetzt ist. Überprüfen Sie die Abrechnungsinformationen Ihres Kontos.

Sicherheit

  • Der Browser-Daemon akzeptiert nur Verbindungen von localhost.
  • Playbooks werden nicht aus nicht vertrauenswürdigen Quellen ausgeführt.
  • TTS-Audiodateien werden lokal zwischengespeichert.

Verwandte Skills