thời gian đọc: 8 minutes

Hai tuần trước, tôi đã ra mắt`capsule-gradle`— một plugin biến một bộ thẻ (deck) reveal.js trong capsule video WebM với TTS. Hôm nay, tôi thêm một plugin mới: hyperframes-gradle. Nó thực hiện một điều mà capsule-gradle không làm: chuyển đổi AsciiDoc trực tiếp thành video MP4, mà không thông qua reveal.js.

Đây là lý do tại sao plugin này tồn tại, cách nó kết nối với những gì hiện có, và những gì công cụ HyperFrames của HeyGen mang lại cho quy trình sản xuất nội dung.

Lỗ hổng trong Pipeline Video

Pipeline tài liệu của tôi tạo ra hai loại video:

  1. Capsule ôn tập (capsule-gradle) — một bản reveal.js được ghi lại dưới dạng WebM với

thuyết minh TTS. Hoàn hảo để xem lại một học phần.

  1. Slide hoạt hình (slider-gradle) — một bản reveal.js HTML tương tác cho

giảng viên đào tạo trực tiếp.

Nhưng vẫn còn thiếu một định dạng thứ ba: vidéo standalone.

Trường hợp sử dụng Giải pháp hiện tại Thiếu

Slide dành cho đào tạo viên

slider-gradle → reveal.js

Sẵn sàng.

Capsule ôn tập

capsule-gradle → WebM

Sẵn sàng.

Video teasing

Không có

❌

Bản demo kỹ thuật có hoạt ảnh

Không có

❌

Từ tài liệu sang video

Không có

❌

Trường hợp sử dụng đầu tiên mang tính then chốt: làm thế nào để tạo tự động một video dài 60 giây giới thiệu một dự án hoặc một module, với các hiệu ứng chuyển động GSAP, thuyết minh TTS, và nhạc nền — tất cả từ cùng một tệp AsciiDoc chỉ các slide thôi sao?

Capsule-gradle không thể phản hồi: nó đã cần một deck reveal.js. slider-gradle tạo ra deck này một cách chính xác, nhưng nó không được thiết kế để kết xuất video. Cần một pipeline trực tiếp: AsciiDoc → video.

HyperFrames: Bộ máy

Tôi đã khám phá rahttps://github.com/heygen-com/hyperframes[HyperFrames] il y a vài ngày. Đây là một framework mã nguồn mở (Apache 2.0) được tạo ra bởi HeyGen, kỳ lân của video AI. 22 700 sao trên GitHub. Phần giới thiệu gói gọn trong một câu:

Viết HTML. Render video. Xây dựng cho các agent.

Nguyên lý là: bạn viết HTML với các`data-*`thuộc tính, bạn tham chiếu một hiệu ứng GSAP (hoặc CSS, Lottie, Three.js…), và công cụ sẽ xuất tất cả ra định dạng MP4 via Puppeteer (headless Chrome) + FFmpeg. Kết quả mang tính xác định: cùng đầu vào, cùng các frames, cùng một video.

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

