Communitygithub.com

suxrobGM/logistics-app

使用 Playwright 驅動應用程式、ffmpeg 編輯影片,製作並交付短片預告/展示影片:包含腳本規劃、認證畫面擷取、PII 審查、動畫標題卡片、MP4 + GIF。適用於「製作預告片」、「錄製展示影片」、「產品發布影片」、「為 README 製作螢幕錄影」等場景。

logistics-app 是什麼?

這個技能讓 AI 代理能夠自動化製作應用程式的簡短預告影片(約 30-45 秒),過程涵蓋從腳本規劃到最終交付的完整工作流程。它透過 Playwright 驅動真實的 UI 來「拍攝」畫面,並使用 ffmpeg 進行剪輯,最終產出 MP4 和 GIF(適用於 README)。支援的平台包括任何可透過瀏覽器存取的網頁應用,並可利用 CDP screencast 進行離屏拍攝,避免干擾使用者。其運作方式包含:先用 `scout.js` 偵查並截圖所有候選畫面,撰寫腳本表格;接著透過 `rig.js` 使用 `Page.startScreencast` 進行拍攝,並可處理認證狀態和 PII 審查(確保沒有個人資訊被錄入)。最後使用 `build.js` 標準化片段、加入交叉淡入淡出,並在交付前產生 contact sheet 和逐帧畫面以供審查。

相容平台✓Claude Code~Codex CLI✓Cursor
npx skills add https://github.com/suxrobGM/logistics-app/tree/main/.claude/skills/teaser-video

在你喜歡的 AI 中提問

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

說明文件

預告影片製作

為正在運行的應用程式製作一個具備發布品質的預告片(約 30-45 秒):規劃腳本、透過驅動真實 UI 來拍攝、使用 ffmpeg 剪輯,最後交付 MP4 以及一個適用於 README 的 GIF。

輸出成品必須看起來像產品影片,而不是螢幕錄影。兩者的區別在於導向——場景安排、畫面構圖和節奏控制——而非解析度。

參考實作位於 reference/ 目錄;它們是可運行的 ESM 模組,不是虛擬碼。請在暫存目錄中設定,切勿在專案內執行:

cp -r <skill>/reference/* "$SCRATCH/" && cd "$SCRATCH" && npm install
export TEASER_BASE_URL="https://the-app.example.com"

reference/package.json 宣告了 "type": "module" 以及三個依賴套件。每個腳本都會讀取 TEASER_BASE_URL,因此不會對任何特定應用程式進行硬編碼。

首要之務:兩條嚴格規則

1. 絕不要在未經明確、逐項同意下觸發真實世界的副作用。

拍攝真實應用程式意味著點擊真實的按鈕。其中有些按鈕可能會發送電子郵件、公開發布內容、收取費用,或向第三方提交表單。在您觸碰應用程式之前:

  • 逐一列出腳本中所有離開本機的操作。
  • 告訴使用者每個操作的具體作用及執行次數,然後取得使用者對次數的同意。
  • 優先選擇能在不可逆步驟前停止的模式(預覽、模擬執行、一個您可以拍攝並隨後拒絕的確認閘門)。

在即時系統上不存在所謂的唯讀探測。一個落在已執行工作階段中的「診斷性」點擊,將會真實觸發。如果您正在除錯某個操作為何未生效,請假設您的下一次點擊將會生效,並做好準備。

如果某個操作意外觸發:立即從源頭停止程序(終止工作階段/處理程序,而不僅是 UI 按鈕,因為後者可能無效),透過讀取狀態來驗證已停止,並在您的最終訊息中向使用者清楚說明——包括次數。

2. 假設每一幀畫面都是公開的且充滿 PII。

真實帳戶會攜帶姓名、電子郵件、地址和文件。請預先與使用者共同決定政策:

  • 以畫面構圖避開(預設)- 構圖時排除個人身分。在 ffmpeg 階段裁切持續存在的瀏覽器元件(側邊欄、頭像、帳戶選單)。
  • 在拍攝前隱藏 - 在開拍之前,使用 page.evaluate 對有問題的卡片設定 visibility: hidden。切勿拍攝後再希望繞過它。
  • 使用預先準備的演示帳戶 - 如果有的話,這是最乾淨的方式。

在交付前,以全解析度審查最終剪輯的每一幀畫面。不是檢視縮圖,而是檢視實際畫格。

工作流程

1. 偵查與腳本規劃

首先對每個候選畫面進行經過認證的截圖(reference/scout.js)。檢視這些截圖。然後撰寫一個腳本表格:節拍、鏡頭、觀眾應該感受到什麼,以及長度。一個沒有指定任務的鏡頭,在拍攝前就會被剪掉。

有效的敘事弧線:緊張(問題)→ 揭露(產品)→ 證明(它真的能做到)→ 規模(成果)→ 信任(它在哪裡運行)→ 結尾。

在腳本中標註哪些畫面包含 PII,哪些是安全的。

2. 佈置場景

在拍攝前整理,而不是之後:

  • 選擇資料看起來最佳的畫面 - 完整的圖表、活躍的清單、可識別的名稱、非零的計數。切勿拍攝載入中、空白狀態或半渲染的圖表。
  • 透過初始化腳本中的 localStorage 或拍攝前的 page.evaluate,有意識地設定 UI 狀態(面板寬度、展開/收合、篩選器、滾動位置)。
  • 在鏡頭外關閉提示訊息、橫幅和 Cookie 同意視窗。
  • 讓資料穩定下來:networkidle 再加上幾秒鐘。

3. 拍攝

使用 CDP screencast(Page.startScreencast),而不是螢幕錄影。它會以約 100fps 的速率在螢幕外捕捉頁面,因此使用者正在進行的任何操作都不會出現在畫面中,且機器仍可正常使用。Playwright 負責驅動;CDP 負責拍攝。相關實作請參考 reference/rig.js。

  • 每個鏡頭只有一個主體。拍攝這個事物本身,而不是「整個應用程式」。
  • 鏡頭移動來自頁面內部的腳本化緩動滾動(cameraScroll),而不是任何濾鏡。請參考下方關於 zoompan 的警告。
  • 游標是一個演員:使用內建的 SVG 游標(cursorClick),它會以緩動方式滑動並在按壓時下沉,或者將其隱藏。不要讓它無目的地飄移。
  • 對每個鏡頭進行排練,提取畫格,檢視它們,調整,然後正式拍攝。

拍攝外部視窗(應用程式自身開啟的瀏覽器、桌面應用程式)需要使用作業系統層級的畫面擷取 - gdigrab/x11grab/avfoundation(在 rig 中為 recordDesktop)。這會捕捉螢幕上的一切,包括使用者自己的工作。警告使用者,請他們離開,並逐幀審查結果;如果捕捉到任何私人內容,請立即刪除。

4. 標題卡片

使用在瀏覽器中拍攝的動態 HTML/CSS,而非靜態圖片。在應用程式自身的來源(origin)上,將卡片標記注入一個空白頁面,以便解析其網頁字型和調色盤,然後進行 screencast 拍攝。從即時頁面(getComputedStyle)提取真實的顯示字型,並固定一個已知良好的等寬字型堆疊,而不是去猜測一個。

匹配應用程式的動畫語言(其自身的緩動曲線和持續時間)。在設計卡片前,如果專案沒有既定的卡片風格,請先載入 frontend-design 技能。

5. 剪輯

reference/build.js 將每個片段標準化為統一的尺寸/幀率,然後對整個序列進行交叉淡入淡出。保持每約 2.5-4 秒一個剪輯。讓高潮時刻以正常速度有足夠的展現空間,同時壓縮其周圍的例行操作。

6. 審查,然後交付

  • 產生一個 contact sheet 以及每秒的全解析度畫格。
  • 檢查畫格中是否有 PII、被裁切的面板以及難以閱讀的文字。
  • 使用探測工具驗證持續時間和尺寸。
  • 交付一個 MP4,以及針對 README 的、經過調色板最佳化的 GIF(GitHub 不會內嵌播放提交的 MP4)。將 GIF 保持在約 10 MB 以下。
  • 除非要求,否則保持無聲;您無法授權音樂。請說明這一點。

寶貴的實戰經驗

切勿對推近鏡頭使用 zoompan。 它會逐幀重新計算縮放,並將裁切視窗四捨五入到整數像素,導致影像前後抖動——看起來像地震。請使用鎖定鏡頭加上真實的頁面內部滾動。如果必須使用推近鏡頭,請先將來源預先放大 4 倍,並使用畫格差異測量工具(reference/jitter.js)進行驗證:一個鎖定的靜態鏡頭其平均差異應遠低於 1.0;可見的抖動會讀取到 3 以上。

當動畫靜止時,Screencast 會停止發送畫格。 一個動畫在 1.2 秒後結束的卡片,只會產生一個 1.2 秒的片段。請使用 tpad=stop_mode=clone:stop_duration=N 進行填補,並用 -t 剪裁到您想要的長度。

組合帶有時間戳的畫格,而非固定幀率。 Screencast 畫格會攜帶 metadata.timestamp;請撰寫一個 ffmpeg concat 列表,其中包含真實的每幀持續時間,然後重新取樣為固定的 60fps。假設固定間隔會產生抖動。

將 ffmpeg-static 作為開發依賴,並透過模組路徑解析。永遠不要依賴 ffmpeg 在 PATH 上。(ffprobe 不在該套件中——請改用 ffmpeg -i 的標準錯誤輸出進行解析。)

認證畫面擷取: 以有頭模式登入一次,儲存 storageState,並在每次拍攝中重複使用(reference/login.js)。工作階段會過期——請在同一天完成拍攝,或重新執行。同時也在那裡植入任何 localStorage 的 UI 偏好設定。

從已部署的來源(origin)存取 localhost 會被 Chrome 的本機網路存取政策封鎖。 如果頁面必須連接到本機服務,請使用 --disable-features=LocalNetworkAccessChecks,PrivateNetworkAccessChecks,BlockInsecurePrivateNetworkRequests 啟動。

以固定偏移量裁切持續存在的瀏覽器元件。 以 1920 + railWidth 的 viewport 寬度進行拍攝,然後使用 crop=1920:1080:railWidth:0 來移除側邊欄並精確對齊 1080p。

交付成果

回報檔案路徑、持續時間和尺寸;清楚說明使用者仍需提供什麼(音樂、GitHub 原生影片上傳);並揭露拍攝過程中發生的任何使用者可能想知道的事情。

相關技能