Communitygithub.com

Perso Dubbing — Multi-Lang Lip-Sync-Ship

Perso-AI-Auto-Dub: Upload→Split→Translate→Merge→MP4 mit Lip-Sync. Multi-Target in einem Befehl. README mit Demo-GIFs. 38★.

Was ist Perso Dubbing — Multi-Lang Lip-Sync-Ship?

Video Localization Schritt 3: Perso 38★ Lip-Sync-Multi-Dub. Frisch vs. VoxCPM 26.09. und IndexTTS 24.09.

Funktioniert mit✓Claude Code✓Codex CLI✓Cursor✓Antigravity✓Gemini CLI
npx skills add perso-ai/perso-dubbing-plugin

In Ihrer bevorzugten KI fragen

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

Dokumentation

/dubbing

Eine Fähigkeit, die Videos automatisch über die Perso AI Dubbing API synchronisiert.

Kernregeln (müssen befolgt werden)

  • Nur der Worker sieht den rohen Schlüssel. Öffnen Sie den Schlüssel niemals mit Read, geben Sie ihn nicht aus und übergeben Sie ihn nicht als Befehlszeilenargument. Worker senden ihn nur im XP-API-KEY-Header.
  • Ein Befehl = die gesamte Aufgabe. scripts/dubbing.mjs übernimmt Hochladen · Aufteilen · Übersetzen · Zusammenführen · Speichern selbstständig. Führen Sie prepare_input.mjs oder probe_split.mjs niemals davor aus – sie sind Debug-Werkzeuge, und probe_split.mjs führt einen echten Upload durch (das Video würde zweimal hochgeladen).
  • Führen Sie dubbing.mjs immer im Hintergrund aus. Aufgaben dauern Minuten bis Stunden; ein Timeout der Shell im Vordergrund bricht die Ausführung ab.
  • Sprachen nicht angegeben → Quelle auto, Ziel en.
  • Mehrere Sprachen in einem Befehl (--target en,zh,ja) – Hochladen/Aufteilen erfolgt einmal und wird pro Sprache wiederverwendet. Führen Sie es niemals einmal pro Sprache aus (lädt die Quelle jedes Mal erneut hoch).
  • Geben Sie den Fortschritt originalgetreu weiter. Geben Sie die [progress]-Zeilen der Worker-Standardausgabe wörtlich oder zusammengefasst an den Chat weiter – und kündigen Sie keine Schritte an, die nicht vorkamen (Aufteilen/Zusammenführen gibt es nur für Videos, die das Limit überschreiten). Die eingerückten Detailprotokolle auf stderr müssen nicht weitergegeben werden.
  • Halten Sie den Benutzer während der Ausführung auf dem Laufenden. Synchronisation, Lippenbewegungen und Audioseparation geben alle einen [status]-Herzschlag aus (Phase + Anzahl der Elemente, z.B. ja 4/6 · en 1/6 oder separating — file 2/5, mit einem Hinweis next check ~Nm), und jedes fertige Element wird als [progress]-Zeile gestreamt. Überprüfen Sie die Hintergrundausgabe etwa 3 Minuten nach dem Start, dann im angegebenen Intervall (10 min für Medien ≤10 min, 30 min für längere): Geben Sie jede neue [progress]-Zeile sofort weiter, ansonsten posten Sie die neueste [status]-Zeile als einzeiliges Update. Erfinden Sie niemals Prozentsätze, vergangene Zeit oder ETAs – geben Sie nur das weiter, was die Zeilen sagen. Stopps, die den Benutzer benötigen ([space-select], [split-confirm], [free-limit], [resume-check], [credit-check], Guthaben aufgebraucht, Abschluss) beenden den Prozess, sodass sie ohne Abfrage sichtbar werden.
  • Benennen Sie Ihre Laufzeit für die Telemetrie (still). Fügen Sie --host <claude-code|codex|cursor|antigravity|gemini> zum Worker-Befehl hinzu und benennen Sie den Agenten, als der Sie gerade arbeiten, wenn Sie es erkennen können. Es markiert nur die Nutzungstelemetrie – zeigen Sie es dem Benutzer niemals an und fragen Sie ihn niemals danach. Lassen Sie es weg, wenn Sie unsicher sind.
  • Nicht unterstützte Formate werden automatisch übersprungen und der Rest wird weiterverarbeitet – geben Sie den Hinweis zum Überspringen weiter.
  • Eine Pause ist kein Fehler. Eine Zeile [space-select], [split-confirm], [free-limit], [credit-check] oder [resume-check] bedeutet, dass die Ausführung angehalten wurde, um Sie etwas zu fragen – sie beendet sich mit 0 (sieht also nie wie ein Fehler aus), aber die Aufgabe ist nicht abgeschlossen. Immer wenn eine dieser Zeilen vorhanden ist, melden Sie die Ausführung niemals als abgeschlossen: Geben Sie sie weiter und handeln Sie danach. Die Zeilen sind das Signal, nicht der Exit-Code.

