外掛安裝: 在執行設定或更新命令之前,若此技能位於 HyperFrames 外掛內,請遵循外掛執行規則。獨立安裝則保留下方更新說明。
首先,保持此技能最新 — 在使用前先向使用者確認並執行:
npx hyperframes skills update talking-head-recut。如果所有內容都是最新的,這會是一個快速的空操作;否則它會重新整理此技能及其依賴的核心領域技能,然後再使用它們。
談話性頭像重剪
Talking Head Recut 會將本地影片完整播放,並在其上層疊一系列按時間設計的圖形卡片 — 標題、下方三分之一處、數據提示、引言、側邊面板、子母畫面 — 並與說話內容同步。代理會設計卡片(時間 + 內容),並在對話中直接撰寫每張卡片的 HTML,然後組合成一個組合 HTML,並透過 hyperframes 渲染為 MP4。沒有固定的原型列表,也沒有規定的卡片結構 — 疊加內容完全來自逐字稿的實際內容。
入口是
/hyperframes。 此技能將現有的談話性頭像片段與設計好的圖形卡片(標題、下方三分之一處、數據提示、引言、側邊面板、PiP)打包 — 不是純字幕(口語文字作為文字)。片段保持不變播放。 任何其他意圖 — 純字幕、獨立圖形、從頭建立影片 — 或不確定時 → 請先閱讀/hyperframes:意圖層負責所有路由決策。
embedded-captions的圖形包裝兄弟技能。 字幕是將口語文字加為可讀字幕;這是在播放的影片上添加設計好的圖形。純字幕 →embedded-captions。從頭建立影片 → 創作工作流程(product-launch-video/faceless-explainer/ …)。
透過 /hyperframes 路由後,意圖層僅確認輸入(哪個片段)並宣布渲染策略問題為延後詢問 — 長寬比、佈局、風格組和卡片數量保留在第 7 步,由探查過的素材和逐字稿提供建議;該層的執行形狀問題不適用。當存在 BRIEF.md 時,它會攜帶已確認的輸入和使用者備註 — 請優先閱讀它。
工作目錄中可檢查的中間檔案:
metadata.json— 時長 / 寬度 / 高度 / fpsaudio.mp3— 提取的音訊transcript.json— 一個扁平的單字陣列[{ text, start, end }, …](Whisper;沒有segments,沒有words包裝)storyboard.json— 輕量級卡片大綱(代理的計劃)public/cards/card-XX.html— 每張卡片的 HTML 片段public/index.html— 最終組合的組合output.mp4— 渲染的影片
CLI 解析
# hyperframes — 語音辨識(本地 Whisper)+ 將組合 HTML 渲染為 MP4
npx hyperframes --help
此技能完全在 hyperframes CLI 加上系統 ffmpeg / ffprobe 上執行。語音辨識是本地 Whisper,透過 hyperframes transcribe — 無需第三方服務、API 金鑰或速率限制代理。
工作流程
1. 檢查環境
npx hyperframes doctor # ffmpeg, headless browser, render deps
# 確認捆綁的資產:
ls "<SKILL_DIR>/assets/fonts" "<SKILL_DIR>/assets/vendor/gsap.min.js"
所需項目:
ffmpeg/ffprobe(系統)<SKILL_DIR>/assets/fonts/*.woff2、<SKILL_DIR>/assets/vendor/gsap.min.js(捆綁在此技能內,在第 9 步中推送到工作目錄)
語音辨識不需要金鑰 — hyperframes transcribe 在本地執行 Whisper(第 4 步)。
在 macOS 上強烈建議用於 hyperframes render:
export PRODUCER_BROWSER_GPU_MODE=hardware
2. 建立工作目錄
所有產出檔案都放在 videos/<project-name>/ 下 — 與其他影片工作流程(product-launch-video / faceless-explainer / pr-to-video)相同的慣例。保持 cwd 在工作區根目錄;以下所有內容都寫入這個子目錄。
VIDEO_PATH="/absolute/path/input.mp4"
WORK_DIR="videos/$(basename "$VIDEO_PATH" | sed 's/\.[^.]*$//')"
mkdir -p "$WORK_DIR"
3. 提取音訊和中繼資料
# 中繼資料 — 時長 / 寬度 / 高度 / fps
ffprobe -v error -select_streams v:0 \
-show_entries stream=width,height,r_frame_rate \
-show_entries format=duration -of json "$VIDEO_PATH" > "$WORK_DIR/metadata.json"
# 音訊
ffmpeg -y -i "$VIDEO_PATH" -vn -acodec libmp3lame -q:a 2 "$WORK_DIR/audio.mp3"
輸出:metadata.json(讀取 width/height/duration;fps = r_frame_rate 分數評估結果,例如 30000/1001 → 29.97)+ audio.mp3。
4. 語音辨識
npx hyperframes transcribe "$WORK_DIR/audio.mp3" -d "$WORK_DIR" --json --model small.en
本地 Whisper — 無需 API 金鑰、無代理、無速率限制。將逐字層級的 transcript.json 寫入工作目錄(單詞 text + start / end 時間戳)。讀取它以獲取驅動第 6 步卡片時間的單詞/句子時間;如果需要區段級別的區塊,請自行根據標點符號/停頓將單詞分組為句子。
限制到媒體時長。 Whisper 可能返回最後一個單詞的 end 略超過實際片段長度 — 將每個卡片 endSec 和 composition.durationSeconds 限制為 metadata.json 中的時長,否則渲染將在影片結束後顯示黑色尾部。
5. 修正逐字稿
transcript.json 是一個扁平的字詞物件陣列 — [{ "text": "…", "start": s, "end": s }, …](沒有 segments 陣列,沒有 words 包裝;每個字詞的鍵是 text)。讀取它並修正明顯的 ASR 錯誤:
- 同音字、產品名稱、技術術語、標點符號
- 就地編輯單詞的
text;保留其start/end時間戳 - 沒有預先分組的
segments陣列 — 當您需要區段級別的區塊用於卡片時間時,請自行將單詞分組為句子(在終端標點符號/停頓處分割)
6. 起草輕量級分鏡腳本(在聊天中)
不涉及 CLI。 讀取 transcript.json + metadata.json 並直接設計卡片。storyboard.json 是代理內部的規劃產出 — 沒有 CLI 命令會消費它;它的存在是為了讓您可以在撰寫每張卡片的 HTML 之前,清晰思考時間和內容。保持形狀與下面的範例一致,以便相同的大綱可以驅動您在第 9 步中撰寫的組合:
{
"schemaVersion": 3,
"composition": {
"fps": 30,
"width": 1080,
"height": 1920,
"durationSeconds": 121.2,
"layout": "portrait",
"themeId": "noir",
"seed": 42
},
"videoTrack": {
"sourcePath": "input-video.mp4",
"startSec": 0,
"endSec": 121.2,
"bounds": { "x": 0, "y": 0, "width": 1080, "height": 1920 }
},
"subtitles": { "enabled": false },
"cards": [
{
"id": "card-01",
"intent": "用演講者焦慮的午夜問題吸引注意",
"startSec": 0.5,
"endSec": 13.0,
"accentIndex": 0,
"zone": "fullscreen",
"contentHints": {
"kicker": "一個誠實的問題",
"title": "晚上11點的靈魂拷問",
"detail": "客戶的60秒語音訊息:'如果人民幣升值,這是否意味著我的美元保單是巨大損失?'"
}
}
]
}
必填卡片欄位:
| 欄位 | 類型 | 用途 |
|---|---|---|
id | 字串 | 卡片 HTML 和 GSAP 選擇器中使用的穩定 ID |
intent | 字串 | 自然語言描述;提供給卡片合成 |
startSec / endSec | 數字 | 以秒為單位的時間(endSec > startSec) |
accentIndex | 0 | 1 | 2 | 3 | 4 | 此卡片從 5 個主題強調色中選取哪一個 |
zone | 列舉(見下文) | 卡片在畫布上的位置 |
contentHints | 物件 | 自由形式的袋子;代理在此放置 kicker/title/detail/data/quote |
archetype(可選) | 字串 | 您可以附加的自由形式標籤,用於記住卡片模式;不存在則表示自由形式,這是預設值 |
transition(可選) | 列舉:cut | fade | slide | wipe | 宣告式的卡片到卡片轉場 |
五個 zone 值:
| zone | 解析後的邊界 | 使用時機 |
|---|---|---|
fullscreen | 覆蓋整個畫布 | 英雄時刻、大數字、口號 |
whiteboard-area | 內縮 40px 邊距(或直向高度的 45%) | 密集的數據/註解內容 |
lower-third | 底部 30% 帶狀區域 | 在可見影片上進行註解 |
side-panel | 右側 42%(橫向)或底部 40%(直向) | 資料在一側,影片在另一側 |
video-overlay | 完整畫布,期望大部分透明的卡片 | 在全出血影片上的註解疊加 |
當您在第 9 步中組裝組合時,請根據上表將每個卡片的 zone 解析為卡片主機包裝器上的像素邊界。影片邊界在組合層級(videoTrack.bounds)設定一次;要使影片在卡片之間“移動”,請在組合的 <script> 中針對 #video-wrap 撰寫 GSAP 補間動畫(參見第 9 步)。
沒有規定的卡片角色,沒有規定的敘事弧線。 卡片從影片實際說的內容中出現 — 可能全是引言或全是數據,可能以數字開頭或以故事開頭。讓逐字稿驅動節奏。
要有多少個重點? — 自動從時長和密度推斷。 沒有固定的上限。根據影片時長選擇基礎節奏,然後根據資訊密度進行調整。只有下限是固定的:至少 5 張卡片,因此即使短影片也有節奏。
步驟 1 — 按時長決定基礎節奏(中等密度的自然秒數/卡片):
| 影片時長 | 基礎節奏(每張卡片的秒數) | 理由 |
|---|---|---|
| < 60 秒(短 Reels) | 6–8 秒 | 觀看者在短格式中期望快速剪輯 |
| 60 秒 – 3 分鐘 | 8–12 秒 | 正常的社交媒體節奏 |
| 3 – 10 分鐘 | 12–20 秒 | 給予呼吸空間;每張卡片承載更多 |
| 10 – 30 分鐘 | 20–35 秒 | 長格式演講/訪談節奏 |
| > 30 分鐘 | 30–60 秒 | 情節式,接近章節感 |
步驟 2 — 密度乘數(乘以基礎節奏):
| 逐字稿中的信號 | 乘數 | 效果 |
|---|---|---|
| 高密度 — 很多數字、不同的主張、斷斷續續的節奏、類似清單的列舉、每 1–2 句話就是一個新想法 | × 0.7 | 剪輯更快,更多卡片 |
| 中等密度 — 數據和敘述混合的流暢流程 | × 1.0 | 基礎節奏 |
| 低密度 — 一個延伸的故事、重複的重新構框、緩慢反思的節奏、單一論點展開 | × 1.5 | 剪輯更慢,更少卡片 |
步驟 3 — 計算:
secPerCard = 基礎節奏 × 密度乘數
cardCount = max(5, round(影片時長秒 / secPerCard))
範例(注意 — 沒有上限限制;長影片自然會產生更多卡片):
- 30 秒 Reels,單一妙語(低密度) → 7 × 1.5 = 10.5 秒/卡片 → round(30/10.5)=3 → 下限為 5 張卡片
- 60 秒反思獨白(低密度) → 10 × 1.5 = 15 秒/卡片 → 4 → 下限為 5 張卡片
- 121 秒談話性頭像搭配豐富數據(高密度) → 10 × 0.7 = 7 秒/卡片 → 17 張卡片
- 5 分鐘訪談,混合密度 → 16 × 1.0 = 16 秒/卡片 → 19 張卡片
- 10 分鐘深度探討,高密度 → 16 × 0.7 = 11 秒/卡片 → 55 張卡片
- 30 分鐘講座,中等密度 → 28 × 1.0 = 28 秒/卡片 → 64 張卡片
- 1 小時播客,低密度 → 45 × 1.5 = 67.5 秒/卡片 → 53 張卡片
當一張卡片持續超過 ~15 秒時,請計劃一個更豐富的卡片(數據塊、多步驟揭示、透過間隔動畫展開的幾個子要點)— 靜態的一句台詞在超過 8 秒後會變得無聊。對於長片段,如果許多卡片超過 30 秒,請考慮將時間線分塊為子組合(每個章節一個 .html,使用 data-composition-src 掛載),以便每個檔案的 GSAP 時間線保持可管理 — 請參閱 HyperFrames lint 警告 timeline_track_too_dense。
content 可以是純字串("標題:年化 5.69%\n備註:…")或任何能捕捉數據的 JSON 形狀。代理決定每個卡片的形狀。
可選的片尾。 此技能沒有固定的品牌片尾。如果使用者想要結束卡片,請自行設計一個中性的(字標 + 一行標語,~1.5-2 秒,淡入 -> 短暫停留 -> 淡出),附加到 cards[],並延長 `composition.durationSec