Communitygithub.com

SaviourV2/video-storytelling

設計與建構長篇訪談影片的視覺層,讓鏡頭在一個持續存在的世界中移動,而非一系列獨立圖形。

video-storytelling 是什麼?

這項技能(SaviourV2/video-storytelling)旨在解決長篇訪談影片中常見的「場景思維」問題:每隔幾秒更換圖形會迫使觀眾不斷重新理解畫面,最終導致「太 confusing」或「東西太多」的模糊反饋。其核心方法是將整支影片視為一個「持續存在的世界」,所有元素一旦出現就永不消失、移動或重新標記,新內容直接疊加在既有空間中。 技能定義了四大原則:持久世界、鏡頭即剪輯、注意力聚光燈、空間性開放循環。持久世界要求影片建立在一個不重置的空間中,鏡頭移動須符合特定的空間語法(例如由左至右代表朝向結果)。注意力聚光燈規則強制在任何時刻僅有一個元素保持全亮度,其餘元素保持靜默但可讀,這使得世界可以累積到十幾個元素卻不顯得擁擠。空間性開放循環則透過在畫面中留下視覺上不完整的元素來製造懸念與回報。 此技能支援需要腳本的任何訪談影片:新聞評論、單主題深潛、比較、教學、清單文等。它與 hyperframes-video-beats 不同——後者是在說話者頭像上疊加覆蓋卡片,而本技能設計的是影片「本身」的視覺內容。實作上要求每個章節使用單一生成器腳本、時間軸必須對齊逐詞轉錄、並遵循嚴格的 token 系統(5 種顏色、5 種固定意義、零裝飾)。已為 Claude Code 和 Cursor 等平台設計,參考實作包含完整的設計系統、開放循環幾何及品質驗證閘道。

相容平台~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/SaviourV2/acevids-editor/tree/HEAD/.claude/skills/video-storytelling

在你喜歡的 AI 中提問

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

說明文件

影片敘事

如何建構長篇影片的視覺層,讓觀眾在九分鐘時仍能保持方向感。適用於任何有腳本的訪談影片:新聞評論、單主題深潛、比較、教學、清單文。

此技能要取代的失敗模式是「場景思維」。每隔幾秒更換圖形會迫使觀眾每隔幾秒重新理解畫面,而沒有任何單一圖形是錯的——這就是為什麼反饋往往以模糊的「confusing」或「東西太多」形式出現,而不是具體缺陷。

如需中性的練習節奏表,請參閱儲存庫根目錄的 docs/STORYTELLING-WORKBOOK.md。可重複使用的設計系統在技能專屬的 reference/design-system.md;已完成的開放循環幾何在 reference/patterns/wall-of-slots/。不需要私人原始影片。

這不是 hyperframes-video-beats。那個技能是在說話者頭像上疊加覆蓋卡片。此技能設計的是影片「本身」的內容。

1 · 四項原則

一個持續存在的世界

影片存在於一個單一空間中,且永不重置。觀眾已經看過的所有事物仍然留在原來的位置,新材料是疊加上去而非取代它。一個元素一旦被繪製,就永不重繪、移動或重新標記。

此技能中的其他所有內容都依賴於此。如果空間不斷變化,鏡頭就無處可去;如果畫面上沒有其他東西,聚光燈就毫無意義;開放循環在一個會重置的世界中也無法保持開放。

這個世界也必須值得觀眾停留,因此在建構任何東西之前要先決定空間語法,並在整個播放期間保持一致。在參考建構中:從左到右是朝向結果,向上是朝向人類且是畫面上唯一的溫暖元素,向下是進入記錄系統。在最初兩分鐘學會這個語法的觀眾,之後就能免費讀懂整支影片。

刻意打破語法恰好一次,為了意義。參考建構在十分鐘內唯一一次從右到左的移動,是一張已解決的票卡沿著「reopen rate」這個詞回溯到佇列中。它不發一語便落地,因為在過去三分鐘內方向已經代表了某種意義。

鏡頭就是剪輯

