agentsclimarketplace

Voice clone

Skill puntorigen/avatar-skills/voice-clone

Clone a narrator's voice from a clean voice audio file using MiniMax voice-cloning on Replicate, then generate new speech (TTS) in that cloned voice with MiniMax speech-2.8-hd. Cloning takes the clean voice MP3/WAV (e.g. voice_concat.mp3 from the voice-isolate skill), trains a voice (default speech-2.6-hd) and saves voice_id + a preview under <avatar>/voices/<name>.json. Generation reuses the avatar's trained voice (or trains one if missing), auto-detects the text language for MiniMax's language_boost, supports per-line emotion and expressive interjections ((laughs), (sighs), …) plus manual <#x#> pauses, and saves audio under <avatar>/generated-audios/ with a manifest.json. Use when the user wants to clone a voice, create/train a TTS voice, get a voice_id, or GENERATE speech / narration / audio in a cloned voice, or mentions "clonar la voz", "voice clone", "voice_id", "entrenar la voz", "generar audio", "text to speech", or "TTS con la voz".From its SKILL.md

Install
npx -y skills add puntorigen/avatar-skills --skill voice-clone

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

SKILL.md

8.8 KB, ~2.2k tokens by cl100k_base, as published. Nobody here has run it

Voice Clone

Two capabilities, one skill:

  1. Clone a narrator's voice with MiniMax voice-cloning → a reusable voice_id saved in the avatar folder.
  2. Generate new speech in that cloned voice with MiniMax speech-2.8-hd, saved under <avatar>/generated-audios/ with a manifest.

The clone input is a clean voice file — ideally voice_concat.mp3 produced by the voice-isolate skill.

Requirements

  • pip3 install -r requirements.txt (replicate client + langid for language detection).
  • A Replicate API token. It is shared with the other Replicate skills (avatar-video-reel, gpt-image-2, bg-music, …) and discovered automatically. To set/refresh it: python3 scripts/setup_key.py YOUR_REPLICATE_API_TOKEN.
  • The voice file must be MP3/M4A/WAV, 10s–5min, <20MB.
  • A local tunnel — cloudflared (preferred) or ngrok — installed on PATH (only for cloning, not for generation). brew install cloudflared (no account needed) or ngrok config add-authtoken <token> once. See How the upload works below.

How the upload works

minimax/voice-cloning re-fetches the audio from MiniMax's own servers, so it needs a public URL with a real extension — a raw file object or Replicate's auth-protected upload both fail with invalid file ext. To avoid uploading your voice to a third party, the skill serves the file straight from your machine over a short-lived tunnel that is torn down as soon as the clone finishes:

  1. Prefer cloudflared quick tunnel (no account, ephemeral per-run URL), then fall back to ngrok, then — only if neither is installed — a temporary public host (tmpfiles.org / catbox.moe).
  2. Reachability is verified the way MiniMax sees it: if the local resolver blocks the tunnel domain (some ISPs filter *.trycloudflare.com), it re-checks via public DNS (1.1.1.1 / 8.8.8.8) so a blocked local resolver is not mistaken for an unreachable URL.

Clone a voice

python3 scripts/clone_voice.py <video>_voice/voice_concat.mp3

That's it — everything else is auto:

  • Model: speech-2.6-hd by default (the current HD model; MiniMax may serve it on a newer HD engine). Override with --model (speech-2.6-turbo, speech-02-hd, speech-02-turbo).
  • Defaults match the model: --accuracy 0.7, noise reduction off, volume normalization off (the input is already clean). Flags: --noise-reduction, --volume-normalization.
  • Where it saves (auto-inferred):
    • Source name: if the file is <stem>_voice/voice_concat.mp3 → <stem>; otherwise the file's own stem. Override with --name.
    • Avatar dir: the folder containing a videos/ directory (e.g. lolo/). Override with --avatar-dir.

Output (in <avatar>/voices/)

FileWhat it is
<name>.jsonThe record: voice_id, model, source, preview_url, created_at
<name>_preview.mp3Preview clip of the cloned voice (skip with --no-preview)
index.jsonRegistry mapping every name → voice_id for this avatar

The voice_id is what you pass to MiniMax text-to-speech to synthesize new speech in this cloned voice — which is exactly what generate_speech.py does.

Report the voice_id and the path to <name>.json when done.

