Remotion 卡点短视频流水线
Objetivo: Dado un tema y una canción de fondo, producir un video final de 88–90 segundos / 16:9 / sin locución / subtítulos bilingües chino-inglés / cada escena corta en el tiempo fuerte de la frase musical, además de tres versiones de portada, paquete de publicación y lista de hechos a verificar. Todo es código, modificar subtítulos es modificar cadenas, y volver a renderizar toma aproximadamente 35 minutos.
Cuándo usar
- "Graba este tema como un video de conocimiento de TikTok / explicación de juego de estrategia"
- "Haz un video con ritmo musical usando tal BGM"
- "Haz un video de este fragmento de la novela" (propiedad intelectual ficticia, ver
references/fact-check.md) - Se necesita entrega completa: video final + portada + texto de publicación + verificación de hechos
Cuándo NO usar
- Se requiere locución en off (este flujo es narrativa sin voz con subtítulos; si se necesita locución, primero generar pista TTS y luego sincronizar)
- Se requiere mezcla de material real/AIGC (este flujo es solo imágenes SVG con código)
- Solo se necesita texto e imagen, no video
〇、ADN de estilo (leer primero, todo son conclusiones de pruebas reales)
| Dimensión | Especificación | Por qué |
|---|---|---|
| Formato | 1920×1080 / 30fps (para vertical abrir Composition aparte) | La cuenta ya está fijada en 16:9, los datos muestran mayor eficiencia de contenido |
| Duración | 88–90 segundos (≈42 compases) | Dentro del rango de prueba "60–90s por episodio" |
| Sonido | Sin locución, BGM + efectos de sonido sintetizados | Requisito de estilo; también evita el costo de alineación TTS |
| Subtítulos | Dos líneas bilingües chino-inglés, chino ≤22 caracteres, cada frase permanece ≥2.2 segundos | Estilo de la cuenta (recomendación general de TikTok es un solo idioma, esta es una elección de la cuenta) |
| Gancho | Segundo 1 = una frase de conflicto completa + un objeto concreto | La tasa de abandono en 2 segundos es el mayor punto de fuga |
| Narrativa | Una persona + un problema + una cadena causal | Evitar "catálogo de conceptos" y "mezcla de personajes" |
| Estructura | Gancho→Título→Regla→Trampa→Contraataque→Contragolpe→Revelación→Elevación→Cierre | Ver references/script-template.md |
| Ritmo | Cada escena corta desde el tiempo fuerte de la frase musical; las acciones clave caen en el tiempo fuerte | La sincronización proviene de la estructura musical, no de alineación manual |
| Imagen | Fondo oscuro + textura metálica/madera/dorada + tipografía grande + pocas etiquetas | Legible en la vista reducida del móvil |
| Zona segura | Elementos de escena y ≤ 850; subtítulos y≈870–1000; esquina superior izquierda y 50–95 | Lo que más falla en las pruebas reales |
| Final | Debe dar una lista que se pueda capturar (punto de guardado) + una pregunta | La tasa de guardado es la mayor debilidad |
| Rigor | Propiedad intelectual ficticia debe marcar "La ilustración es solo representación"; los hechos se etiquetan por nivel | Ver references/fact-check.md |
一、Proceso en ocho pasos (ejecutar paso a paso, sin saltos)
Paso 1: Establecer el proyecto (tema + confirmación)
- Si el usuario no da tema, primero dar 3 candidatos (cada uno con: núcleo en una frase / gancho del segundo 1 / por qué se puede dibujar / puntos de guardado / riesgos), y que el usuario elija.
- Los candidatos deben verificar existencia antes de presentar: para IP ficticia debe poder encontrar nombre de capítulo o entrada; para conocimiento debe poder encontrar fuente.
- Una vez que el usuario elige, obtener el material original del tema (mejor fragmento original; si solo hay resumen de segunda mano, debe marcar el nivel de fuente, ver paso 8).
Paso 2: Pista de audio y tempo (determina todo el tiempo)
# ① Extraer pista de audio (mp4/mp3 ambos; si no hay ffmpeg del sistema, usa automáticamente el binario de imageio-ffmpeg)
python scripts/extract_audio.py 输入.mp4 work/ # → work/audio.f32 + work/music.mp3
# ② Tempo / tiempos fuertes / secciones / tonalidad
python scripts/analyze_beats.py work/audio.f32 src/beats.json
# ③ Escanear energía, seleccionar ventana (paso clave)
python scripts/scan_energy.py src/beats.json work/audio.f32 --seconds 89
- La salida dará: START_BAR / END_BAR, gráfico de energía por compás, porcentaje donde cae el silencio en la ventana.
- Colocar la inversión en el primer tiempo fuerte después del silencio — es el segundo más valioso de todo el video.
- La ventana no debe comerse la sección de atenuación final (dejaría una cola muerta).
- Si una canción ya ha sido usada por la serie, priorizar la segunda mitad no usada para evitar repetición visual.
Paso 3: Escribir el guión (src/script.ts)
- Cada escena declara
bars(cuántos compases ocupa), la suma de todos los bars de las escenas debe ser igual a END_BAR − START_BAR (si no,placeScenesescalará proporcionalmente y dará advertencia). - Subtítulos escritos en
subs:{zh, en, at}, dondeates el tiempo fuerte dentro de la escena (se puede escribir 4.5 para medio tiempo). Una frase ocupa 4–5 tiempos es lo más cómodo. - Efectos de sonido escritos en
cues:{id, beat, sfx, vol, impact};impact:'big'= destello blanco + vibración de pantalla + dispersión cromática + cesión de volumen de música 40 fotogramas. - Presupuesto de ritmo:
número de frases × 2.5–3 segundos ≈ duración total. 89 segundos son aproximadamente 30 frases.
Paso 4: Componentes visuales y escenas (src/*/kit.tsx + src/*/scenes.tsx)
- Escribir todos los componentes primero, luego las escenas: un tema suele tener 6–10 componentes (ejemplo: caja de metal/candado/llave/trituradora/microondas/silueta de persona/estatua/lámpara/boleto de lotería/monedas de Dao).
- Todos los componentes son SVG puro, coordenadas fijas en 1920×1080, reutilizados mediante
translate/scale. - Los componentes de escena solo se encargan de colocar componentes según el tiempo fuerte:
const bf = (n) => beatFrame(scene, n), las entradas siempre usan progreso de easing comopp(f, bf(n), 8). - Lista de verificación en
references/visual-kit.md.
Paso 5: Configuración del proyecto
Un proyecto puede contener múltiples videos: src/<episode>/{script.ts,timeline.ts,fx.tsx,kit.tsx,scenes.tsx,Main.tsx},
registrar un segundo <Composition> en src/Root.tsx, cada uno usando su propio beats.json y music.mp3.
- El segundo video debe llevar su propio envoltorio de tempo (Shell/ImpactFlash en
fx.tsxdebe usar su propio cueFrame, de lo contrario los puntos de impacto se desplazarán). - El audio se usa con
<Audio startFrom={OFF}>, el contenido completo con<Sequence from={-OFF}>, para que dentro de la escena siempre se use "fotograma musical" para el tiempo. - Ver detalles en
references/pipeline.md.
Paso 6: Autocomprobación de fotogramas fijos (no renderizar sin pasar)
node <node> node_modules/@remotion/cli/remotion-cli.js still <Comp> out/s1.png --frame=<punto medio de la escena>
Renderizar un fotograma por escena, revisar visualmente cuatro cosas:
- Si los subtítulos presionan elementos de la escena (lo más común)
- Superposición de elementos (etiqueta sobre etiqueta, etiqueta sobre gráfico)
- Zona segura (elementos y ≤ 850)
- Legibilidad del texto en vista reducida del móvil (chino ≥24px, título principal ≥120px)
Paso 7: Renderizado y autocomprobación del producto final
node <node> node_modules/@remotion/cli/remotion-cli.js render <Comp> out/<name>.mp4 --codec=h264 --crf=18 --concurrency=6
python scripts/check_mp4.py out/<name>.mp4 # duración / número de pistas / resolución / parámetros de audio
check_mp4.py no necesita ffprobe: analiza directamente la caja mp4, confirma pistas vide + soun, duración correcta, 1920×1080, AAC 48kHz.
Paso 8: Entrega
python scripts/make_covers.py --src out/<fotograma fijo>.png --crop x0,y0,x1,y1 \
--title 主标题 --kicker 副标 --sub 一句话 --out-prefix out/封面_XXX
Entrega cuatro elementos:
- Video final mp4 (copiar al directorio raíz del proyecto, nombre de archivo con el tema)
- Tres versiones de portada (16:9 / 3:4 / 9:16) — nunca usar captura automática de fotogramas
- Paquete de publicación (texto principal + comentario fijado + plan de portada + tabla de juicio de 24 horas), plantilla en
references/cover-and-publish.md - Lista de hechos a verificar (esencial para IP ficticia) + storyboard (tabla de códigos de tiempo)
二、Reglas de hierro (todas basadas en pruebas reales)
- El primer fotograma no es la cabecera, es el gancho: una frase de conflicto completa + un objeto concreto ("El rehén está encerrado en el microondas, la cuenta atrás está en marcha").
- Zona segura de subtítulos: elementos de escena siempre presionados en y ≤ 850, subtítulos en 870–1000. En la autocomprobación de fotogramas fijos, revisar esto primero.
- Una frase de subtítulo ≤22 caracteres, permanencia ≥2.2 segundos; frase principal en chino + traducción al inglés en dos líneas.
- El final debe poder capturarse: una lista de tres pasos/tres señales + "Recomiendo guardarlo primero"; un final solo con emociones no obtiene guardado.
- Silencio = punto de inversión:
scan_energy.pyte dirá en qué compás cae el silencio, coloca la inversión más fuerte justo después. - Los grandes impactos con moderación:
impact:'big'activa destello blanco + vibración + dispersión cromática + cesión de música; 5–8 veces en todo el video es suficiente, más y se vuelve insensible. - No deslizamiento uniforme: todas las entradas con easing (
Easing.out(cubic)), las etiquetas al salir con un poco de desplazamiento + escala. - Tipografía: no usar "fuentes subconjunto recortadas según texto antiguo" (el texto nuevo faltará caracteres) — escribir directamente la pila de fuentes del sistema
'Noto Sans SC','Microsoft YaHei'. - public/ se copia completamente: solo conservar los efectos de sonido utilizados (ejemplo: 148 → 16, cada renderizado ahorra 60MB de copia).
- El ETA de Remotion es alto al principio: no te asustes con "3 horas restantes"; en pruebas reales es estable a ~1.35 fotogramas/segundo, 2700 fotogramas ≈ 35 minutos.
- Tres niveles de etiquetado para IP ficticia: texto original de la obra / resumen de lectores / mi inferencia — en el video solo escribir la parte de consenso de los dos primeros niveles, el resto va a la lista de verificación.
- No escribir números fijos en el video ("cuatro signos zodiacales"→"varios signos zodiacales"), no escribir números de capítulo fijos ("Capítulo 359"→"Alrededor del Capítulo 359").
三、Convención de directorios
<project>/
├── public/music.mp3 # BGM de este video
├── public/music.f32(+.json) # Para análisis de tempo (se puede eliminar)
├── public/sfx/*.wav # Efectos de sonido sintetizados según tonalidad
├── src/beats.json # Salida de analyze_beats
├── src/script.ts # Tabla general de texto (solo modificar aquí para cambios de contenido)
├── src/timeline.ts # Mapeo escena→tiempo fuerte + OFF/TOTAL
├── src/Root.tsx # Registro de Composition
├── src/fx.tsx # Vibración de pantalla/destello blanco/dispersión cromática/subtítulos bilingües
├── src/<episode>/** # Segundo video en adelante: script/timeline/fx/kit/scenes/Main independientes
├── tools/ # Scripts de este skill
└── out/ # Fotogramas fijos + video final + portadas
四、Archivos de referencia
references/pipeline.md—— Configuración del entorno y comandos completos (incluyendo todas las trampas de esta máquina: sin ffmpeg / scipy / npm)references/script-template.md—— Plantilla de estructura de guión + tabla de conversión de tiempo fuerte + códigos de tiempo reales de los dos videos de esta sesiónreferences/visual-kit.md—— Especificaciones de componentes visuales, zona segura, paleta de colores, trampas comunes de superposiciónreferences/sfx-and-mix.md—— Síntesis de efectos de sonido (según tonalidad), cesión de volumen laterales, sonoridadreferences/fact-check.md—— Métodos de verificación de IP ficticia y especificaciones de etiquetado de "resumen de lectores" (incluye interfaz Bilibili disponible)references/cover-and-publish.md—— Especificaciones de tres versiones de portada + plantilla de paquete de publicación + juicio de 24 horasexamples/十日终焉-两集.md—— Estructura, datos y decisiones de dos casos reales
五、Límites de capacidad (honesto con el usuario)
- Este flujo no produce locución; si se necesita narración, debe configurarse TTS aparte y realinear los subtítulos.
- En entornos con red restringida (muchos dominios bloqueados por DNS), los detalles de las reglas de IP ficticia pueden solo tener fuentes secundarias — en ese caso, debe ir a la lista de verificación del paso 8, no escribir a la fuerza.
- El renderizado es trabajo intensivo de cómputo: en una laptop de 4 núcleos, un video de 89 segundos a 1080p toma aproximadamente 35 minutos; no prometer "en minutos".
- Derechos de autor: BGM extraído de videos de TikTok solo es adecuado para referencia personal; al publicar, usar la biblioteca de canciones de la plataforma/tarjeta de sonido original.