Communitygithub.com

SallyRS/real-sfx

為動態影片進行聲音設計,使用使用者自己收藏的真實錄製音效(包含分類好的主音效包:呼嘯聲、撞擊聲、上升音效、爆裂聲、鈴聲、按鍵聲、擬音、環境音,以及備用音效庫)和 uisfx 的 UI 音效,絕不使用合成音效。

real-sfx 是什麼?

real-sfx 是一個專為動畫影片、螢幕錄影、UI 動畫和動態圖形設計的聲音設計工具,它完全基於使用者提供的真實錄製音效庫,而非合成音效。它能從專案的提示清單、合成腳本、HyperFrames 合成、螢幕錄影(如打字、提示、滾動、點擊等區域)或影片畫面本身,自動偵測需要音效的時刻,並挑選、處理及對齊音效。此工具支援 Claude Code、Cursor、Codex 等 AI 代理平台,並能保留原始影片中的音樂與人聲,同時移除已合成到影片中的音效層以避免重複。最終產出一個新的 MP4 檔案、一個獨立的 SFX WAV 音軌、一份音效報告以及一份自我評估分數表。`real-sfx` 與其他聲音設計工具的關鍵區別在於其嚴格的「無合成」原則,即使備用音效庫中的 UI 音效(uisfx)本身是合成的,但僅用於 UI 時刻,且可透過選項完全關閉。其工作流程包含多個 Python 腳本,從初始設定檢查、事件偵測、音效混音、批評分析到音準校對,並提供詳細的參考文件(如 `references/` 目錄下的內容)來指導使用者如何處理特定情境,例如如何從投影檔案中讀取合成音效、如何處理螢幕錄影,以及如何在有音樂的影片中調整音準。

相容平台✓Claude Code~Codex CLI✓Cursor
npx skills add https://github.com/SallyRS/video-director/tree/HEAD/skills/video-director/real-sfx

在你喜歡的 AI 中提問

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

說明文件

real-sfx: 為動態影片提供真實音效

目標:讓影片聽起來就像是由一位擁有良好音效庫的專業人士剪輯出來的。所以:

  • 音效絕不合成。 來源:使用者的音效庫(config.json)和 uisfx(一個現成的 CC0 介面音效包,本身是合成的:唯一的例外,僅用於介面時刻;「無合成」選項可將其關閉:--ui library)。沒有合適的音效:該時刻保持靜音,並會記錄在報告中。這會覆蓋 motion-standards 中的「無音軌:合成」規則。
  • 你無法「聽見」。 聲音是以數字、文字和圖片的形式讀取(references/listening.md)。請不要將選擇描述為「聽過」:請說明是透過眼睛和測量檢查了哪些部分,以及使用者應該聽哪些部分。
  • 保留音樂和人聲,當它們主導影片時。最終結果總是包含一個新的 MP4 和一個獨立的 WAV 音軌。
  • 不要重複。 已合成到影片渲染音訊中的音效,會被真實音效取代,而不是疊加在它們之上(第一步)。批評分析會將此量化為一個數值(doubling 軸)。
  • 不要修改專案或技能資料夾。 將所有工作檔案放在你自己的資料夾中(work/, result/)。

在 Video Director 內部

(在 Video Director 的副本中新增;原始 Clipwing 版本沒有。UPSTREAM.md 列出了所有變更。) 此副本位於 Video Director 技能內部,並由其聲音階段執行:../references/sound-stage.md,「聲音工程」。這些步驟會決定哪些時刻需要音效,只將這些時刻傳遞給此技能(build/audio/sfx/events.json),固定使用者選擇的錄音(sound_handoff.py pins),以 --ui library、--no-loudnorm 且不包含紋理層或基底的方式執行,並只取回效果音軌和已解析的提示(sound_handoff.py collect)。請遵循這些步驟,並僅針對它們未涵蓋的選項閱讀此檔案。將 REAL_SFX_CONFIG, REAL_SFX_INDEX, REAL_SFX_TASTE, REAL_SFX_RATINGS, REAL_SFX_STEADY 和 REAL_SFX_STYLES 設定為 ~/.config/real-sfx/ 下的路徑(該插件每次安裝新版本都會放在新資料夾中,因此此處寫入的任何內容在下次更新時都會遺留),並且不要使用 --remember,因為它會寫入此資料夾(learn_style.py 也是如此:將學習到的樣式複製到 ~/.config/real-sfx/styles/)。

