/bw-song-ad — 黑白卡通歌曲廣告,直到完稿
2026-10-18,使用「おひさまパンツ H-OHI-023a」製作的流程。參考來源為 X 上的 WhiteHat MRR(骨密度・黑白卡通・約4分鐘)。 本人的反應是「歌太火了,簡直是神」。參考影片的真面目是並非短小的鈴聲,而是將長格式 VSL 的腳本近乎原封不動地唱出來。
順序(不可變更)
歌詞 → 歌曲(Suno) → 逐字時間對齊 → 場景分割 → 角色表 → 關鍵幀 → 影片化 → 背景匯出 → Remotion → 品檢。 歌曲就是時鐘。如果先製作畫面,會因為與歌曲節奏不符而全部重做。
S=~/.agents/skills/bw-song-ad
AD=<案件資料夾>/<廣告ID> # lyrics.md / captions.txt / song/ / shots.py / keys/ / clips/ / remotion/
cp -R $S/remotion $AD/remotion && cd $AD/remotion && NODE_USE_ENV_PROXY=1 npm install
0. 先檢查庫存
如果同品牌之前做過圖片或影片,優先使用它們(查看各品牌的素材庫存表 ASSETS.md,新增時請追記)。 需要生成時,請先告知「圖片◯張・影片◯部・約◯點數」。本次實績:圖片61張約15點,Grok 影片61部約265點。
1. 歌詞(lyrics.md)— reference/lyrics.md 的格式
- 將 VSL 的段落逐段唱出。不押韻。應與參考一一對應: 專業人士開場 → 經典開場「不一樣」×3 → 更重要的事 → 原因不在你想像的地方 → 體內的盟友與反派 → 過去曾經順利 → 現在反派佔上風 → 問題從這裡開始(忽略的連鎖)→ 賣場全是同樣的東西 → 但改變了(解決方案)→ 前往文章(無需註冊)→ 庫存 →「已經不用再〜」×3 →「沒關係。點擊下方」
- 全部使用平假名。數字也寫平假名(Suno 對漢字和數字容易出錯)。
- 不唱商品名(用畫面標籤顯示)。不提及金額。承諾僅限於商品頁面範圍。
- 先展示再作曲。
2. 歌曲(Suno・Playwright)
- 僅登入由本人操作。其餘則將歌詞、Style、Title 輸入到
suno.com/create?mode=CUSTOM然後 Create。 - Style(推薦):
1930s vintage upbeat jazz, old cartoon soundtrack, swing, clarinet, muted trumpet, ragtime piano, brushed snare, upright bass, warm female vocal, Japanese, clear diction, storytelling sung melody - 每次會產生2首曲子。用 whisper 全部聽寫並對照歌詞,選取沒有走音的那首。
- 下載方式:前往歌曲頁面的 More options → Download → MP3 →「Unlock & Download」(使用一次免費額度)。
cdn1.suno.ai會回傳403,用於播放的 m4a 已加密。不採用從瀏覽器 blob 提取以規避次數限制的方法。 - 存放於
song/song.mp3。
3. 字幕文字(captions.txt)
- 歌詞每段一行。行內用
/分隔(一個區塊=畫面顯示一次的內容。大約12個字以內)。 - 改寫為容易閱讀的漢字假名混合日語(歌詞為平假名,但字幕使用一般表記)。
- 若想顯示為兩行,使用
|(例如:下方的按鈕|閱讀文章)。
4. 逐字時間對齊
uv run --python 3.12 --with openai-whisper python $S/scripts/align.py $AD
→ 產生 $AD/cap_events.json(每個區塊的 開始秒數・結束秒數)與 $AD/line_starts.json(每行的開始歌詞時間)。
- 不使用 whisper-cli 的行級時間。因為它會將前奏(沒有歌詞的前幾秒)視為從0秒開始唱歌,且行內也平均分配,導致字幕在「沒唱歌時仍向前推進」。
- 在歌曲停頓的地方(超過0.8秒)隱藏字幕。
- 若匹配率低於80%,表示歌曲走音或 captions.txt 與歌詞不符。
5. 場景分割(shots.py)
- 定義
STYLE(所有鏡頭通用的畫面風格描述)和SHOTS = [(行號, 該行的第幾個鏡頭, 場景, 動作), ...]。 - 每個鏡頭2〜5秒。長行分割成2〜3個鏡頭。約3分半鐘約60個鏡頭。
- 長片不全部做成影片:若一半鏡頭使用靜態圖緩慢拉近,則影片生成量可減半。
- 角色:老師(鮑伯頭・圍裙)/媽媽(低丸子頭・條紋)/小孩(娃娃頭)/體內傳令兵2人(條紋連身褲・帽子)/反派(黑色圓形・角・海綿與吸管)/商品(實物花紋)。
6. 角色表與關鍵幀(Higgsfield gpt_image_2_5・9:16・每張0.25)
- 先製作一張角色表,之後的所有鏡頭都將角色表+參考漫畫一格作為
image_references傳入。 - 開頭加上
STYLE:black and white 1930s rubber-hose cartoon, thick clean ink lines, cross-hatching, grayscale only, vintage Fleischer-era look, slightly grainy film, soft dark round vignette, no text python3 $S/scripts/make_reqs.py $AD image→ 每次12筆,呼叫generate_image_batch。- 讓小孩穿上衣服(內衣或尿布造型會因 NSFW 而被拒絕)。如果參考圖片中有內衣,也同樣會被拒絕。
- 商品需在提示詞中描述其實物花紋(若出現不存在的花紋則需重做)。
- 全部以連接觸控表檢視:確認畫風・無文字・符合角色表。
7. 影片化(Grok Imagine grok_video_v15_lite・720p・僅使用 start_image・1秒≒1點數)
python3 $S/scripts/make_reqs.py $AD video→ 每次12筆,呼叫generate_video_batch。長度為負責區段+0.5秒(3〜8秒)。- 提示詞:「讓這張圖動起來:<動作>。保持相同畫風・構圖・角色,彈跳的橡膠軟管動作、底片閃爍、攝影機固定、無剪輯、無新增文字」。
- 若被拒絕且回傳 preset,則將
declined_preset_id放入 params 重新提交。 - 將所有結尾幀並排檢視。 當商品轉向側面或旋轉時花紋會變形 → 只使用變形前的秒數(
SRC_MAX),或讓正面部分來回播放。
8. 匯出背景(無文字)
python3 $S/scripts/bg.py $AD # → 產生 $AD/bg.mp4(1080x1920・30fps)與 shot_starts.json
- 鏡頭切換時機對齊每行開始歌唱的時間(line_starts.json)。第一個鏡頭從0秒開始。
- 若前奏無歌詞,可考慮快速切換強烈場景(反派・大洪水・用印章壓扁等)來填補。
9. Remotion($AD/remotion)
- 放置
public/bg.mp4(背景)・public/song.mp3・src/data.json:python3 $S/scripts/make_data.py $AD --hook-end 29.3 --cta 192.9 --brand 44,46,47,50 --hook-top "進行如廁訓練的媽媽們" --hook-main "尿布脫不掉" --hook-mark "真正的原因" --brand-name "<商品名>" --keys "<要變成黃色的關鍵詞,逗號分隔>" - 疊加內容(
src/SongAd.tsx):- 上方鉤子:使用紙卡(黑色粗框・偏移陰影・略微傾斜),在最初1秒內讓觀眾了解「目標對象+話題內容」。例如「進行如廁訓練的媽媽們/尿布脫不掉真正的原因」。
- 字幕:黑色圓角白色粗體字,彈跳出現。只有關鍵詞使用黃色(黑白中唯一的色彩)。
- 商品名標籤:僅在商品出現的鏡頭中,於上方以小字顯示。
- CTA:從最後的「點擊下方」到結束,黃色箭頭三層向下流動彈跳+「點擊下方按鈕|閱讀文章」。
- 渲染(此 Mac 上無頭 Chrome 會單獨崩潰 → 使用
chrome-wrap.sh,在沙箱外執行):
cd $AD/remotion && NODE_USE_ENV_PROXY=1 npx remotion render src/index.ts SongAd out/<廣告ID>.mp4 --browser-executable=./chrome-wrap.sh --concurrency=6 --crf=20
- 交付時使用
-crf 23 -movflags +faststart重新編碼(黑白噪點會使檔案變大。3分半鐘約200MB)。
10. 品檢(務必在開啟前執行)
- 讀取約每秒24格的接觸表:確認字幕與歌曲無偏移/沒有歌詞的地方未出現字幕/商品花紋未變形/CTA 箭頭在畫面內/無多餘文字。
- 特別檢視最初3秒(鉤子是否能一眼看出)。
- 建立 HTML 預覽頁面並開啟。廣告名稱直接使用 AdLab 發佈的名稱(H-XXX-000a)作為檔案名稱。
遇到的問題(本次實測)
- 字幕從開頭就偏移:歌詞從4.9秒開始,但 whisper-cli 卻從0秒開始計算 → 透過
align.py(使用 openai-whisper 的 word_timestamps 與 difflib 進行文字對齊)解決。 - 關鍵幀的 NSFW:小孩穿著內衣、參考圖片中的內衣 → 讓角色穿上衣服/在畫風提示詞中說明參考圖。
- 商品旋轉變形:Grok 經常讓商品轉向側面。只使用正面的秒數。
- 製作過量:本次一部影片使用了61張圖片+61段影片。下次應利用庫存與靜態拉近鏡頭減半數量。
- 長段結尾文字有一個字掉到下一行 → 使用
|指定行數。
相關:reference/lyrics.md(歌詞格式與實例)、/zackd-ad(3D 動畫類型)、AdLab(製作前先註冊假說)。