agentsclimarketplace

Music disc video

Skill unbias38/my-claude-skills/music-disc-video

把一首歌做成旋轉碟片配同步滾動歌詞的視覺:輸出可雙擊播放的單一 HTML (圖與音樂內嵌)和/或 MP4 影片。六套版面:16:9、9:16、1:1, 各有含歌詞與純音樂兩種。素材需要封面圖(正方形)+ mp3 + 歌詞 (.srt / .lrc / 純文字皆可,沒有時間軸會產生對時工具)。 當使用者想把歌曲做成可分享的視覺、歌詞影片或碟片動畫時使用。 觸發語:把這首歌做成有歌詞的影片、音樂碟片、旋轉唱片 歌詞、歌詞影片、 做一個音樂視覺化、把 mp3 做成影片、IG 限動音樂動畫、短影音 音樂 歌詞、 lyric video、music disc video、music visualizer。From its SKILL.md

Install
npx -y skills add unbias38/my-claude-skills --skill music-disc-video

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

SKILL.md

9.9 KB, ~4.2k tokens by cl100k_base, as published. Nobody here has run it

music-disc-video:一首歌 → 旋轉碟片 + 滾動歌詞

把「封面圖 + 音樂 + 歌詞」做成:

  • 單一 HTML 檔 —— 雙擊就能播,圖跟音樂都內嵌,複製到任何電腦都不會破
  • MP4 影片 —— 1920×1080 / 1080×1920 / 1080×1080,可直接上傳社群

第一次使用先做這個

python3 <SKILL_DIR>/scripts/env.py

會檢查 numpy、Pillow、中文字型、ffmpeg 有沒有齊。有 ✗ 的照著它給的指令裝。

Windows 上通常沒有 python3 這個指令,本文所有 python3 都改成 python。 跑起來說「找不到 python3」就是這個原因,不是環境壞了。


工作流(給 Claude 跟著做)

💡 <SKILL_DIR> 是本 SKILL.md 所在的資料夾。 ⚠️ 所有產出都寫進使用者的歌曲資料夾,不要寫進 skill 資料夾。

步驟 1:確認素材,建立歌曲資料夾

跟使用者要三樣東西,放進同一個資料夾:

素材說明
封面圖.png / .jpg正方形最好(會同時當背景、封面、碟片)
音樂.mp3
歌詞.srt / .lrc / 純文字都可以,沒有時間軸也沒關係(見步驟 2)

然後在該資料夾建立 project.json

{
  "title":    "歌名",
  "subtitle": "英文副標或留空",
  "art":      "cover.png",
  "audio":    "song.mp3",
  "lyrics":   "lyrics.txt",
  "layout":   "16x9",
  "out_prefix": "musicdisk"
}

layout 要問使用者想要哪一種(用 AskUserQuestion):

尺寸適合
16x91920×1080YouTube、電腦螢幕、上課投影
9x161080×1920IG Reels、抖音、YouTube Shorts
1x11080×1080IG 貼文
16x9-solo 9x16-solo 1x1-solo同上純音樂版(無歌詞,碟片放大置中)

純音樂版不需要 lyrics 欄位。

步驟 2:歌詞沒有時間軸的話,先對時

有兩條路。先建議方法 A,使用者做不到才走方法 B。

方法 A:請 Gemini 直接聽出時間軸(快,優先推薦)

叫使用者到 Google AI Studio 上傳這首歌的音檔或影片,送出這段 prompt:

請提取這部影片的完整字幕,格式要求如下:

1. 使用 SRT 字幕格式
2. 每一句話(以句號、問號、感嘆號為斷句點)獨立一條,不要把多句話合併
3. 時間軸精確到秒,格式為 HH:MM:SS,毫秒 --> HH:MM:SS,毫秒
4. 不要用時間區間概括一整段,要逐句對應

輸出範例:

1
00:00:01,000 --> 00:00:03,500
第一句話。

2
00:00:03,500 --> 00:00:05,200
第二句話。

把輸出存成 .srt 放進歌曲資料夾、更新 project.jsonlyrics 就好 —— 標準 SRT 是 lyrics.py 原生支援的格式,不用再轉檔。

第 2 點(逐句斷開)和第 4 點(不要用區間概括)是關鍵: 少了它們,模型很容易回一整段配一個大時間區間,那樣歌詞會整段整段跳、不會逐句走。

拿到之後一定要在步驟 4 的網頁版驗收。 唱歌的咬字和拖拍跟講話不一樣, 模型抓的時間點常常偏早或偏晚一點,尤其是前奏後的第一句和轉折句。 偏移不大的話直接在歌詞檔上手改幾句最快。

方法 B:手動敲拍對時(方法 A 不能用時的備案)

python3 <SKILL_DIR>/scripts/timetap.py <歌曲資料夾>

會產生「敲拍對時.html」。主動幫使用者打開它,並說明: 播放後每唱到一句新歌詞就敲一下空白鍵,敲錯按 Backspace, 標完按「匯出歌詞檔」。然後把下載到的檔案放回資料夾、更新 project.jsonlyrics

這條路要使用者從頭聽完整首歌,4 分鐘的歌大約花 5 分鐘,但時間點是他自己敲的、最準。

步驟 3:準備(自動調校 + 挑主色)

python3 <SKILL_DIR>/scripts/prepare.py <歌曲資料夾>

它會自動算好三件事並寫回 project.json

  • 字級 —— 保證最長那句放大後也不會被切掉
  • 背景遮罩濃度 —— 依封面亮度反推,讓白色歌詞有足夠對比
  • 主色 —— 抽 3 個候選色,畫成對照圖 _主色候選.png

