Geração de Narração com ElevenLabs
Gere narrações profissionais com IA para vídeos Remotion usando a API ElevenLabs.
Pré-requisitos
ELEVENLABS_API_KEYem.env.local
Início Rápido
# Gerar narração a partir de texto
node .claude/skills/elevenlabs-remotion-skill/generate.js --text "Seu texto aqui" --output public/audio/voiceover.mp3
# Gerar com estilo de narrador (mais natural)
node .claude/skills/elevenlabs-remotion-skill/generate.js --text "Seu texto" --character narrator --output voiceover.mp3
# Gerar cenas com costura de requisições
node .claude/skills/elevenlabs-remotion-skill/generate.js --scenes remotion/scenes.json --output-dir public/audio/project/
# Regenerar uma única cena
node .claude/skills/elevenlabs-remotion-skill/generate.js --scenes scenes.json --scene scene2 --new-text "Texto atualizado"
# Listar vozes e predefinições de personagens disponíveis
node .claude/skills/elevenlabs-remotion-skill/generate.js --list-voices
node .claude/skills/elevenlabs-remotion-skill/generate.js --list-characters
Predefinições de Personagens
Use as predefinições de personagens para narrações mais naturais, em vez da leitura literal de texto de tela:
| Personagem | Descrição | Melhor Para |
|---|---|---|
literal | Lê o texto exatamente como escrito | Texto de tela, citações |
narrator | Contador de histórias profissional, suave e envolvente | Explicativos, documentários |
salesperson | Entusiástico, persuasivo, energético | Marketing, anúncios |
expert | Autoritário, confiante, conhecedor | Conteúdo jurídico, tutoriais |
conversational | Casual, amigável, natural | Redes sociais, conteúdo casual |
dramatic | Intenso, emocional, impactante | Ganchos, declarações de problema |
calm | Suave, tranquilizador, gentil | Construção de confiança, conclusões |
# Usar estilo narrador globalmente
node .claude/skills/elevenlabs-remotion-skill/generate.js --scenes scenes.json --character narrator --output-dir public/audio/
# Ou definir por cena em scenes.json
{
"scenes": [
{ "id": "scene1", "text": "Declaração do problema", "character": "dramatic" },
{ "id": "scene2", "text": "Solução", "character": "calm" }
]
}
Geração Baseada em Cenas com Costura de Requisições
Gere múltiplas cenas com prosódia consistente usando a costura de requisições da ElevenLabs:
Formato scenes.json
{
"name": "product-demo",
"voice": "George",
"character": "narrator",
"scenes": [
{
"id": "scene1",
"text": "Texto para fala genérico soa robótico. Sua marca merece mais.",
"duration": 4.5,
"character": "dramatic"
},
{
"id": "scene2",
"text": "Com clonagem de voz, você pode usar sua própria voz para conteúdo ilimitado.",
"duration": 5.5
},
{
"id": "scene3",
"text": "Grave uma pequena amostra. Clone-a. Crie narrações profissionais em minutos.",
"duration": 6,
"delay": 0.3
}
]
}
Gerar Todas as Cenas
node .claude/skills/elevenlabs-remotion-skill/generate.js \
--scenes remotion/product-demo-scenes.json \
--output-dir public/audio/product-demo/
Isso cria:
product-demo-scene1.mp3atésceneN.mp3product-demo-combined.mp3(todas as cenas costuradas)product-demo-info.json(metadados com durações)
Regeneração de Cena Individual
Se uma cena começar muito cedo, tiver tempo errado ou precisar de texto diferente:
# Regenerar scene2 com novo texto
node .claude/skills/elevenlabs-remotion-skill/generate.js \
--scenes remotion/scenes.json \
--scene scene2 \
--new-text "Texto atualizado da cena 2" \
--output-dir public/audio/project/
# Regenerar scene3 com personagem diferente
node .claude/skills/elevenlabs-remotion-skill/generate.js \
--scenes remotion/scenes.json \
--scene scene3 \
--character salesperson \
--output-dir public/audio/project/
# Apenas regenerar (mesmo texto, mesmo personagem)
node .claude/skills/elevenlabs-remotion-skill/generate.js \
--scenes remotion/scenes.json \
--scene scene1 \
--output-dir public/audio/project/
# Incorporar miniatura em um vídeo MP4
node .claude/skills/elevenlabs-remotion-skill/generate.js \
--embed-thumbnail public/videos/my-video.mp4 \
--thumbnail public/videos/my-thumbnail.png \
--output public/videos/my-video-with-thumb.mp4
A ferramenta automaticamente:
- Usa costura de requisições de cenas anteriores para prosódia consistente
- Atualiza o arquivo info.json com novos metadados
- Atualiza scenes.json se
--new-textfor fornecido
Incorporação de Miniatura
Incorpore uma imagem de miniatura em vídeos MP4 para que plataformas como Twitter, YouTube e players de vídeo exibam sua miniatura personalizada em vez do primeiro quadro.
Incorporar Miniatura no Vídeo
# Uso básico - gera video-thumb.mp4
node .claude/skills/elevenlabs-remotion-skill/generate.js \
--embed-thumbnail public/videos/promo.mp4 \
--thumbnail public/videos/thumbnail.png
# Caminho de saída personalizado
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
Fluxo de Trabalho com Remotion
# 1. Renderize seu vídeo
npx remotion render MyVideo public/videos/my-video.mp4
# 2. Renderize sua miniatura (use composição Still)
npx remotion still MyVideoThumbnail public/videos/my-thumbnail.png
# 3. Incorpore a miniatura
node .claude/skills/elevenlabs-remotion-skill/generate.js \
--embed-thumbnail public/videos/my-video.mp4 \
--thumbnail public/videos/my-thumbnail.png \
--output public/videos/my-video-final.mp4
Formatos Suportados
- Vídeo: MP4 (H.264/H.265)
- Miniatura: PNG, JPG, JPEG
A incorporação usa a flag -disposition:v:1 attached_pic do ffmpeg para definir a miniatura como uma imagem anexada, que a maioria dos players de vídeo e plataformas reconhece.
Validação de Tempo
A skill valida automaticamente o tempo após a geração usando ffprobe:
O Que Verifica
| Verificação | Limiar | Descrição |
|---|---|---|
| Discrepância de duração | >15% | Avisa se a duração real difere da esperada |
| Silêncio inicial | >200ms | Áudio começa tarde (narração atrasada) |
| Silêncio final | >500ms | Silêncio desnecessário no final |
| Taxa de fala | 2-4.5 pps | Ideal ~3 palavras/segundo |
Validar Áudio Existente
# Validar todas as cenas de um projeto
node .claude/skills/elevenlabs-remotion-skill/generate.js --validate public/audio/product-demo/
Exemplo de saída:
🔍 Validando product-demo (6 cenas)
❌ scene1: 3.00s (esperado: 4.5s)
❌ Áudio 1.50s mais curto que o esperado
👍 8 palavras @ 3.1 palavras/seg
⚠️ scene2: 6.35s (esperado: 5.5s)
⚠️ Silêncio inicial: 235ms (pode começar tarde)
🐢 10 palavras @ 1.8 palavras/seg
✅ scene4: 4.36s (esperado: 4s)
👍 9 palavras @ 2.3 palavras/seg
📊 Duração total: 30.80s (esperado: 30.00s)
info.json Atualizado
Após a validação, o info.json inclui medições reais:
{
"scenes": [
{
"id": "scene1",
"duration": 4.5,
"actualDuration": 3.0,
"leadingSilence": 0.05,
"wordsPerSecond": 3.1
}
]
}
Use actualDuration em sua composição Remotion para sincronia precisa.
Opções
| Opção | Descrição | Padrão |
|---|---|---|
--text, -t | Texto para converter em fala | Obrigatório (ou --file/--scenes) |
--file, -f | Ler texto de arquivo | - |
--output, -o | Caminho do arquivo de saída | output.mp3 |
--output-dir | Diretório de saída para cenas | public/audio |
--voice, -v | Nome ou ID da voz | George |
--model, -m | ID do modelo | eleven_multilingual_v2 |
--character, -c | Predefinição de personagem | literal |
--scenes | Arquivo JSON com cenas | - |
--scene | Regenerar ID de cena individual | - |
--new-text | Novo texto para regeneração de cena | - |
--validate | Validar diretório de áudio existente | - |
--skip-validation | Pular validação automática | false |
--embed-thumbnail | Arquivo de vídeo para incorporar miniatura | - |
--thumbnail | Arquivo de imagem de miniatura (PNG/JPG) | - |
--stability | Estabilidade da voz (0-1) | varia por personagem |
--similarity | Similaridade da voz (0-1) | varia por personagem |
--style | Exagero de estilo (0-1) | varia por personagem |
--no-combined | Pular arquivo combinado | false |
Vozes Recomendadas
| Voz | Estilo | Melhor Para |
|---|---|---|
George | Britânica calorosa e cativante | Narração, explicativos |
Antoni | Profissional, calorosa | Conteúdo jurídico, tutoriais |
Arnold | Autoritária, profunda | Corporativo, tópicos sérios |
Josh | Amigável, conversacional | Marketing, conteúdo casual |
Integração com Remotion
Após gerar as narrações das cenas, use-as em sua composição:
import { Audio, Sequence, staticFile } from "remotion";
// Use arquivos de áudio de cena individuais para sincronia precisa
const SCENE_DURATIONS = {
scene1: 4.5, // De info.json
scene2: 5.5,
scene3: 8.0,
};
export const VideoWithVoiceover: React.FC = () => {
const { fps } = useVideoConfig();
const scene1Frames = Math.round(SCENE_DURATIONS.scene1 * fps);
const scene2Frames = Math.round(SCENE_DURATIONS.scene2 * fps);
return (
<>
<Sequence from={0} durationInFrames={scene1Frames}>
<Audio src={staticFile("audio/project/project-scene1.mp3")} />
<Scene1Visual />
</Sequence>
<Sequence from={scene1Frames} durationInFrames={scene2Frames}>
<Audio src={staticFile("audio/project/project-scene2.mp3")} />
<Scene2Visual />
</Sequence>
</>
);
};
Dicas para Melhores Resultados
- Use predefinições de personagens: Não leia texto de tela literalmente - use
narratorouexpertpara fluxo natural - Pontuação importa: Use pontos para pausas, vírgulas para pausas breves
- Números: Escreva números por extenso ("quinhentos" não "500") para fala natural
- Abreviações: Escreva palavras completas ("vinte e quatro horas" não "24h")
- Cena por cena: Cenas diferentes podem ter personagens diferentes (introdução dramática, CTA calmo)
- Ajuste fino: Use
--scenepara regenerar cenas individuais sem refazer tudo - Costura de requisições: Mantém a voz consistente em todas as cenas
Exemplo de Fluxo de Trabalho
# 1. Crie scenes.json com seu roteiro
# 2. Gere todas as cenas com estilo narrador
node .claude/skills/elevenlabs-remotion-skill/generate.js \
--scenes remotion/my-video-scenes.json \
--character narrator \
--output-dir public/audio/my-video/
# 3. Visualize no Remotion, perceba que a cena2 começa muito cedo
# 4. Regenerar apenas a cena2 com texto atualizado
node .claude/skills/elevenlabs-remotion-skill/generate.js \
--scenes remotion/my-video-scenes.json \
--scene scene2 \
--new-text "Texto um pouco mais longo para preencher o tempo visual" \
--output-dir public/audio/my-video/
# 5. Atualize a composição do vídeo com a nova duração do info.json
# 6. Repita até que o tempo esteja perfeito