Communitygithub.com

digitalsamba/synthetic-ui-demo

製作產品示範與發行說明影片,無需螢幕錄製。從原始碼重建應用程式的靜態 React 畫面,並在 Remotion 中以腳本化的游標與鏡頭驅動。

synthetic-ui-demo 是什麼?

此 AI 技能提供一種創新的方法來製作產品示範與發行說明影片,完全擺脫傳統螢幕錄製的依賴。Claude Code 會讀取產品儲存庫,將場景所需的畫面重建為靜態 React 元件,然後透過 Remotion 以腳本化的游標與鏡頭執行整個流程。每個點擊動作對應一個影格編號,確保場景每次都能一致地重新渲染,無需種子帳號或即時環境。當產品更新時,只需編輯程式碼即可同步更新影片。此方法特別適合需要頻繁重新製作的發行說明與功能導覽,或是在 Playwright 錄製因資料不足或環境不穩而不可靠時使用。支援的觸發條件包括:synthetic demo、rebuild the UI、release video、feature… 等。

相容平台✓Claude Code~Codex CLI✓Cursor
npx skills add https://github.com/digitalsamba/claude-code-video-toolkit/tree/HEAD/.claude/skills/synthetic-ui-demo

在你喜歡的 AI 中提問

開啟一個已預先載入此 Agent Skill 的新對話。

說明文件

Synthetic UI Demos

沒有任何畫面是螢幕錄製的。Claude Code 讀取產品的儲存庫,僅重建場景所需的靜態 React 畫面,並透過腳本化的游標與鏡頭在 Remotion 中執行流程。每個點擊對應一個影格編號,因此場景可以完全一致地重新渲染,永遠不需要種子帳號或即時環境,當產品變更時只需編輯程式碼即可更新。

參考建置(請與此技能一同閱讀;兩者都不需要產品儲存庫即可建置):

  • examples/ds-free-schedule-demo:一個 26 秒的流程(排程通話),附有旁白方塊。最簡單的完整案例。其 src/Demo.tsx 是一個單一時間軸,包含所有游標關鍵影格、點擊和鏡頭移動。
  • examples/ds-release-649:一個 80 秒的發行說明影片,橫跨三個應用程式的八個場景。templates/ds-release-notes 是其可重複使用的形狀(作為發行版本 650 發布)。src/Release.tsx 串聯場景,src/scenes/ 中每個發行項目一個檔案,src/room/ 和 src/ac/ 是畫面套件。

何時使用此方法 vs. Playwright

Synthetic(此技能)Playwright 錄製 (/record-demo)
你可以讀取應用程式的原始碼你只有執行中的應用程式
每個版本都需要重新製作的發行說明和功能導覽一次性捕捉真實行為或真實資料
流程需要你沒有的資料(完整的通話、其他使用者、管理員檢視)真實情況易於達成且外觀正確
鏡頭移動、精確的點擊時間、語音變更後重新渲染重建成本高昂的長而複雜的互動

建構區塊 (lib/components)

import { Stage, typed, cursorAt, near } from '../../../../lib/components';

<Stage
  url="app.example.com/settings"             // 網址列;主機名稱顏色較深,路徑顏色較淺
  camera={CAMERA}                             // [{ f, z, x, y }] 以畫素為單位,已補間,並裁切至視窗
  path={PATH}                                 // [{ f, x, y }] 游標關鍵影格,以畫素為單位
  clicks={CLICKS}                             // 壓扁游標並產生漣漪效果的影格
  aiNote                                      // "顯示的人物為 AI 生成"(或傳入自訂文字)
  canvasWidth={1440} canvasHeight={810}       // 預設值
>
  <SettingsScreen field={typed(frame, 'Q4 Product Review', 128)} />
</Stage>
  • Stage 在固定大小的應用程式畫布周圍繪製瀏覽器邊框,套用鏡頭,並將游標置於 zIndex 100 之上。縮放 1 倍時,視窗為畫面寬度的 fit(0.8625)。關鍵影格重複一個值以保持其狀態。
  • Cursor 和 cursorAt 可獨立用於非瀏覽器場景;near(cursor, target) 驅動懸停狀態。
  • 產品特定的畫面套件(主題、圖示、佈局)保留在專案中。它們不屬於 lib 素材。

方法

1. 透過子代理從應用程式儲存庫提取視覺規格

