Communitygithub.com

pedrojaques99/site-reels

錄製網站或網頁應用程式(WebGL 英雄區、3D、滾動)的最佳場景,輸出為 1080p MP4 供簡報使用,上傳至 Figma Slides,並在 Remotion 中製作品牌或產品展示影片。請使用「記錄網站場景」、「簡報網站影片」、「展示影片」、「發布影片」、「gerar vídeo do site」、「vídeo pro deck」、「reel do produto」、/site-reels 等指令觸發。

site-reels 是什麼?

Site Reels 是一個 AI 代理工具,用於自動化從網站或網頁應用程式擷取高品質影片片段的流程。它使用 Puppeteer 和 puppeteer-screen-recorder 以無頭模式錄製腳本化的場景(如 WebGL 英雄區、3D 部分和滾動互動),輸出 1920×1080、30fps、x264 編碼的 MP4 檔案,容量小於 100MB。錄製的影片可以透過 Figma MCP 上傳至 Figma Slides(使用技能 figma-use 和 figma-use-slides),並在 Remotion 中用於製作品牌或產品展示影片。該技能支援 Windows、macOS 和 Linux,需要 Node.js 18+、ffmpeg/ffprobe 以及 Chrome/Chromium/Edge。它提供兩個錄製引擎:record.mjs(適用於一般場景,基於 CDP screencast)和 snap.mjs(適用於需要 60fps 的鎖定畫面,使用 timeweb 虛擬時鐘以確保確定性)。已知的限制包括:隱藏視窗會凍結動畫幀、重新載入時 UI 隱藏 CSS 會消失、以及懶加載的 3D 內容需要等待。技能還包括審計步驟(如生成聯絡表)以及上傳影片至 Figma Slides 的解決方案(使用封面圖片,因為 MCP 不支援直接上傳影片)。品牌展示影片使用 Remotion 從乾淨的畫面合成,而產品展示影片則使用 Playwright 錄製真實的應用程式畫面並在 Remotion 中重新繪製游標。

相容平台~Claude Code~Codex CLI✓Cursor
npx skills add https://github.com/pedrojaques99/visant-skills-public/tree/HEAD/site-reels

在你喜歡的 AI 中提問

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

說明文件

Site Reels: 網站 → MP4 → 簡報

需求

需要項目檢查方式
所有功能Windows、macOS 或 Linux,需有 GPU 和可見桌面(Chrome 以有頭模式執行)不適用
所有功能Node.js 18+node -v
所有功能ffmpeg + ffprobe 需在 PATH 中(或設定 FFMPEG=<完整路徑>)ffmpeg -version
所有功能Chrome、Chromium 或 Edge(自動偵測,詳見下文)node -e "import('./scripts/find-chrome.mjs').then(m=>console.log(m.findChrome()))"
record.mjspuppeteer-core + puppeteer-screen-recorder(npm,在專案中)npm ls puppeteer-core puppeteer-screen-recorder
snap.mjspuppeteer-core + timesnap(內含 timeweb)npm ls timesnap
展示影片Remotion 專案npx remotion --version
審計(選用)ImageMagickmagick -version
Figma 上傳Figma MCP(use_figma、upload_assets)+ 技能 figma-use、figma-use-slidesMCP 工具列表

Chrome 偵測(scripts/find-chrome.mjs,由 record.mjs 和 snap.mjs 使用):如果設定了 CHROME 環境變數則使用該路徑;否則使用已安裝的 Chrome/Edge(Windows:Program Files 和 LocalAppData;macOS:/Applications 和 ~/Applications;Linux:PATH 中的 google-chrome、chromium、microsoft-edge);否則使用最新的 ms-playwright/chromium-<N>(或 PLAYWRIGHT_BROWSERS_PATH);否則停止執行並告知如何設定 CHROME 或執行 npx playwright install chromium。在 Windows 上會加上 --use-angle=d3d11;在其他作業系統上 Chrome 保留預設的 GPU 後端。

功能說明

錄製在本地端運行的網站之腳本化場景,並產出準備好可用於 Figma 的 MP4 檔案(1920×1080、30fps、x264、小於 100MB)。驗證過的引擎:puppeteer-core + puppeteer-screen-recorder(CDP screencast + ffmpeg)。絕不進行螢幕錄製。

執行

mkdir <proj>-reels && cd <proj>-reels && npm init -y && npm i puppeteer-core puppeteer-screen-recorder
mkdir -p scripts && cp <skill-dir>/scripts/{record,find-chrome}.mjs scripts/
cp <skill-dir>/scripts/scenes.example.mjs scenes.mjs   # 編輯場景
# 在網站 repo 中:npx next build && npx next start -p 3100   (生產環境建置:WebGL 更流暢)
OUT="<輸出資料夾>/Videos" node scripts/record.mjs scenes.mjs [scene ...]

