ElevenLabs TTS a MP3
Convierte texto de guiones a locuciones MP3 mediante la API de texto a voz de ElevenLabs.
Valores predeterminados
- ID de voz:
K7ewtjKRNtwwt3lKQ6M0(voz de marca de Hoang — fija) — se puede sobrescribir medianteELEVENLABS_VOICE_IDen entorno o--voice_id - Modelo:
eleven_v3(el más expresivo, compatible con etiquetas de audio como [excited], [whisper], [laugh]; ideal para contenido narrativo) — se puede sobrescribir mediante--model_id. Alternativas:eleven_multilingual_v2(alta calidad, más lento),eleven_turbo_v2_5(rápido, ligeramente plano),eleven_flash_v2_5(el más rápido) - Formato de salida:
mp3_44100_128(44,1 kHz / 128 kbps) — se puede sobrescribir mediante--output_format - Ajustes de voz:
stability=0,5,similarity_boost=0,75,style=0,use_speaker_boost=true(valores predeterminados de ElevenLabs) - Mapa de pronunciación: se carga automáticamente desde
assets/vn-pronunciation-map.json— desactivar con--no-pronounce-map, o apuntar a otro archivo con--pronounce-map path.json - Límite de caracteres: 5000 por solicitud (límite estricto de ElevenLabs). Texto > 5000 caracteres → el script sale con error y pide al usuario que divida manualmente.
Uso rápido
Desde archivo
uv run .claude/skills/mkt-elevenlabs-tts-to-mp3/scripts/text_to_mp3.py \
--file ruta/al/guion.txt \
-o workspace/content/YYYY-MM-DD/locucion.mp3
Desde texto directo
uv run .claude/skills/mkt-elevenlabs-tts-to-mp3/scripts/text_to_mp3.py \
"Xin chào các bạn, hôm nay mình chia sẻ về AI Agent" \
-o workspace/assets/elevenlabs/ejemplo.mp3
Voz / modelo personalizado
uv run .claude/skills/mkt-elevenlabs-tts-to-mp3/scripts/text_to_mp3.py \
--file guion.txt \
--voice_id K7ewtjKRNtwwt3lKQ6M0 \
--model_id eleven_turbo_v2_5 \
-o salida.mp3
Ajustar expresividad de la voz
uv run .claude/skills/mkt-elevenlabs-tts-to-mp3/scripts/text_to_mp3.py \
--file guion.txt \
--stability 0.4 \
--similarity_boost 0.8 \
--style 0.2 \
-o salida.mp3
Ajustes de voz — cuándo modificarlos
| Ajuste | Rango | Efecto |
|---|---|---|
stability | 0,0–1,0 | Más alto = más monótono/predecible; más bajo = más emocional/variable. 0,5 es el punto ideal para narración. Baja a 0,3–0,4 para ganchos casuales; sube a 0,7+ para explicaciones formales. |
similarity_boost | 0,0–1,0 | Qué tan cerca clonar la voz de referencia. 0,75 predeterminado. Sube hacia 0,9 si la voz suena "diferente" al original. |
style | 0,0–1,0 | Exageración de estilo. 0 predeterminado. Añade latencia cuando > 0. Útil (0,1–0,3) para contenido expresivo. |
use_speaker_boost | booleano | Afina la similitud del hablante. Mantén true para consistencia de la voz de marca. |
Mapa de pronunciación (corrección de palabras en inglés)
Los modelos multilingües de ElevenLabs intentan leer todo el texto en el idioma dominante. En un guion vietnamita, palabras en inglés como doc, chat, git se pronuncian como sílabas vietnamitas y suenan incorrectas. Para solucionarlo sin editar manualmente cada guion, la habilidad carga automáticamente un mapa de sustitución de palabras completas sin distinción entre mayúsculas y minúsculas desde assets/vn-pronunciation-map.json y lo aplica antes de enviar el texto a la API.
Mapeo predeterminado:
{
"doc": "đóc",
"chat": "chát",
"git": "gít"
}
Cómo funciona: cada clave se compara sin distinción de mayúsculas/minúsculas con límites \b...\b, luego se reemplaza con el valor fonético vietnamita. El modelo ve "đóc" en lugar de "doc" y lo pronuncia cercano a /dɒk/. Esto solo afecta al audio — tu guion fuente se mantiene limpio.
Seleccionando el diccionario — escucha primero, añade después:
- Ejecuta la habilidad en un guion de prueba corto que contenga la palabra candidata
- Si el modelo ya la lee correctamente, no la agregues (el sobreajuste romperá cosas)
- Cuidado con colisiones: agregar
"code"también reescribiríaCodeenClaude Code(nombre de marca) → nunca hagas eso - Para nombres de marca que necesiten protección, déjalos fuera completamente
Sobrescribir / desactivar:
# Usar un mapa personalizado para un proyecto específico
uv run scripts/text_to_mp3.py --file s.txt --pronounce-map workspace/.../map.json -o salida.mp3
# Omitir la sustitución por completo
uv run scripts/text_to_mp3.py --file s.txt --no-pronounce-map -o salida.mp3
El script imprime cada sustitución aplicada en stderr (ej. 'doc' -> 'đóc' (4x)) para que puedas verificar qué cambió.
Flujo de trabajo
- Cargar
ELEVENLABS_API_KEYdesde el archivo.envdel proyecto - Leer texto desde
--fileo argumento posicional, eliminar espacios en blanco - Aplicar mapa de pronunciación (a menos que
--no-pronounce-map) — reemplazo de palabras completas sin distinción de mayúsculas/minúsculas - Validar
len(text) <= 5000 POST https://api.elevenlabs.io/v1/text-to-speech/{voice_id}?output_format=mp3_44100_128- Cabecera:
xi-api-key: <clave>,Content-Type: application/json,Accept: audio/mpeg - Cuerpo:
{ "text": "...", "model_id": "eleven_v3", "voice_settings": { "estabilidad": 0.5, "similitud_boost": 0.75, "estilo": 0, "usar_boost_de_voz": true } }
- Cabecera:
- Transmitir bytes de audio directamente al MP3 de salida (sin necesidad de transcodificación — el servidor devuelve MP3)
- Imprimir
ruta_de_salida,tamaño_mb,num_caracteres,id_voz,id_modelo
Convención de salida
- Corto/prueba:
workspace/assets/elevenlabs/<nombre>.mp3 - Producción de video:
workspace/content/YYYY-MM-DD/video-short/<proyecto>/locucion.mp3
Requisitos
ELEVENLABS_API_KEYen el archivo.envdel proyecto (autenticación por cabecera:xi-api-key)- Opcional
ELEVENLABS_VOICE_IDen.envpara fijar una voz predeterminada diferente - Dependencias de Python gestionadas mediante metadatos en línea PEP 723 (instaladas automáticamente por
uv run):requests,python-dotenv - No se necesita
ffmpeg— ElevenLabs devuelve MP3 directamente
Por qué no hay división en fragmentos
ElevenLabs limita las solicitudes a 5000 caracteres. La habilidad falla rápidamente por encima de ese límite en lugar de dividir automáticamente porque:
- Una locución única debe ser un fragmento coherente — dividir a mitad del guion causa saltos de prosodia en los límites de concatenación
- El contenido del usuario (ganchos, guiones cortos, segmentos de video) típicamente cabe bien por debajo de 5000 caracteres
- Si el usuario realmente necesita audio más largo, debe dividir el guion semánticamente (saltos de párrafo) y llamar a esta habilidad por fragmento, luego concatenar con ffmpeg en su propio flujo
Referencia de API
- Endpoint:
POST https://api.elevenlabs.io/v1/text-to-speech/{voice_id} - Autenticación: Cabecera
xi-api-key: <clave_api> - Catálogo de modelos: https://elevenlabs.io/docs/models
- Catálogo de voces (explorar / obtener IDs de voz): https://elevenlabs.io/app/voice-library
- Documentación de API: https://elevenlabs.io/docs/api-reference/text-to-speech/convert
- Límites de tasa: dependen del nivel de suscripción — consulta https://elevenlabs.io/pricing
- Formatos de salida:
mp3_44100_128(predeterminado),mp3_44100_192(mayor calidad, solo de pago),pcm_44100,ulaw_8000(telefonía)