阅读时间 : 8 minutes

两周前,我发起了`capsule-gradle`— 一个转换牌组的插件 reveal.js 在 WebM 视频胶囊中带 TTS。今天,我添加了一个新插件: hyperframes-gradle. 它做了一件 capsule-gradle 不会做的事情 : 直接将 AsciiDoc 转换为 MP4 视频,无需使用 reveal.js。

这就是此插件存在的原因,以及它如何与现有功能集成, 以及 HeyGen 的 HyperFrames 引擎为内容生产管道带来了什么。

视频管道中的洞

我的纪录片流水线生成两种类型的视频:

  1. 复习胶囊 (capsule-gradle) — 一个使用 reveal.js 捕获的 WebM 幻灯片,带有

narration TTS。非常适合复习模块。

  1. 动画幻灯片 (slider-gradle) — 一个交互式的 reveal.js HTML 幻灯片牌组,用于

现场培训师

但它缺少第三种格式:独立视频。

用例 当前解决方案 缺少

培训师幻灯片

slider-gradle → reveal.js

✅

胶囊复习

capsule-gradle → WebM

✅

预告视频

没有

❌

动画技术演示

没有

❌

文档转视频

没有

❌

第一个用例是关键的:如何自动生成 一个60秒的视频,展示一个项目或模块,包含 GSAP 动画, TTS 旁白,以及背景音乐 — — 全部来自同一 AsciiDoc 文件 幻灯片怎么样?

Capsule-gradle` 无法响应:它已经需要一个 reveal.js 演示文稿。 slider-gradle 能够生成此牌组,但它并不是为视频渲染设计的。 需要一个 direct 的流水线:AsciiDoc → 视频。

HyperFrames : 引擎

我发现了https://github.com/heygen-com/hyperframes[超帧] il y a 几天。这是一个由 HeyGen 创建的开源框架(Apache 2.0), AI 视频独角兽。GitHub 上有 22,700 颗星。简介只需 一句话:

编写 HTML。渲染视频。专为代理构建。

原则:你编写HTML,使用`data-*`attributes, 您引用 一个 GSAP 动画(或 CSS、Lottie、Three.js…),引擎将其全部渲染为 MP4 通过 Puppeteer (无头 Chrome) + FFmpeg。结果确定性:相同的输入, 相同的帧,相同的视频。

<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>

HyperFrames 与 Remotion 有什么不同?没有 React,没有 bundler,无 JSX。AI 代理能够原生编写的原始 HTML。 这是 正是 为我的流水线量身定制的:planner-gradle 与 deepseek 可以从 SPG/SPD 计划生成此 HTML,并且还有 Gradle 插件 可以将其转换为 MP4。

插件的架构

hyperframes-gradle 遵循与我的所有插件相同的模式: 该 模式 « 独立插件 + 消费者根 »

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

四步管道

@startuml
skinparam backgroundColor #FEFEFE
skinparam defaultFontSize 11

title Pipeline hyperframes-gradle

rectangle "AsciiDoc\n源" as adoc #LightYellow
rectangle "AsciidoctorJ" as asciidoctorj #LightBlue
rectangle "HTML HyperFrames\n(data-* attrs)" as html #LightGreen
rectangle "HyperFrames CLI\n(Node.js 22+)" as cli #Lavender
rectangle "video.mp4" as mp4 #Gold

adoc -right-> asciidoctorj : 解析自定义块
asciidoctorj -right-> html : 生成 HTML
html -right-> cli : ProcessBuilder\nnpx hyperframes render
cli -right-> mp4 : Puppeteer + FFmpeg
@enduml
  1. AsciidoctorJ 解析 AsciiDoc 源码并提取自定义块

[hyperframes-composition], [hyperframes-track], [hyperframes-animation]。

  1. GenerateHyperframesHtmlTask 生成 HyperFrames HTML 与

`data-*`对应的属性。

  1. RenderHyperframesTask 通过 调用 HyperFrames CLI`ProcessBuilder`:

npx hyperframes render --input index.html --output video.mp4.

  1. MP4 已部署在`output/`带有一个`metadata.json`用于编配。

AsciiDoc DSL

插件的真正增值是 AsciiDoc DSL。用户 他从不编写 HTML。他会注释他现有的 AsciiDoc 文档:

= 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;

docinfo 属性(:hyperframes-width:) 设置尺寸。 自定义块定义了组成和轨道。块 `[hyperframes-animation]`包含原始的 GSAP 代码 — 该 AI 代理 可以从自然语言描述生成。

Node.js 桥

唯一的技术摩擦点:HyperFrames 使用 Node.js/TypeScript, 我的插件使用 Kotlin/JVM。解决方案是一个`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"
        }
    }
}

