Producción completa de videos explicativos en serie
Convertir «un tema» en «un video terminado»: planificación → maquetación de página (animación HTML) → guion → locución → subtítulos → 1080p MP4 → portadas para Douyin (horizontal 16:9 + vertical 9:16). El archivo de estilo predeterminado se ha consolidado a partir de la práctica real de la serie de videos explicativos del «Tao Te Ching» (tinta china neoclásica / voz masculina Yunjian / subtítulos blancos con brillo negro), todo el conjunto es reutilizable y cada elemento se puede sobrescribir.
Ruta visual (a partir de v2.0, por defecto se usa animación HTML; v2.1 colaboración texto-imagen):
- Por defecto: Página de animación HTML — Genera una página de presentación HTML con efectos de entrada y transiciones suaves entre páginas basadas en el guion, renderizando fotogramas determinísticamente para crear el video, con una sincronización del 100% de la animación en el producto final (consulta
references/html-animation.mdpara el plan y las reglas de maquetación). - v2.1 Colaboración texto-imagen: Biblioteca de escenas SVG de tinta china incorporada (ola solitaria/ondas/montañas/bambú de tinta/mirando la luna/carpa koi) + iconos de elementos + soporte para imágenes externas, que se emparejan automáticamente o se especifican explícitamente según el guion, con entrada escalonada de componentes gráficos y maquetación unificada con efectos de texto.
- Alternativa: Fotogramas PPT estáticos + xfade (se usa cuando se necesitan tablas/diseños complejos nativos de PPT, o cuando el usuario solicita explícitamente .pptx).
A partir de v2.3, cada episodio incluye portadas para Douyin: Horizontal 16:9 + vertical 9:16, generadas por IA en conjunto según el tema (horizontal como ancla → confirmación del usuario → derivación vertical), sin tomar fotogramas del video; el proceso se detalla en la etapa ⑥ y en references/douyin-covers.md.
Cinco preguntas iniciales (se preguntan al inicio de cada episodio; si el usuario dice «como el anterior» o «lo de siempre», se toman todos los valores predeterminados y se comienza directamente)
- ¿De qué trata este episodio? (Tema / capítulo del texto)
- Profundidad del contenido: Explicación detallada / Explicación de los puntos clave? (Por defecto: Explicación detallada)
- ¿Duración objetivo del video final? (Por defecto 6-7 minutos)
- ¿Estilo PPT: tinta china neoclásica? (Por defecto: Sí)
- ¿Voz: Yunjian, subtítulos blancos con brillo negro? (Por defecto: Sí)
Archivo de estilo (se adopta directamente cuando el usuario no lo especifica)
| Elemento | Valor predeterminado |
|---|---|
| Estilo PPT | Tinta china neoclásica: blanco papel de arroz + negro tinta + verde azulado + bermellón |
| Fuente | Título SimSun (Song), cuerpo Microsoft YaHei (SlideDSL siempre usa font-family en inglés) |
| Elementos visuales | Ilustraciones SVG de tinta china (no usar IA para generar imágenes, 100% fidelidad, modificable repetidamente) |
| Animación | Página de animación HTML: título blur-in / elementos escalonados fade-up / transición suave entre páginas / énfasis en puntos clave con cue (la «animación de elementos rechazada» anterior era para el esquema de superposición ffmpeg, la ruta de renderizado determinista HTML se ha validado en v2.0) |
| Voz | zh-CN-YunjianNeural (Yunjian · Masculino · Profundo) |
| Velocidad | +0% (uniforme en todo el video; solo se cambia si el usuario lo solicita explícitamente, no se puede segmentar por densidad de contenido) |
| Subtítulos | Texto blanco + brillo exterior negro (blur 0.8), fondo transparente, centrado en la parte inferior |
| Tamaño de fotograma | 1920×1080 (16:9) |
| Corrección de pronunciación | «老子» → TTS lee «老紫» (lǎo zǐ, tercer tono), los subtítulos siguen mostrando «老子» |
| Portada Douyin | Horizontal 16:9 + vertical 9:16; nombre del episodio en cuatro caracteres grandes; generada por IA en conjunto (cadena de anclaje), sin tomar fotogramas del video |
Convención del directorio de trabajo
Crear directorio de trabajo de video/ en el espacio de trabajo, con un subdirectorio por episodio (nombrado con el tema):
directorio de trabajo de video/{nombre del episodio}/
├── {BASE} guion.json # Fuente de datos única: título/voz/corrección de pronunciación/guion de cada página (+ texto de la página)
├── {BASE} guion_editable.txt # Exportado por export_txt.py, para que el usuario lo revise en el bloc de notas
├── 01_deck/ # deck.html (página de presentación animada, se puede previsualizar) + deck.json (lista de la línea de tiempo)
├── 01_html_frames/ # f_XXXXX.png fotogramas + frames_manifest.json (ruta HTML)
├── 01_frames/ # frame_01.png ... (ruta alternativa PPT estático)
├── 02_audio/ # slide_01.mp3 ... slide_NN.mp3 (voz de cada página)
├── 配音试听/ # mp3 de prueba de múltiples voces + 配音试听.html
└── 03_output/ # Producto final {BASE}(con subtítulos).mp4
BASE = nombre del episodio (si contiene las palabras «guion», se eliminan automáticamente). El JSON del guion se genera programáticamente con Python json.dump, está prohibido escribir JSON a mano con comillas chinas (se escaparían y causarían errores).
El lienzo de la portada {nombre del episodio}-portada-douyin.miora se coloca en la raíz del espacio de trabajo según las especificaciones de entrega de medios generados, y los PNG de ambos tamaños en su directorio _assets/.
Proceso por fases (incluye 4 puertas de confirmación, se espera la respuesta del usuario para cada una antes de continuar)
Antes de comenzar (en la primera vez o si el entorno es anómalo), ejecuta primero la verificación del entorno:
python scripts/doctor.py, completa los MISSING y luego comienza. Límites de ritmo, lista de compuertas, BGM y tabla de alcance de modificación enreferences/pacing-and-gates.md(Fusionado de la metodología de liyupi/ai-promo-video-maker: estándares duros de ritmo / verificación de datos / doble compuerta / disciplina de modificación).
Fase ① Planificación de contenido (Puerta 1: Cinco preguntas iniciales)
Después de determinar el plan según las cinco preguntas, produce un paquete de planificación conciso (estructura del texto / plan visual / plan de audio), y tras la aprobación del usuario, pasa a la fase ②.
Fase ② Maquetación de página (Ruta de animación HTML = predeterminada)
- Ya no se hace PPT: genera directamente programáticamente
{BASE} guion.json, escribiendo el guiontextpágina por página; Cada página puede incluir opcionalmentetitle(título de la página),points(array de elementos en pantalla),layout(title/bullets/quote/end),cues(énfasis en puntos clave, ver más abajo) — si faltan, se deducen automáticamente del guion (reglas en references/html-animation.md), pero para producción formal se recomienda darlos explícitamente para mayor calidad y estabilidad. - El número de páginas se determina por la profundidad del contenido (explicación detallada: aproximadamente 8 páginas); las tablas/datos todavía se recomienda usar la ruta alternativa de PPT estático.
Fase ②′ Creación de PPT (Ruta alternativa estática)
- Usa workbuddy-pptx (SlideDSL) para crear las diapositivas, el número de páginas según la profundidad del contenido (explicación detallada: aproximadamente 8 páginas).
- Notas del orador (notes) = guion página por página: se escribe una vez y se reutiliza en múltiples lugares (locución de video / línea de tiempo DOCX / importación a Jianying).
- Las fuentes usan nombres en inglés (SimSun / Microsoft YaHei), los nombres chinos no se renderizan.
- Esquema de colores y elementos según el archivo de estilo; las páginas con tablas/datos priorizan elementos nativos de PPT.
Fase ③ Finalización del guion (Puerta 2: Revisión del guion)
-
Extrae el guion de las notas PPT, genera programáticamente
{BASE} guion.json(estructura a continuación). -
Exporta texto editable para revisión:
python scripts/export_txt.py "{BASE} guion.json" -
Indica claramente al usuario que abra el txt con el bloc de notas y lo revise página por página; después de que el usuario devuelva los cambios, sincroniza de vuelta al JSON:
python scripts/import_txt.py "{BASE} guion.json" "{BASE} guion_editable.txt"Si el usuario solo responde «el texto está bien» sin modificaciones, se omite la sincronización.
Fase ④ Locución (Puerta 3: Prueba de voz, puerta dura voice_confirmed)
-
Genera una página de prueba para que el usuario seleccione la voz:
python scripts/preview_voices.py 配音试听 -
Una vez que el usuario selecciona, escribe en el JSON y establece
voice_confirmed=true(sin esto, TTS y síntesis se niegan a ejecutar):python -c "import json;p='{BASE} guion.json';d=json.load(open(p,encoding='utf-8'));d['voice']='zh-CN-YunjianNeural';d['rate']='+0%';d['voice_confirmed']=True;json.dump(d,open(p,'w',encoding='utf-8'),ensure_ascii=False,indent=2)"La velocidad predeterminada
+0%no se modifica; solo se cambia si el usuario solicita explícitamente un cambio de velocidad, y se aplica uniformemente a todo el video.
Fase ⑤ Síntesis del video final (Puerta 4: Confirmar con el usuario antes de comenzar la síntesis)
Orden: Sintetizar voz → Generar página de animación → Renderizar fotogramas → Sintetizar video (ruta HTML); o Renderizar fotogramas → Voz → Video (ruta estática).
Ruta de animación HTML (predeterminada):
-
Sintetizar voz página por página (debe hacerse primero — la duración de cada página se toma de la duración real de la voz):
python scripts/tts_synth.py --narration "{BASE} guion.json" --out 02_audio -
Generar página de presentación animada (deck.html se puede previsualizar con
#previewen el navegador):python scripts/gen_html_deck.py --narration "{BASE} guion.json" --audio 02_audio --out 01_deck -
Renderizar fotograma a fotograma (solo renderiza la ventana de animación, se completa en minutos):
node scripts/render_html_frames.mjs --deck 01_deck --out 01_html_frames -
Sintetizar video (concatena la secuencia de fotogramas + subtítulos oración por oración, estilo predeterminado blanco con brillo negro):
python scripts/compose_html_video.py --deck 01_deck --frames 01_html_frames --audio 02_audio --narration "{BASE} guion.json" --out 03_outputPor defecto produce
{BASE}(con subtítulos).mp4;--also-plainañade una versión sin subtítulos;--bgm <archivo>añade música de fondo (ducking automático, baja la música cuando comienza la locución; biblioteca Mixkit gratuita para uso comercial, debe ser probada por el usuario antes de decidir).
Ruta alternativa PPT estático:
-
Renderizar fotogramas de la pantalla (primera opción: PowerPoint COM, requiere PowerPoint instalado localmente):
powershell -ExecutionPolicy Bypass -File scripts/export_frames.ps1 -Pptx "{BASE}.pptx" -OutDir 01_framesSi ya hay un PDF, se puede usar la ruta pymupdf:
python scripts/pdf_to_frames.py "{BASE}.pdf" 01_frames 1920. Después del renderizado, comprobar 3 páginas al azar (primera página, una página con mucho contenido, una página con tabla) para confirmar que no hay anomalías en las fuentes. -
Sintetizar voz página por página: igual que tts_synth.py anterior.
-
Sintetizar video (páginas estáticas + xfade + subtítulos oración por oración):
python scripts/compose_video.py --frames 01_frames --audio 02_audio --narration "{BASE} guion.json" --out 03_output -
Verificación de entrega: Comprobar fotogramas en las entradas/transiciones para confirmar que la animación es normal y no hay parpadeos negros; comprobar fotogramas en medio de la página para confirmar los subtítulos; Ejecutar compuerta de video final:
python scripts/verify_output.py --video "03_output/{BASE}(con subtítulos).mp4" --deck 01_deck(solo se entrega si todas las especificaciones/duración/sonoridad/fotogramas negros/silencio pasan);present_filesentrega.
Fase ⑥ Portadas para Douyin (estándar para cada episodio: Horizontal 16:9 + Vertical 9:16)
Se entregan junto con el video final, para facilitar la subida directa a Douyin. No se toman fotogramas del video — se genera un conjunto por IA según el tema de este episodio, entregando lienzo .miora + PNG de ambos tamaños;
Plantilla de prompts / correspondencia de imágenes / lista de verificación en references/douyin-covers.md. Se omite si el usuario dice explícitamente que no quiere portada.
- Texto: El nombre del episodio en cuatro caracteres es la única letra grande en la imagen (ej. «有无相生»); no añadir subtítulos en letra pequeña (se verá borroso); excepto el texto principal, la imagen no tiene texto.
- Cadena de anclaje del conjunto (regla estricta): Ancla horizontal (texto a imagen puro 1920×1080) → Confirmación del usuario → Versión vertical derivada usando el ancla como imagen de referencia (1080×1920, composición vertical de tres secciones); el token de estilo se reutiliza del original, prohibido enviar ciegamente dos imágenes.
- Visual: Mismo estilo que el video final (blanco papel de arroz + negro tinta + verde azulado + bermellón, difuminado de tinta, espacios en blanco amplios); la imagen se toma del tema de este episodio (ej. «有无相生» → luna llena + reflejo de la luna en el agua).
- Tamaño real: El modelo puede redondear y dar 1920×1072 / 1072×1920 (diferencia de 8px), informar con precisión; si el usuario requiere precisión, añadir bordes hasta los valores estándar.
- Entrega: Raíz del espacio de trabajo
{nombre del episodio}-portada-douyin.miora+ tarjetas de imagen de ambos tamaños; el texto y las dimensiones de la portada se registran en需求确认.md.
(Cuando se necesita un control del 100% del texto o una plantilla reutilizable entre episodios, se puede cambiar a la exportación de diseño editable; por defecto se genera por IA).
Fase ⑦ Ajustes iterativos
- Mantener
需求确认.mdpor directorio de episodio: respuestas a las cinco preguntas + registro de cada modificación (las palabras textuales del usuario se archivan), al recibir comentarios, primero registrar y luego modificar, solo rehacer los pasos necesarios (alcance del cambio → tabla de pasos a rehacer enreferences/pacing-and-gates.md). - Ajuste de estilo/color de subtítulos → ver
references/subtitle-style.md(los colores ASS están en orden inverso BBGGRR, lectura obligatoria). - Problemas de pronunciación → solo modificar
tts_replacementsy reejecutar TTS + síntesis, los subtítulos no se modifican. - Sincronización de subtítulos → compose lee preferentemente
02_audio/timing_XX.json(línea de tiempo real a nivel de oración TTS, producida automáticamente por tts_synth). - Problemas visuales/de animación (ruta HTML) → modificar title/points/visual/cues del JSON del guion o la maquetación en
gen_html_deck.py→ reejecutar: generar deck → renderizar → sintetizar (el audio se reutiliza, a menos que el guion también haya cambiado). - Problemas visuales (ruta estática) → modificar PPT y reexportar fotogramas, el audio se reutiliza.
- Modificación de portada → si el texto/imagen no es correcto, solo rehacer el elemento correspondiente; si el estilo general no es correcto, rehacer el ancla y luego derivar (ver
references/douyin-covers.md).
Fase ⑧ Entrega y aceptación (lista de autoverificación)
- Visual: sin anomalías en fuentes/esquema de colores; página con tabla (si la hay) renderizada correctamente
- Animación: entrada de título/elementos natural, transiciones entre páginas suaves, énfasis cue alineado con la locución (ruta HTML)
- Locución: audible, sin palabras tragadas, velocidad uniforme en todo el video
- Pronunciación: palabras leídas correctamente (ej. «老子» = lǎo zǐ)
- Subtítulos: sincronizados oración por oración con la voz, estilo uniforme, sin desbordamiento ni recorte
- Transiciones: crossfade suave, sin parpadeos negros, sin fotogramas en blanco
- Duración: ≈ duración objetivo (±10 segundos)
- Formato: 1920×1080 / H.264 / AAC / .mp4
- Portada: dos versiones, cuatro caracteres sin errores de trazo, estilo conjunto, tamaño real (lista en
references/douyin-covers.md)
Estructura JSON del guion (fuente de datos única)
{
"title": "Laozi hoy - La bondad suprema como el agua",
"voice": "zh-CN-YunjianNeural",
"rate": "+0%",
"voice_confirmed": true,
"tts_replacements": { "老子": "老紫" },
"slides": [
{ "idx": 1, "text": "Texto del guion de la primera página..." },
{ "idx": 2, "text": "Texto del guion de la segunda página...",
"title": "Tres virtudes del agua", "points": ["Altruista, nutre a todos los seres", "No compite, se contenta con estar abajo"],
"cues": [ { "t": 4.5, "dur": 0.9, "target": 0 } ] }
]
}
idxnumerado consecutivamente desde 1, corresponde estrictamente conframe_XX.png(ruta estática) /slide_XX.mp3.- Campos opcionales por página en la ruta de animación HTML:
title(título de la página),points(array de elementos en pantalla),layout(title/bullets/quote/end),cues(énfasis en puntos clave:t=segundos relativos dentro de la página,target=índice del elemento comenzando desde 0,dur=duración del énfasis,action=pulse); Colaboración texto-imagen (v2.1):visual(escena de tinta china water/ripples/mountain/ bamboo/moon/fish, por defecto se empareja automáticamente con palabras clave del guion),icons(icono de elemento droplet/wave/mountain/moon/leaf),image(ruta de imagen externa, incrustada en la columna derecha). Si faltan, se deducen automáticamente del guion; para producción formal se recomienda darlos explícitamente. tts_replacements: tabla de corrección de pronunciación, solo afecta a la entrada TTS, los subtítulos y el texto editable mantienen los caracteres originales. Se deja{}vacío para series generales.voice_confirmedpor defecto false, la puerta ③ lo establece en true, de lo contrario el script rechaza la síntesis.
Solución rápida de fallos comunes
| Síntoma | Causa | Solución |
|---|---|---|
| El color del borde del subtítulo no coincide con lo esperado | Los colores ASS están en orden inverso BBGGRR | Rojo=&H000000FF Azul=&H00FF0000 Negro=&H00000000 |
| Una palabra se lee en voz coloquial en lugar de literaria (ej. 老子 lǎo zi) | TTS toma por defecto la lectura coloquial | Añadir a tts_replacements y reejecutar TTS |
| La fuente PPT no se renderiza | El nombre chino no se reconoce | Usar SimSun / Microsoft YaHei |
| Pantalla blanca/cadena de filtros rota en la síntesis de un solo paso | Superposición overlay después de xfade | Dividir en dos pasos: primero base y luego superponer; escapar coma \, |
| El fotograma «se generó» pero no se encuentra | pymupdf falla silenciosamente | El script usa abspath + verificación posterior a la escritura; o usar export_frames.ps1 |
--rate -10% da error «expected one argument» | argparse malinterpreta la opción | Usar --rate=-10% o solo modificar el rate en el JSON |
| La síntesis informa «la voz aún no está confirmada» | Falta la puerta ③ | Establecer voice_confirmed=true y reejecutar |
| Error al escribir JSON con comillas chinas | Error de escape manual | Generar programáticamente con Python json.dump |
| La generación del deck informa «falta la voz» | La ruta HTML requiere TTS primero | Ejecutar tts_synth.py primero, luego gen_html_deck.py |
| El renderizado informa «no se encuentra Chromium» | La ruta del navegador ha cambiado | Usar --browser para especificar chrome.exe / msedge.exe |
| La página de título no está centrada | Escritura del selector de clase CSS | Usar .inner.layout-title (elemento de la misma clase), no usar selectores descendientes |
| Los elementos se rompen en fragmentos (oraciones numeradas se convierten en elementos independientes) | Las oraciones cortas numeradas no se fusionaron | gen_html_deck.py ya tiene fusión incorporada; los points personalizados pueden evitarlo por completo |
| La duración del último fotograma del video no es correcta | Rareza del archivo final en concat | compose_html_video.py ya tiene repetición del archivo final incorporada, no eliminar |
| El énfasis cue no aparece | cue excede la duración de la página | Comprobar si el t de slides[].cues es menor que la duración de la voz de esa página |
| Faltan trazos/palabras incorrectas en los caracteres grandes de la portada | La IA renderiza frases largas en chino de forma inestable | Reducir el texto a cuatro caracteres o menos y regenerar; si los caracteres del ancla son incorrectos, regenerar el ancla primero y luego derivar |
| El lado corto de la portada es 1072≠1080 | Redondeo del modelo | Entregar tal cual (la proporción sigue siendo ≈16:9/9:16); si se requiere precisión, añadir bordes hasta 1920×1080 / 1080×1920 |
| Las dos portadas no parecen un conjunto | Cada imagen de texto a imagen se desvía por su cuenta | Debe ser una cadena de anclaje: la vertical se deriva usando el ancla horizontal como imagen de referencia |
Para una lista completa de problemas y experiencia arquitectónica, ver references/pitfalls.md; para más detalles sobre la ruta de animación HTML, ver references/html-animation.md.
Recursos
scripts/doctor.py— Verificación del entorno (ejecutar al inicio de cada episodio, completar MISSING y luego comenzar)scripts/verify_output.py— Compuerta de video final (especificaciones/duración/sonoridad/fotogramas negros/silencio, solo entregar si todo pasa)scripts/gen_html_deck.py— Guion → Página de presentación HTML de colaboración texto-imagen + lista deck.json (entrada de la ruta HTML)scripts/render_html_frames.mjs— Renderizado determinista fotograma a fotograma con Playwright (solo captura la ventana de animación, reutiliza el último fotograma para segmentos estáticos)scripts/compose_html_video.py— Síntesis de secuencia de fotogramas + voz + subtítulos con temporización real + BGM ducking (ruta HTML)scripts/tts_synth.py— Síntesis por lotes de edge-tts (corrección de pronunciación + línea de tiempo real a nivel de oración + puerta voice_confirmed)scripts/compose_video.py— Síntesis de páginas estáticas + xfade + subtítulos oración por oración (ruta alternativa estática)scripts/export_txt.py/scripts/import_txt.py— Sincronización bidireccional entre guion y txt editablescripts/preview_voices.py— Página de comparación de 5 voces (reproducible sin conexión)scripts/export_frames.ps1— Exportación de fotogramas 1920×1080 con PowerPoint COM (primera opción para la ruta estática)scripts/pdf_to_frames.py— Renderizado de fotogramas PDF con pymupdf (opción secundaria para la ruta estática)references/douyin-covers.md— Proceso completo de portadas Douyin: reglas de texto / plantilla de prompts / cadena de anclaje / lista de verificación (estándar para cada episodio, ambos tamaños)references/html-animation.md— Ruta de animación HTML: conclusiones de viabilidad / reglas de maquetación / problemas comunes (lectura obligatoria)references/pacing-and-gates.md— Límites de ritmo / verificación de datos / doble compuerta / BGM / tabla de alcance de modificación (lectura obligatoria)references/playbook.md— Manual del proceso completo: tabla de elementos a confirmar / stack tecnológico / ruta de optimizaciónreferences/pitfalls.md— Lista de problemas comunes y experiencia arquitectónicareferences/subtitle-style.md— Manual de estilos de subtítulos ASS (orden inverso de colores / efecto de brillo / preajustes de estilo)assets/narration-template.json— Plantilla JSON del guion
Dependencias: playwright-core (node_modules en el directorio raíz de la habilidad, ya instalado); orden de detección de Chromium
caché ms-playwright → Edge del sistema, si ambos faltan, especificar con --browser.