HyperFrames-Gradle: Transformar AsciiDoc em vídeo MP4
Publié le 31 May 2026
Há duas semanas, eu lancei`capsule-gradle`— um plugin que transforma um deck reveal.js em cápsula de vídeo WebM com TTS. Hoje, estou adicionando um novo plugin : hyperframes-gradle. Ele faz algo que o capsule-gradle não faz : transformar o AsciiDoc diretamente em vídeo MP4, sem passar por reveal.js.
Aqui está por que esse plugin existe, como ele se articula com o existente, e o que o motor HyperFrames da HeyGen traz para o pipeline de produção de conteúdo.
O Buraco no Pipeline de Vídeo
Meu pipeline documental produz dois tipos de vídeos :
-
Cápsula de revisão (capsule-gradle) — um deck reveal.js capturado em WebM com
narration TTS. Perfeito para rever um módulo.
-
Slides de animação (slider-gradle) — um deck reveal.js HTML interativo para
o formador presencial
Mas falta um terceiro formato: o vídeo standalone.
Caso de uso |
solução atual |
Falta |
Slides do formador |
slider-gradle → reveal.js |
✅ |
Cápsula de revisão |
capsule-gradle → WebM |
✅ |
vídeo teaser |
Nenhuma |
�❌ |
Demo técnica animada |
Nenhuma |
❌ |
Doc-para-vídeo |
Nenhuma |
�❌ |
O primeiro caso de uso é crítico: como gerar automaticamente um vídeo de 60 segundos que apresenta um projeto ou um módulo, com animações GSAP, narration TTS, música de fundo — tudo desde o mesmo arquivo AsciiDoc os slides ?
Capsule-gradle não pode responder: ele já precisa de um deck reveal.js. slider-gradle produz bem esse deck, mas não foi projetado para a renderização de vídeo. Precisava de um pipeline direto: AsciiDoc → vídeo.
HyperFrames : O Motor
Descobrihttps://github.com/heygen-com/hyperframes[HyperFrames] il y a alguns dias. É um framework open-source (Apache 2.0) criado pelo HeyGen, o unicórnio do vídeo IA. 22 700 estrelas no GitHub. O pitch se encaixa em uma frase :
Escreva HTML. Renderize vídeo. Construído para agentes.
O princípio: você escreve HTML com`data-*`attributes, você referencia uma animação GSAP (ou CSS, Lottie, Three.js…), e o motor renderiza tudo em MP4 via Puppeteer (headless Chrome) + FFmpeg. Resultado determinístico: mesmo input, mesmas frames, mesmo vídeo.
<div id="stage" data-composition-id="intro" data-start="0" data-width="1920" data-height="1080">
<video class="clip" data-start="0" data-duration="6" data-track-index="0"
src="background.mp4" muted playsinline></video>
<h1 id="title" class="clip" data-start="1" data-duration="4" data-track-index="1">
Formation Docker & Kubernetes
</h1>
<audio data-start="0" data-duration="6" data-track-index="2"
data-volume="0.3" src="music.wav"></audio>
<script src="https://cdn.jsdelivr.net/npm/gsap@3/dist/gsap.min.js"></script>
<script>
const tl = gsap.timeline({ paused: true });
tl.from("#title", { opacity: 0, y: 40, duration: 0.8 }, 1);
window.__timelines = window.__timelines || {};
window.__timelines.intro = tl;
</script>
</div>
O que torna o HyperFrames diferente do Remotion? Sem React, sem bundler, sem JSX. HTML simples que os agentes de IA sabem escrever nativamente. É exatamente ajustado para o meu pipeline: planner-gradle com deepseek pode gerar esse HTML a partir de um plano SPG/SPD, e um plugin Gradle pode convertê-lo para MP4.
A Arquitetura do Plugin
hyperframes-gradle segue o mesmo padrão que todos os meus plugins: o padrão « Plugin Indépendant + Racine Consommateur ».
hyperframes-gradle/
├── settings.gradle.kts ← racine consommateur (dogfood)
├── build.gradle.kts ← 3 lignes : apply plugin hyperframes
├── hyperframes-plugin/ ← BUILD INDÉPENDANT
│ ├── gradlew ← son propre wrapper
│ ├── build.gradle.kts ← java-gradle-plugin
│ ├── src/main/kotlin/education/cccp/hyperframes/
│ │ ├── HyperframesPlugin.kt
│ │ ├── GenerateHyperframesHtmlTask.kt
│ │ ├── RenderHyperframesTask.kt
│ │ └── HyperframesExtension.kt
│ ├── .agents/ ← gouvernance agent
│ └── doc/
│ └── HYPERFRAMES_ARCHITECTURE.adoc
└── video.yml ← configuration dogfood
O Pipeline em Quatro Etapas
Failed to generate image: PlantUML preprocessing failed: [From <input> (line 8) ] @startuml skinparam backgroundColor #FEFEFE skinparam defaultFontSize 11 title Pipeline hyperframes-gradle rectangle "AsciiDoc fonte" as adoc #LightYellow ^^^^^ Syntax Error? (Assumed diagram type: activity) @startuml skinparam backgroundColor #FEFEFE skinparam defaultFontSize 11 title Pipeline hyperframes-gradle rectangle "AsciiDoc fonte" as adoc #LightYellow rectangle "AsciidoctorJ" as asciidoctorj #LightBlue rectangle "HTML HyperFrames (data-* attrs)" as html #LightGreen rectangle "HyperFrames CLI\n(Node.js 22+)" as cli #Lavender rectangle "video.mp4" as mp4 #Gold adoc -right-> asciidoctorj : parse blocs customs asciidoctorj -right-> html : génère HTML html -right-> cli : ProcessBuilder\nnpx hyperframes render cli -right-> mp4 : Puppeteer + FFmpeg @enduml
-
AsciidoctorJ analisa o fonte AsciiDoc e extrai os blocos personalizados
[hyperframes-composition], [hyperframes-track], [hyperframes-animation].
-
GenerateHyperframesHtmlTask gera o HTML HyperFrames com as
`data-*`atributos correspondentes.
-
RenderHyperframesTask chama a CLI HyperFrames via`ProcessBuilder`:
npx hyperframes render --input index.html --output video.mp4.
-
O MP4 é implantado em`output/`com um`metadata.json`para a orquestração.
O DSL AsciiDoc
O verdadeiro valor agregado do plugin é o DSL AsciiDoc. O usuário nunca escreve HTML. Ele anota seu documento AsciiDoc existente :
= Formation Docker & Kubernetes
:hyperframes-width: 1920
:hyperframes-height: 1080
:hyperframes-fps: 30
[hyperframes-composition, id="intro"]
== Introduction
Le titre apparaît avec un fondu GSAP sur fond vidéo.
[hyperframes-track, index=0, start=0, duration=6]
video::assets/background.mp4[muted, playsinline]
[hyperframes-track, index=1, start=1, duration=4]
Formation Docker & Kubernetes
[hyperframes-animation, type=gsap]
const tl = gsap.timeline({ paused: true }); tl.from("#title", { opacity: 0, y: 40, duration: 0.8 }, 1); window.timelines = window.timelines || {}; window.__timelines.intro = tl;
Os atributos docinfo (:hyperframes-width:) configuram as dimensões. Os blocos personalizados definem as composições e as faixas. O bloco `[hyperframes-animation]`contém o código GSAP bruto — que o agente IA pode gerar a partir de uma descrição em linguagem natural
O Bridge Node.js
O único ponto de atrito técnico: HyperFrames está em Node.js/TypeScript, e meus plugins são em Kotlin/JVM. A solução é um`ProcessBuilder`:
class RenderHyperframesTask : DefaultTask() {
@TaskAction
fun render() {
val process = ProcessBuilder(
"npx", "hyperframes", "render",
"--input", inputHtml.absolutePath,
"--output", outputMp4.absolutePath
)
.inheritIO()
.start()
val exitCode = process.waitFor()
require(exitCode == 0) {
"HyperFrames render failed with exit code $exitCode"
}
}
}
Zero acoplamento código JVM ↔ Node.js. O contrato é por linha de comando e arquivos no disco. É o mesmo padrão que`plantuml-gradle` (que chama a CLI PlantUML) ou`slider-gradle`(que chama AsciidoctorJ). Nada de novo sob o sol — apenas aplicado a uma ferramenta mais recente.
Dois plugins de vídeo, dois usos
cápsula-gradle |
hyperframes-gradle |
Source |
Deck reveal.js (HTML existente) |
AsciiDoc → HTML HyperFrames |
caso de uso |
Cápsula de revisão |
vídeo explicativo standalone |
natureza |
slides → vídeo |
Documento → vídeo |
entregue |
Playwright Java → WebM |
HyperFrames CLI → MP4 |
Animação |
Transições reveal.js nativas |
atributos de dados GSAP/CSS |
Pilha |
100% JVM (Kotlin) |
JVM + Node.js CLI externo |
Eles não se substituem. Eles se complementam. A cadeia de valor completa:
AsciiDoc ──→ slider-gradle ──→ deck reveal.js ──→ capsule-gradle ──→ WebM (cápsula de revisão)
AsciiDoc ──→ hyperframes-gradle ──→ MP4 (vídeo autônomo)
O utilizador escreve um único ficheiro AsciiDoc. slider-gradle produz os slides. capsule-gradle produz a cápsula de revisão. hyperframes-gradle produz o vídeo teaser e as demonstrações técnicas
Os 6 EPICs da Roadmap
O plugin é estruturado em 6 EPICs :
EPIC |
Descrição |
Prioridade |
HF-0 |
Bootstrap governança + enquadramento da arquitetura |
✅ CONCLUÍDO |
HF-1 |
Plugin Gradle stub + Integração AsciidoctorJ |
P0 |
HF-2 |
Bridge CLI HyperFrames (ProcessBuilder → npx → MP4) |
P1 |
HF-3 |
Costumes do DSL AsciiDoc (blocos, docinfo, modelos) |
P1 |
HF-4 |
Integração runner-gradle (metadata.json) |
P2 |
HF-5 |
Modelos prontos para uso (title-card, code-diff, captions) |
P3 |
HF-6 |
CI + publicação Maven Central / Gradle Portal |
P3 |
A sessão 000 (bootstrap) já terminou. A sessão 001 atacará HF-1 : o stub do plugin Gradle e a integração AsciidoctorJ.
Por que funciona
Três razões :
-
HyperFrames é "built for agents". Meu pipeline depende de agentes de IA
(planner-gradle + deepseek) que geram conteúdo. HyperFrames aceita de HTML bruto — o formato que os LLMs dominam melhor. Sem React, não de JSX, sem curva de aprendizagem para o agente.
-
O DSL AsciiDoc é natural. Todo o meu ecossistema fala AsciiDoc.
slider-gradle, codex-gradle, training-gradle — todos consomem do`.adoc`. Adicionar blocos personalizados`[hyperframes-composition]`é uma extensão lógico, não uma ruptura.
-
O bridge Node.js é um padrão comprovado. ProcessBuilder fora da JVM,
isso é o que eu já faço para PlantUML, Graphviz, Piper. Adicionar HyperFrames não muda nada na arquitetura — é mais uma ferramenta externa, pilotado a partir do Gradle.
|
A verdadeira força do padrão é que não há nenhuma dependência npm em o build Gradle. O plugin não importa código Node.js. Ele executa uma comando shell. Se HyperFrames evolui ou quebra, o plugin não está acoplado — basta atualizar o comando. |
Conclusão: O elo faltante
Com hyperframes-gradle, meu pipeline de vídeo está completo. Eu tenho :
-
As slides interativas (slider-gradle)
-
As capsules de revisão (capsule-gradle)
-
vídeos standalone (hyperframes-gradle)
Três formatos. Um único arquivo fonte: o AsciiDoc.
O próximo objetivo é HF-1 : compilar o plugin e gerar um primeiro HTML HyperFrames a partir de um documento AsciiDoc anotado. A sessão 001 já está enquadrada.
hyperframes-gradle existe. A governança está instalada. O backlog est escrito. A arquitetura está documentada. O plugin nasceu.
Referências
-
Artigo 0124 — Arquitetura do Plugin Independente + Raiz do Consumidor
-
foundry/public/hyperframes-gradle/hyperframes-plugin/doc/HYPERFRAMES_ARCHITECTURE.adoc— Arquitetura detalhada