執行已複製到專案中的腳本:ESM 會從腳本所在的資料夾解析 puppeteer-core,而非從當前工作目錄。

環境變數:BASE(預設 http://localhost:3100)、OUT、CHROME、FFMPEG、W、H、DPR、MOBILE=1(觸控模擬)、KEEP_UI=1(保留導覽列)、MIN_FPS(24)。手機 4:5 比例:W=360 H=450 DPR=2 MOBILE=1 產生 720x900。

每個場景 = { name, path, theme?, trim?, crf?, css?, prepare(page, ctx), act(page, ctx) }。prepare 在錄製前執行(滾動到區段、等待 3D 載入);act 則是錄製到影片中的內容。ctx 包含 wait、scrollTo(page, y|selector, ms) 和 scrollThrough(page, selector|null, ms, from, to)(含緩動效果)。載入時執行的開場:在 act 中使用 page.reload(),並使用 trim 剪掉載入過程。

有效的品牌腳本:標誌/英雄區開場(淺色和深色)、英雄媒體切換、3D 區段(鏡頭隨滾動進入)、沈浸式路線(漫步)、頁尾字標和一次全頁瀏覽。5–7 個場景,每個 12–55 秒。

交付前審計(請勿信任 exit code)

  • 每個影片的聯絡表:ffmpeg -i x.mp4 -vf "fps=6/<dur>,scale=480:-1,tile=3x2" -frames:v 1 sheet.png,然後仔細查看。
  • 19 秒的 1MB 影片 = 空白場景。大於 100MB 則無法放入 Figma(可用場景的 crf 修正;顆粒和拖尾場景使用 24)。
  • 在數個時間點檢查頂部條狀區域(crop=1920:120:0:0)以捕捉外漏的導覽列。
  • LOW-FPS 並在開始/結束時有長時間暫停是假警報(計量器會計算靜止幀);請檢查聯絡表。

已知陷阱

  1. 隱藏視窗會凍結 rAF → 導致畫面凍結。啟動時已傳入 --disable-backgrounding-occluded-windows --disable-renderer-backgrounding --disable-background-timer-throttling --disable-features=CalculateNativeWinOcclusion。刻意使用 headless: false:無頭模式會回退到 SwiftShader,WebGL 會卡頓。
  2. 隱藏 UI 的 CSS 在重新載入及 React 水合清除 <head> 時會消失 → 腳本會每 100 毫秒重新附加一個 <style id="reels-hide"> 到 body。
  3. 一個無效的選擇器會使整個規則失效:在 JS 模板字面量中的 \[ 會變成 [,而 .z-[60] 會使 header, nav, .z-[60] 失效。每個有風險的選擇器使用單獨的規則。
  4. 不要隱藏 [data-cursor]:網站會用它來標記 3D 畫布和輪播。請定位自訂游標元素(fixed + mix-blend + pointer-events-none)。
  5. 懶加載的 3D(IntersectionObserver + 動態匯入):在到達該區段後等待 5–7 秒。沒有 preserveDrawingBuffer 時,讀取 WebGL 畫布會回傳空白:請使用固定等待或螢幕截圖。
  6. Screencast 每秒傳送約 32 個唯一幀 → 以 30fps 錄製(60 會產生不規則的重複幀)。預設 trim 0.3 秒會刪除第一個快取幀。
  7. 在負載較重的機器上(Photoshop 開啟、並行渲染)Screencast 會卡頓:MP4 會顯示「30fps」,但實際每秒只有 9–18 個唯一幀。record.mjs 會測量(mpdecimate=hi=64:lo=24:frac=0.05)並在低於 MIN_FPS(24)時重新錄製最多 2 次。對於 WebGL/3D 畫面,建議使用 snap.mjs。
  8. Cookie 橫幅:在 prepare 中接受它(點擊「Accept/Aceitar/OK」等通用文字),然後再開始錄製。
  9. 沒有滾動的工具頁面(產生器、效果編輯器)錄製後會靜止不動:場景必須進行互動(上傳檔案到 input[type=file]、按按鈕文字點擊預設值)。自訂滑桿不會回應合成的 input 事件。

60fps 鎖定畫面:snap.mjs(確定性)

scripts/snap.mjs 注入 timeweb(timesnap 的虛擬時鐘:rAF、performance.now、setTimeout 和 video),每幀前進 1/60 秒並截圖。獨立於機器負載。場景:{ name, path, theme, css, dur, wait(載入 3D 的實際毫秒數), pre(滾動前的虛擬毫秒數,2000;**如果開場在載入時執行則設為 0**), start(跳過的虛擬秒數), scroll: { sel, from, to, at, len } | { bottom: [from, to] 以螢幕高度為單位 }, frame(page, t)(例如滑鼠) }。滾動是虛擬時間的函數。

npm i puppeteer-core timesnap && mkdir -p scripts
cp <skill-dir>/scripts/{snap,find-chrome,patch-timeweb}.mjs scripts/
npm pkg set scripts.postinstall="node scripts/patch-timeweb.mjs" && npm run postinstall
FPS=60 OUT=... node scripts/snap.mjs scenes-snap.mjs [scene]
  • 請勿直接使用 timesnap():搭配 Next + R3F + Lenis 時,它錄製到空白頁面,並在 WebGL 英雄區留下凍結的片段(rAF 未執行)。自訂迴圈(goTo + scrollTo + screenshot)在所有環境都有效:60/60 唯一幀。
  • 必須套用 timeweb 修補:它會將 video.play() 替換為沒有 Promise 和 playing 事件的版本 → 否則 video.play().catch() 會拋出錯誤,頁面變成空白。
  • 強制在 getContext 上設定 preserveDrawingBuffer: true(可使用 preserve: false 關閉)。
  • 幀會寫入 OS 臨時目錄,絕不會寫入同步磁碟機(數千張 jpg 同步會出問題)。
  • 不要並行進行 GPU 工作(Remotion 渲染、Photoshop):WebGL 會失去 context,只錄製到背景畫面。腳本會警告 FLASH(根據亮度判斷畫面閃爍);長段空白畫面只會出現在聯絡表中。請仔細檢查。
  • 真正的流暢度審計:在全解析度下使用 magick compare -metric MAE 比較相鄰幀。0 = 重複幀。
  • 交付:scripts/deliver.example.sh(複製並重新命名畫面;需要 V=)會建立揭開效果、循環(loop.sh)和乾淨的 3D,將 crf 提高 3 直到小於 95MB。

上傳至 Figma Slides(隱藏,不干擾團隊)

MP4 不透過 MCP 上傳:use_figma 沒有網路功能,Plugin API 也無法從位元組建立影片;upload_assets 只接受圖片(≤ 10MB)。因此:

  1. 每個影片的封面:ffmpeg -ss <t> -i x.mp4 -frames:v 1 -q:v 2 _capas/x.jpg。
  2. use_figma(技能 figma-use + figma-use-slides):在最後一張投影片前使用 createSlideRow(idx),row.name = 'WIP · Motion (hidden)',每個影片使用一個 createSlide(idx, i) 並設定 isSkippedSlide = true,黑色背景,一個 1920×1080 的矩形命名為 VIDEO · x.mp4,並在 speakerNotes 中提供指示。
  3. upload_assets 搭配矩形的 nodeIds → 以 multipart POST 上傳封面圖片。
  4. 使用者將 MP4 拖曳到矩形上(封面會被影片取代)。請清楚說明這點;絕不要承諾會自動插入影片。

getSlideGrid() 會省略被跳過的投影片:請透過 SLIDE_GRID.children[i].children 檢查結構。

品牌展示影片(Remotion):畫面 + 設計場景

對於品牌展示影片(標誌、顏色、字體、版面、宣言、模型),只從網站錄製乾淨的畫面(無文字:每個場景的 CSS 會隱藏標題/導覽列),並在 Remotion 中組合其餘部分(逐幀渲染,無抖動)。值得擁有的可重用建構區塊放在 src/fx.tsx:Mist、MistWords、Grain、KenBurns、Plate、nevoa()(薄霧)轉場,並在 brand.ts 中包含品牌資料。

  • 視覺識別來自簡報,而非網站:在投影片中檢查官方字體和色板(網站可能偏離品牌指南)。
  • 有效的場景:在薄霧中顯示開場語句、錄製的揭開效果、標誌建構(evolvePath + 在標誌點陣圖上測量的輔助線)、逐句顯示宣言、具有可變 wght 軸的支柱、色板帶狀顯示、字體排版、分層圖形、帶有 mix-blend-difference 文字標題的 3D、滾動版面欄位、1/2/3 欄模型蒙太奇、與名稱同步的產品、以字標收尾。
  • 在渲染前透過靜止幀(npx remotion still ... --frame=N + 蒙太奇)進行審查。
  • 使用 --concurrency=3 渲染:在 8 並行、Photoshop 開啟的情況下,32GB 的機器會耗盡記憶體。
  • 循環:scripts/loop.sh in out [start] [dur] [crossfade]。使用 magick compare -metric RMSE 檢查首尾幀的接縫(< 0.5% = 不可見)。
  • 壞的畫面就是廢棄物:一個旋轉的實心體顯示不出運動;為直幅畫布構圖的鏡頭在 16:9 中看起來很小。
  • 快速展示影片(經審核的節奏):25–35 秒、60fps、Series 搭配在 120 BPM 網格(30 幀)上的硬切、每 3–6 幀的影像爆發、在網格上的巨大標誌裁切、閃爍的字體粗細、重新排列的色板區塊、圓形遮罩中的直幅人像、圖形爆發、動感短語、一拍模型、結束標誌停留約 2.5 秒。零標籤:文字僅作為圖形使用。慢速 1:40 的展示影片已被拒絕。
  • 柔和/煙霧展示影片:錄製英雄區煙霧效果時不帶標誌或照片,黑色背景,純白色(場景設定 storage = localStorage 中的參數和 block: ['assets/logo.png'];空白 PNG 必須是透明的;不要封鎖影片:損壞的影片會凍結 timeweb)。將畫面作為 mix-blend-mode: multiply 疊加層使用:在場景開始時開啟,反轉版本(ffmpeg -vf reverse)結束它;剪輯落在黑色上。轉場約 1.1 秒(速率 2),或半個場景變黑。
  • Figma Slides 版面組合:複製投影片(跳過),將每張卡片複製 3 倍,僅顯示背景/標誌/文字,使用 download_assets(比例 2)下載每個節點,然後刪除複本。Slides 不匯出透明度:在黑色背景上匯出標誌/文字,然後在白色背景上匯出,並透過差異(ImageMagick)提取透明通道。絕不透過 use_figma 回傳 base64(會使上下文負載過大)。

產品展示影片(真實應用程式拍攝)

螢幕是真實拍攝的(Playwright + CDP screencast 以 2 倍速,步驟 goto/move/click/type/scroll/wait,游標軌跡儲存為 <id>.cursor.json),然後在 Remotion 中重新繪製游標。

已拒絕,請勿重複:

  • 將設計好的展示影片與真實畫面拼接(插圖開場 + 拍攝的中段 + 繪製的 CTA):兩種語言,角色消失又出現,場景之間的黑色卡片打斷節奏。每個影片使用一種語言。
  • 在 16:9 視窗中的小型加速產品畫面:動態消息和排名變成難以閱讀的一團。
  • 會裁切畫面的縮放以及疊加在影片上的文字內容(巨大的動詞、01/07 計數器、漸層):會干擾。
  • 畫面中的空等待(「waiting…」):直接跳到動作。
  • 模糊的文案:必須清晰明瞭,並使用觀眾的日常口語。

有效的形式: 每個動作,先顯示文字本身,置中且簡短(2 拍),然後是完整的、未裁切的畫面,以捕捉時的寬高比顯示在置中視窗中,背景乾淨。低調的文字(粗細 700,逐詞進入搭配輕微模糊),無計數器、無漸層。在音軌網格上剪輯(14 幀 = 128.57 BPM)。最長 40 秒。

有效的技術:

  • 加速擷取:<OffthreadVideo trimBefore={from} playbackRate={rate}> 並重新計算點擊幀 / rate(聲音和游標環)。
  • 中途開始另一個合成:<Sequence from={X}><Sequence from={-start}><Comp/></Sequence></Sequence>。檢查該段的第一幀:一個共享元素「飛入」時會顯得鬆散。跳過幾幀並重新放置落下的撞擊音效。
  • 每個合成使用一種語言,搭配模組級時間軸:一個 globalThis 標誌由它自己的、在 Root 之前匯入的入口檔案設定。
  • 跨剪輯的連續音軌:在床音上使用 trimBefore,使其從前一段停止的地方繼續。
  • 響度:渲染、測量並使用 2-pass loudnorm(-14 LUFS / -1 dBTP)進行正規化,複製影片。只在最後測量:Remotion 的原始混音會超過 0 dBFS。
  • 審計:每個渲染都製作帶有時間戳記的聯絡表(fps=2,drawtext=%{pts\:hms},tile=8x6),並在每個段落連接處製作密集表(fps=6)。
  • 沒有 git 的專案,被另一個工作階段同時編輯:將新的剪輯放在新檔案中,在編輯共享檔案前建立 *.bak-* 備份,並告知使用者。

作品集卡片和工作室展示影片

  • record.mjs 搭配 KEEP_UI=1(卡片顯示網站原貌)和上面的手機預設值。
  • 從庫存檔案生成場景(僅限具有有效 URL 的公開項目);無有效 URL = 使用螢幕截圖的 Ken Burns 效果。
  • 卡片套件:從結尾到開頭的交叉淡入循環、2-pass 位元率以達到 KB 上限、同時提供 VP9 WebM、第一幀的 WebP 海報。
  • 帶有透明背景的網頁用標誌:-

…(其餘內容已截斷,但已翻譯部分已完整保留)

相關技能