Community程式設計與開發github.com

Salt-555/SaltySkills

這裡將發布我為 Hermes-Agent 設計的有趣技能。隨意取用,只要在談話中提到我時不吝讚美即可。

SaltySkills 是什麼?

此技能為 AI 代理(如 Hermes-Agent)提供一個完整的影片製作工作流程,專注於「電影節拍」風格的影片創作。其核心理念是視覺主導、音訊跟隨,確保動畫以自然時長播放,不因音訊長度而截斷或加速。技能涵蓋從腳本撰寫、素材生成到最終渲染的所有階段,包括圖像、p5js、manim、ASCII 動畫等多種視覺類型,並透過多次使用者檢查點(beat script、visual check-in、audio check-in)確保品質與方向正確。此外,它還整合了獨特的 VHS 濾鏡和乾/濕位元粉碎效果,為影片增添復古美學與標誌性音訊特徵。

相容平台~Claude Code✓Codex CLI~Cursor
npx skills add Salt-555/SaltySkills

Installed? Explore more 程式設計與開發 skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

在你喜歡的 AI 中提問

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

說明文件

電影節拍影片風格

核心哲學

視覺主導時序,音訊跟隨。 動畫和 ASCII 場景以其自然運行時長播放,不會為了配合音訊長度而被截斷、加速或停滯在最終畫面上。節拍之間的空隙是刻意設計,而非需要填補的空白。

  • TTS: 每個鏡頭一句話,追求最高信噪比,沒有填充式旁白。
  • 視覺: 完整的自然運行時長,讓動畫自由呼吸。
  • 剪輯: 僅使用硬切,無淡入淡出。
  • 音樂: 使用者提供音軌,在語音段落自動進行閃避。
  • 檢查點: 每個製作階段完成後,將素材交付使用者審查,再繼續下一階段。

專案結構

~/videos/[project-name]/
  project.md          # 動態文件 — 分鏡腳本、決策、修改記錄
  beats/              # 個別節拍素材
    beat-01/
      visual.mp4      # 生成的視覺素材(含動態的圖片或動畫)
      audio.mp3       # 此節拍的 TTS 音檔 (僅限 MP3 — 請參閱關鍵規則)
      note.txt        # 此節拍內容的一行說明
    beat-02/
      ...
  music/              # 使用者提供的背景音樂曲目
  output/             # 中間及最終渲染檔

第一階段:節拍腳本

建立 project.md,包含節拍明細。每個節拍 = 一個視覺 + 一句 TTS。

撰寫節拍

TTS 規則:

  • 每個鏡頭一句話,句號。
  • 最高信噪比 — 每個字都有其存在的價值。
  • 如果一個想法需要兩句話,那就分成兩個節拍。
  • 目標:每段音檔 5-15 個單詞。越短越好。
  • 不要有開場填充詞(「那麼…」、「現在讓我們來看…」)。直接切入重點。

視覺規則:

  • 描述視覺畫面呈現什麼 — 而非持續多久。
  • 視覺的運行時長由其自然完成決定,而非 TTS 長度。
  • 圖片剪輯:靜態圖片搭配 Ken Burns 動態(緩慢縮放/平移)。運行時長:至少 4-6 秒。
  • 動畫剪輯 (p5js/manim/ascii):完整播放動畫。不論需要多久 — 8 秒、12 秒、15 秒都可以。
  • 節拍持續時間 = max(視覺持續時間, 音訊持續時間) + 暫停。

project.md 中的節拍模板:

# [專案名稱]

## 概念
[一段話 — 說明這部影片的主題與想傳達的感受]

## 音樂
- 曲目:[使用者將提供的音樂檔案名稱或描述]
- 氛圍:[描述]

## 節拍

### 節拍 01
**視覺:** [類型: image | p5js | manim | ascii] — [提示/描述]
**TTS:** "一句簡潔有力的台詞。"
**狀態:** [ ] visual [ ] audio [ ] approved

### 節拍 02
...

## 備註
[決策、修改、使用者回饋的運行記錄]

剪輯類型

類型工具運行時長最適合用於
imageimage_generate + Ken Burns4-6 秒照片、場景、人像、定場鏡頭
p5jsp5js 技能自然時長 (8-15 秒)生成式藝術、粒子、資料視覺化、流場
manimmanim-video 技能自然時長 (8-20 秒)數學動畫、圖表、技術講解
asciiascii-video 技能自然時長 (6-12 秒)終端機美學、復古運算、駭客主題
captionffmpeg drawtext4-8 秒深色背景上置中顯示 TTS 文字 — 將焦點拉至文字本身