零耦合 JVM 代码 ↔ Node.js. 合约通过命令行 和磁盘上的文件。这是相同的模式`plantuml-gradle` (调用 PlantUML CLI) 或`slider-gradle`(调用 AsciidoctorJ). 太阳下没有新事物 — 只是应用于一个更新的工具。

两个视频插件,两种用法

胶囊Gradle hyperframes-gradle

来源

Deck reveal.js (现有HTML)

AsciiDoc → HTML HyperFrames

用例

复习胶囊

独立解释性视频

自然

幻灯片 → 视频

文档 → 视频

呈现

Playwright Java → WebM

HyperFrames CLI 转换为 MP4

动画

过渡 reveal.js 原生

GSAP/CSS 数据属性

栈

100% JVM (Kotlin)

JVM + Node.js 外部 CLI

他们不能互相取代。他们相互补充。完整的价值链 :

AsciiDoc ──→ slider-gradle ──→ deck reveal.js ──→ capsule-gradle ──→ WebM (胶囊复习)

AsciiDoc ──→ hyperframes-gradle ──→ MP4 (独立视频)

用户编写单个 AsciiDoc 文件。slider-gradle 生成幻灯片。 capsule-gradle 生产审查胶囊。 hyperframes-gradle 生产 预告视频和技术演示。

路线图的 6 个 EPICs

该插件由6个EPIC组成:

史诗 描述 优先级

HF-0

Bootstrap 治理 + 架构范围划定

✅ 完成

HF-1

Gradle 插件存根 + AsciidoctorJ 集成

P0

HF-2

Bridge CLI HyperFrames (ProcessBuilder → npx → MP4)

P1

HF-3

DSL AsciiDoc 习俗(块, 文档信息, 模板)

P1

HF-4

集成 runner-gradle (metadata.json)

P2

HF-5

可直接使用的模板(title-card, code-diff, captions)

P3

HF-6

CI + 发布至 Maven Central / Gradle Portal

P3

会话 000(引导)已经完成。会话 001 将攻击 HF-1 : Gradle插件的存根以及AsciidoctorJ的集成。

为什么有效

三个原因:

  1. HyperFrames 是为代理而构建的。我的流水线依赖于AI代理

(planner-gradle + deepseek) 生成内容。HyperFrames 接受 原始 HTML — LLMs 最擅长的格式。没有 React,没有 的JSX,代理没有学习曲线

  1. AsciiDoc DSL 是自然的. 我的整个生态系统都使用 AsciiDoc.

slider-gradle, codex-gradle, training-gradle — 都在消耗`.adoc`。 添加自定义块`[hyperframes-composition]`是一个扩展 是逻辑,而不是断裂。

  1. Node.js 桥接是一种经过验证的模式. ProcessBuilder 在 JVM 之外,

这是我已经为 PlantUML、Graphviz、Piper 做的事情。添加 HyperFrames 它不会改变架构 — — 这只是一个外部工具。 从 Gradle 控制。

该模式的真正力量在于,它没有 任何 npm 依赖 Gradle 构建。该插件不导入 Node.js 代码。它执行一个 shell命令。如果 HyperFrames 发生变化或出现故障,插件则不耦合 — 只需更新命令即可。

结论:缺失的环节

使用 hyperframes-gradle,我的视频管道已经完成。我有:

  • 这些 交互式幻灯片 (slider-gradle)

  • 复习胶囊 (capsule-gradle)

  • 独立的视频 (hyperframes-gradle)

三种格式。单一文件源: AsciiDoc。

下一个目标是 HF-1:编译插件并生成一个 第一个 HTML HyperFrames 从一个标注的 AsciiDoc 文档。会话 001 已经框定。

hyperframes-gradle 存在。治理已到位。待办列表 已被写成。 架构已被记录。 插件已诞生。

参考文献

相关文章