一定要把 _主色候選.png 打開給使用者看,讓他挑一個(用 AskUserQuestion,把三個顏色和說明列出來)。 選好之後:

python3 <SKILL_DIR>/scripts/prepare.py <歌曲資料夾> --accent 2

步驟 4:先出網頁版給使用者確認

python3 <SKILL_DIR>/scripts/build_html.py <歌曲資料夾>

產出後主動打開給使用者看explorer.exe / open / xdg-open),並請他確認:

  1. 按播放有沒有聲音?碟片有沒有轉?暫停時碟片會停嗎?
  2. 拖進度條,歌詞和頻譜會不會一起跟著跳?
  3. 金色高亮跟唱的時間對不對得準?
  4. 轉速、字級、顏色、背景亮度喜不喜歡?

要改的話改 project.jsonoverrides(見下方「常見調整」),重跑 build_html.py。

預設會直接覆蓋舊檔。使用者已經點頭的版本要留著,就用 --out 另存, 免得後面越調越糟卻回不去:

python3 <SKILL_DIR>/scripts/build_html.py <歌曲資料夾> --out musicdisk_v2.html

render_video.py 也吃同一個參數。兩支都是「只給檔名就寫進歌曲資料夾」。

步驟 5:使用者滿意後才出影片

先出 30 秒試片,挑一段換句多的:

python3 <SKILL_DIR>/scripts/render_video.py <歌曲資料夾> --start 88 --end 118

試片確認後才跑全長。全長要用背景執行(4 分鐘的歌約 13 分鐘):

python3 <SKILL_DIR>/scripts/render_video.py <歌曲資料夾>

完成後自我檢查:時長對不對、有沒有聲軌、抽幾格看歌詞高亮正不正確, 然後打開給使用者看。


常見調整

project.jsonoverrides,重跑 build_html.py / render_video.py 即可。 網頁和影片讀同一份設定,改一次兩邊都會變。

"overrides": {
  "disc":       { "period": 16.0 },                    比 12 大 = 轉得慢
  "colors":     { "accent": "#7FD4FF" },               主色
  "lyrics":     { "size": 34, "zoom": 1.24 },          字級、當前句放大倍率
  "background": { "mask_base": 0.62, "mask_side": 0.5 } 背景壓暗程度(0~1)
  "video_progress": null                               影片不要底部那條進度線
}

想動版面座標(碟片位置、歌詞欄大小)就改 layouts/*.json16x9.json 是手寫的,其餘五套由 layouts/_generate.py 產生 —— 要改那五套請改 _generate.py 再重跑它,不要直接改產生出來的 JSON。


改完程式一定要跑回歸測試

第一次用要先建立自己的基準(repo 裡不附,見下方說明):

python3 <SKILL_DIR>/tests/regress.py --bless

之後每次改完程式跑這個比對:

python3 <SKILL_DIR>/tests/regress.py

用合成的測試素材把六套版面各畫 12 格,跟基準逐像素比對(比的是整張圖的 SHA)。 刻意改了外觀而且確認新的比較好,才用 --bless 重新定基準。

為什麼基準不附在 repo 裡? 因為比對方式是「整張圖的 SHA 完全相等」,只要 Pillow 版本、系統字型、 Chrome 版本任一不同,算出來的像素就會有微小差異,別台機器的基準一定全部對不上。 基準的用途是「抓自己這次改壞了什麼」,本來就該在自己的環境產生。


設計原則(改東西之前先讀這段)

1. 所有動畫都是「時間 t 的函數」 碟片角度、歌詞位置、哪句金色、柱子多高,全部只依賴 t,不依賴「上一格畫了什麼」。 這是拖進度條、暫停、跳轉不會亂掉的原因,也是影片能單獨渲染任何一格的原因。 不要引進任何會累加的狀態。

2. 版面數字只有一個來源 全部在 layouts/*.json。網頁的 CSS 和影片的 Python 都從那裡讀。 以前兩邊各寫一份,改一邊忘另一邊就會不一致 —— 不要走回頭路。

3. 碟片中心不能蓋白圓 要用遮罩挖出「真正透明」的孔(看得到底下的背景),外面一圈只留 14% 模擬透明塑膠。 蓋白圓中間會死白一片,那是最明顯的廉價感來源。

4. 背景保持清晰,不要模糊 讀不清楚就把遮罩壓深,不要用模糊解決 —— 模糊會讓整體質感掉一階。


踩過的坑(別再踩一次)

症狀原因
圖片全黑大圖不能放進 CSS 變數再引用,要直接寫在規則裡
長句右半邊被切掉忘了「放大倍率」也會增加寬度。autotune 已自動處理
影片顏色比網頁暗兩層都半透明時,合成後要除以總透明度,否則等於乘兩遍
碟片蓋在封面前面網頁靠 DOM 順序,Python 要自己排:背景→碟片→封面→歌詞→頻譜
渲染到最後卡住不動ffmpeg 的訊息不能導到管線(只有 64KB,塞爆會死結),要導到檔案
歌詞位置偶爾整批偏掉不要去量 DOM 高度(字型晚載入會量錯),用公式算 + 禁止折行
同一份檔案截圖每次不同will-change:transform 會讓次像素對齊飄動,拿掉

What ships with it: 27 files

604.5 KB alongside SKILL.md, 13 of them executable

assets/

layouts/

scripts/

Keep looking

Skills are one crate of 325,949. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.