Einrichtung (träge – kein vorbereitender Schritt)

  1. API-Schlüssel – kein Schritt, den Sie zuerst ausführen. Der Worker blockiert sich selbst, sobald ein Befehl ausgeführt wird, der die Perso-API benötigt: Beim ersten solchen Lauf öffnet er eine Browserseite (Anmelden, ein Klick – der Schlüssel wird verschlüsselt gespeichert) oder druckt dateibasierte Anweisungen, wenn kein Browser geöffnet werden kann – geben Sie diese an den Benutzer weiter. Auf einem headless/SSH-Rechner überspringt der Worker den Browser-Flow vollständig und beginnt mit der Datei-/--import-Registrierung (die Browserseite kann einen Schlüssel nur an den Rechner ausliefern, auf dem sie läuft) – geben Sie diese Anweisungen auf die gleiche Weise weiter. Lösen Sie die Schlüsselregistrierung niemals selbst aus: Der Worker startet bei Bedarf connect.mjs/resolve_key.mjs --watch, führen Sie diese also nicht aus, und führen Sie resolve_key.mjs --check nicht als vorbereitenden Schritt aus (nur wenn der Benutzer explizit fragt, ob ein Schlüssel registriert ist – ein fehlender Schlüssel ist kein Fehler). Fügen Sie den Schlüssel niemals in den Chat ein. Holen Sie sich einen Schlüssel: https://developers.perso.ai/api-keys
  2. ffmpeg/ffprobe – wird nur automatisch installiert, wenn ein Video das Planlimit überschreitet und aufgeteilt werden muss (genehmigen Sie, wenn um Erlaubnis gebeten wird). Manuelle Überprüfung: node scripts/check_deps.mjs.

Ausführung

Sammeln Sie die Eingabe (lokaler Pfad oder URL – fragen Sie erneut, wenn sie fehlt) und führen Sie sie im Hintergrund aus – der Worker führt die Schlüsselsperre bei Bedarf selbst durch; geben Sie nur seine gedruckten Anweisungen weiter, wenn die Registrierung startet:

  • Einzeln: node scripts/dubbing.mjs "<Datei|URL>" [--source auto] [--target en] [--space "Bereichsname"] [--out resultat.mp4] [--lipsync] [--no-save]
  • Mehrere Sprachen / Mehrere Eingaben (eine oder mehrere Eingaben; URLs und Dateien können gemischt werden): node scripts/dubbing.mjs "<URL>" "<Datei>" --target en,ja – eine Ausgabe pro Eingabe × Sprache, neben jeder Quelle gespeichert (--out <Ordner> sammelt sie).
  • Ordner (Stapel): node scripts/dubbing.mjs "<Ordner>" [--target en,zh] [--recursive] [--out Ausgabeordner]

