產品影片 是做什麼的?
製作一部 60 至 120 秒的旁白影片,使用產品的真實畫面來展示產品。輸出為一個 HyperFrames 專案(一個產生的 index.html 加上素材)以及一個渲染過的 MP4 檔案。
所有交付成果(腳本、螢幕文字、README)都應使用觀眾的語言撰寫。此檔案僅供指示用,故保留英文。
輸出目錄結構
為每部影片建立一個資料夾,放在任何程式碼儲存庫之外(除非使用者另有指示):
<Product>-video/
ROTEIRO.md | SCRIPT.md 腳本、主張表格、待確認要點
LEIA-ME.md | README.md 哪些是真實的、哪些是重建的、限制、如何重新執行
01-.. 0N-.. 已擷取的素材,每個來源一個資料夾
voz/ | voice/ 旁白區段(文字與每場景音訊)
ferramentas/ | tools/ 配置與 gen.js(合成產生器)
hyperframes/
index.html GENERATED。絕不手動編輯。
assets/{img,video,audio,fonts}
renders/
工作流程
依序執行各階段。每個階段結束時需進行檢查;檢查通過前不得開始下一階段。
P1. 來源
- 找出使用者提及的每個來源。來自另一台機器的路徑不存在:請在目前使用者的資料夾下搜尋同一個專案,並告知使用了哪一個。
- 分類產品的呈現方式:
- 即時應用程式,可存取: 擷取它(P3,
site-capture.cjs、record-interaction.cjs)。 - 公開 Figma 檔案: 透過原型檢視擷取影格(P3,
figma-frames.cjs)。無需 Token。 - 需要登入但無存取權限: 請對方提供螢幕截圖或測試帳號。不得憑記憶重建畫面。
- 即時應用程式,可存取: 擷取它(P3,
- 提取產品自身的用語:登陸頁面文案、功能名稱、數字、常見問題、條款。這些是主張的唯一允許來源。
檢查: 你能說出目標觀眾、產品的模組,以及每個你打算使用的事實的來源。
P2. 腳本
閱讀 references/script.md 並依照其範本撰寫腳本檔案。最重要的規則:
- 口語速度預算為每秒 2.3 到 2.6 個詞。250 個詞約為 100 秒。
- 每場一個想法,每場持續 8 到 16 秒,總共 6 到 9 場。
- 旁白中的每個主張,在主張表格中都必須有一行對應的來源。刪除任何來源無法支持的內容。
- 為語音撰寫:品牌名稱使用正確發音,數字拼寫出來,不使用會讓語音逐字母拼讀的縮寫。
檢查: 主張表格中沒有任何空白來源欄位,且「待確認要點」清單中列出了所有來自行銷文案的數字。
P3. 素材
閱讀 references/capture.md 以取得配置範例。
| 來源 | 腳本 | 輸出 |
|---|---|---|
| 即時網頁應用程式,靜態 | scripts/site-capture.cjs | 首屏、全頁、步驟截圖、捲動影片、擷取元素 |
| 即時網頁應用程式,流程 | scripts/record-interaction.cjs | 含游標或輕觸疊加層的互動片段 |
| 公開 Figma 檔案 | scripts/figma-frames.cjs | 每影格一張 PNG,裁切至影格邊界 |
同時收集品牌素材:標誌(向量檔尤佳)、品牌字型檔案及其授權,以及來自產品 CSS 的色彩 Token。使用 scripts/page-styles.cjs <url> 讀取產品自身頁面使用的樣式:標題字體家族、粗細、行高與字距、按鈕樣式以及任何毛玻璃表面。影片會複製這些樣式而非自行猜測。
檢查: 打開幾個擷取結果並查看。顯示登入牆、Cookie 橫幅或開發者疊加層的擷取結果即為失敗。
P4. 語音
閱讀 references/voice.md。在產生任何內容前,先詢問使用者要使用的語音:透過 MCP 或 API 金鑰存取的付費服務優先,其次為使用者提供的旁白。免費的本地模型僅適用於主動要求的使用者,因為它會在其機器上安裝模型。
- 透過 MCP 的語音服務: 將整個旁白生為一個連續的錄製(每場景一個段落,開頭一個傳遞標籤)。使用
scripts/voice.py --existing進行對齊,使用scripts/split-take.py --level在停頓處分割,再使用scripts/voice.py --parts "voz/cena-{id}.wav"合併場景檔案。場景邊界精準,且從第一場到最後一場的語氣保持一致。逐場請求的旁白會在請求之間改變情緒。 - 透過 API 金鑰的語音服務:
scripts/voice.py --provider elevenlabs --el-voice <id>產生並合併。scripts/elevenlabs.py檢查連線、排名聲音並創作音樂。 - 提供的旁白: 傳遞
--existing。場景邊界來自將轉錄稿與腳本對齊。
使用表達性模型時,在錄製開頭設定一個 [audio tag] 來指定傳遞方式。每個場景都包含 text(純文字,用於字幕)並可能包含 tts(語音實際接收的文字,當兩者不同時)。
在所有模式下,文字時間碼都與腳本文字對齊,因此字幕絕不會顯示轉錄錯誤。閱讀它列印的 misheard 清單:除拼寫出的數字和同音詞外,任何其他內容都是發音問題。修正腳本文字並重新產生。
在合成前,將旁白歸一化至約 −18 LUFS。
檢查: voiceover.json 存在,總時長在目標值的 ±10% 內,misheard 已說明,且 scripts/voice-tone.py --scenes 報告場景間的中位音高差距約在 3 個半音或以下。
P5. 合成
閱讀 references/hyperframes.md(渲染器強制執行的規則),並從 assets/gen-template.js 開始。
- 從腳本產生
index.html。每次語音變更時時間碼都會改變;產生器能吸收這種變更,但手動編輯不行。 - 每個動畫都錨定到旁白的片語(
at(3, '在面板上')),絕不錨定到單個短詞。「的」、「和」、「一個」在每場會出現多次,第一個匹配到的往往是錯的。 - 保留畫面底部 17% 的區域用於字幕。其他元素不得進入該區域。
- 在瀏覽器視窗或裝置模擬框中顯示真實畫面。將說明文字放在其旁邊,而非覆蓋其上。
- 傾向於每句話一個清晰的亮點(圓圈、縮放、游標移動),而非多個小亮點。
- 標題採用產品自身的標題樣式,標籤採用其介面語言風格,兩者皆在 P3 階段讀取。不要預設使用最粗的字重。
- 對於 Stories、Reels 或 Shorts,閱讀
references/vertical.md,並從assets/gen-vertical-template.js開始,使用相同的旁白建立第二個垂直合成。絕不要裁剪 16:9 的那個。
檢查: npx hyperframes lint 必須顯示 0 個錯誤。
P6. 驗證
npx hyperframes check必須以「Check passed」結束(檢查:lint、執行時期、版面、動態、對比度)。npx hyperframes snapshot --no-end --at <每場景一個時間點,外加每個亮點>並查看每個影格。使用 ffmpeg 建立 2×2 審查表以加快檢查。- 將每個影格與該秒鐘的旁白進行比較。常見缺陷:畫面與句子不符、亮點在錯誤的元素上、文字換行、元素進入字幕區域。
- 渲染草稿(
render -q draft),然後驗證 MP4 本身:使用ffprobe檢查時長和串流,使用loudnorm檢查音量(目標 −16 至 −17 LUFS 含音樂),並使用 ffmpeg 提取影格。
檢查: 你已查看過取自 MP4 的每個場景的至少一個影格,而非僅來自快照。
P7. 交付
撰寫 README,內容包含:哪些是真實的(已擷取)、哪些是使用真實資料以 HTML 重建的、哪些是概念性的、已知限制、用於預覽、檢查和渲染的指令,以及如何更換語音。然後向使用者報告:已製作了什麼、已驗證了什麼,以及哪些仍需人工決定(未確認的數字、音樂、語音品質)。
已預先了解的常見陷阱
| 代碼 | 症狀 | 原因與修正 |
|---|---|---|
| X1 | 畫面提早一秒切換 | at() 匹配到了第一個「的」或「和」。錨定到片語。 |
| X2 | 元素在整個場景中保持隱藏 | 同一元素有兩個 fromTo 補間動畫;後一個會立即渲染其「from」狀態。每個出現使用一個元素,或使用 to() 從 CSS 初始狀態開始。 |
| X3 | 網站回應 403,但在瀏覽器中可開啟 | 無頭使用者代理。使用 lib/browser.cjs,它會發送桌面版 UA。 |
| X4 | 啟動時顯示「Executable doesn't exist」 | 安裝的瀏覽器建置版本與 Playwright 版本不同。lib/browser.cjs 會回退到最新的本地 Chromium,然後是 Chrome。 |
| X5 | 全頁截圖在某一折處被截斷 | 應用程式在內部容器中滾動。找到最大的可滾動元素,並將視口高度增長到其高度。 |
| X6 | 滾動錄製卡頓 | 螢幕錄製的幀率不穩定。改為逐幀渲染滾動。 |
| X7 | 反覆檢查一個從不改變的檔案 | 記錄器寫入的資料夾與你檢查的不同。列印並驗證輸出路徑。 |
| X8 | 計數器在巨大的「%」旁顯示得很小 | 一個後代選擇器(.num span)也匹配了內部的計數器 span。對標籤使用子選擇器。 |
| X9 | 字幕顯示錯誤的文字 | 字幕來自原始轉錄稿。將時間碼對齊到腳本文字(voice.py 會處理此步驟)。 |
| X10 | 語音發錯品牌或術語的音 | 將其寫成口語形式(一個寫成單詞的品牌名被讀成兩個詞,外來術語使用本地短語),拼寫出數字,展開縮寫。 |
| X11 | 第二次擷取執行覆蓋了第一次的索引 | 改為合併各次執行的索引檔案,而非覆寫。 |
| X12 | 計時包裝器內的影片未通過檢查 | 計時媒體本身帶有 class="clip";其容器則沒有計時。 |
| X13 | 原型擷取包含提示框或 Cookie 橫幅 | 在截圖前關閉並隱藏疊加層,然後裁切至影格。 |
| X14 | 錄製顯示僅原型按鈕 | 在錄製前透過選擇器或文字前綴隱藏測試和開發按鈕。 |
| X15 | 產品無法證明的主張 | 「第一」、「總計」、「保證」需要來源。刪除它們或將其移至「待確認要點」。 |
| X16 | 行銷數字沒有根據 | 在使用前檢查其來源:搜尋文件和頁面的 git 歷史(git log -S'<數字>')。在文案編輯中手動填入的數字不算證據。捨棄它。 |
| X17 | 垂直裁切無法閱讀 | 桌面螢幕在 9:16 比例下只有 9px 文字,裁剪後看起來仍像桌面畫面。一次在面板上顯示一個已調整的元素,就像產品行動登陸頁面所做的那樣(references/vertical.md)。 |
| X18 | 旁白聽起來戲劇化或興奮 | 非語言標籤(如 [sighs])、[excited] 和 [serious] 在產品影片中會顯得過頭。使用 [calm] 和 [warm],僅重新產生被指名的場景,並使用 scripts/voice-tone.py 比較不同錄製。 |
| X19 | 版面看起來像網頁 | 左對齊欄位、標題上方的章節標籤、角落的小標誌。在垂直影片中:將所有內容置中,刪除標籤,使標誌更大且置中。 |
| X20 | 標語離標誌很遠 | 匯出的標誌有透明邊距。修剪檔案並相對於實際標記定位。 |
| X21 | 旁白在某些場景平淡,在其他場景興奮 | 每個場景是帶有自己標籤的單獨請求,因此每個都是不同的表演。產生一個帶有單一標籤的連續錄製,使用 scripts/split-take.py 在停頓處分割,並使用 scripts/voice-tone.py --scenes 測量。場景間 5 個半音的差距聽起來像情緒波動,2 個半音則感覺均勻。 |
| X22 | 標題看起來很粗重且不像產品風格 | 字重是假設的(800)。使用 scripts/page-styles.cjs 讀取產品自身的標題樣式,並複製字體家族、粗細、行高和字距。 |
| X23 | 標題中文字擠在一起 | 從網頁複製的緊湊字距在影片尺寸下會縮小詞間的間距。添加 word-spacing: .07em。 |
| X24 | 毛玻璃標籤看起來像純白色,或其模糊效果在淡入後才出現 | 背景太過不透明(保持下部接近 0.6),或淡入效果在父元素上:在祖先元素上低於 1 的不透明度會將元素與其後方內容隔離開來。對具有 backdrop-filter 的元素進行動畫處理。 |
| X25 | 對比度檢查在看起來正常的文字上失敗 | 檢查取樣了淡入淡出中間的一個影格。在報告的時間點拍攝快照。如果元素正在進入,將進入時間延後幾幀並重新執行檢查。非常短的合成最常遇到此問題。 |
此技能包含的檔案
references/script.md:腳本範本、節奏、主張表格、發音表格。references/capture.md:三個擷取腳本的配置、擷取規格、品牌素材。references/voice.md:TTS 設定、語音、對齊、音量、音樂、更換旁白。references/hyperframes.md:合成規則、CLI 指令、版面區域。references/vertical.md:用於限時動態的 9:16 版本:安全區域、螢幕上的相機、字幕、分割成多個部分。assets/gen-template.js:16:9 合成產生器,需複製到專案的 tools 資料夾。assets/gen-vertical-template.js:垂直產生器,包含完整版和短版。scripts/lib/browser.cjs、scripts/site-capture.cjs、scripts/record-interaction.cjs、scripts/figma-frames.cjs、scripts/element-shots.cjs、scripts/page-styles.cjs、scripts/voice.py、scripts/split-take.py、scripts/voice-tone.py、scripts/elevenlabs.py、scripts/lib/eleven.py。
ElevenLabs API 程式碼(--provider elevenlabs、elevenlabs.py)是在沒有金鑰可測試的情況下編寫的。其首次實際執行可能需要修正;--parts 路徑和本地路徑則已測試過。