Communitygithub.com

khmer-money-explainer

Crea un video explicativo horizontal de 8 a 10 minutos en idioma jemer sobre una decisión financiera de la vida real, con un estilo limpio y cálido de figuras de palo (personajes originales, etiquetas de dinero, frascos, gráficos, un narrador tranquilo, fuentes citadas), renderizado con Remotion y con voz de KiriTTS.

¿Qué es khmer-money-explainer?

Esta habilidad está diseñada para crear videos educativos animados en jemer que analizan decisiones financieras cotidianas, como alquilar vs comprar, salario y deuda, franquicia vs marca propia, o tontina vs banco. El video sigue a dos personas comunes enfrentando la misma elección, realiza los cálculos aritméticos en voz alta y muestra quién termina mejor, dejando al espectador la capacidad de decidir por sí mismo. Está optimizado para la audiencia camboyana, con un estilo visual único de figuras de palo, personajes originales (incluyendo una guía con krama) y un narrador calmado. La habilidad se apoya en Remotion para la renderización y KiriTTS para la locución, y sigue un flujo de trabajo estricto que incluye investigación con fuentes primarias camboyanas, creación de scripts detallados, y un riguroso control de calidad. Se debe usar cuando el usuario solicite un explicador de finanzas o negocios en jemer, un video de "quién termina con más" o "cuál es mejor", un explicador con figuras de palo para una audiencia camboyana, otro video "como el de la tontina", o quiera ideas de temas para dicho canal.

Compatible con~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/SopheaktraKP/khmer-money-explainer-skill/tree/HEAD

Preguntar en tu IA favorita

Abre un nuevo chat con esta habilidad de agente ya precargada.

Documentación

Explicador de dinero en jemer

Cada video sigue a dos personas comunes a través de la misma decisión sobre dinero, hace la aritmética en voz alta y deja al espectador capaz de decidir por sí mismo. Los espectadores se quedan por los números y confían en el canal porque los números son honestos.

El ejemplo de trabajo es el video de tontina vs banco en templates/project/ (src/story/).

Reglas que protegen el canal

  • Solo trabajo original. La investigación de estilo puede mirar otros canales, pero nunca copiar sus guiones, personajes, miniaturas, logotipos o tomas, y nunca nombrarlos en un video o descripción. Nuestro elenco, historias e identidad visual (incluyendo la guía con krama) son propios.
  • Dinero honesto. Muestra los supuestos en pantalla. Da ambos lados, incluidos los riesgos de la opción que parece mejor. Da preguntas para hacer, no una recomendación personal. Cada descripción termina con una línea de no-asesoría-financiera y dice que los personajes son ficticios.
  • Personas reales se quedan fuera. Las acusaciones de fraude contra personas o empresas nombradas no son el trabajo de este formato. Describe patrones de casos reportados, enlazados en la descripción.
  • Gastos: la voz cuesta créditos de KiriTTS: el piloto de 1,100 caracteres usó 433, así que un video de 9 minutos tiene aproximadamente 3,000-3,500. Revisa get_usage antes de poner la voz, informa al usuario la estimación y obtén la aprobación del guion primero.

Flujo de trabajo

1. Tema

Si el usuario no da un tema, sugiere 3 con una línea cada uno. Un tema fuerte es una bifurcación que todos en Camboya reconocen, tiene números que pueden ser referenciados y tiene un giro donde la respuesta obvia es incorrecta o incompleta. Busca lo que sea actual antes de sugerir.

Acuerda al inicio, y solo pregunta sobre lo que aún no se sabe: tema, voz (por defecto Maly; la cuenta puede tener voces clonadas, ver list_voices), y nombre del canal (CHANNEL en story.tsx; vacío oculta la insignia).

