用 HyperFrames 剪 Reels:一次不算成功的換工具實驗

hyperframes cover

最近在做一支主打 Salsa 雙人課的招生 Reels,前半段用 Remotion 把腳本組裝完,剪輯階段本來一切順利。HeyGen 開源的 HyperFrames 剛好上線,主打「寫 HTML、渲染成 MP4,專為 agent 設計」,而且內建一個可以把 Remotion 專案直接翻譯過去的 skill。我問 Claude Code:

「你可以用 HyperFrames 剪同一支影片嗎?」

Claude 建議先移植過去試試看,我說「先試試,效果好就會換」,於是就有了這篇。

移植:交給內建的 skill 處理

HyperFrames 有一個 remotion-to-hyperframes skill,專門做「把現有 Remotion 專案的 React 原始碼翻成 HyperFrames 的 HTML」這件事。Claude 先跑了一個 lint script 掃過我們的 Remotion 原始碼,確認沒有翻不動的地方(像 useState、非同步的 calculateMetadata 這種),再照 skill 附的 API 對照表把 <Sequence><Audio><OffthreadVideo> 這些元件改寫成對應的 data-* attribute。

我們這支片很單純:七段影片依序播放,配八段對齊的 VO,沒有動畫或特效(特效留給 CapCut 手動做)。這種案例翻譯起來幾乎是機械式的,半小時內 Claude 就把整支片的時間軸搬過去,渲染也一次成功。HyperFrames 內建的 npm run check 一個指令跑完 lint、runtime、layout、motion、對比度檢查,這點確實比我們在 Remotion 裡手動抽格核對安全區要方便。

「音軌有問題」

後續調整時間軸、重新渲染幾次之後,我聽出不對勁,回報:

「音軌有問題。」

Claude 用 Whisper 把渲染出來的音軌轉錄出來核對,發現某一句台詞被排到完全錯誤的位置,另一句該出現的地方反而是靜音。查下去發現是 HyperFrames 的素材快取機制在搞鬼:時間軸改版後,快取沒有正確更新,等於拿舊排程拼接。加上 --frames-cache-dir off 關掉快取就解決了,Claude 順手把這個參數寫進 package.jsonrender script,之後不用每次手動加。

同一份原始碼,渲染兩次、兩種錯法

以為關掉快取就沒事了,後來加了一段收尾片段之後,音軌又亂了。這次 Claude 直接拿同一份 index.html 渲染了兩次做對照,結果兩次的錯法還不一樣,也就是說渲染流程本身有競態條件,不是快取的問題了。

Claude 查到官方文件裡有一條:本機渲染可能因字體、Chrome 版本而不確定,用 --docker 模式可以拿到確定性輸出。我說「do it」,Claude 開了本機的 Docker Desktop,重新用 --docker 渲染一次,再用 Whisper 逐句核對音軌,這次順序終於完全正確。代價是渲染時間從本機的 1.5 分鐘暴增到 6.5 分鐘,還多了「本機要開著 Docker Desktop」這個相依性。

哪個比較可靠?

整個過程走完,我直接問 Claude:

「你覺得 HyperFrames 跟 Remotion 哪一個可靠?」

Claude 的回答,濃縮起來是:這支片在 Remotion 那邊全程只出過一次跟 ffmpeg 濾鏡有關的音檔問題,跟 Remotion 本身的渲染邏輯無關;HyperFrames 則是連續踩到兩個直接影響核心渲染流程的問題,一個是快取,一個是本機渲染的非確定性。對於 VO 要精準對齊畫面的短影音來說,音軌排程的可靠性幾乎是不能妥協的底線,HyperFrames 這次剛好命中要害,所以結論是先留在 Remotion。

不是說 HyperFrames 不好,它的 lint/check 工具、純 HTML/CSS authoring 的直覺性、內建的 skills 系統都是實打實的優點,只是這次「可靠性」沒有贏過已經用習慣的 Remotion。之後如果這個非確定性問題修掉了,會是值得重新考慮的選項。