每當剪接到一個新圖形,就要觀眾付出一次重新定位的成本。在一個保持不動的空間中移動則不花費任何成本。因此,推鏡放大讀起來是「靠近一點看你已經理解的那部分」,而拉遠鏡頭則是這項工作的回報——因為到目前為止所建構的一切都還在。

在三種高度間工作,並在相鄰高度間移動:

高度顯示用途
世界整個空間定位、回報、「這是我們所在的位置」
區域正在討論的子圖大部分播放時間
細節一個元素數字、狀態變更、決策

從細節跳到世界會令人迷失方向,除非這是一個刻意的回報節拍——在這種情況下,它就是最好的選擇。

需要花一次重建才能學到的規則:

  • 將取景命名為精確的世界視窗,而非比例因子。 視窗邊界必須落在標籤之間。將取景指定為「scale 0.6」會在畫面邊緣將文字切成兩半。
  • 為相同目的重複使用相同的視窗。 如果定位鏡頭是某個特定視窗,就永遠使用那個精確的視窗。幾乎相同的取景會讀起來像是漂移。
  • 根據移動距離變化持續時間,而非使用一個全域預設值。
  • 鏡頭與全幅擦拭依序進行,永不重疊。 如果同時進行,它們會將內容側切。先鏡頭,再擦拭。
  • 覆蓋圖層需在鏡頭在其下方移動之前變成不透明。 如果順序相反,部分移動會暴露出來,讀起來像是跳接。
  • 距離畫面邊緣 60px 內不得有標籤。 元素可以超出格線並讀作「世界仍在繼續」;但在字形中間被切斷的文字則讀起來像一個 bug。用放置位置解決,而不是用遮罩——因為柔邊羽毛無法捕捉以約 1800 px/s 移動的刀刃。
  • 在相同主體上連續兩次移動讀起來像是故障。 一個完成後「再」一個開始的重新取景是放大、死停、再第二次動作——客戶稱之為「一個故障加一個停頓」。將它們合併為一個手勢:共享對稱緩動(power2.inOut),落在同一影格上,讓面板讀起來像在推開素材。相關:在「可見素材」移動上使用前置緩動(power3/4.out)會將約 90% 的移動前置並爬行到停止;保留用於元素進場,此時爬行讀起來像是就定位。(在已完成的範例開場中導致了一個客戶標記的修訂。)

注意力就是聚光燈

在任何時刻,恰好一個元素處於全亮度。所有其他已繪製的元素保持安靜但可讀。 非這樣不可。這條規則讓一個世界可以累積到十幾個元素卻從不感覺擁擠,也是讓拉遠鏡頭可讀而不至於令人不知所措的原因。

層次來自於「活躍/安靜」的比值,而非讓所有東西變暗。參考建構的第一個原型最亮像素為 101/255,在 960x540 下無法閱讀;解決方法是使用更亮的墨色,而非更多暗色。

狀態目標亮度 (Y, 16-235)參考中的不透明度
活躍的線條 + 標籤200-2351.0
背景,已繪製且仍然相關120-1500.56
已用盡,已表達完85-1050.33
任何標籤,任何狀態永不低於 90

實作是一個函數,在每個敘事節拍時根據正在討論的 ID 呼叫 (build_s01.py, lit()):

def lit(t, active, warm=(), dur=0.5, floor=FLOOR):
    active = list(active) + [g + "-l" for g in active if g + "-l" in order]
    for gid in order:
        if gid not in opac:      # 從未繪製:無需點亮
            continue
        tgt = 1.0 if gid in active else (WARM if gid in warm else floor)
        if gid not in active:
            tgt = min(tgt, MUTED.get(gid, 1.0))
        ...