快速路徑

首先執行 python scripts/setup.py check(ffmpeg、主要/額外音效庫、索引、uisfx)和 python scripts/look.py FILM.mp4 --out work/look(包含時間和原始聲音的影格)。然後,根據你擁有的資料:

# 1. 專案有事件清單(docs/cues.json, scripts/cues.json)或合成其聲音的腳本(audio.cjs)
python scripts/from_cues.py PROJECT_FOLDER|docs/cues.json --video RENDER.mp4 --out work/cues.json
# 2. 沒有清單的螢幕錄影:ui_events.py ...(references/screencast.md),然後 from_cues.py work/ui/events.json
# 3. 僅有影片:                    find_moments.py FILM.mp4 --out work/moments; suggest_cues.py work/moments/moments.json --out work/cues.json
# 3b. 沒有清單的柔和彩色動畫(UI 預覽、插圖、動態圖形):自動化會看到 40 個動作中的 5-6 個。
#     步驟 2,「沒有清單的無聲動畫」:find_moments.py FILM --out work/moments --fine; look.py FILM --at T --span 2.4
#     --step 0.1 --out work/at.png; 根據影格自行建立事件清單(references/typed-cues.md)-> from_cues.py - --ui library
python scripts/mix.py work/cues.json --out result/film_sfx.mp4 --plan     # 查看每個音效的位置;然後不加 --plan 執行
python scripts/critique.py result/film_sfx_resolved_cues.json result/film_sfx_sfx_track.wav
python scripts/levels.py   result/film_sfx_resolved_cues.json result/film_sfx_sfx_track.wav --json work/edits.json
# 一個聲音只有 SFX(沒有自己的音樂或人聲)的影片:在間隙中放置細小聲音,然後再次執行 mix.py(步驟 4,「細小聲音層」)
python scripts/texture.py work/cues.json --moments work/moments/moments.json
# 同一個影片:一個基底(一個在整個影片下方的長段昏暗真實錄音;步驟 4,「基底」),然後再次執行 mix.py
python scripts/bed.py work/cues.json [--list]
# 與九個完成的 SFX 卷軸進行比較(步驟 6,「對照參考」):沒有分數,不影響最終判斷
python scripts/critique.py RESOLVED.json WAV --style clean-sfx-refs
# 讓人工聆聽變得簡單(步驟 6):一個包含批評問題和單擊判斷的頁面;遮罩模型
python scripts/listen_page.py build work/listen --moments result/film_sfx.mp4 --critique RESOLVED.json WAV
python scripts/listen_page.py serve work/listen [--lan]        # 然後:listen_page.py results work/listen --log
python scripts/mix.py work/cues.json --out result/film_sfx.mp4 --masking        # 其餘聲音隱藏哪些部分(需要虛擬環境)

專案資料夾會找到自己的事件清單(docs/, scripts/, assets/);合成器腳本只在沒有清單時讀取。在編輯工作表之前選擇所有 from_cues.py 標誌:再次執行它會清除手動編輯(然後使用 sheet.py apply)。

影片中有人聲:mix.py ... --voice-safe(深度 normal;當有許多安靜紋理時使用 --voice-depth light,deep 僅用於暫停中的稀有聲音:它會完全將介面從混音中移除)。音樂主導影片:--duck。 響度:預設情況下,重建的基底會匹配原始響度;你自己的設定:--target-lufs NUMBER。