2. Investigación y aritmética

  • Usa fuentes primarias camboyanas donde existan: Banco Nacional de Camboya, Instituto Nacional de Estadística, hojas de tasas bancarias, notas fiscales de bufetes de abogados, prensa reputable. Anota las fechas de publicación: las tasas y las reglas fiscales cambian.
  • Reescribe scripts/calc.py para el tema. Cada número en pantalla y en la narración proviene de ahí y se escribe en src/story/numbers.json. Añade comprobaciones de cordura. Ejecuta varios escenarios, incluyendo uno donde el "ganador" pierde.
  • Separa lo que está referenciado de lo que está supuesto, y etiqueta los valores supuestos en pantalla con <Note>. Si un hecho no puede ser referenciado, enmárcalo como un supuesto claro o elimínalo, e informa al usuario.

3. Guion

Alrededor de 7,000-9,000 caracteres jemeres para 8-10 minutos; la voz del piloto corrió a unos 15 caracteres por segundo. Un compás es una o dos oraciones de alrededor de 70 caracteres, así que un video de 9 minutos tiene aproximadamente 100-120 compases. Lee references/script-formula.md para la estructura y las reglas de escritura en jemer.

Escríbelo en src/story/script.json (las escenas contienen compases; formato abajo) y muestra al usuario el guion completo en jemer con las fuentes y supuestos. Espera la aprobación antes de dar voz. El usuario es la autoridad en redacción y términos en jemer.

4. Configura el proyecto

Copia templates/project/ a una nueva carpeta, ejecuta npm install, luego reemplaza src/story/script.json, src/story/story.tsx y scripts/calc.py. Deja src/engine/ en paz a menos que añadas algo reutilizable. Usa una ruta corta (ver Problemas).

5. Prueba visual antes de gastar créditos

python scripts/calc.py
python scripts/build_timeline.py --placeholder
python scripts/check_numbers.py
npx tsc --noEmit
node scripts/stills.mjs out/look/x_ 100,400,900 0.5

Revisa los fotogramas tú mismo, contra la lista de verificación en references/visual-style.md. Una vez con voz, revisa cada línea dos veces, cerca de su inicio y cerca de su final: las imágenes fijas tomadas solo al final ocultan las tarjetas que permanecen vacías mientras la voz se acumula hasta un número. Escribe las escenas una por una y revisa cada una, porque los problemas de diseño son mucho más baratos de arreglar ahora.

6. Voz

python scripts/tts_todo.py

Esto lista solo los compases que son nuevos o han cambiado. Para cada uno, llama a KiriTTS text_to_speech con el campo tts del compás (o text) y una voz consistente, dejando sin configurar los ajustes de entrega. Descarga la URL a voice/<id>.mp3 (los enlaces caducan en aproximadamente un día) y regístralo con python scripts/tts_todo.py --done <id> <speech_id>. Un clip por compás significa que una palabra incorrecta cuesta una oración de arreglo.

Las señales precisas por palabra son opcionales: guarda la salida de get_word_timestamps como voice/<id>.words.json, luego usa at('b03', 'word'). Las fracciones como at('b03', .5) suelen ser suficientes. Escucha los números, nombres y palabras extranjeras; si KiriTTS lee mal una, añade una ortografía tts para ese compás.

7. Línea de tiempo, sonido, renderizado

python scripts/build_timeline.py
python scripts/make_audio.py
npx remotion render src/index.ts Main out/video.mp4 --codec h264 --crf 18 --muted
ffmpeg -y -i out/video.mp4 -i out/mix.wav -map 0:v:0 -map 1:a:0 -c:v copy -c:a aac -b:a 192k -shortest out/final.mp4
python scripts/qa.py out/final.mp4 out/qa
npx remotion still src/index.ts Thumbnail out/thumb.png

Los videos largos toman tiempo, así que ejecuta el renderizado en segundo plano. Renderiza un piloto corto de las primeras escenas para la revisión del usuario antes del video completo cuando el aspecto o la voz sean nuevos.

8. QA

Lee out/qa/report.md, y mira cada hoja de contactos. Investiga fotogramas negros o congelados y volumen lejos de -15 LUFS. Verifica que cada cifra en pantalla coincida con numbers.json y que ningún texto en jemer esté cortado o superpuesto.