Điều gì khiến HyperFrames khác với Remotion? Không React, không bundler, không có JSX. Chỉ là HTML thuần mà các tác nhân AI có thể viết một cách tự nhiên. Nó được thiết kế chính xác cho pipeline của tôi: planner-gradle với `deepseek có thể tạo HTML này từ một bản kế hoạch SPG/SPD, và một plugin Gradle có thể chuyển đổi nó sang MP4.

Kiến trúc của Plugin

hyperframes-gradle tuân theo cùng một pattern với tất cả các plugin của tôi: pattern « Plugin Độc lập + Gốc Người tiêu dùng ».

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

Pipeline Bốn Bước

@startuml
skinparam backgroundColor #FEFEFE
skinparam defaultFontSize 11

title Pipeline hyperframes-gradle

rectangle "AsciiDoc\nnguồ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 : phân tích các phong tục
asciidoctorj -right-> html : tạo HTML
html -right-> cli : ProcessBuilder\nnpx hyperframes render
cli -right-> mp4 : Puppeteer + FFmpeg
@enduml
  1. AsciidoctorJ phân tích cú pháp nguồn AsciiDoc và trích xuất các khối customs

[hyperframes-composition], [hyperframes-track], `[hyperframes-animation]`Vui lòng cung cấp văn bản cần dịch.

  1. GenerateHyperframesHtmlTask tạo HTML HyperFrames với các

`data-*`các thuộc tính tương ứng.

  1. RenderHyperframesTask gọi CLI HyperFrames thông qua`ProcessBuilder`Vui lòng cung cấp nội dung cần dịch.

`npx hyperframes render --input index.html --output video.mp4`Bạn chưa cung cấp văn bản cần dịch. Vui lòng gửi đoạn văn bản tiếng Pháp mà bạn muốn tôi dịch sang tiếng Việt.

  1. MP4 được triển khai trong`output/`với một`metadata.json`cho việc điều phối.

DSL AsciiDoc

Giá trị gia tăng thực sự của plugin chính là DSL AsciiDoc. Người dùng không bao giờ viết HTML. Anh ấy chú thích tài liệu AsciiDoc hiện có của mình:

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

Các thuộc tính docinfo (:hyperframes-width:) cấu hình các kích thước. Các khối customs định nghĩa các composition và các track. Khối `[hyperframes-animation]`chứa mã GSAP thô — mà tác nhân AI có thể tạo ra từ một mô tả bằng ngôn ngữ tự nhiên.

Bridge Node.js

Điểm ma sát kỹ thuật duy nhất là: HyperFrames được viết bằng Node.js/TypeScript, và các plugin của tôi được viết bằng Kotlin/JVM. Giải pháp là một`ProcessBuilder`Vui lòng cung cấp văn bản cần dịch.

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

Không có sự ràng buộc mã nguồn giữa JVM ↔ Node.js. Hợp đồng được thực hiện thông qua dòng lệnh và các tệp trên đĩa. Đây là cùng một pattern với`plantuml-gradle` (gọi CLI PlantUML) hoặc`slider-gradle`(gọi AsciidoctorJ). Không có gì mới dưới ánh mặt trời — chỉ là áp dụng cho một công cụ mới hơn.

Hai Plugin Video, Hai Mục đích Sử dụng

capsule-gradle hyperframes-gradle

Nguồn

Deck reveal.js (HTML hiện có)

AsciiDoc → HTML HyperFrames

Trường hợp sử dụng

Ôn tập tóm tắt

Video giải thích độc lập

Thiên nhiên

Slide → video

Tài liệu → video

Kết quả render

Playwright Java → WebM

HyperFrames CLI → MP4

Hoạt ảnh

Các hiệu ứng chuyển cảnh native của reveal.js

Các thuộc tính dữ liệu (data-attributes) của GSAP/CSS

Ngăn xếp

100% JVM (Kotlin)

JVM + CLI Node.js bên ngoài

Chúng không thay thế cho nhau. Chúng bổ trợ cho nhau. Chuỗi giá trị đầy đủ:

AsciiDoc ──→ slider-gradle ──→ deck reveal.js ──→ capsule-gradle ──→ WebM (capsule ôn tập)

AsciiDoc ──→ hyperframes-gradle ──→ MP4 (video độc lập)

Người dùng viết một tệp AsciiDoc duy nhất. slider-gradle tạo ra các slide. capsule-gradle tạo ra capsule revision. hyperframes-gradle tạo ra video teaser và các bản demo kỹ thuật.

6 EPICs của Roadmap

Plugin được cấu trúc thành 6 EPICs:

EPIC Mô tả Ưu tiên

HF-0

Khởi tạo quản trị + định khung kiến trúc

✅ HOÀN THÀNH

HF-1

Gradle stub plugin + tích hợp AsciidoctorJ

P0

HF-2

Bridge CLI HyperFrames (ProcessBuilder → npx → MP4)

P1

HF-3

Tùy chỉnh DSL AsciiDoc (blocs, docinfo, templates)

P1

HF-4

Tích hợp runner-gradle (metadata.json)

P2

HF-5

Các mẫu sẵn dùng (title-card, code-diff, captions)

P3

HF-6

CI + xuất bản lên Maven Central / Gradle Portal

P3

Phiên 000 (bootstrap) đã kết thúc. Phiên 001 sẽ tấn công HF-1 : stub của plugin Gradle và tích hợp AsciidoctorJ.

Tại sao nó hoạt động

Ba lý do:

  1. HyperFrames được "built for agents". Pipeline của tôi dựa trên các agent AI

(planner-gradle + deepseek) tạo nội dung. HyperFrames chấp nhận HTML thô — định dạng mà các LLM thành thạo nhất. Không React, không không JSX, không có đường cong học tập cho agent.

  1. DSL AsciiDoc rất tự nhiên. Toàn bộ hệ sinh thái của tôi đều nói ngôn ngữ AsciiDoc.

slider-gradle, codex-gradle, training-gradle — tất cả đều tiêu thụ`.adoc`Vui lòng cung cấp văn bản cần dịch. Thêm các khối custom`[hyperframes-composition]`là một tiện ích mở rộng logic, không phải là một sự đứt gãy.

  1. Bridge Node.js là một pattern đã được kiểm chứng. ProcessBuilder bên ngoài JVM,

đó là những gì tôi đang làm cho PlantUML, Graphviz, Piper. Thêm HyperFrames không thay đổi gì về kiến trúc — đó chỉ là thêm một công cụ bên ngoài, được điều khiển từ Gradle.

Sức mạnh thực sự của pattern này là không hề có phụ thuộc npm nào trong build Gradle. Plugin này không nhập mã Node.js. Nó thực thi một lệnh shell. Nếu HyperFrames thay đổi hoặc bị lỗi, plugin sẽ không bị ảnh hưởng theo — chỉ cần cập nhật lệnh.

Kết luận: Mắt xích còn thiếu

Với hyperframes-gradle, pipeline video của tôi đã hoàn tất. Tôi có:

  • Các slide tương tác (slider-gradle)

  • Các capsules de révision (capsule-gradle)

  • Các video standalone (hyperframes-gradle)

Ba định dạng. Một tệp nguồn duy nhất: AsciiDoc.

Mục tiêu tiếp theo là HF-1: biên dịch plugin và tạo một HTML HyperFrames đầu tiên từ một tài liệu AsciiDoc được chú thích. Phiên 001 đã được đóng khung.

hyperframes-gradle` đã tồn tại. Quản trị đã được thiết lập. Backlog được viết. Kiến trúc đã được lập tài liệu. Plugin đã ra đời.

Tham khảo

Bài viết liên quan