HyperFrames-Gradle : Chuyển đổi AsciiDoc thành video MP4
Đăng ngày 31 May 2026
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:
-
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.
-
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
-
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.
-
GenerateHyperframesHtmlTask tạo HTML HyperFrames với các
`data-*`các thuộc tính tương ứng.
-
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.
-
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:
-
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.
-
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.
-
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
-
foundry/public/hyperframes-gradle/hyperframes-plugin/doc/HYPERFRAMES_ARCHITECTURE.adoc— Kiến trúc chi tiết