透過 CLI 產生影片
快速參考
# 撰寫設定檔 → 產生 JSON → 渲染
node scripts/gen_canvas.mjs /tmp/video-<name>.mjs /tmp/video-<name>.json
npx hypr-video-cli /tmp/video-<name>.json -o ./output/<name>.mp4
工作流程
- [ ] 步驟 1:閱讀參考資料並規劃場景
- [ ] 步驟 2:建立設定檔並產生 JSON
- [ ] 步驟 3:渲染並驗證
步驟 1 — 閱讀參考資料並規劃場景
1a. 閱讀以下參考資料(務必閱讀):
- gen-canvas.md — 設定規格:
theme()(24 種主題)、11 個角色輔助函數、autoTracks()、內聯animIn/animOut/kf、SVG 輔助函數、buildCanvas。常見陷阱會以 ⚠️ 標記標示。
1b. 規劃場景:識別影片類型、列出場景名稱與長度、為每個場景挑選最佳的 SVG 輔助函數、挑選最佳元素與表情符號。
1c. 根據規劃閱讀額外資料:
| 當使用時機 | 參考資料 |
|---|---|
| 使用 SVG 輔助函數(幾乎都會用到) | svg-helpers.md — 所有 65 個輔助函數的參數 |
| 選擇字型 | font-assets.md — 18 種內建字型與配對建議 |
| 添加表情符號 / unicode 裝飾 | icons.md |
步驟 2 — 建立設定檔並產生 JSON
2a. 撰寫一個設定檔 .mjs。設定檔與 JSON 請放在 /tmp/ 目錄中 — 絕對不要寫入 examples/。
export default function build(h) {
const {
makeShape, makeEffect, buildCanvas, theme, autoTracks,
svgVignette, svgDotGrid, svgGradientOrb, svgParticles,
svgCheckMark, svgNumberCounter, // ...依需求加入 SVG 輔助函數
} = h;
const t = theme("cyberpunk"); // 24 種主題 — 包含顏色、角色輔助函數與字型
const MAX = 25000;
// ── 全域圖層 ──
const g_dot = svgDotGrid("g_dot", { start: 0, end: MAX, opacity: 0.04, color: t.ACCENT });
const g_vig = svgVignette("g_vig", { start: 0, end: MAX, opacity: 0.6 });
// ── 場景 1:開場 (0–7s) ──
const s1_orb = svgGradientOrb("s1_orb", {
x: 360, y: 60, w: 1200, h: 960, start: 0, end: 7500, opacity: 0.10, color: t.ACCENT,
});
const s1_title = t.hero("s1_title", "產品名稱", {
x: 160, y: 340, start: 0, end: 7000,
animIn: ["blurIn", 1200], animOut: ["blurOut", 700],
kf: { scale: { dur: 7000, amp: 0.02 } },
});
const s1_div = makeShape("s1_div", "rect", t.ACCENT, {
x: 760, y: 510, w: 400, h: 3, start: 500, end: 6500,
animIn: ["expandIn", 500], animOut: ["fadeOut", 300],
});
const s1_sub = t.subtitle("s1_sub", "這裡放標語", {
x: 260, y: 540, start: 700, end: 6500,
animIn: ["fadeIn", 800], animOut: ["fadeOut", 500],
});
// ── 場景 2:功能特色 (6.5–16s) ──
// ...更多場景遵循相同模式
const elements = [g_dot, g_vig, s1_orb, s1_title, s1_div, s1_sub /* ... */];
return buildCanvas({
bg: t.BG, maxTime: MAX,
// t.fonts 是一個物件 { Montserrat: {...}, "Fira Code": {...}, ... } — 不是陣列
// 要加入額外字型(例如中文字型),請使用物件展開運算符:
fontAssets: {
...t.fonts,
"Noto Sans SC": { url: "skill/assets/fonts/NotoSansSC-Variable.ttf", fileType: "ttf" },
},
elements, tracks: autoTracks(elements),
fps: 30, quality: "medium",
});
}
node scripts/gen_canvas.mjs /tmp/video-<name>.mjs /tmp/video-<name>.json
2b. 在渲染前,請驗證以下事項:
- 所有文字都使用角色輔助函數 (
t.hero…t.eyebrow) — 僅在需要自訂字型/大小/顏色時(例如程式碼區塊、使用Noto Sans SC的中文文字)才直接使用makeText - 每個可見元素都要有
animIn+animOut;元素之間的間隔時間為 300–500 毫秒 - SVG 背景透明度 ≤ 0.15;每個場景使用 2–4 個輔助函數;全域圖層跨越
0–MAX maxTime>= 最後一個元素的end時間
步驟 3 — 渲染並驗證
npx hypr-video-cli /tmp/video-<name>.json -o ./output/<name>.mp4
CLI 參數:--fps 24|30|60、--quality low|medium|high|very_high、--format mp4|mov|mp3、--width N、--height N、-q (安靜模式)。
如果渲染失敗 → 請檢查 gen-canvas.md 中的 ⚠️ 常見陷阱
關鍵規則
maxTime>= 最大元素的end時間 — 設定太小會導致元素被截斷- 設定檔請放在
/tmp/— 絕對不要寫入examples/ - 務必使用現代 API —
theme()+ 角色輔助函數 + 內聯animIn/animOut/kf+autoTracks()。 - 場景結構 — 元素 ID 請以
s1_/s2_… 為前綴,依場景區分;場景之間使用註解區塊// ── 場景 N:標題 (Xs–Ys) ── - 轉場效果 需要相鄰元素在同一音軌上(建議使用基於特效的閃爍/故障切換)
- 使用
backgroundColor時請透過bg: t.BG— 不要使用全螢幕背景形狀 gen_canvas.mjs路徑 — 請從技能根目錄執行:node scripts/gen_canvas.mjs(不是skill/scripts/)t.fonts是一個物件,不是陣列 — 請使用{ ...t.fonts, "額外字型": { url: "...", fileType: "ttf" } }來新增字型。切勿使用[...t.fonts](陣列展開)