Los videos cortos para TikTok, Reels, YouTube Shorts y las páginas de producto de los marketplaces necesitan narración, y grabar cada guion usted mismo lleva tiempo. Los servicios de texto a voz en línea cobran por carácter y exigen subir sus guiones. Kokoro es un modelo de voz de pesos abiertos con voces de sonido natural, lo bastante pequeño para ejecutarse en un servidor con CPU convencional. Esta guía explica cómo instalarlo, le ayuda a elegir voces, convierte archivos de guion en locuciones WAV con subtítulos SRT sincronizados, resuelve las palabras en inglés dentro de una narración en chino y prepara el audio para subirlo.
# Debian 12 / Ubuntu 22.04 or 24.04 (Kokoro needs Python 3.10 to 3.12)
apt install -y python3-venv espeak-ng ffmpeg
python3 -m venv /opt/tts
/opt/tts/bin/pip install --upgrade pip
/opt/tts/bin/pip install torch --index-url https://download.pytorch.org/whl/cpu # CPU-only build, much smaller
/opt/tts/bin/pip install kokoro soundfile "misaki[zh]"
# Japanese voices additionally need:
/opt/tts/bin/pip install "misaki[ja]"
/opt/tts/bin/python -m unidic download # Japanese dictionary, about 500 MB
Si el Python de su sistema es la versión 3.13 o posterior (por ejemplo, en Debian 13), cree el entorno con Python 3.12 mediante uv; --seed añade pip, de modo que todos los comandos siguientes siguen siendo los mismos:
curl -LsSf https://astral.sh/uv/install.sh | sh
~/.local/bin/uv venv --seed -p 3.12 /opt/tts
/opt/tts/bin/pip install torch --index-url https://download.pytorch.org/whl/cpu
/opt/tts/bin/pip install kokoro soundfile "misaki[zh]"
El modelo (unos 330 MB) y cada voz se descargan de Hugging Face la primera vez que se usan.
| Código | Idioma | Voces de ejemplo |
|---|---|---|
| a | Inglés estadounidense | af_heart, af_bella, am_michael, am_adam |
| b | Inglés británico | bf_emma, bf_isabella, bm_george, bm_daniel |
| z | Chino mandarín | zf_xiaobei, zf_xiaoni, zm_yunxi, zm_yunjian |
| j | Japonés | jf_alpha, jf_nezumi, jm_kumo |
| e | Español | ef_dora, em_alex |
| f | Francés | ff_siwis |
| i | Italiano | if_sara, im_nicola |
| p | Portugués de Brasil | pf_dora, pm_alex |
| h | Hindi | hf_alpha, hm_omega |
La primera letra del nombre de una voz indica su idioma, y la segunda, si es femenina (f) o masculina (m). Kokoro no habla coreano, ruso, tailandés, vietnamita ni malayo; para esos mercados, use subtítulos u otro motor de voz.
cat > /opt/tts/tts.py <<'EOF2'
import os, sys
import numpy as np
import soundfile as sf
from kokoro import KPipeline
LANG = os.environ.get("TTS_LANG", "a") # a = US English, z = Mandarin Chinese, j = Japanese ...
VOICE = os.environ.get("TTS_VOICE", "af_heart")
SPEED = float(os.environ.get("TTS_SPEED", "1.0"))
PAUSE = float(os.environ.get("TTS_PAUSE", "0.3")) # seconds of silence after each line
RATE = 24000
def ts(t):
ms = int(round(t * 1000))
h, ms = divmod(ms, 3600000)
m, ms = divmod(ms, 60000)
s, ms = divmod(ms, 1000)
return f"{h:02d}:{m:02d}:{s:02d},{ms:03d}"
pipeline = KPipeline(lang_code=LANG, repo_id="hexgrad/Kokoro-82M")
for path in sys.argv[1:]:
lines = [l.strip() for l in open(path, encoding="utf-8") if l.strip()]
parts, srt, pos = [], [], 0
for i, line in enumerate(lines, 1):
show, _, say = line.partition("|") # "subtitle text|text to speak" (optional)
chunks = [np.asarray(a, dtype=np.float32) for _, _, a in pipeline(say or show, voice=VOICE, speed=SPEED)]
audio = np.concatenate(chunks) if chunks else np.zeros(RATE // 2, dtype=np.float32)
srt.append(f"{i}\n{ts(pos / RATE)} --> {ts((pos + len(audio)) / RATE)}\n{show.strip()}\n")
silence = np.zeros(int(PAUSE * RATE), dtype=np.float32)
parts += [audio, silence]
pos += len(audio) + len(silence)
base = os.path.splitext(path)[0]
sf.write(base + ".wav", np.concatenate(parts), RATE)
with open(base + ".srt", "w", encoding="utf-8") as f:
f.write("\n".join(srt))
print(f"{path}: {len(lines)} lines, {pos / RATE:.1f}s -> {base}.wav, {base}.srt", flush=True)
EOF2
Cada línea de un archivo de texto se convierte en una frase de la narración y en un subtítulo. El script genera, junto al archivo de texto, un archivo WAV y un archivo SRT cuyos tiempos coinciden exactamente. El idioma, la voz, la velocidad y la pausa entre líneas se configuran con variables de entorno.
mkdir -p /data/voice && cd /data/voice
cat > demo.txt <<'EOF2'
这款竹制笔记本支架有六档高度可调。
支持 USB-C 接口和 iPhone。|支持 优艾斯比西 接口和爱疯。
折叠后可以放进背包,重量只有一点一公斤。
EOF2
TTS_LANG=z TTS_VOICE=zf_xiaobei /opt/tts/bin/python /opt/tts/tts.py demo.txt
# English: TTS_LANG=a TTS_VOICE=af_heart Japanese: TTS_LANG=j TTS_VOICE=jf_alpha
En nuestras pruebas, las voces en chino leyeron correctamente números como 39.9 o 2026, pero omitieron o pronunciaron mal palabras en alfabeto latino como USB-C o iPhone. Para esas líneas, escriba primero el texto del subtítulo, después | y el texto que se debe pronunciar, como en la segunda línea del ejemplo anterior: el subtítulo muestra el nombre correcto del producto, mientras que la voz lee la versión fonética. El mismo truco sirve para los nombres de marca en japonés (escríbalos en katakana después de |).
# Render the same text with several voices to compare them
for v in zf_xiaobei zf_xiaoni zm_yunxi zm_yunjian; do
cp demo.txt "try-$v.txt"
TTS_LANG=z TTS_VOICE=$v /opt/tts/bin/python /opt/tts/tts.py "try-$v.txt"
done
# Slightly faster speech and shorter pauses, typical for short videos
TTS_LANG=z TTS_VOICE=zm_yunxi TTS_SPEED=1.1 TTS_PAUSE=0.2 /opt/tts/bin/python /opt/tts/tts.py demo.txt
Descargue los archivos WAV y escúchelos en un teléfono, que es donde los oirá la mayoría de los espectadores. Las frases cortas con comas en lugares naturales suenan mucho mejor que las largas y complejas.
# Normalise loudness to about -14 LUFS (common for short-video platforms) and make an MP3
ffmpeg -i demo.wav -af loudnorm=I=-14:TP=-1.5 -ar 48000 -ac 2 demo-final.wav
ffmpeg -i demo-final.wav -c:a libmp3lame -q:a 2 demo.mp3
Importe el audio y demo.srt en su editor de video, o deje que un script cree el video completo a partir de fotos, voz y subtítulos, como se describe en crear videos cortos de producto automáticamente. Para convertir un video existente a otro idioma, consulte doblar videos a otro idioma con IA.
Kokoro es un modelo pequeño. En un servidor multinúcleo moderno suele generar la voz más rápido que en tiempo real, de modo que una locución de un minuto tarda bastante menos de un minuto una vez cargado el modelo. La velocidad depende de la CPU y de la longitud del texto.
Kokoro solo ofrece sus voces integradas. La clonación de voz requiere otros modelos, normalmente con GPU. Clone voces únicamente con el consentimiento explícito de la persona que habla y siga las normas de cada plataforma sobre contenido sintético.
En el momento de redactar esta guía, el código y el modelo de Kokoro se publican bajo la licencia Apache 2.0, que permite el uso comercial. Compruebe la licencia vigente en la página del proyecto antes de basarse en ella y siga las normas de las plataformas para el contenido generado por IA.
El inglés y varios otros idiomas usan espeak-ng para las palabras que no están en el diccionario. Asegúrese de que el paquete espeak-ng del paso 1 esté instalado y vuelva a ejecutar el script.
¿Sigue sin resolverlo después de seguir estos pasos? Abra un ticket de soporte y el equipo técnico de IMIDC, disponible 24/7, le ayudará. Incluya la IP del servidor, el sistema operativo y la versión de Python, el comando que ejecutó y la salida completa del error para que podamos localizar el problema más rápido.