Sprachcodes – --target akzeptiert einen Sprachcode (en, ja) oder ein regionales Tag. Regionale Varianten gibt es nur für Englisch (en = US-Standard, en-GB = UK), Portugiesisch (pt = Brasilien-Standard, pt-PT = Portugal) und Spanisch (es = Mexiko-Standard, es-ES = Spanien); en-US, pt-BR und es-MX sind akzeptierte Schreibweisen dieser Standards. Jede andere Sprache hat eine einzelne Variante, und --source benötigt nur die Sprache (ein regionales Tag dort wird als die reine Sprache behandelt).

  • Region im Anfrage genannt → verwenden Sie genau dieses Tag. Eine Region ohne Variante (z.B. australisches Englisch) → teilen Sie dem Benutzer mit, dass nur die aufgeführten Optionen existieren, und lassen Sie ihn vor der Ausführung wählen.
  • Zwei-Buchstaben-Token sind Sprachcodes, keine Länder: uk ist Ukrainisch – britisches Englisch ist en-GB. Gleiche Falle für ca (Katalanisch), be (Weißrussisch), eu (Baskisch). Wenn die Formulierung des Benutzers beides bedeuten könnte, fragen Sie vor der Ausführung, welche gemeint ist.
  • Sprache ohne Region genannt → die Standardvariante. Für diese drei Sprachen nennen Sie die angewandte Standardeinstellung im Lieferhinweis (z.B. „Spanisch (Mexiko) – verwenden Sie es-ES für Spanien").

Speicherort – --out akzeptiert entweder einen Ordner (ein bestehendes Verzeichnis oder ein Pfad, der mit / endet), der die Ergebnisse darin sammelt, oder einen Dateipfad für eine einzelne Eingabe (die tatsächliche Erweiterung wird angehängt, wenn der Pfad keine hat). Standardmäßig wird neben jeder Quelldatei gespeichert; fragen Sie nicht. Geben Sie es beim ersten Auftrag der Sitzung in der Startzeile an (z.B. „Ergebnisse werden neben den Originalen gespeichert – sagen Sie mir jetzt Bescheid, wenn Sie einen anderen Ordner wünschen") und starten Sie sofort, ohne auf eine Antwort zu warten. Wenn der Benutzer einen Ordner nennt – mit dieser Anfrage oder zu einem späteren Zeitpunkt in dieser Sitzung – führen Sie mit --out "<Ordner>" aus und verwenden Sie diesen Ordner für alle weiteren Aufträge, bis er geändert wird. Wenn er nach einem bereits gestarteten Lauf umleitet, verschieben Sie die fertigen Dateien dorthin, wenn der Lauf abgeschlossen ist. Ausnahme: Wenn jede Eingabe eine URL ist (kein lokaler Quellordner), fragen Sie vor dem Start nach dem Speicherort.

Bereichsauswahl – bei mehreren Arbeitsbereichen stoppt der Worker vor dem Hochladen, gibt [space-select]-Zeilen aus (Name | (Plan) | verbleibendes Guthaben) und stoppt. Zeigen Sie dem Benutzer NUR diese Optionen (keine internen Zahlen), fragen Sie, welcher, und führen Sie erneut mit --space "<Bereichsname>" aus. Ein Bereich → keine Frage; PERSO_SPACE_SEQ fixiert ihn.

Bestätigung der Aufteilung – wenn die Eingabe das Längen- oder Größenlimit überschreitet und automatisch aufgeteilt & zusammengeführt werden muss (Synchronisation, Synchronisation+Lippenbewegungen oder Audioseparation), stoppt der Worker und gibt [split-confirm]-Zeilen aus. Geben Sie sie weiter und fragen Sie den Benutzer: Es überschreitet das Längen-/Größenlimit, daher ist eine automatische Aufteilung → Verarbeitung → Zusammenführung erforderlich, die weniger ausgereift sein kann, als wenn sie es selbst aufteilen – automatisch fortfahren? Bei einem Ja führen Sie den gleichen Befehl mit --allow-split erneut aus (bis zu diesem Punkt wird nichts berechnet, daher ist die erneute Ausführung kostenlos). Stapelläufe: --allow-split autorisiert jede Aufteilung im Lauf.

Nicht speichern (nur Server) – wenn der Benutzer das Video synchronisiert haben möchte, aber nicht als lokale Datei speichern möchte, fügen Sie --no-save hinzu: Der Worker belässt das Ergebnis im Perso-Arbeitsbereich des Benutzers und überspringt den Download, wobei Kept on server, not saved: … → project <seq> ausgegeben wird (die [project-ref]-Zeile wird dennoch ausgegeben, sodass die Synchronisation später lippensynchronisiert oder abgerufen werden kann). Nur einzelne/nicht aufgeteilte Videos – die zusammengeführte Datei eines aufgeteilten Videos benötigt einen lokalen Download, daher wird sie normal gespeichert und der Worker gibt dies an. Kann nicht mit --lipsync kombiniert werden (das lippensynchrone Video muss heruntergeladen werden).

Kostenloser Plan (Ergebnisse bleiben auf Perso) – ein kostenloser Arbeitsbereich kann synchronisieren, lippensynchronisieren und trennen, aber der Server verweigert jeden Download, daher speichert der Worker dort nie eine Datei. Es wird Free plan — <name>: … ready on Perso → <url> (downloads need a paid plan) ausgegeben – geben Sie diesen Link als das gelieferte Ergebnis weiter: Der Lauf ist abgeschlossen, nichts ist fehlgeschlagen und es gibt nichts fortzusetzen. Wenn der Benutzer tatsächliche Dateien möchte, ist ein kostenpflichtiger Plan erforderlich – bieten Sie den Upgrade-Pfad an (siehe Plan-Upgrade und Guthaben), niemals eine erneute Ausführung.

Kostenloser Plan [free-limit]-Pausen – zwei davon, beide bevor etwas berechnet wird:

  • 30-Sekunden-Vorschau. Eine Synchronisations-/Lippensynchronisations-Eingabe, die länger als 30 s ist, stoppt mit [free-limit]-Zeilen: Bei Kostenlos würde nur die erste 30 Sekunden synchronisiert, der Rest weggelassen. Geben Sie die Frage weiter, und bei einem Ja führen Sie den gleichen Befehl mit --allow-preview erneut aus (der Worker schneidet die ersten 30 s lokal zu und übermittelt nur diesen Teil). Ein von Perso importierter Plattformlink kann nicht zugeschnitten werden – dort ist die Antwort eine lokale Datei, ein kürzerer Clip oder ein Upgrade.
  • Über dem Planlimit. Medien, die das Längen-/Größenlimit des Plans überschreiten, erhalten kein Aufteilungsangebot bei Kostenlos (--allow-split gilt nicht): Die [free-limit]-Zeilen besagen, dass eine kürzere Datei oder ein Upgrade die einzige Möglichkeit ist. Geben Sie sie weiter und stoppen Sie.

Während der Ausführung (zur Erklärung der Wartezeit):

  • Aufteilung: Die gesamte Datei wird zuerst hochgeladen; nur eine Ablehnung aufgrund des Planlimits installiert ffmpeg und teilt verlustfrei auf. Externe URLs (YouTube·TikTok·Drive·Vimeo) werden serverseitig verarbeitet.
  • Warteschlange: Alle Eingaben × Teile × Sprachen teilen sich einen Pool; eine volle Warteschlange wird alle 5 Minuten erneut überprüft. Ein Motorfehler bei einem Teil bricht die anderen Sprachen dieses Teils ab; ein stiller Teil übergibt das Original; eine Leerlaufsicherung verhindert Endlosschleifen.
  • Speichern: Teile werden wieder zu einer Datei pro (Eingabe × Sprache) zusammengeführt. Ein nicht aufgeteiltes Ausgabe behält den Perso-Dateinamen; ein zusammengeführtes ist <ursprünglicher-Name>.dubbed.<lang>.<ext>; Kollisionen erhalten _2,_3….

Lippenbewegungen

Lippenbewegungen (Mund an die synchronisierte Audiospur angepasst) werden nach der Synchronisation am abgeschlossenen Synchronisationsprojekt durchgeführt. Nur Video – Audioeingaben werden abgelehnt. Es ist eine lange Aufgabe: im Hintergrund ausführen und dem Benutzer vorab mitteilen, dass es erheblich länger dauert als die Synchronisation. Guthaben (Serverabrechnung ist maßgeblich): Synchronisation ≈ Sekunden ×1 · Lippenbewegungen ≈ ×2 · beides ≈ ×3 – Synchronisation jetzt + Lippenbewegungen später kosten das gleiche wie beides gleichzeitig. 4K+-Quellen: Jeder Satz ×3 auf Pro/Business/Enterprise-Plänen (z.B. eine 1-minütige 4K-Synchronisation+Lippenbewegung ≈ 60×3×3 = 540) – erwähnen Sie dies, wenn das Video 4K ist.

Wählen Sie den Ablauf basierend auf dem, was existiert:

  1. Neues Video + Lippenbewegungen – ein Befehl führt die gesamte Kette aus (Synchronisation → Lippenbewegungen → Speichern); warnen Sie, dass beide Phasen abgerechnet werden: node scripts/dubbing.mjs "<Datei|URL>" --target en --lipsync Wenn [credit-check]-Zeilen ausgegeben werden und es stoppt, übersteigt die Schätzung das verbleibende Guthaben: Zeigen Sie diese Zeilen (die Aufladungs-URL ist enthalten) und führen Sie erneut mit --force nur aus, nachdem der Benutzer aufgeladen oder die Fortsetzung trotzdem genehmigt hat.
  2. Bereits früher in dieser Sitzung synchronisiert – jeder abgeschlossene Lauf gibt eine [project-ref] {...}-Zeile aus. Behalten Sie sie; zeigen Sie sie dem Benutzer niemals an. Lippenbewegungen ohne erneute Synchronisation (×2, keine Synchronisationsgebühr): node scripts/dubbing.mjs --lipsync-only '<das [project-ref] JSON>'
  3. Kein [project-ref] in dieser Sitzung – fragen Sie, ob der Benutzer die Projektnummer aus dem Perso-Portal kennt (--lipsync-only <Nummer>, ×2). Andernfalls muss das Video erneut synchronisiert werden (--lipsync, ×3) – bestätigen Sie vor der erneuten Synchronisation.

Regeln:

  • Wiederholte Lippenbewegungen am selben Projekt werden erneut abgerechnet (keine serverseitige Deduplizierung). Wenn diese Sitzung bereits lippensynchronisiert wurde, verweisen Sie auf die vorhandene Datei und führen Sie nur bei expliziter Bestätigung erneut aus.
  • Wenn Lippenbewegungen fehlschlagen, speichert der Worker stattdessen das synchronisierte Video und teilt dies im Abschlussbericht mit – geben Sie das klar weiter; die Synchronisationsguthaben sind nicht verschwendet.
  • Guthaben zwischen Synchronisation und Lippenbewegungen aufgebraucht: Die synchronisierten Videos werden gespeichert, und die Fortsetzung beendet nur die Lippenbewegungen – geben Sie die Aufladungs-URL weiter und setzen Sie über den [resume-state]-Pfad fort, sobald bezahlt (siehe Unterbrechung und Fortsetzung).

Sprecher (nur Synchronisationsprojekte)

Um einen neuen Sprecher einem oder mehreren Sätzen eines bereits synchronisierten Projekts zuzuweisen, führen Sie aus:

node scripts/speaker.mjs "<Projekt-URL|projektSeq>" --at "5s,22s,98s" (kommagetrennte Zeitcodes/-bereiche) node scripts/speaker.mjs "<Projekt-URL|projektSeq>" --text "erste Zeile|zweite Zeile" (pipe-getrennt, zitierter Text) node scripts/speaker.mjs "<Projekt-URL|projektSeq>" --sentence 1234,1288 (erneute Ausführung nach einer [sentence-select]-Frage) node scripts/speaker.mjs "<Projekt-URL|projektSeq>" --list (Projektsätze durchsuchen, um das richtige Ziel zu finden)

Nur Synchronisationsprojekte – der Worker lehnt Untertitel (STT), Audioseparations- und Lippenbewegungsprojekte sowie unvollständige/fehlgeschlagene ab. Er ermittelt den Arbeitsbereich automatisch aus dem Projektlink; Sie müssen nicht nach dem Bereich fragen.

Eine Pause ist kein Fehler. Eine [sentence-select]-Zeile bedeutet, dass der Worker kein einzelnes Ziel identifizieren konnte (nichts wurde angegeben, nichts stimmte überein oder mehr als ein Satz stimmte überein) – er beendet sich sauber, um Sie etwas zu fragen, nicht weil er fehlgeschlagen ist. Die nummerierte Liste darunter (Index, Zeitmarke, Text) kann gefahrlos wie besehen an den Benutzer weitergegeben werden. Direkt nach dieser Liste gibt eine [sentence-ref]-Zeile eine JSON-Zuordnung derselben Nummern zu den internen Satznummern des Workers aus – diese Zeile ist nur für Ihre eigene Suche: zeigen Sie sie niemals an und lesen Sie sie nicht vor. Sobald der Benutzer eine Nummer auswählt, suchen Sie sie in dieser Zuordnung nach und führen Sie denselben Befehl mit --sentence auf diesen Wert gesetzt erneut aus. Ein [speaker-resolve]-Block daneben bedeutet, dass einige Ziele bereits aufgelöst wurden, aber noch nichts geschrieben wurde – er hat seine eigene nummerierte Liste und seine eigene [sentence-ref]-Zeile; die --sentence-Liste der erneuten Ausführung muss sowohl diese bereits aufgelösten Werte als auch die neu ausgewählten enthalten, da die aufgelösten sonst fallen gelassen würden. Wenn ein Lauf mehr als eine [sentence-select]-Gruppe ausgibt (mehrere mehrdeutige Ziele gleichzeitig), enthält jede Gruppe …

[abgeschnitten für Übersetzung]

Individual skills in this repo

This repo contains 3 individual skills — each has its own dedicated page.

Verwandte Skills