為每個應用程式或區域發送一個子代理,並行處理,讓每個子代理傳回精簡的規格而非檔案傾印:

  • 主題: 色板、字型堆疊、圓角半徑、間距、陰影(來自主題檔案或 CSS 變數)。
  • 字串: 場景中顯示的每個標籤、選單項目、對話框和提示的準確英文本地化字串(public/locales/en/*.json,src/i18n/locales/en/*)。切勿改寫 UI 文字。
  • 圖示: 如果應用程式使用圖示字型,其 icomoon/fontello selection.json 包含每個字型的 SVG 路徑。將你需要的路徑提取到一個小的 JSON 中,並以 <svg><path d=...> 渲染。否則複製 SVG 元件。
  • 佈局與行為: 所顯示畫面的元件樹、工具列順序、預設值、每個控制項的作用。

從遠端讀取預設分支(git show origin/main:path,或執行 git fetch 然後讀取 origin/<default>)。本機簽出通常已過時,會給你上一季的 UI。

對於發行說明,請追蹤每個項目到首次發布的提交和元件。這會給你準確的字串和要顯示的預設值。

2. 僅重建場景顯示的內容,位於固定畫布上

  • 在固定畫布(1440x810 是很好的預設值)上使用絕對定位放置每個元素。將重要的矩形匯出為常數(SAVE_BTN = { x, y, w, h }),如此點擊目標就是算術計算而非猜測。
  • 僅建置鏡頭看到的內容。從未入鏡的面板可以是純色。
  • 保持靜態 React:無狀態,無效果。每個視覺變化都是 frame 的函數。
  • 將套件放在自己的資料夾(src/ui/,src/room/)中,並使用 theme.ts 存放常數。

3. 先處理語音,再將時間軸放入影格

  • 每個場景寫一行,在句子處分割(每個片語一個 .txt),並先產生音訊(voiceover.py --scene-dir ...)。三次錄音加上 tools/pick_takes.py 勝過單次錄音加上 --max-wpm:因為克隆會複製其參考剪輯的節奏和平坦度,所以如果台詞聽起來急促或單調,請使用 tools/voice_prosody.py expand 修正剪輯,而不是拉伸輸出(請參閱 CLAUDE.md 中的「Clone Prosody」)。讀取測量的持續時間,以及 tools/captions.py 以取得單字時間。
  • 將每個場景的大小設定為其台詞加上一個節拍,並在頂部保留一個標題註解,列出每行台詞的開始和長度。該註解是事實來源(請參閱 CLAUDE.md 中的「Audio-Anchored Timelines」)。
  • 所有內容都是場景檔案頂部的影格常數:游標關鍵影格、CLICKS、鏡頭關鍵影格、UI 狀態切換(frame >= C.save 顯示對話框)。匯出點擊影格,以便父層可以放置點擊音效。
  • 從旁白中查找影格,不要手動設定。 voice()(位於 lib/components/cues.ts;ds-release-notes 範本有一個副本)接收場景的片語及其 .captions.json 和起始影格,而 cue('save') 會傳回該單字開始的影格。將每個動作錨定到它說明的單字上,並帶有偏移量,並將每個游標和鏡頭關鍵影格錨定到這些錨點上:
    import line06a from '../../public/audio/scenes/06a_link.captions.json';
    export const LINK_VOICE = voice([{ file: '06a_link', at: 10, captions: line06a }, ...]);
    const { cue } = LINK_VOICE;
    const C = { field: cue('before', { offset: -3 }), save: cue('save') };
    const PATH = [{ f: C.field - 6, ...field }, { f: C.save - 24, ...saveBtn }];
    
    重新產生或重新調整時間一個片語,點擊、打字、游標和鏡頭都會跟著它。一個其單字不再被說出的提示會在捆綁時失敗,並附上正在說的單字。選項:offset、edge: 'end'、after(一個影格,用於重複的單字)、nth、in(一個片語)。父層從 LINK_VOICE.lines 放置音訊,因此片語的起始影格只寫一次。templates/ds-release-notes/src/scenes/FreeCustomLink.tsx 是範例實作。

4. 在停頓處分割密集的列表行

列出多個項目(「排程、聯絡人、錄音和轉錄」)的行對一次錄音來說太快了。在停頓處將音訊分割成多個片語檔案(07a、07b...),給每個片語自己的鏡頭,並將每個片語放在自己的節拍上。ds-release-649 的 moreVo 欄位就是這樣處理的。

5. 在完整渲染前,從接觸表測量點擊目標

猜測的座標通常在鏡頭縮放後偏離 20-50 畫素。在每個點擊影格及其前幾個影格處渲染靜止影像,將它們拼貼,並檢查游標尖端是否位於目標上:

i=1; for f in 46 78 122 212; do npx remotion still MyComp out/stills/s$i.png --frame=$f; i=$((i+1)); done
ffmpeg -start_number 1 -i out/stills/s%d.png -vf "scale=640:-1,tile=2x2" -frames:v 1 out/contact.png

修正常數,重新渲染靜止影像,然後才渲染影片。

6. 標記螢幕上 AI 生成的人物

任何非真實人物(FLUX.2 在圖塊中的肖像、頭像、旁白者)都必須有可見的標籤:Stage 上的 aiNote,或旁白者方塊上的「AI」標記。姓名、聯絡人和通話資料也是虛構的,因此請保持明顯的虛構性。

7. 渲染,然後標準化

在渲染前執行 tools/qc.py --project ...,然後執行 qc.py --render out/video.mp4 --fix 以達到 -14 LUFS。qc.py --project ... --layout 檢查影片自身文字(字幕、卡片、AI 備註)的大小和對比度,並分別列出產品 UI 的文字。Stage 將其視窗標記為 data-qc="product";在外部建立的任何手機或平板模擬器上也加上相同的屬性,否則其 UI 文字將被視為影片的一部分。

注意事項

  • 單色 SVG 標誌渲染為黑色。 logo_mono.svg 通常有黑色填色;在深色背景上使用 filter: brightness(0) invert(1)。
  • 過時的本機分支。 讀取 origin/<default>,而不是本機簽出所在的分支。
  • rsync --exclude src 也會移除 node_modules/*/src。 複製專案或套件時,使用前導斜線將排除規則錨定到傳輸根目錄:--exclude /src。
  • 鏡頭會裁切。 靠近畫布邊緣的鏡頭中心會被向內拉,使視窗邊緣永遠不會超出畫面。如果縮放落在意想不到的位置,這就是原因;將目標瞄準更內部的點。
  • 選單和對話框必須位於畫布內部。 畫布會裁切其子元素。將選單定位在向內開啟的位置,就像真實應用程式一樣。
  • 懸停狀態來自游標路徑。 使用 near(cursorAt(frame, PATH), target) 而不是第二組影格常數,這樣移動關鍵影格時懸停狀態也會跟著移動。
  • 變更的語音行會移動其後的所有內容。 在提示場景中,點擊、游標和鏡頭會自行跟隨,但場景長度和後續片語的 at 仍然需要檢查。在手動設定的場景中,重新測量每個影格。無論哪種方式,更新標題註解和場景長度,然後重新檢查點擊靜止影像。如果唇形同步的旁白者由組合的語音軌道驅動,也要重新產生它。
  • 套件比示範更長壽。 重建的畫面套件可以託管其他影片:ds-release-notes 的房間變成了一個惡搞短片的品牌版本舞台,其圖塊中帶有動畫臉孔,且無需新的畫面工作。將套件複製到新專案中,並將其邏輯畫布縮放到影格(.claude/skills/parody-short/formats.md)。

Individual skills in this repo

This repo contains 4 individual skills — each has its own dedicated page.

digitalsamba/claude-code-video-toolkit

Python video composition with moviepy 2.x — overlaying deterministic text on AI-generated video (LTX-2, SadTalker), compositing clips, single-file build.py video projects. Use when adding labels/captions/lower-thirds to LTX-2 or SadTalker outputs, building short ad-style spots in pure Python without Remotion, or doing programmatic video composition. Triggers include text overlay on video, label LTX-2 clip, caption SadTalker output, lower third, build.py video, moviepy, Python video composition, sub-30s ad spot.

digitalsamba/claude-code-video-toolkit

Video and audio processing with FFmpeg. Use for format conversion, resizing, compression, audio extraction, and preparing assets for Remotion. Triggers include converting GIF to MP4, resizing video, extracting audio, compressing files, or any media transformation task.

digitalsamba/ideogram4

Prompting patterns for Ideogram 4 text-to-image — best-in-class in-image text rendering and exact color/layout control via structured JSON captions. Use when generating images that need legible on-image text (title cards, thumbnails, logos, signage, CTAs), precise brand colors, or controlled spatial layout. Triggers include title slide image, thumbnail with text, on-image text, legible text in image, brand color palette image, bounding-box layout, Ideogram.

digitalsamba/parody-short

Comedy shorts about a group's own life - a team's launch, quarter end, office move or leaving do; a club's season; a class's year; a family's Christmas - or about a shared topic everyone recognises (video calls, the return to the office), told in a borrowed genre (80s action intro, creature feature, Dickens Christmas ad, heist, nature documentary) and starring the group's real, animated photos or an invented cast. Covers mining the group's own context for in-jokes (chat, email, calendars,...

相關技能