Generate speech (TTS)

Synthesize new audio in the avatar's cloned voice with minimax/speech-2.8-hd.

# Reuse the avatar's trained voice (auto-detects language, here Spanish):
python3 scripts/generate_speech.py "Hola, soy Lolo" --avatar-dir lolo

# Train automatically first if the avatar has no voice yet:
python3 scripts/generate_speech.py "Hello!" --source lolo/videos/clip_voice/voice_concat.mp3

# Pick an emotion explicitly:
python3 scripts/generate_speech.py "Great news!" --avatar-dir lolo --emotion happy

Voice resolution (automatic):

  1. --voice-id if given.
  2. Else the avatar's already-trained voice (<avatar>/voices/). With one trained voice it's picked automatically; with several, pass --name.
  3. Else, if --source is given, it trains one first (a clean voice file, or a video whose <stem>_voice/voice_concat.mp3 exists), then generates.
  4. Else it errors asking for --source or --voice-id.

Key options:

  • --emotion (default auto): auto, happy, sad, angry, fearful, disgusted, surprised, calm, fluent, neutral. The agent should choose one that fits the line when appropriate.
  • language_boost defaults to None (no boost) so the cloned voice keeps its own accent. Boosting a language nudges pronunciation toward a "standard"/regional accent that can fight the clone — e.g. a neutral or Chilean voice drifting into Argentinian voseo. Pass --language-boost detect to auto-detect from the text (Unicode script for CJK/Cyrillic/Arabic/… + langid for Latin scripts), or a locale (Spanish, English, …) only when you specifically need that pronunciation help.
  • Audio: --speed, --volume, --pitch, --audio-format (mp3/wav/flac/pcm), --sample-rate, --bitrate, --channel, --english-normalization.
  • Text: pass inline or via --text-file script.txt.

Expressive interjections & pauses

speech-2.8-hd renders expressive interjections written inline in the text, so the voice doesn't sound flat. Drop them right where they happen:

python3 scripts/generate_speech.py "Lo logramos (laughs softly)… (sighs) y por fin puedo soltar." --avatar-dir lolo
  • Recognized (common, reliably-rendered) set: (laughs), (laughs softly), (chuckles), (giggles), (sighs), (gasps), (coughs), (clears throat), (sneezes), (sniffs), (groans), (yawns), (whistles), (humming), (hums), (exhales), (inhales), (breathes), (gulps), (crying), (sobs), (screams), (applause). The model recognizes 20+; run python3 scripts/generate_speech.py --list-interjections to print them.
  • The script logs the interjections it detects and warns about any other parenthesized text (which may otherwise be read out literally). Detected interjections are recorded in manifest.json per clip.
  • Manual pauses: <#x#> inserts x seconds of silence (0.01–99.99), e.g. "Respira hondo <#0.6#> y continúa." — useful for beats and emphasis.
  • Use interjections sparingly — one or two per passage reads as natural; overusing them sounds theatrical. Pair with --emotion for the overall tone.

Long narrations: synthesize per sentence

The model degrades on very long single takes (its own docs recommend short sentences for smoother delivery). For multi-paragraph scripts, synthesize one sentence at a time and join the clips rather than sending everything in one call. The avatar-reel-composer skill's narrate.py does exactly this (one MiniMax call per sentence + a small silence gap); reuse that flow for reels.

Output (in <avatar>/generated-audios/)

FileWhat it is
<NNN>_<slug>.<ext>The generated audio clip (auto-numbered)
manifest.jsonitems[] mapping each file → text, voice_id, voice_name, emotion, language_boost, and synth params

Report the audio path, the voice_id used, and the detected language_boost.

Notes

  • One clone per source recording: re-running with the same name overwrites its record and updates index.json.
  • The clone quality depends on the input. Use the clean, SFX-free voice_concat.mp3 from voice-isolate for best results; keep --noise-reduction off when the audio is already clean.
  • Generation never re-uploads the voice sample (it only sends the voice_id + text), so it needs no tunnel and is fast.
  • A trained voice_id works across MiniMax speech models, so the voice trained with speech-2.6-hd is used for speech-2.8-hd generation.

What ships with it: 6 files

53.8 KB alongside SKILL.md, 5 of them executable

scripts/

Keep looking

Skills are one crate of 325,949. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.