關鍵:在製作任何 p5js/manim/ascii 節拍之前,請先使用 skill_view(name) 載入技能。 這些技能包含品牌色板、字體規則和實作模式,必須嚴格遵守。

第二階段:腳本批准關卡

暫停。將 project.md 呈現給使用者。在獲得明確批准之前,請勿生成素材。

在 project.md 的備註部分更新批准時間戳記。

第三階段:生成視覺素材

根據類型生成所有視覺素材。儲存為 beats/beat-XX/visual.mp4。

圖片節拍 (VHS 濾鏡 Ken Burns)

  1. 透過 image_generate 生成圖片
  2. 對圖片套用 VHS 濾鏡(顆粒、掃描線、暗角、色差):
python3 scripts/vhs-filter.py \
  --input beat-XX-image.png \
  --output beat-XX-vhs.png \
  --seed 42 \
  --intensity 1.0

需求: pip install numpy Pillow (numpy 用於陣列效果,Pillow 用於圖片輸入輸出)。

強度等級:0.7 (輕微 — 僅顆粒 + 暗角),1.0 (標準 — 所有效果),1.5 (強烈 — 強色差、明顯掃描線)。預設值為 1.0。

  1. 對套用 VHS 濾鏡的圖片應用 Ken Burns 動態以產生 MP4:
ffmpeg -loop 1 -i beat-XX-vhs.png -t 5 \
  -vf "zoompan=z='min(zoom+0.001,1.3)':x='iw/2-(iw/zoom/2)':y='ih/2-(ih/zoom/2)':d=125:s=1920x1080:fps=25" \
  -c:v libx264 -pix_fmt yuv420p -r 25 beats/beat-XX/visual.mp4

為什麼先處理 VHS,然後才做 Ken Burns? zoompan 濾鏡會模糊顆粒和掃描線。先在靜態圖片上套用 VHS,然後再加上動態。在經過 VHS 濾鏡處理的圖片上疊加 Ken Burns 動態,能營造出一種生活化的類比感 — 就像透過有點老舊的 CRT 觀看舊影片。

動畫節拍 (p5js/manim/ascii)

先載入相關技能,再進行生成。將輸出儲存為 beats/beat-XX/visual.mp4。

解析度: 所有視覺素材必須為 1920x1080,25fps。調整 manim 輸出尺寸:

ffmpeg -y -i raw-manim.mp4 \
  -vf "scale=1920:1080:flags=lanczos,setsar=1:1,fps=25" \
  -c:v libx264 -pix_fmt yuv420p -r 25 beats/beat-XX/visual.mp4

批次處理: 每 6 個一組進行 image_generate 呼叫。如果被標記,則中性改寫提示詞並重試一次。

VHS 濾鏡參考

VHS 濾鏡 (scripts/vhs-filter.py) 對單張圖片套用以下效果:

效果作用視覺結果
色差R/B 通道偏移 (0-2px)邊緣出現色彩條紋,像未對準的 CRT
類比噪訊每通道 ±8 階顆粒 (按強度縮放)陰影與中間調呈現底片質感
掃描線每第四行調暗至 96%CRT 磷光柵格疊層
CRT 暗角邊緣變暗 (依強度 15-35%)圓形螢幕角落,像老電視

對於圖片: 所有效果以單一隨機種子套用一次。色差和噪訊是可見的;抖動/追蹤線條因為只有單格而較為細微。

注意: 此濾鏡僅適用於圖片 — 不處理影片輸入。要產生動態,請先對靜態畫面套用濾鏡,然後再加上 Ken Burns/zoompan。

第三點五階段:視覺檢查關卡

暫停。將每個視覺片段傳送給使用者審查。

使用 MEDIA: 路徑包含螢幕截圖或 MP4。依照編號呈現:

節拍 01: [MEDIA 路徑] — [簡短描述]
節拍 02: [MEDIA 路徑] — [簡短描述]
...

詢問:「在我們繼續處理音訊之前,有任何需要修改的地方嗎?」

在使用者批准視覺素材之前,請勿生成 TTS。 將回饋記錄在 project.md 的備註中。

如果需要修改,僅重新生成受影響的節拍並重新進行檢查。

第四階段:生成 TTS 音訊

生成所有 TTS 音檔 — 每個節拍一個。使用 text_to_speech 工具,輸出路徑為 .mp3。儲存為 beats/beat-XX/audio.mp3。

關鍵:音訊格式始終使用 MP3。 OGG 在 Telegram 傳遞和 ffmpeg 串接操作中存在編解碼器相容性問題。將 TTS 提供者設定為 OpenAI 並以 MP3 輸出。