其中有三個細節是關鍵:

  • 標籤總是繼承其元素狀態(透過 -l 後綴納入)。一個點亮的元素在其下有一個無法閱讀的標籤,正是要修復的缺陷。
  • 已完成的道具透過 MUTED 上限退場到不透明度 0,而非 0.3。靜音到 0.3 會在畫面留下無法解釋的碎屑,持續到該節結束。生成器規則:在任何後續開始的 lit() 之前發出 mute(),否則在其補間完成時 mute 會被覆寫。
  • 不透明度事件必須按時間軸順序發出,否則追蹤器會看到過時的狀態並計算出錯誤的目標值。使用 seq() 守衛,在亂序發射時引發異常。
  • 每個元素每個視窗只有一個不透明度權威。 兩個同時活躍的補間驅動同一個元素的不透明度到不同值,在獨立章節中渲染流暢,但在組合的 master 中會以約 10Hz 閃爍,因為獲勝的補間在每一影格交替。參考建構在每個過渡處都發送了這個缺陷。當像 lit() 這樣的掃描與顯式的變亮或靜音重疊時,後續開始的補間是唯一的驅動者,而掃描則跳過這些 ID(lit(..., skip=(...)))。閘道:掃描組合渲染,檢查每個過渡視窗中是否有單影格折返亮度跳動(參考建構中的 qa/v4/flicker/qa-flicker.mjs)。

開放循環是空間性的

永遠不要說「我們稍後會再回來」。在世界中留下一些明顯不完整的東西,然後再回到它。一個觀眾能看到的承諾,就是他們能感受到的懸念。

無論形狀如何,機制都是相同的:

  1. 在鉤子中,在空間中,在做出承諾的那條線上種下它。
  2. 在每個邊界處重新展示它。 任何章節交接都是一個邊界。重新展示大約花兩秒鐘,是留存機制;跳過它就是為什麼回報最終一無所獲。
  3. 讓它明顯地進展。 觀眾必須看到不完整之處縮小。
  4. 在你打開的那個圖像上關閉它。

根據腳本選擇形狀:

腳本形狀世界什麼不完整
N 個平行項目主幹上的 N 個插槽空插槽(參閱 reference/patterns/wall-of-slots/)
一個深度流程完整的管線,佈置出來一個斷裂或遺失的連結
層級或階層一個向上堆疊的堆疊堆疊頂端是一個鬼影
比較共享軸上的兩個欄位一個欄位為空,或一個未填滿的計分卡
新聞或公告時間軸,或一個地圖右側,未來,是空白的
教學或跟做完成的架構,鬼影每個尚未建構的節點

將一個項目放到其插槽中是一個即時鏡頭移動,約 1.4 秒,絕非剪接到一個預先製作的填滿狀態圖片。觀眾看著他們剛剛學到的東西變成那個圖塊。如果影片有數字符碼,在同一個移動中作為里程表滾動它,使用相同的開始時間、持續時間和緩動,否則它們會在滾動中途合併成一個頻帶。

計數器需要一個名稱,而不只是一個數字。 角落的數字符碼告訴觀眾他們在序列中的位置,但不會告訴他們當前項目是「什麼」;九分鐘後,「03」不傳達任何資訊。將數字符碼與 1-2 個詞的標籤配對,標籤命名當前項目(支援、語音 AI),使用相同的銘牌化學,作為一個剛性支架與數字符碼一起移動,在同一個里程表滾動中交換。參考建構的客戶審查正是要求這一點:視覺效果很好,但觀眾仍然無法追蹤畫面上是哪個使用案例。

2 · 紀律

如果它沒得到一個詞,它就不會被繪製

每個形狀都是一個有標籤的元素、一個連接有標籤元素的連接器、移動的主題、或者是環境背景。除此之外別無他物。

這來自一個靜音測試審查,該審查評分理解度為 7/10 並指出了原因:圖表是乾淨的,裝飾不是。十幾個未標籤的形狀,以與有意義的形狀相同的權重和調色板繪製,使得初次觀看的觀眾無法區分信號和質感,並花費真正的注意力去解碼那些從未打算被解碼的東西。這就是「東西太多」從文字重新定位到形狀。

預算:每個章節約 20 個畫面上的詞。 沒有句子。標籤是 1-2 個詞,位於其元素下方。參考章節 1 在 84 秒內有 21 個詞。

