Damit baut dir Claude Code ein echtes Hand-Tracking, das deine Fingerspitzen und Gesten erkennt. Keine App, kein Abo, läuft offline auf deinem Rechner.
So gehst du vor:
- Neuen leeren Ordner anlegen, Terminal darin öffnen,
claudestarten. - Den Block unten komplett reinkopieren und abschicken.
- Wenn es fertig ist:
npm run live, dannhttp://localhost:5757im Browser öffnen.
Du brauchst Node.js (Version 20 oder neuer) und Claude Code. Sonst nichts.
Prompt 1 — Live an der Webcam
Baue mir ein Hand-Tracking, das live über meine Webcam läuft und Grafiken auf meine Hände zeichnet.
Technik:
- Nutze
@mediapipe/tasks-vision(npm) mit demHandLandmarkerim ModusrunningMode: "VIDEO",numHands: 2.- Lade das Modell einmalig herunter und lege es lokal ab, damit alles offline läuft:
https://storage.googleapis.com/mediapipe-models/hand_landmarker/hand_landmarker/float16/1/hand_landmarker.task- Die WASM-Dateien kommen aus
node_modules/@mediapipe/tasks-vision/wasm.- Das Modell liefert 21 Punkte pro Hand mit x/y normalisiert auf 0..1. Rechne sie mit der Canvas-Breite/-Höhe in Pixel um.
Aufbau: Eine HTML-Seite mit einem Canvas, dazu ein winziger Node-Static-Server auf Port 5757, gestartet über
npm run live. Zeichne pro Frame das Kamerabild aufs Canvas und die Grafiken darüber.Diese vier Dinge unbedingt so umsetzen — sie sind die üblichen Stolperfallen:
- Die Seite MUSS über
http://localhostlaufen. Ein direkt geöffnetesfile://scheitert doppelt:getUserMediabraucht einen sicheren Ursprung, und die ES-Module-Importe werden von der CORS-Policy blockiert. Deshalb der kleine Server.- Das
<video>-Element MUSS im DOM hängen (unsichtbar ist ok:position:absolute;width:1px;opacity:0). Ein percreateElementerzeugtes, nicht eingehängtes Video bleibt in Chrome mit echter Kamera beireadyState 0stehen — die Zeichenschleife läuft dann, malt aber nie, und du siehst nur ein schwarzes Bild ohne Fehlermeldung.- Warte auf das
loadeddata- bzw.playing-Event UND aufvideoWidth > 0, nicht nur darauf, dassplay()durchläuft.detectForVideo()braucht streng steigende Zeitstempel. Nimmperformance.now()und überspringe den Frame, wenn der Wert nicht größer ist als beim letzten Mal.Glättung: Die Rohpunkte zittern ein paar Pixel pro Frame. Lege einen EMA-Filter mit Faktor 0.45 über alle Landmarks und setze ihn zurück, sobald eine Hand aus dem Bild verschwindet — sonst zieht die Grafik beim Wiederauftauchen sichtbar nach.
Gesten — normiere jedes Maß auf die Handflächenlänge
dist(0,9), sonst ändert sich der Wert mit dem Abstand zur Kamera:
- Pinch:
dist(4,8) / dist(0,9) < 0.30- Finger gestreckt:
dist(mcp,tip) / (dist(mcp,pip)+dist(pip,dip)+dist(dip,tip)) > 0.90. Ketten: Zeigefinger5,6,7,8· Mittelfinger9,10,11,12· Ringfinger13,14,15,16· kleiner Finger17,18,19,20.- Hand offen: alle vier Finger gestreckt UND Pinch-Verhältnis > 0.80. Die zweite Bedingung ist nötig, sonst gilt ein Griff mit gestreckten Fingern als offene Hand.
- Entprelle jeden Zustand über 3–5 Frames, sonst flackert er.
Probiere NICHT die Fingerspreizung (Zeigefingerspitze zu kleiner Fingerspitze) als „Hand offen” — der kleine Finger bleibt beim Greifen gespreizt, das Maß bleibt hoch und der Zustand ist unbrauchbar.
Zeichnen: Eckklammern um jede Hand, ein kleines Quadrat auf jeder Fingerspitze, und zwei Reaktionen: beim Pinch eine Linie zwischen Daumen- und Zeigefingerspitze, bei offener Hand ein Viereck auf der Handfläche. Baue das Viereck aus der Handachse selbst — Hochachse vom Handgelenk (0) zum Mittelfinger-Knöchel (9), Querachse vom Zeigefinger-Knöchel (5) zum Kleinfinger-Knöchel (17). Dann kippt es korrekt mit, statt flach über der Hand zu kleben.
Am Ende: kurze README mit dem Startbefehl.
Prompt 2 — Auf fertiges Videomaterial anwenden
Erst wenn Prompt 1 läuft. Damit werden deine Overlays exakt reproduzierbar, statt live einmalig.
Erweitere das Projekt so, dass ich das Tracking auf eine fertige Videodatei anwenden kann statt auf die Webcam.
Schritt 1: Frames mit
ffmpegextrahieren. Schritt 2: dieselbe HandLandmarker-Logik headless über Playwright drüberlaufen lassen und die Landmarks als eine JSON-Datei speichern (normalisiert 0..1, plus Breite/Höhe/fps). Schritt 3: ein zweites Skript, das aus dieser JSON die Overlays auf die Frames zeichnet und mitffmpegwieder zu einem MP4 zusammensetzt.Zwei Fallen dabei:
- Lade die Seite per
page.gotovon deinem lokalen Server, nicht überpage.setContent— sonst liegt sie aufabout:blankund jedesfetchauf die Frames scheitert am Cross-Origin-Check.- Sammle die fertigen Frames NICHT als dataURL in einem Array. Bei ein paar hundert Full-HD-Frames sprengt das den Speicher. Schreib jeden Frame sofort auf die Platte.
Den Ton aus der Quelldatei am Ende wieder dazumuxen, das Video selbst dabei nicht neu kodieren.
Wenn was klemmt
| Symptom | Ursache |
|---|---|
| Schwarzes Bild, Status sieht ok aus | <video> hängt nicht im DOM (Punkt 2 oben) |
| Kamera startet gar nicht | Seite läuft nicht über localhost, oder eine andere App belegt die Kamera |
| Grafik zittert | EMA-Glättung fehlt oder Faktor zu hoch |
| Geste flackert | Entprellung fehlt |
| Hand wird nicht erkannt | Hand ragt aus dem Bild — angeschnittene Hände fallen komplett aus dem Tracking |
Fürs Filmen: Hände komplett im Bild lassen, nie am Rand anschneiden. Hände nicht ineinander verschränken — überlappende Hände ergeben nur eine Erkennung. Gesten rund eine Sekunde halten.