規則:

  • 每次呼叫一句話。不要串接。
  • 生成後使用 ffprobe 測量每個音檔的持續時間。
  • 在 project.md 中每個節拍旁記錄持續時間。
ffprobe -v error -show_entries format=duration -of csv=p=0 beats/beat-XX/audio.mp3

第四點五階段:音訊檢查關卡

暫停。將音訊片段呈現給使用者。

套用語音濾鏡 (必做)

對每個 TTS 片段套用乾/濕位元粉碎鏈 — 這是我們的標誌性語音。完整技術與陷阱請參閱 references/dry-wet-bitcrush.md。

提供兩種方法:

A) 靜態混音 (簡單、一致):

# 步驟 1:透過 wav 中繼檔建立粉碎版本 (保持時長)
ffmpeg -y -i beats/beat-XX/audio.mp3 \
  -af "aresample=resampler=soxr:osr=2000,aformat=sample_fmts=u8,aresample=resampler=soxr,lowpass=f=2500" \
  temp-crushed.wav

# 步驟 2:混合乾 + 濕訊號,並加上壓縮膠合
ffmpeg -y -i beats/beat-XX/audio.mp3 -i temp-crushed.wav \
  -filter_complex "[0:a]volume=0.7[dry];[1:a]volume=0.3[wet];[dry][wet]amix=inputs=2:duration=first:normalize=0,acompressor=threshold=0.05:ratio=4:attack=10:release=100[out]" \
  -map "[out]" beats/beat-XX/audio-filtered.mp3

rm temp-crushed.wav

B) 動態混音 (訊號退化效果 — 建議使用): 使用 Python 腳本 (scripts/vibey-mix.py),透過零階保持升取樣實現真實位元粉碎,音高正確。

需求: pip install numpy pydub (numpy 用於陣列處理,pydub 用於 MP3 讀寫)。

鎖定參數 (dec5-bit8 變體):

  • 抽取: 5 倍 (丟棄每 5 個樣本,然後透過零階保持重複)
  • 量化: 8 位元 (固定)
  • 乾/濕基線: 80% 乾 / 20% 濕
  • 衰減模式: 大約每 1.2 秒,乾訊號降至約 35%,濕訊號升至約 65% (持續時間約 0.25 秒)
  • 僅作用於濕訊號的顫音: 4Hz 三角波,深度 70% (濕訊號在 30-100% 之間脈動)
  • 拍擊延遲: 80ms,-18dB (約 0.12 音量),套用於最終混音
python3 scripts/vibey-mix.py beats/beat-XX/audio.mp3
cp beats/beat-XX/audio-dynamic.mp3 beats/beat-XX/audio-filtered.mp3

鏈路分解: 乾淨的乾訊號與極端的數位偽影 (5 倍抽取、8 位元量化經零階保持升取樣) 分層混合,週期性的衰減會提高濕訊號電平以產生「傳輸中退化」效果,濕訊號上的顫音提供節奏性脈動,拍擊延遲增加空間感。保持鏈路結構完整 — 僅在必要時調整個別參數。

在所有後續階段使用 audio-filtered.mp3。保留原始 audio.mp3 以供參考。

將決策記錄在 project.md 的備註中。

第五階段:合成節拍

對於每個節拍,將視覺與音訊以硬切 (無轉場) 合併。節拍持續時間由視覺和音訊中較長者決定。

如果視覺 >= 音訊:

音訊在整個視覺期間播放。無需填充。

ffmpeg -i beats/beat-XX/visual.mp4 -i beats/beat-XX/audio-filtered.mp3 \
  -c:v libx264 -pix_fmt yuv420p -c:a aac \
  -shortest -r 25 output/beat-XX-composed.mp4

如果音訊 > 視覺:

視覺保持其最終畫面以填滿剩餘時間。對影片使用 tpad:

AUDIO_DUR=$(ffprobe -v error -show_entries format=duration -of csv=p=0 beats/beat-XX/audio-filtered.mp3)
ffmpeg -i beats/beat-XX/visual.mp4 -i beats/beat-XX/audio-filtered.mp3 \
  -vf "tpad=stop_mode=clone:stop_duration=$AUDIO_DUR" \
  -c:v libx264 -pix_fmt yuv420p -c:a aac \
  -t $AUDIO_DUR -r 25 output/beat-XX-composed.mp4

如果未套用音訊濾鏡,則使用 audio.mp3 代替 audio-filtered.mp3。

節拍之間暫停

相關技能