9. Entrega

Envía el mp4 y la miniatura con SendUserFile. También escribe out/description.md en jemer, que contenga: un gancho, un resumen trabajado con los supuestos, riesgos, preguntas para hacerte a ti mismo, las líneas de personajes ficticios y no-asesoría-financiera, un aviso de comentario, capítulos con marcas de tiempo reales de timeline.json, enlaces a fuentes y hashtags. Nunca subas o publiques sin que el usuario lo pida.

Formato de script.json

{ "gap": 0.3, "scene_gap": 0.7, "tail": 1.5,
  "scenes": [{ "id": "Hook", "chapter": 0, "music": "light", "beats": [
    { "id": "h1", "text": "Oración en jemer", "tts": "ortografía hablada opcional", "sfx": [{"at": 0.75, "type": "coin"}] }
  ]}]}
  • id de una escena debe coincidir con un componente en SCENES en story.tsx.
  • chapter indexa CHAPTERS; 0 es el gancho y oculta la barra.
  • music: light, tense o resolve.
  • tipos de sfx: pop whoosh coin cash ding thud tick paper sad tada alarm. at es una fracción del compás. Úsalos en revelaciones, no en cada línea.

Escribir escenas

Lee src/story/story.tsx: es la referencia de cómo se escribe una escena. En resumen, const {f, at} = useScene() da el fotograma y los tiempos del compás, y cada elemento entra a través de <Show at={...} out={...} x y>. Nada se temporiza en segundos, por lo que cambiar la voz nunca rompe una escena.

Partes disponibles:

  • engine/Figure: caras, poses, caminar y accesorios en la mano. Define cada personaje una vez al principio de la historia.
  • engine/Props: Title, Label, Chip, Tag, Bubble, ThoughtCloud, Jar, Coin, Bill, MoneyBag, Calendar, Bank, House, Stall, Notebook, Phone, Rock, Umbrella, StormCloud, CheckMark, VsBadge, Arrow, FlyingMoney, Note, Moto, NameChip.
  • engine/Charts: Card, Counter, Bars, LineChart, MonthGrid, y money().
  • engine/Stage: mood, tint, zoom, focus.

Si un tema necesita un nuevo accesorio, dibújalo en el mismo estilo entintado en el archivo de la historia, y muévelo a engine/Props.tsx si es reutilizable.

Problemas (cada uno ha ocurrido)

  • Límite de ruta en Windows. Remotion falla cuando la ruta del proyecto es tan larga que los archivos dentro de node_modules superan los 260 caracteres: Failed to launch the browser process / spawn ... chrome-headless-shell en imágenes fijas, y errores getExecutableDir en renderizados completos. Apuntar a un navegador diferente no soluciona el segundo. Mantén el proyecto en una ruta corta como D:/videos/<nombre> (menos de unos 100 caracteres), y ejecuta npm install allí.
  • Espacio temporal. Cada paquete se copia a la carpeta temporal y no se elimina. Si C: está justo, configura RENDER_TMP para stills.mjs, y TEMP/TMP para la CLI, en una unidad más grande.
  • <Show> por defecto a x=0, y=0, lo que coloca un título centrado medio fuera de la pantalla. Siempre pasa x={960} para elementos centrados.
  • Los dígitos de Koulen se leen mal ("12" parece "I2"). Title ya establece dígitos y símbolos en la fuente del cuerpo; no lo evites.
  • Etiquetas sobre caras. La cabeza de una figura de pie alcanza aproximadamente y=470, y las manos levantadas van más alto. Coloca las etiquetas en y≈300-350 sobre una figura.
  • Remotion no escribe audio utilizable con --muted, así que siempre multiplexa mix.wav después como se muestra.
  • Los heredocs de Bash con mucho TSX pueden fallar al analizarse en algunos shells en Windows. Escribe los archivos fuente con la herramienta de archivo.

Skills relacionados