Generación de Locuciones con ElevenLabs
Genera locuciones profesionales con IA para videos de Remotion usando la API de ElevenLabs.
Requisitos Previos
ELEVENLABS_API_KEYen.env.local
Inicio Rápido
# Generar locución desde texto
node .claude/skills/elevenlabs-remotion-skill/generate.js --text "Tu texto aquí" --output public/audio/voiceover.mp3
# Generar con estilo de narrador (más natural)
node .claude/skills/elevenlabs-remotion-skill/generate.js --text "Tu texto" --character narrator --output voiceover.mp3
# Generar escenas con request stitching
node .claude/skills/elevenlabs-remotion-skill/generate.js --scenes remotion/scenes.json --output-dir public/audio/project/
# Regenerar una sola escena
node .claude/skills/elevenlabs-remotion-skill/generate.js --scenes scenes.json --scene scene2 --new-text "Texto actualizado"
# Listar voces y ajustes preestablecidos disponibles
node .claude/skills/elevenlabs-remotion-skill/generate.js --list-voices
node .claude/skills/elevenlabs-remotion-skill/generate.js --list-characters
Ajustes Preestablecidos de Personaje
Usa ajustes preestablecidos de personaje para locuciones más naturales, en lugar de una lectura literal del texto en pantalla:
| Personaje | Descripción | Mejor Para |
|---|---|---|
literal | Lee el texto exactamente como está escrito | Texto en pantalla, citas |
narrator | Narrador profesional, fluido y atractivo | Videos explicativos, documentales |
salesperson | Entusiasta, persuasivo, enérgico | Marketing, anuncios |
expert | Autoritario, seguro, conocedor | Contenido legal, tutoriales |
conversational | Casual, amigable, natural | Redes sociales, contenido casual |
dramatic | Intenso, emocional, impactante | Ganchos, planteamiento de problemas |
calm | Tranquilizador, tranquilizante, suave | Generación de confianza, conclusiones |
# Usar estilo de narrador globalmente
node .claude/skills/elevenlabs-remotion-skill/generate.js --scenes scenes.json --character narrator --output-dir public/audio/
# O definir por escena en scenes.json
{
"scenes": [
{ "id": "scene1", "text": "Planteamiento del problema", "character": "dramatic" },
{ "id": "scene2", "text": "Solución", "character": "calm" }
]
}
Generación Basada en Escenas con Request Stitching
Genera múltiples escenas con prosodia consistente usando el request stitching de ElevenLabs:
Formato scenes.json
{
"name": "demo-producto",
"voice": "George",
"character": "narrator",
"scenes": [
{
"id": "scene1",
"text": "La conversión genérica de texto a voz suena robótica. Tu marca merece algo mejor.",
"duration": 4.5,
"character": "dramatic"
},
{
"id": "scene2",
"text": "Con la clonación de voz, puedes usar tu propia voz para contenido ilimitado.",
"duration": 5.5
},
{
"id": "scene3",
"text": "Graba una muestra corta. Clónala. Crea locuciones profesionales en minutos.",
"duration": 6,
"delay": 0.3
}
]
}
Generar Todas las Escenas
node .claude/skills/elevenlabs-remotion-skill/generate.js \
--scenes remotion/demo-producto-scenes.json \
--output-dir public/audio/demo-producto/
Esto crea:
demo-producto-scene1.mp3hastasceneN.mp3demo-producto-combined.mp3(todas las escenas unidas)demo-producto-info.json(metadatos con duraciones)
Regeneración de una Sola Escena
Si una escena comienza demasiado pronto, tiene un tiempo incorrecto o necesita texto diferente:
# Regenerar scene2 con nuevo texto
node .claude/skills/elevenlabs-remotion-skill/generate.js \
--scenes remotion/scenes.json \
--scene scene2 \
--new-text "Texto actualizado de la escena 2" \
--output-dir public/audio/project/
# Regenerar scene3 con personaje diferente
node .claude/skills/elevenlabs-remotion-skill/generate.js \
--scenes remotion/scenes.json \
--scene scene3 \
--character salesperson \
--output-dir public/audio/project/
# Simplemente regenerar (mismo texto, mismo personaje)
node .claude/skills/elevenlabs-remotion-skill/generate.js \
--scenes remotion/scenes.json \
--scene scene1 \
--output-dir public/audio/project/
# Incrustar una miniatura en un video MP4
node .claude/skills/elevenlabs-remotion-skill/generate.js \
--embed-thumbnail public/videos/mi-video.mp4 \
--thumbnail public/videos/mi-miniatura.png \
--output public/videos/mi-video-con-miniatura.mp4
La herramienta automáticamente:
- Usa request stitching de escenas anteriores para una prosodia consistente
- Actualiza el archivo info.json con nuevos metadatos
- Actualiza scenes.json si se proporciona
--new-text
Incrustación de Miniatura
Incrusta una imagen de miniatura en videos MP4 para que plataformas como Twitter, YouTube y reproductores de video muestren tu miniatura personalizada en lugar del primer fotograma.
Incrustar Miniatura en Video
# Uso básico - genera video-miniatura.mp4
node .claude/skills/elevenlabs-remotion-skill/generate.js \
--embed-thumbnail public/videos/promo.mp4 \
--thumbnail public/videos/thumbnail.png
# Ruta de salida personalizada
node .claude/skills/elevenlabs-remotion-skill/generate.js \
--embed-thumbnail public/videos/promo.mp4 \
--thumbnail public/videos/thumbnail.png \
--output public/videos/promo-final.mp4
Flujo de Trabajo con Remotion
# 1. Renderiza tu video
npx remotion render MiVideo public/videos/mi-video.mp4
# 2. Renderiza tu miniatura (usa composición Still)
npx remotion still MiVideoThumbnail public/videos/mi-miniatura.png
# 3. Incrusta la miniatura
node .claude/skills/elevenlabs-remotion-skill/generate.js \
--embed-thumbnail public/videos/mi-video.mp4 \
--thumbnail public/videos/mi-miniatura.png \
--output public/videos/mi-video-final.mp4
Formatos Soportados
- Video: MP4 (H.264/H.265)
- Miniatura: PNG, JPG, JPEG
La incrustación usa el flag -disposition:v:1 attached_pic de ffmpeg para establecer la miniatura como una imagen adjunta, que la mayoría de los reproductores y plataformas reconocen.
Validación de Tiempos
La habilidad valida automáticamente los tiempos después de la generación usando ffprobe:
Qué Comprueba
| Comprobación | Umbral | Descripción |
|---|---|---|
| Desajuste de duración | >15% | Advierte si la duración real difiere de la esperada |
| Silencio inicial | >200ms | El audio comienza tarde (locución retrasada) |
| Silencio final | >500ms | Silencio innecesario al final |
| Velocidad de habla | 2-4.5 pps | Óptimo ~3 palabras/segundo |
Validar Audio Existente
# Validar todas las escenas de un proyecto
node .claude/skills/elevenlabs-remotion-skill/generate.js --validate public/audio/demo-producto/
Ejemplo de salida:
🔍 Validando demo-producto (6 escenas)
❌ scene1: 3.00s (esperado: 4.5s)
❌ Audio 1.50s más corto de lo esperado
👍 8 palabras @ 3.1 palabras/segundo
⚠️ scene2: 6.35s (esperado: 5.5s)
⚠️ Silencio inicial: 235ms (puede comenzar tarde)
🐢 10 palabras @ 1.8 palabras/segundo
✅ scene4: 4.36s (esperado: 4s)
👍 9 palabras @ 2.3 palabras/segundo
📊 Duración total: 30.80s (esperado: 30.00s)
info.json Actualizado
Después de la validación, el info.json incluye mediciones reales:
{
"scenes": [
{
"id": "scene1",
"duration": 4.5,
"actualDuration": 3.0,
"leadingSilence": 0.05,
"wordsPerSecond": 3.1
}
]
}
Usa actualDuration en tu composición de Remotion para una sincronización precisa.
Opciones
| Opción | Descripción | Por Defecto |
|---|---|---|
--text, -t | Texto a convertir en voz | Requerido (o --file/--scenes) |
--file, -f | Leer texto desde un archivo | - |
--output, -o | Ruta del archivo de salida | output.mp3 |
--output-dir | Directorio de salida para escenas | public/audio |
--voice, -v | Nombre o ID de la voz | George |
--model, -m | ID del modelo | eleven_multilingual_v2 |
--character, -c | Ajuste preestablecido de personaje | literal |
--scenes | Archivo JSON con escenas | - |
--scene | Regenerar ID de escena única | - |
--new-text | Nuevo texto para regeneración de escena | - |
--validate | Validar directorio de audio existente | - |
--skip-validation | Omitir validación automática | false |
--embed-thumbnail | Archivo de video para incrustar miniatura | - |
--thumbnail | Archivo de imagen de miniatura (PNG/JPG) | - |
--stability | Estabilidad de la voz (0-1) | varía según el personaje |
--similarity | Similitud de la voz (0-1) | varía según el personaje |
--style | Exageración de estilo (0-1) | varía según el personaje |
--no-combined | Omitir archivo combinado | false |
Voces Recomendadas
| Voz | Estilo | Mejor Para |
|---|---|---|
George | Británico cálido y cautivador | Narración, videos explicativos |
Antoni | Profesional, cálido | Contenido legal, tutoriales |
Arnold | Autoritario, profundo | Corporativo, temas serios |
Josh | Amigable, conversacional | Marketing, contenido casual |
Integración con Remotion
Después de generar las locuciones de las escenas, úsalas en tu composición:
import { Audio, Sequence, staticFile } from "remotion";
// Usa archivos de audio de escenas individuales para sincronización precisa
const DURACIONES_ESCENAS = {
scene1: 4.5, // De info.json
scene2: 5.5,
scene3: 8.0,
};
export const VideoConLocucion: React.FC = () => {
const { fps } = useVideoConfig();
const fotogramasEscena1 = Math.round(DURACIONES_ESCENAS.scene1 * fps);
const fotogramasEscena2 = Math.round(DURACIONES_ESCENAS.scene2 * fps);
return (
<>
<Sequence from={0} durationInFrames={fotogramasEscena1}>
<Audio src={staticFile("audio/project/project-scene1.mp3")} />
<VisualEscena1 />
</Sequence>
<Sequence from={fotogramasEscena1} durationInFrames={fotogramasEscena2}>
<Audio src={staticFile("audio/project/project-scene2.mp3")} />
<VisualEscena2 />
</Sequence>
</>
);
};
Consejos para Mejores Resultados
- Usa ajustes preestablecidos de personaje: No leas el texto de la pantalla literalmente; usa
narratoroexpertpara un flujo natural - La puntuación importa: Usa puntos para pausas, comas para descansos breves
- Números: Escribe los números en palabras ("quinientos" no "500") para un habla natural
- Abreviaturas: Escribe palabras completas ("veinticuatro horas" no "24h")
- Escena por escena: Diferentes escenas pueden tener diferentes personajes (introducción dramática, CTA calmada)
- Ajusta finamente: Usa
--scenepara regenerar escenas individuales sin rehacer todo - Request stitching: Mantiene la voz consistente en todas las escenas
Ejemplo de Flujo de Trabajo
# 1. Crea scenes.json con tu guión
# 2. Genera todas las escenas con estilo de narrador
node .claude/skills/elevenlabs-remotion-skill/generate.js \
--scenes remotion/mi-video-scenes.json \
--character narrator \
--output-dir public/audio/mi-video/
# 3. Previsualiza en Remotion, nota que scene2 comienza demasiado pronto
# 4. Regenera solo scene2 con texto actualizado
node .claude/skills/elevenlabs-remotion-skill/generate.js \
--scenes remotion/mi-video-scenes.json \
--scene scene2 \
--new-text "Texto ligeramente más largo para llenar el tiempo visual" \
--output-dir public/audio/mi-video/
# 5. Actualiza la composición del video con la nueva duración de info.json
# 6. Repite hasta que el tiempo sea perfecto