沒有索引,或音效庫已移動:python scripts/build_index.py,然後 python scripts/listen.py tag-index。 沒有 uisfx:setup.py init --uisfx。 另一台機器:setup.py scan FOLDER,setup.py add-library NAME PATH [--tier main|extra] --index。 從技能資料夾執行腳本;引用包含空格或非拉丁字元的路徑;在 Windows 上使用含非拉丁路徑的自訂 Python:PYTHONUTF8=1。在 PowerShell 中,引號會破壞 JSON 引數:將它們放入檔案中。

聲音的來源

需要的聲音類型來源
基礎:呼嘯聲、撞擊聲、上升音效、爆裂聲、鈴聲、按鍵聲、紙張聲、擬音、環境音主音效庫(tier: main,路徑在 config.json 中)。一個包含 catalog.json / catalog.csv 的分類包,為每個聲音提供類型和來源錄音,這比根據檔案名稱猜測要好
主音效庫缺少的:低沉掉落聲、硬幣聲、短促雜訊備用音效庫(tier: extra,在結果中標記為 ~):僅在主音效庫少於三個合適聲音時使用
具有特定角色的設計包角色 granular, atmosphere, power, music_transition, voice 從不透過自動選取請求:請明確使用它們(--role, "pick": {"role": ...})
介面時刻:點擊聲、滴答聲、視窗聲、通知聲uisfx(--ui auto),當清單本身命名了介面類型(click, chime...)時:from_cues 會說明原因和位置(routes: key -> library:click, pop -> uisfx:select)
打字聲始終使用音效庫的真實鍵盤,即使使用 --ui auto 也是如此;from_cues 會自動將連續 8 個以上、間隔 35-170 毫秒的 click 事件識別為打字(--no-typing-detect)
物理接觸:球、腳步、珠子、物體始終使用音效庫:地板上的球是沉悶的重擊聲,而不是 select 聲音(配方見下文)

如果還沒有音效庫:僅使用 setup.py init --uisfx 即可獲得 78 個 CC0 UI 提示。值得檢查的免費真實錄音來源(請閱讀每個授權):Freesound(CC0 篩選器)、Sonniss GDC 包、Mixkit、Pixabay 音效。

「從我的音效庫」、「無合成」或「聲音聽起來很合成」:--ui library。在帶有 uisfx 介面聲音的專案中,為標誌加上重音或「cha-ching」聲:--from-library pop,bell(清單中的種類名稱);對於單個聲音:sheet.py set --at T --label bell id=65。

在調性音樂下:

  • uisfx 重複音調和音效庫調性聲音(chime, pop, glass, coin)的音高步進在專案有樂譜時會自動關閉(--ui-pitch off|cycle);
  • 真實聲音的音高會被調整以配合音樂的樂音:mix.py 會使用工作表的 music_ref(無效果的基底,或音樂音軌)或 --music-ref FILE,並將調性聲音最多移調 2 個半音,再加上將其置於某個音符上的音分(總共 2.5 音分),前提是這樣能讓它落在一個音符上;噪音則保持不變(--no-tonal-fit;scripts/tonal.py SOUND --music FILE --at T 會顯示音符);
  • 作者原始頻率的間隔(tick(t, 1800 * 2 ** (4 * i / 12)))會成為替換音效的音高步進(melody:)。

工作流程

1. 聲音中已有的內容

