Mit jedem Chatten
Klone die Stimme einer realen Person aus einem Online-Video oder erstelle eine Stimme aus einem Foto und spiele dann die Rolle dieser Person mittels TTS.
Wichtig: Ethische Nutzung & Urheberrecht
Diese Fertigkeit synthetisiert Sprache, die echte Stimmen imitiert. Bevor der Agent fortfährt, muss er:
- Niemanden zur Täuschung, Betrug oder Belästigung imitieren.
- Nur öffentlich zugängliche Medien (öffentliche Reden, Interviews, Pressekonferenzen) als Referenzaudio verwenden.
- Den Benutzer informieren, dass das generierte Audio synthetisch ist und nicht als echte Aufnahme präsentiert werden darf.
- Anfragen ablehnen, die auf Privatpersonen ohne Einwilligung abzielen oder offensichtlich der Täuschung, Belästigung oder Verleumdung dienen.
Wenn die Absicht des Benutzers schädlich erscheint, lehne höflich ab und erkläre den Grund.
Voraussetzungen
| Abhängigkeit | Typ | Wie überprüfen |
|---|---|---|
ffmpeg | System-Binärdatei | ffmpeg -version |
yt-dlp | System-Binärdatei | yt-dlp --version |
tts-Skill | Cursor-Skill | ls skills/tts/scripts/tts.py |
NOIZ_API_KEY | Umgebungsvariable oder Datei | python3 skills/tts/scripts/tts.py config --show |
Vor dem ersten Durchlauf überprüfe alle Abhängigkeiten:
ffmpeg -version && yt-dlp --version && ls skills/tts/scripts/tts.py
Falls yt-dlp fehlt, installiere es:
uv pip install yt-dlp
Falls der Noiz-API-Schlüssel nicht konfiguriert ist:
python3 skills/tts/scripts/tts.py config --set-api-key YOUR_KEY
Modusauswahl
- Benutzer nennt eine Person (real oder fiktiv) --> Arbeitsablauf A
- Benutzer stellt ein Bild bereit, Person nicht erkennbar --> Arbeitsablauf B
- Benutzer stellt ein Bild bereit, Person ist erkennbare öffentliche Figur --> Arbeitsablauf A (echte Stimme ist authentischer)
- Mehrere Personen im Bild --> Frage zuerst, welche Person gemeint ist
Arbeitsablauf A: Namensbasiert (Stimme aus Online-Video)
Verfolge den Fortschritt mit dieser Checkliste:
- [ ] A1. Charakter eindeutig identifizieren
- [ ] A2. Referenzvideo finden
- [ ] A3. Audio + Untertitel herunterladen
- [ ] A4. Bestes Referenzsegment extrahieren
- [ ] A5. Sprache generieren
A1. Charakter eindeutig identifizieren
Wenn die Angabe mehrdeutig ist (z. B. „US-Präsident“, „Spider-Man-Darsteller“), frage den Benutzer, bevor du fortfährst.
A2. Ein Referenzvideo finden
Verwende eine Websuche, um ein YouTube- (oder Bilibili-)Video zu finden, in dem die Person deutlich spricht. Geeignet sind: Interviews, Reden, Pressekonferenzen. Vermeide Videos mit starker Hintergrundmusik.
Suchabfragen zum Ausprobieren:
{CHARACTER_NAME} Interview/{CHARACTER_NAME} 采访{CHARACTER_NAME} Rede/{CHARACTER_NAME} 演讲{CHARACTER_NAME} Pressekonferenz
A3. Audio und Untertitel herunterladen
mkdir -p "tmp/chat_with_anyone/{CHARACTER_NAME}"
yt-dlp -x --audio-format mp3 \
--write-subs --write-auto-subs --sub-langs "de,en,zh-Hans" \
--convert-subs srt \
-o "tmp/chat_with_anyone/{CHARACTER_NAME}/%(title)s.%(ext)s" \
"{VIDEO_URL}"
Nach dem Herunterladen liste das Ausgabeverzeichnis auf, um die Audiodatei und die SRT-Untertiteldatei zu identifizieren:
ls tmp/chat_with_anyone/{CHARACTER_NAME}/
Erwartete Ausgabe: eine .mp3-Audiodatei und eine oder mehrere .srt-Untertiteldateien.
Falls keine Untertiteldateien erscheinen: versuche ein anderes Video mit automatisch generierten Untertiteln oder passe --sub-langs für die Zielsprache an.
A4. Bestes Referenzsegment extrahieren
Verwende das automatische Extraktionsskript – es analysiert die SRT-Datei, findet das dichteste Sprachfenster von 3–12 Sekunden und extrahiert es als WAV:
python3 skills/chat-with-anyone/scripts/extract_ref_segment.py \
--srt "tmp/chat_with_anyone/{CHARACTER_NAME}/{SRT_FILE}" \
--audio "tmp/chat_with_anyone/{CHARACTER_NAME}/{AUDIO_FILE}" \
-o "tmp/chat_with_anyone/{CHARACTER_NAME}/ref.wav"
Das Skript gibt den ausgewählten Zeitbereich aus und speichert die Referenz-WAV-Datei. Überprüfe, ob die Ausgabedatei existiert und nicht leer ist, bevor du fortfährst.
Falls das Skript kein geeignetes Segment meldet: versuche --min-duration 2 für kürzere Ausschnitte oder lade ein anderes Video herunter.
A5. Sprache generieren und Rollenspiel durchführen
Schreibe eine Antwort im Charakter und synthetisiere sie:
python3 skills/tts/scripts/tts.py \
-t "{RESPONSE_TEXT}" \
--ref-audio "tmp/chat_with_anyone/{CHARACTER_NAME}/ref.wav" \
-o "tmp/chat_with_anyone/{CHARACTER_NAME}/reply.wav"
Präsentiere die generierte Audiodatei zusammen mit dem Text dem Benutzer. Verwende für spätere Nachrichten denselben --ref-audio-Pfad.
Arbeitsablauf B: Bildbasiert (Stimme aus Foto)
Verfolge den Fortschritt mit dieser Checkliste:
- [ ] B1. Bild analysieren
- [ ] B2. Stimme entwerfen
- [ ] B3. Vorschau (optional)
- [ ] B4. Sprache generieren
B1. Das Bild analysieren
Nutze deine Bildverarbeitungsfähigkeit, um das Bild zu untersuchen:
- Falls die Person eine erkennbare öffentliche Figur ist --> wechsle zu Arbeitsablauf A für eine authentische Stimme.
- Falls nicht erkennbar, erstelle eine Stimmbeschreibung mit:
- Geschlecht (männlich / weiblich)
- Ungefähres Alter (z. B. „ungefähr 30 Jahre alt“)
- Erscheinungsmäßiges Auftreten (z. B. fröhlich, autoritär, sanft)
- Kontexthinweise (z. B. Anzug --> professioneller Ton; Sportkleidung --> energisch)
B2. Die Stimme entwerfen
Übergebe sowohl das Bild als auch die Beschreibung an das Stimmentwurfsskript:
python3 skills/chat-with-anyone/scripts/voice_design.py \
--picture "{IMAGE_PATH}" \
--voice-description "{VOICE_DESCRIPTION}" \
-o "tmp/chat_with_anyone/voice_design"
Das Skript gibt aus:
- Erkannte Stimmmerkmale (auf stdout)
- Vorschau-Audiodateien im Ausgabeverzeichnis
voice_id.txtmit der besten Stimmen-ID
Lese die Stimmen-ID:
cat tmp/chat_with_anyone/voice_design/voice_id.txt
B3. Vorschau (Optional)
Präsentiere die Vorschau-Audiodateien aus dem Ausgabeverzeichnis, damit der Benutzer die Stimme hören kann. Falls nicht zufrieden, führe B2 mit angepasster --voice-description oder --guidance-scale erneut aus.
B4. Sprache generieren und Rollenspiel durchführen
python3 skills/tts/scripts/tts.py \
-t "{RESPONSE_TEXT}" \
--voice-id "{VOICE_ID}" \
-o "tmp/chat_with_anyone/voice_design/reply.wav"
Verwende für spätere Nachrichten zur Konsistenz dieselbe --voice-id.
Beispiel: Namensbasiert
Benutzer: Ich möchte mit Donald Trump chatten und ihn bitten, mir eine Gute-Nacht-Geschichte zu erzählen.
Agent-Schritte:
- Charakter: Donald Trump. Keine Disambiguierung nötig.
- Suche
Donald Trump Rede YouTube, finde ein klares Redevideo. - Herunterladen:
yt-dlp -x --audio-format mp3 --write-subs --write-auto-subs --sub-langs "en" --convert-subs srt -o "tmp/chat_with_anyone/trump/%(title)s.%(ext)s" "https://youtube.com/watch?v=..." - Referenz extrahieren:
python3 skills/chat-with-anyone/scripts/extract_ref_segment.py --srt "tmp/chat_with_anyone/trump/....srt" --audio "tmp/chat_with_anyone/trump/....mp3" -o "tmp/chat_with_anyone/trump/ref.wav" - TTS im Trump-Stil generieren:
python3 skills/tts/scripts/tts.py -t "Let me tell you a tremendous bedtime story..." --ref-audio "tmp/chat_with_anyone/trump/ref.wav" -o "tmp/chat_with_anyone/trump/reply.wav" reply.wavund den Geschichtentext dem Benutzer präsentieren.
Beispiel: Bildbasiert
Benutzer: [lädt photo.jpg hoch] Ich möchte mit der Person auf diesem Bild chatten.
Agent-Schritte:
- Bildanalyse: nicht erkennbare junge Frau, ~25, lässiger Pullover, warmes Lächeln.
- Stimme entwerfen:
python3 skills/chat-with-anyone/scripts/voice_design.py --picture "photo.jpg" --voice-description "Eine junge chinesische Frau um die 25, sanfte und warme Stimme, freundlicher Ton" -o "tmp/chat_with_anyone/voice_design" - Stimmen-ID aus
tmp/chat_with_anyone/voice_design/voice_id.txtlesen. - TTS generieren:
python3 skills/tts/scripts/tts.py -t "Hallo! Schön, dich kennenzulernen!" --voice-id "{VOICE_ID}" -o "tmp/chat_with_anyone/voice_design/reply.wav" - Audio präsentieren und Rollenspiel mit derselben
--voice-idfortsetzen.
Fehlerbehebung
| Problem | Lösung |
|---|---|
yt-dlp-Download fehlgeschlagen oder Video nicht verfügbar | Versuche eine andere Video-URL; manche Regionen/Videos sind eingeschränkt. Führe yt-dlp -U aus, um zu aktualisieren |
| Keine SRT-Untertiteldateien | Lade mit --sub-lang de,en,zh-Hans erneut herunter; falls immer noch keine, versuche ein anderes Video mit automatischen Untertiteln |
extract_ref_segment.py findet kein geeignetes Fenster | Verwende --min-duration 2 für kürzere Ausschnitte oder probiere ein anderes Video |
| Stimmentwurf gibt Fehler zurück | Überprüfe den Noiz-API-Schlüssel; stelle sicher, dass das Bild ein klares Foto einer Person ist |
| TTS-Ausgabe klingt falsch | Für Arbeitsablauf A versuche ein anderes Referenzvideo; für Arbeitsablauf B passe --voice-description an |