推論:反模式視覺效果絕不能疊加在建議之上。 先將世界帶到接近黑色,或者將反例放在好圖表不在的地方。

給觀眾一個可以跟隨的東西

透過一個狀態明顯變化的單一移動主題來承載故事:一個包含數據行和分數條的晶片、一份文件、一個請求。行填滿,條移動,邊框改變顏色。觀眾必須能夠僅透過觀看那一個物體來跟隨整個章節,並且它絕不能瞬間移動;它沿著繪製的連接器以恆定速度移動。

一個全域 Token 集

完整細節在 reference/design-system.md。

Token值
線條1.5 / 2.5 / 4 / 7,無其他
字型22 / 30 / 42 / 60 / 84
圓角10 / 22 / 40,始終使用 superellipse(2)

五種顏色,五種固定意義,零裝飾。暖色表示涉及人類,其他任何東西都不會是暖色。字型絕不使用純白色;它在暗色背景上會產生光暈。

此技能要防止的失敗,來自第一個建構的技術審查:「每個決策都是在本地正確做出的;沒有任何決策是全域做出的。」 18 種線條粗細和 9 種字型大小,大多數間隔 0.2,個別不可見且集體致命。眼睛得到的是噪音而不是層次。用一個會導致建構失敗的 token linter 來進行閘控。

動態

進場使用 cubic-bezier(0.16,1,0.3,1),退場比進場快,持續時間隨質量變化——因此一個 290px 的節點和一個 40px 的標籤不會以相同方式減速——並且 back.out 每個章節恰好一次,用在應得的節拍上。

永遠不要使用交叉淡出。 全出血圖層透過在已經不透明的背景上進行裁剪來進場和退場。在任何瞬間,一個像素要不是圖形,就是影片素材。

3 · 建構合約

  • 每個章節一個生成器。 scripts/build_<id>.py 只寫入 compositions/<id>.html。編輯生成器,永遠不要編輯生成的 HTML。章節根目錄 index-*.html 是手動維護的,因此取景變更在那裡進行。
  • 共享模組保持共享。 任何定義共享幾何的東西都由每個章節匯入。如果章節由平行代理建構,禁止它們觸碰共享模組;發散的幾何會默默地破壞每個交接。
  • 在組合之前對 SVG defs 進行命名空間隔離。 每個章節定義自己的 gEdge、shadow、edgeFade。在一個組合的 DOM 中,url(#id) 解析到文件順序中的第一個匹配項,因此一旦較早的合成卸載,後續的每個圖形都繪製「空無一物」。在參考建構中的成本:35 秒的空白畫面,所有閘控都顯示綠色。只有檢查組合的渲染才發現了它。
  • 根據逐詞轉錄將所有內容對齊到詞的開頭,在錨定詞之前 0.15-0.25 秒進入。永遠不要將章節平均劃分為節拍。
  • 審計間隙。 任何超過約 1.5 秒且沒有任何事情發生的片段都是死畫面;讓生成器將它們印出來。
  • 在剪輯中留出空氣。 激進的暫停修剪會在句子邊界產生接近零的間隙,客戶會將其聽成「結結巴巴」和跳接。根據說話者自己的基準進行校準:標記句子邊界間隙比其中位數緊約 10 倍的位置(參考說話者的中位數是 470ms;被標記的接縫處約為 20-40ms),並透過插入 4-8 影格的空氣來修復,絕不觸碰詞。空氣是來自音軌真實房間環境音的捐贈切片,帶有 10ms 淡入淡出,絕不使用 anullsrc:相對於 -50dBFS 底噪的數位靜音是可聽到的掉訊。影片保持不動;在句子之間,說話者的頭部接近靜止,4-8 影格的保持是看不見的。僅插入的變更會確定性地偏移轉錄,因此無需重新轉錄。插入的邊緣必須尊重語音包絡:將捐贈的環境音以 1ms 貼合到詞尾是...

…(以下內容因長度被截斷,但已涵蓋結構)

注意事項、參考及歸屬。

Individual skills in this repo

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

相關技能