Habilidad de Video Explicativo con Remotion (50-60s)
Esta habilidad te guía en la creación de videos explicativos cortos de alta calidad, de 50 a 60 segundos (formato TikTok / YouTube Shorts / Reels: 1080x1920 @ 30fps) sobre cualquier tema.
Combina:
- Mejores prácticas visuales de
remotion-dev/skills(springs exactos a fotograma, interpolaciones con clamp, composición de secuencias, jerarquía tipográfica). - Síntesis de voz por IA mediante
TTS_PROVIDERen.env:edge(edge-tts-universal, online, gratuito) ocit(CIT Voice Studio, voces de estudio vietnamitas sin conexión - descargar en github.com/quyen2867/cit-voice-studio, documentación API:docs/cit-voice-studio.md). - Sincronización exacta de tiempos que mapea las duraciones de las locuciones de voz directamente en las secuencias de fotogramas de Remotion.
1. Estructura del Video y Tiempos (50-60s / 1500-1800 fotogramas @ 30fps)
Un video corto cautivador sigue el marco Hook-Problema-Solución-Valor-Outro:
| Escena | Nombre | Tiempo | Rango de fotogramas (@ 30fps) | Propósito y Visuales |
|---|---|---|---|---|
| 1 | Hook | 0s – 5s | ~150 fotogramas | Atraer atención inmediata: Título grande, pregunta que estimula la curiosidad, insignia flotante. |
| 2 | Contexto / Punto de Dolor | 5s – 15s | ~300 fotogramas | Plantear el problema o contexto de por qué el tema es importante. Icono de advertencia/comparación. |
| 3 | Concepto Clave Parte 1 | 15s – 28s | ~390 fotogramas | Explicar el principio central 1: Tarjeta de vidrio, icono ilustrativo, palabras clave destacadas. |
| 4 | Concepto Clave Parte 2 | 28s – 42s | ~420 fotogramas | Ampliar detalles o mecanismo de funcionamiento: Proceso de 3 pasos, diagrama de flujo suave. |
| 5 | Impacto en el Mundo Real | 42s – 52s | ~300 fotogramas | Aplicación práctica, consejos prácticos o cifras impactantes. |
| 6 | Outro y CTA | 52s – 60s | ~240 fotogramas | Resumen en una frase contundente, llamado a la acción Like/Share/Follow y marca personal. |
Duración total: 1500 – 1800 fotogramas (aproximadamente 50 – 60 segundos).
2. Generación de Locución TTS (edge | cit)
2.1 Configuración de Voz a través de .env
Asegúrate de que el archivo .env esté configurado (consulta .env.example para más detalles):
TTS_PROVIDER=edge # edge | cit
TTS_OUTPUT_DIR=public/audio
# Edge TTS (TTS_PROVIDER=edge)
EDGE_TTS_VOICE=vi-VN-HoaiMyNeural # o vi-VN-NamMinhNeural, en-US-ChristopherNeural
EDGE_TTS_RATE=+10% # +10% a +15% ayuda a que los videos cortos tengan un ritmo rápido y atractivo
# CIT Voice Studio (TTS_PROVIDER=cit)
CIT_TTS_BASE_URL=http://127.0.0.1:8001
CIT_TTS_VOICE=Hải Đăng # lista de voces: docs/cit-voice-studio.md o GET /voices
CIT_TTS_SPEED=1.1 # 0.5 - 2.0
Cuando TTS_PROVIDER=cit:
- La aplicación CIT Voice Studio debe estar abierta. El script llama automáticamente a
GET /healthantes de generar audio; si reporta que no se puede conectar, solicita al usuario que abra la aplicación (o descárguela en github.com/quyen2867/cit-voice-studio). - El diálogo puede incluir etiquetas de emoción
[risa],[suspiro],[carraspeo]y etiquetas de pausa[pausa 0.5s](que no se leerán en voz alta). No abuses: máximo 1 etiqueta/escena. - Error
400 Voice not found= nombre de voz incorrecto (distingue acentos). VerificaCIT_TTS_VOICE.
2.2 Proceso de Generación de Archivos de Audio
Al recibir un tema, crea un archivo de guion de locución y ejecuta el script scripts/generate-tts.ts para generar el audio:
import { generateTopicVoices } from "../../scripts/generate-tts";
const scenes = [
{
id: "scene1_hook",
text: "¿Sabías qué es realmente Docker y por qué todo programador lo necesita?",
},
{
id: "scene2_problem",
text: "Antes, la frase 'en mi máquina funciona' siempre era una pesadilla al entregar el producto.",
},
{
id: "scene3_concept1",
text: "Docker resuelve esto con Contenedores: empaqueta todo el código y el entorno en un solo bloque.",
},
{
id: "scene4_concept2",
text: "A diferencia de las máquinas virtuales pesadas, Docker comparte el núcleo del sistema operativo, iniciándose en un instante.",
},
{
id: "scene5_impact",
text: "Gracias a ello, despliegas aplicaciones sin problemas en cualquier servidor desde AWS, GCP hasta VPS económicos.",
},
{
id: "scene6_outro",
text: "¡Sigue el canal para dominar conocimientos tecnológicos concisos cada día!",
},
];
await generateTopicVoices("DockerShort", scenes);
Los archivos de audio se guardarán automáticamente en public/audio/<TopicName>/<sceneId>.<ext> (.mp3 con edge, .wav con cit) junto con un archivo manifest.json que registra con precisión el número de fotogramas (durationInFrames) y audioPath para cada escena.
- Opcional por escena:
voice(voz del proveedor seleccionado),rate/pitch/volume(solo edge),speed0.5-2.0 (solo cit). - Los archivos existentes se reutilizan (caché). Para regenerar después de modificar el diálogo o cambiar la voz, elimina el archivo de audio correspondiente primero.
3. Reglas de Codificación en Remotion (de remotion-dev/skills)
Al escribir código fuente de Remotion, es OBLIGATORIO seguir las siguientes reglas:
3.1 Uso de Animaciones Spring
No uses keyframes/transiciones CSS ni easing lineales sin vida. Usa spring():
import { spring, useCurrentFrame, useVideoConfig } from "remotion";
const frame = useCurrentFrame();
const { fps } = useVideoConfig();
// Spring suave para Tarjeta/Icono
const scale = spring({
frame,
fps,
config: {
damping: 12, // Menor a 15 crea un rebote elástico natural
stiffness: 100, // Tensión
mass: 0.8,
},
});
const entrance = spring({
frame: frame - 10, // Retraso de 10 fotogramas
fps,
from: 50,
to: 0,
});
3.2 Interpolación Segura (Siempre con Clamp)
Siempre proporciona extrapolateLeft: "clamp" y extrapolateRight: "clamp" para evitar desbordamiento de valores cuando la línea de tiempo se ejecuta fuera del rango:
import { interpolate } from "remotion";
const opacity = interpolate(frame, [0, 15], [0, 1], {
extrapolateLeft: "clamp",
extrapolateRight: "clamp",
});
3.3 Inserción de Audio y Sincronización de Secuencias
Cada escena en la Composition usa <Sequence> o <Series> para gestionar los tiempos con precisión:
import { Audio, staticFile, Sequence } from "remotion";
// En el componente Scene - obtén la ruta del manifest, NO uses hardcode de extensión .mp3 (el proveedor cit genera .wav):
<Sequence from={0} durationInFrames={sceneDuration}>
<Audio src={staticFile(audioManifest.scenes[0].audioPath)} />
<SceneContent />
</Sequence>
- Búfer de Transición Ágil (Snappy Transition Buffer):
- El margen entre escenas solo debe ser de +3 a +4 fotogramas (aproximadamente 0.1s) después de que termine la voz.
- Evita márgenes demasiado largos (+15 a +20 fotogramas) que causen silencios/muertos de ritmo entre escenas. La siguiente escena debe aparecer justo cuando termina la frase anterior para mantener un ritmo intenso y atractivo para videos cortos.
// Ejemplo de cálculo de duración de escenas en Series
const d1 = audioManifest.scenes[0].durationInFrames + 3;
const d2 = audioManifest.scenes[1].durationInFrames + 3;
// ...
3.4 Estándares de Diseño Visual (Vertical 1080x1920)
- Fondo: Modo oscuro premium (
bg-slate-950o gradientefrom-slate-950 via-zinc-900 to-black) combinado con efectos de brillo radial/rejilla difusa. - Tarjetas Glassmorphism:
backdrop-blur-xl bg-white/10 border border-white/20 rounded-3xl p-8 shadow-2xl
- Marca del Canal en la Parte Superior (Brand Header):
- Siempre muestra el componente de marca
⚡ [NOMBRE_CANAL]en la parte superior centrado (top: 150px,left: 50%translate-x) leído de la variable de entornoCHANNEL_NAME(por defecto: "mquyen") para evitar que sea ocultado por la barra de búsqueda y las pestañas Siguiendo / Para ti de la plataforma (TikTok, Shorts, Reels).
- Siempre muestra el componente de marca
- Tipografía Optimizada para Móviles (1080x1920):
- Título principal: 72px - 96px, negrita font-black, gradiente nítido.
- Contenido de tarjeta / cita: 40px - 50px font-extrabold.
- Texto secundario / explicación: 28px - 36px font-semibold.
- Insignia de categoría: 28px - 32px font-black uppercase.
- Diseño Centrado y Subtítulos de una Línea (Single-Line Chunked Caption):
- Diseño principal: Todo el bloque de contenido importante DEBE estar en el centro exacto de la pantalla (
justify-centeren vertical). - Posición de subtítulos: Ubicados debajo del bloque central con un espacio amplio (
mt-64), sin ser ocultados por la barra de herramientas inferior de TikTok/Reels. - Formato de una línea: Los subtítulos aparecen en una sola línea (aproximadamente 5-7 palabras), en texto grande
text-4xl font-black, se cortan automáticamente por frase y se transforman suavemente según el progreso de la voz (durationInFrames). Usa una tarjeta tipo píldorarounded-full bg-slate-950/95 border-2 border-sky-400/50 px-10 py-5con resalte de palabras clave.
- Diseño principal: Todo el bloque de contenido importante DEBE estar en el centro exacto de la pantalla (
4. Proceso Paso a Paso para Crear Video en Antigravity / Codex
Al recibir la solicitud: "Crear video explicativo sobre [Tema X]":
Paso 1: Redactar el Guion (Scripting)
- Identifica las 6 escenas (Hook, Problema, Concepto 1, Concepto 2, Impacto, Outro).
- Escribe el diálogo en vietnamita natural, conciso, con frases cortas (cada escena de 15 a 30 palabras).
Paso 2: Generar la Voz (TTS Generation)
- Lee
TTS_PROVIDERen.envpara saber si se usa edge o cit. - Crea el script
scripts/generate-<topic>-audio.tsque llama agenerateTopicVoices, ejecutanpx tsx scripts/generate-<topic>-audio.ts. - Obtén la lista de duraciones reales en fotogramas desde
manifest.json/src/<TopicName>/audioData.ts.
Paso 3: Crear la Carpeta de Código src/<TopicName>/
Estructura de carpetas estándar:
src/<TopicName>/
├── <TopicName>.tsx # Composición principal que reúne las Series.Sequence
├── types.ts # Esquema y Props
├── audioData.ts # Metadatos de duración de audio
└── scenes/
├── Scene1Hook.tsx
├── Scene2Problem.tsx
├── Scene3Concept1.tsx
├── Scene4Concept2.tsx
├── Scene5Impact.tsx
└── Scene6Outro.tsx
Paso 4: Registrar la Composition en src/Root.tsx
Agrega una nueva Composition en src/Root.tsx:
<Composition
id="<TopicName>"
component={<TopicName>}
durationInFrames={totalFrames}
fps={30}
width={1080}
height={1920}
defaultProps={{}}
/>
Paso 5: Verificar y Reportar
- Ejecuta
npm run lintpara verificar errores de TypeScript/ESLint. - Reporta al usuario el enlace para abrir la Composition en Remotion Studio (
http://localhost:3000) o el comando para renderizar MP4:npx remotion render <TopicName> out/<TopicName>.mp4