look.py 顯示原始聲音的頻譜圖(人聲是片語的頻帶,音樂是帶有節拍的地毯,寂靜是黑色);listen.py voice FILM.mp4 給出語音和音樂的比例。三種情況:

  • 作者的音樂或人聲:它們保留下來,SFX 疊加在上面(--duck / --voice-safe)。 例外情況(真實影片上的人的答覆,2026-10-19):該影片被發送來「進行聲音設計」,其原始聲音只有音樂(listen.py voice:語音 0%),且此人希望不帶音樂的版本,就像他們自己的乾淨 SFX 卷軸一樣。製作一個無音樂的版本(from_cues.py ... --ui library --drop-original,然後使用喜愛的氛圍執行 bed.py --id ... --level -46),如果需要的話也製作一個有音樂的版本,並說明兩者的區別。在三個選項(原始 / 音樂上的效果 / 僅效果)的盲測中,此人毫無疑問地選擇了最後一個。from_cues 在這樣的影片上會印出 BAKED:,儘管沒有烘烤的合成(語音 0%,音樂 84%,攻擊點與事件不匹配:7% 對比隨機的 9%):這是誤報。
  • 合成音效已烘烤到音軌中(專案是為合成配樂編寫的):在其上疊加真實音效會造成重複。from_cues.py 會自行檢查這一點(BAKED:, unbake:)並從基底中移除合成音效,而不影響音樂和人聲;具體方法,以及如果腳本失敗或合成音效位於音樂音軌內部時該怎麼做(--extra-synth):請參閱 references/project-audio.md(當輸出包含 BAKED, WARN stems, unbake: not possible,或專案使用腳本合成其聲音時,請立即閱讀)。建置後,critique.py 會列印 doubling 軸:該圖層與原始和新影片的相關性(應接近 0)。
  • 螢幕錄影視窗內播放剪輯的聲音:原始聲音保留下來;這些視窗內的被捨棄。

2. 找到時刻(從最佳來源到最差來源)

  • 專案的事件清單或合成器腳本 → from_cues.py(見下文)。詳細資訊:references/typed-cues.md。
  • 螢幕錄影 → references/screencast.md(ui_events.py 區域、將按鍵與字元匹配、剪輯聲音)。
  • 帶有 data-start 的 HyperFrames 且無清單:from_hyperframes.py PROJECT --out work/moments.json。 「1 個時刻」包含 18 個元素,表示動作不遵循 data-start:尋找合成器腳本。
  • 僅有影片:find_moments.py FILM --out work/moments [--roi x,y,w,h] [--from A --to B] [--fine];種類 cut, burst, onset, settle(settle 也會在空影格或靜止迴圈上觸發:請查看影格); look.py --moments ... 繪製時刻的影格。骨架:suggest_cues.py(references/recipes.md);草稿是起點,不是答案。--fine 用於柔和彩色動畫(漸層、發光、改變顏色而非亮度的柔和形狀):它也會讀取色度變化,時刻會獲得 src=chroma|luma;在三部此類影片上,它找到了代理從影格中記錄的事件的 33–69%(在 80 毫秒內),而僅使用亮度只有 13–25%;候選項多 3–4 倍(每 10 秒 15–25 個)。這些是候選項:由影格決定。
  • 在音樂下:beats.py FILM --out work/beats.json --plot work/beats.png;使用 usable: true,mix.py --snap-beats(±50 毫秒)。該格線會根據大鼓進行檢查(低頻帶 < 125 Hz 單獨處理):它會列印有多少節拍在 40 毫秒內落在大鼓上。落在大鼓旁邊的格線(跟蹤器位於鈸上,「偏移 0.22 秒」)會被移動到其上;落在無聲處的格線會得到 usable: false,而 --snap-beats 會忽略它。--plot 繪製頻帶、大鼓(綠色標記)和格線(紅色線條):標記應位於線條上,否則不要信任格線。如果音樂是你的且可以配合畫面:beats.py FILM --suggest-offset work/moments.json 會建議將音樂偏移多少,以便剪輯和撞擊聲落在節拍上(僅供建議;音樂本身不會被修改)。

from_cues.py:python scripts/from_cues.py LIST|PROJECT_FOLDER|SCRIPT.cjs|- --video RENDER.mp4 --out work/cues.json(- 從標準輸入讀取清單;來自 PowerShell 的 BOM 也能理解)。它會自行執行並說明:

  • 這是否是正確的渲染:清單與畫面不符(VERDICT);一個設計時期的清單與一個根據人聲計時渲染的檔案:使用來自專案錨點的 time map(帶有 a 的 timing.json)

Individual skills in this repo

This repo contains 1 individual skill — each has its own dedicated page.

相關技能