懶人包
- Motion 是 Mosaic 在 2026-06-18 發表的動態設計影片 agent,打一段需求就生出發表片、產品 demo、動態設計影片。它透過 MCP 接進 ChatGPT、Claude、Cursor,ChatGPT 端要開 Developer mode 自建 app 才接得上。
- Motion 用點數計費:Flex 6 美金 200 點、Pro 每月 29 美金 1,000 點起,官網沒列免費方案。一支影片花幾點看引擎、effort、長度,官方沒給固定數字(2026-10-26 查)。
- 官方文件寫明,Claude 連接器用的 Motion medium 引擎是「用程式碼做動態圖形,再把程式碼渲染成影片」。這條路用現成工具就做得出來:
claude -p寫 Canvas 動畫、Playwright 逐格擷取、ffmpeg 編碼。- 我用這套做了兩支 1080×1920 直式影片:9 秒片頭 270 格、8 秒數據圖 240 格,生成各約 1~2 分鐘,渲染 44 秒到 69 秒。
- 第一版數據圖的「%」被裁掉一半,丟一句修改意見就修好。另一支片頭因為逐格移動的雜訊顆粒,9 秒檔案有 50.9 MB,拿掉顆粒後是 0.91 MB。
- 自建版沒有配音、音樂、品牌抓取和時間軸編輯。要這些、或要交 After Effects/Premiere 工程檔,Motion 比較省事;只要短片頭和數據動畫,自建版夠用。
我在 IG 滑到一支 Reel,文案是「ChatGPT 还能这样玩?留言 Site 发你链接」,hashtag 標了 #MotionGraphic 和 #Mosaic。影片要登入才看得到,我沒看到完整內容,是從文案和 hashtag 對到 Mosaic 出的 Motion。
查下去發現,ChatGPT 本身不會做動態設計影片。是 ChatGPT 透過 MCP 呼叫第三方的 Motion,影片由 Motion 渲染。Motion 的 Claude 文件更直接寫出它的其中一個引擎是「程式碼變影片」,那我就用 Claude 自己做一套試試看。
Mosaic Motion 是什麼?
Motion 官網的介紹是「Motion is a video agent made by Mosaic」。給它一段需求,它會「plan the story, generate the shots, and bring them together with music and sound design」,也就是先規劃內容、生成鏡頭,再配上音樂和音效。官方部落格〈Introducing Motion〉發表於 2026-06-18。
| 項目 | 內容(2026-10-26 查官網與文件) |
|---|---|
| 開發者 | Mosaic(Mosaic AI Labs, Inc.) |
| 能做什麼 | 發表片、產品 demo、talking head、podcast 片段、動態設計 |
| 素材 | 可附影片、圖片、音訊、風格參考,或貼一支影片連結 |
| 修改 | 在對話裡回覆、在預覽畫面上畫出要改的地方,或直接編輯時間軸 |
| 匯出 | After Effects、Premiere Pro、DaVinci Resolve、Remotion、Hyperframes |
| 呼叫方式 | 網頁 app、REST API、MCP(ChatGPT、Claude、Cursor 等) |
| 價格 | Flex 6 美金 200 點(不訂閱、點數不過期);Pro 每月 29 美金 1,000 點起;企業版另議 |
| 免費方案 | 官網沒列 |
Mosaic 自己的剪輯器裡另有一個 Motion Graphics tile,是另一個功能:輸入既有影片加一段描述,替影片加上動態圖形,內建 VOX Style 和 Ali Abdaal Style 兩種預設。文件註明影片超過約 1~2 分鐘可能 timeout。
ChatGPT 怎麼接上 Motion?
照 Motion 的 ChatGPT 文件,流程是在 ChatGPT 自建一個連到 Motion MCP server 的 app:
- ChatGPT 的 Settings → Apps → Advanced settings,打開 Developer mode。
- 回到 Settings → Apps,按 Create app,填名稱、描述和 MCP URL。
- 驗證方式選 OAuth,在瀏覽器登入 Motion 帳號並同意授權。
- 對話時在輸入框選 Developer mode,啟用 Motion。
MCP server 有兩個網址:
| 網址 | 用途 |
|---|---|
https://mcp.motion.so/mcp | 主要版本,含帳務工具 |
https://mcp.motion.so/mcp/openai | 給 OpenAI 的版本,有影片工具和「sponsored generation」,沒有帳務工具 |
sponsored generation 由誰付費、涵蓋多少,文件沒有說明。主要版本提供的工具:
| 工具 | 作用 |
|---|---|
create_video | 開一個影片工作,對話裡出現即時更新的影片卡片 |
create_followup | 修改已完成的影片,或回覆待確認的問題 |
get_session_status | 查進度,完成後給 output.download_url |
list_engines/list_templates | 列出可用引擎和範本 |
show_plans_and_credits | 顯示方案、餘額和付款連結 |
Claude 也接得上
Motion for Claude 文件用的是第三個網址 https://mcp.motion.so/mcp/anthropic,可以加在 Claude 的連接器設定,或用 Claude Code 的 claude mcp add --transport http 加入後在 /mcp 登入。我沒有實際連過。
這份文件有兩個重點。連接器只支援 Motion medium 一個引擎,文件說它「can animate shapes, typography, layouts, and transitions, then render that code as a downloadable video」,也就是程式碼做動畫、再渲染成影片。AI 生圖、生影片、音樂、配音都不在連接器裡,要回 Motion app 才有。
不買點數,用 Claude 自己做一套行不行?
可以。Motion 背後怎麼渲染,官方沒寫細節,但「LLM 寫程式碼動畫、再交給瀏覽器逐格渲染」這條路,用 Claude Code、Playwright、ffmpeg 就能組出來。我的做法分成三支腳本:
| 腳本 | 對應 Motion 的 | 作用 |
|---|---|---|
gen.sh | create_video | 一句需求 → 單檔 Canvas 動畫 HTML |
fix.sh | create_followup | 舊 HTML + 一句修改意見 → 修正版 HTML |
render.mjs | 渲染 | HTML → 逐格 PNG → ffmpeg 編成 MP4 |
關鍵是渲染契約:renderFrame(t) 必須是純函式
要讓瀏覽器動畫能逐格輸出成影片,動畫不能靠 requestAnimationFrame 累積狀態,也不能在畫圖時呼叫 Math.random()。不然擷取第 120 格時,畫面取決於前面跑了多久,同一格每次畫出來都不一樣。
所以 gen.sh 給 Claude 的提示詞裡寫死一份契約:
- 一個 1080×1920 的
<canvas id="stage">。 window.DURATION宣告影片秒數(6~10 秒)。window.renderFrame(t)只依時間 t 畫出那一格;需要亂數就用固定種子的 PRNG,在載入時產生一次。- 一般瀏覽器開啟時自己循環播放;
window.__CAPTURE__為 true 時不自動播,交給渲染器控制。 - 文字要留在 80px 安全邊界內。
gen.sh 全文如下,風格那一行指定了馬賽克方塊母題,仿 Reel 裡看到的視覺:
#!/usr/bin/env bash
# 用法:bash gen.sh <輸出檔名.html> "<一句話需求>"
# 用 claude -p 把一句話需求生成「可逐格渲染」的單檔 HTML 動態設計。
set -euo pipefail
OUT="$1"; IDEA="$2"
DIR="$(cd "$(dirname "$0")" && pwd)"
PROMPT=$(cat <<EOF
You are a senior motion designer who writes code. Produce ONE self-contained HTML file (no external requests, no fonts from CDN; use system-ui / "Microsoft JhengHei" for CJK) that renders a 1080x1920 vertical motion graphic for this brief:
BRIEF: ${IDEA}
Hard contract (a headless renderer depends on it):
- A single <canvas id="stage" width="1080" height="1920"> scaled with CSS to fit the viewport (object-fit contain, black background).
- Define window.DURATION (seconds, between 6 and 10) and window.renderFrame = function(t) that draws the frame at time t (seconds) PURELY from t. No Math.random() at draw time — use a seeded PRNG created once. No requestAnimationFrame-based state, no setTimeout.
- Also auto-play in a normal browser: a requestAnimationFrame loop that calls renderFrame((elapsed % DURATION)) unless window.__CAPTURE__ is true.
- Style: premium motion design — easing curves (easeOutExpo, easeInOutCubic), staggered timing, a mosaic / tile grid motif (tiles flipping, assembling, revealing typography), bold kinetic typography, a strong 2-3 color palette, subtle grain. Text must stay inside the safe area with 80px margins.
- Output ONLY the HTML, starting with <!DOCTYPE html>. No markdown fences, no explanation.
EOF
)
env -u CLAUDECODE claude -p "$PROMPT" --model sonnet > "$DIR/$OUT.raw"
# 去掉模型偶爾加上的 ``` 圍欄
sed -e '/^```/d' "$DIR/$OUT.raw" > "$DIR/$OUT"
rm "$DIR/$OUT.raw"
grep -q "renderFrame" "$DIR/$OUT" && echo "OK $OUT ($(wc -c < "$DIR/$OUT") bytes)"
env -u CLAUDECODE 是把 CLAUDECODE 環境變數拿掉再呼叫 claude -p,我是在 Claude Code 的工作階段裡跑這支腳本的。最後的 sed 刪掉模型偶爾包上的 markdown 圍欄。
render.mjs:逐格擷取再 pipe 給 ffmpeg
渲染器開一個 1080×1920 的無頭 Chromium,先設好 __CAPTURE__,再從第 0 格跑到最後一格。每格呼叫一次 renderFrame(i / fps),把 canvas 轉成 PNG 直接寫進 ffmpeg 的 stdin,不落地存影格:
const browser = await chromium.launch();
const page = await browser.newPage({ viewport: { width: 1080, height: 1920 } });
await page.addInitScript(() => { window.__CAPTURE__ = true; });
await page.goto(pathToFileURL(path.resolve(htmlFile)).href);
await page.waitForFunction(() => typeof window.renderFrame === 'function');
const duration = await page.evaluate(() => window.DURATION);
const total = Math.round(duration * fps);
const ff = spawn('ffmpeg', [
'-y', '-loglevel', 'error', '-f', 'image2pipe', '-framerate', String(fps), '-i', '-',
'-c:v', 'libx264', '-pix_fmt', 'yuv420p', '-crf', '20', '-movflags', '+faststart', outFile,
], { stdio: ['pipe', 'inherit', 'inherit'] });
for (let i = 0; i < total; i++) {
const dataUrl = await page.evaluate((t) => {
window.renderFrame(t);
return document.getElementById('stage').toDataURL('image/png');
}, i / fps);
await write(Buffer.from(dataUrl.split(',')[1], 'base64'));
}
write 是把 ff.stdin.write 包成 Promise 的小函式,迴圈結束後關掉 stdin、等 ffmpeg 結束、關瀏覽器。fix.sh 更短:把「保持同一份契約、只改回饋提到的地方」的指示、修改意見和舊 HTML 一起丟給 claude -p。
實測:一句話做出兩支直式影片
兩支的需求都是一句中文:
- 發表片頭:「產品發表片頭:一個叫『LINE Lab』的 AI 研究小幫手上線,主標『丟一個網址,交回一份研究』,副標『研究 · POC · 報告』,結尾出現 LINE Lab logo 字樣」
- 數據動畫:「數據動態圖:台灣 2026 年 AI 工具使用率 68%(虛構示範數據,畫面角落標示『示範數據』),用馬賽克方塊拼出數字 68% 並逐格翻轉揭示,再出現三條橫條:寫程式 41%、做簡報 33%、剪影片 21%」
| 項目 | 發表片頭 | 數據動畫 |
|---|---|---|
| 生成的 HTML | 10,680 bytes | 9,521 bytes |
| 生成時間 | 約 1~2 分鐘 | 約 1~2 分鐘 |
| 影片長度 | 9 秒,270 格 | 8 秒,240 格 |
| 渲染時間(30 fps) | 1 分 09 秒 | 44 秒 |
| 輸出 | 1080×1920 H.264 | 1080×1920 H.264 |
片頭從暗格點亮開始,網址膠囊滑入、箭頭往下指、主標分兩行出現,最後整面翻成綠色馬賽克收在 logo。緩動、錯開時間、方塊翻轉,這些都是 Claude 依那一句需求自己安排的,我沒有指定鏡頭順序。
兩支動畫我包成一個展示頁放在 html.yanchen.app/motion-mosaic-poc,瀏覽器打開會直接循環播放,播的就是同一份 HTML。
第一版的「%」被裁掉,一句修改意見修好
數據動畫第一版渲染完,我抽最後一格出來看,馬賽克拼的「68%」,% 的右半邊超出格子區,只剩一半。
我用 fix.sh 丟了一句修改意見:
在最終畫面,馬賽克大數字 '68%' 的 % 符號右半邊被格子區域裁掉了,只看得到一半。請確保 6、8、% 三個字元的點陣完整落在格子內(加寬格子欄數或縮小每格尺寸),整體置中、左右各留 80px 安全邊界。
第二版重新渲染,三個字元都完整落在格子內,其他畫面沒有被動到:
這次的經驗是:模型讀不到自己畫出來的畫面,程式碼看起來對,渲染出來不一定對。流程裡一定要有「渲染 → 抽影格看 → 修」這一輪。我這次是自己看圖、自己寫修改意見;下一步可以把抽出的影格丟回給模型自審,讓它自己寫修改意見。
為什麼 9 秒的片頭有 50.9 MB?
兩支影片長度差不多,檔案大小差很多:
| 檔案 | 長度 | 大小 |
|---|---|---|
| 數據動畫第一版 | 8 秒 | 0.78 MB |
| 數據動畫修正版 | 8 秒 | 0.76 MB |
| 發表片頭 | 9 秒 | 50.9 MB |
| 發表片頭,拿掉雜訊顆粒 | 9 秒 | 0.91 MB |
我把片頭 HTML 裡呼叫 drawGrain(t) 的那一行註解掉,用同一支 render.mjs 重新渲染,檔案從 50.9 MB 變成 0.91 MB。要上傳社群的片子,提示詞裡可以直接拿掉 grain,或要求顆粒固定不動。
自建版跟 Motion 差在哪?
| 面向 | Motion | Claude 自建版 |
|---|---|---|
| 入口 | 網頁 app、API、ChatGPT/Claude/Cursor 的 MCP | Claude Code CLI 加三支腳本 |
| 費用 | 點數制,6 美金 200 點起 | 用 Claude Code 既有的帳號額度,不另外買點數 |
| 音樂、配音 | 有(Claude 連接器裡沒有,要回 Motion app) | 沒有 |
| 風格與品牌 | 可用外掛帶入品牌素材,或附參考影片讓它跟著節奏和字型走 | 要自己寫進需求 |
| 修改 | 對話、標記預覽、直接拖時間軸 | 一句修改意見重生 HTML |
| 匯出 | MP4 外加 After Effects、Premiere、DaVinci、Remotion 工程 | MP4,加上可以繼續改的 HTML 原始碼 |
| 可重現 | 依服務而定 | 同一份 HTML 每次渲染結果一樣 |
- 適合自建:Shorts 片頭、課程裡的數據動畫、一兩句字卡。直式 MP4 可以直接接上傳流程,HTML 也能放進 git 管版本。
- 適合 Motion:需要配音和音樂、要套公司品牌、要交工程檔給剪輯師接手,或不想自己維護腳本。
- 還沒比過:我沒有付費試用 Motion,兩邊的畫面品質沒有並排比較。
怎麼自己跑一次?
我的環境(2026-10-26 讀回):
| 工具 | 版本 |
|---|---|
| Node.js | v24.11.1 |
| Playwright | 1.58.2(含 Chromium) |
| ffmpeg | 8.0(gyan.dev full build) |
| Claude Code CLI | 2.1.310,已登入 |
gen.sh、render.mjs、fix.sh 放在同一個資料夾,裝好 Playwright 後依序跑:
bash gen.sh anim-stats.html "數據動態圖:台灣 2026 年 AI 工具使用率 68%(虛構示範數據)..."
node render.mjs anim-stats.html stats.mp4 30
ffmpeg -v error -y -i stats.mp4 -vf "select=eq(n\,230),scale=540:960" -frames:v 1 stats-end.png
第三行抽第 230 格存成縮圖,用來檢查最後畫面。有問題就:
bash fix.sh anim-stats.html anim-stats-v2.html "<一句修改意見>"
node render.mjs anim-stats-v2.html stats-v2.mp4 30
已知限制:
- 一次生成不保證完美,至少留一輪看影格修正。
- 沒有聲音。要配樂得另外用 ffmpeg 合音軌。
- 用系統字型。提示詞要求不從 CDN 載字型,中文吃 Windows 的微軟正黑體,換到沒有這套字型的機器,字會不一樣。
- 渲染是一格一格截 PNG,9 秒片在我的機器上要半分鐘到一分多鐘,比即時播放慢。
FAQ
Mosaic Motion 有免費方案嗎?
2026-10-26 查官網,沒有列免費方案或免費點數。最低是 Flex 6 美金 200 點,不用訂閱、點數不過期。給 OpenAI 用的 MCP 版本有「sponsored generation」,但文件沒說明怎麼計費。
ChatGPT 免費版能用 Motion 嗎?
Motion 文件只寫 Developer mode 能不能開「depends on your ChatGPT plan and workspace settings」,沒列方案。要先在 ChatGPT 的 Settings → Apps → Advanced settings 看得到 Developer mode 開關,才接得上。
Claude 可以直接呼叫 Motion 嗎?
可以。Claude 的連接器設定或 Claude Code 加入 https://mcp.motion.so/mcp/anthropic,用 OAuth 登入 Motion 帳號。只支援 Motion medium 引擎,扣的是 Motion 點數,沒有 AI 生圖、配音和音樂。
自己用 Claude 做動態影片要花錢嗎?
不用買 Motion 點數,但 claude -p 會用到你 Claude 帳號的額度。Playwright 和 ffmpeg 都是免費開源工具。