本文へ移動
cccskills
無料GitHub で公開

music-mix

Lays a music bed under a finished video — the music is trimmed and faded to the video's exact length and ducks beneath the voice, while the video stream is copied untouched. Use when the user asks to add music, add a background track, add a music bed or soundtrack, or asks for something like "make a lofi mix of this": "put music under this ad", "add a background track", "give me a couple of music versions". Entered from a finished cut — captions already burned is the preferred input, not a problem. It never edits the picture and never changes the video's length.

インストール方法を見る

含まれるファイル(5)

  • SKILL.md8.5 KB
  • evals.md18.2 KB
  • routing-eval.jsonl1.7 KB
  • scripts/music_mix.py33.2 KB
  • scripts/test_music_mix.py36.3 KB

SKILL.md(原文)

インストールする前に、エージェントに与えられる指示の中身を確認できます。

Music mix

Puts a music bed under a finished video. The bed is trimmed to the video's exact duration, faded out at the tail, and ducked under the voice. This is the last step of the pack: base video → b-roll overlay → burned captions → music.

Mixing mechanics live entirely in scripts/music_mix.py. This file is judgment only — when to enter, what track to pick, where the music comes from, what the user sees.

Entry condition

A finished video the user has signed off on. Captions already burned in is the preferred input, because music is genuinely the last thing that happens. That is safe because the script copies the video stream packet for packet (-c:v copy) and verifies afterwards that the output's video packets hash identical to the input's — so burned captions come through bit-exact, not "re-encoded but probably fine".

If the cut is still moving, wait. Remixing is cheap; re-rendering the pipeline is not.

Track judgment

  • Match the genre to the ad's mood, not to your taste. Calm skincare and a punchy supplement ad do not want the same bed. Read the script's tone first.
  • Lofi is the default — it is what the reference edit used, and it sits under a talking head without competing with it. Depart from it deliberately, and say why.
  • Always produce 2–3 named variants. The reference edit shipped a final-mixes folder with lofi-jazzy and lofi-warm of the same cut. Vary the track or --music-gain, name them for what they are, and let the user pick — each extra mix is one ffmpeg pass and no credits.
  • Instrumental only. Lyrics compete with the voiceover for the same attention.

Sourcing the music

REST key required. A Novoads MCP connector is not a substitute. If NOVOADS_API_KEY is missing or still the placeholder, stop before any generation work and tell the user: "Before continuing, create an API key at https://novoads.ai/dashboard/settings?tab=api and paste it into .env." That holds even when mcp__novoads__* tools are connected and authenticated in the session. Never call mcp__novoads__* tools from this repo's workflows: they are a different surface with different behavior, including the units they quote costs in. Repo installs verify with ./scripts/check-novoads-env.sh; a solo install checks NOVOADS_API_KEY in the environment.

Pack version. Every /v1 response carries X-Novoads-Pack-Version; mention a newer pack at https://github.com/novoads/agent-skills only when that header names a version NEWER than this file's metadata.packVersion — equal or older is nothing to say, and it is never a reason to stop.

(a) Generated through the Novoads API — the default. POST /v1/music on the $NOVOADS_API_KEY this pack already uses: no second account, no second bill. Price it with POST /v1/estimates {"kind":"music"} and get approval first, like every generation here — that arm takes the kind and nothing else. Then poll GET /v1/generations/{jobId} to terminal, about 75 seconds. Fields, limits and failure modes: novoads-api skill, reference.md § POST /music.

One request returns two tracks, as audio[] on the succeeded job, both yours for the one charge — so the 2–3 variants above cost one generation, not three. Download both audio[].url; they are presigned at read time, so re-poll rather than reuse a stale one. Tracks run one to two minutes whatever you hint — the script trims them.

(b) When (a) is not available, diagnose before you improvise. There is no second generation vendor in this pack. Two different things can block (a), and they have different answers:

  • $NOVOADS_API_KEY is absent. Stop. Do not look for another credential. Tell the user to create a key at novoads.ai/dashboard/settings?tab=api and put it in .env (see scripts/setup.sh), then resume.
  • Music is off on that deployment. invalid_input is also what a typo'd body returns, so confirm which before concluding anything. The reliable test is the free, keyless GET /v1/openapi.json: no /music path means the deployment has music off; a /music path means your request was malformed. If music really is off, say so plainly and fall back to (c). If the path is there, fix your body and retry (a).

Never send a user to a second signup, and never over a malformed field.

(c) A file the user supplies. Always allowed, no questions. Licensing is theirs.

Music from (a) is AI-generated and its clearance is the user's call, not this skill's to guarantee: Novoads' terms §11 "AI-Generated Music" make no representation that it is free of third-party rights and put use (their jurisdiction, their platforms) on the customer. Say that once for client-facing or paid media, and improvise no legal advice past it.

Hard rule: mixing always goes through the script

Never hand-write mixing ffmpeg for this task. music_mix.py owns validation, rendering and verification, and it fails loudly on what fails silently by hand: a track shorter than the video, a re-encoded picture, a duration that drifts, loudness that will get turned down by the platform, an output path that would overwrite one of its own inputs, and — the sneakiest one — a bed so quiet it is not in the mix at all.

That last one is caught before the render, and it is worth knowing why: the audio is re-encoded on every path, so a finished file with no music in it looks exactly like one with music. The script measures the music's own loudness up front and refuses a silent track or a gain that would put the bed below audibility. A verifier cannot do that job.

Escape hatch: if a request genuinely doesn't fit this model — music that must hit a specific cut point, a track that needs an intro trimmed off the front, stems, a mid-video music change — say so and ask the user how to proceed. Do not improvise around the script.

Running it

python3 scripts/music_mix.py video.mp4 music.mp3 out-lofi-warm.mp4
  • --music-gain DB — bed level, default −18 dB, range ±60. The main knob between variants, and the first one to reach for when loudness verification fails.
  • --no-duck — flat bed, no ducking. For a video with no voiceover.
  • --dry-run — validate and print the plan, render nothing.
  • --verify-only OUT --video INPUT — re-check any existing output, including one from an old session. Standalone: mixing it with render arguments is an error.

Report the script's verification line verbatim — the measured loudness and true peak, not a paraphrase. Do not upgrade it: it establishes duration, an un-re-encoded picture, rebuilt audio and the loudness envelope, and says nothing about how the bed sounds. Exit codes: 2 validation, 3 render, 4 verification. A nonzero exit is a real failure — surface it, don't retry blindly.

The refusals worth recognising, so you fix the input instead of retrying:

MessageWhat to do
music is Xs, video is Ys — the track is too shortGet a longer track. Never loop or pad.
music track is silent / music inaudible at these gainsWrong file, or --music-gain is too low.
input voice is silent/near-silentThis is not a music-bed job; the video needs a soundtrack.
has N audio streamsPick one voice track with ffmpeg first — the script will not guess.
output ... is the same file as the videoThe output path aliases an input (hardlink, symlink, or a case-variant name on macOS). Choose a new name.
master gain clampedThe input is more than 30 dB off target; fix its level upstream.

Evals

evals.md defines the six scenarios this skill is held to (MM1–MM6). scripts/test_music_mix.py implements the five mixing ones mechanically against synthetic fixtures, in 15 cases — run it after touching the script. MM6 (sourcing on the Novoads key alone) is a text-and-flow eval; the script has no part in it.

レビュー

まだレビューはありません。使ってみた感想をお寄せください。

同じリポジトリのスキル

概要と使いどころ

Analyze a reference video and reverse-engineer its style into a reusable Seedance 2.0 prompting template for the Novoads API. The output is a new formula file — like seedance-2-ugc.md — that captures the video's structure, pacing, camera work, edit style and tone so it can be recreated with any product, any person, in any setting. Use this whenever someone provides a video they want to use as a style reference, says "I want to make videos like this", "deconstruct this video", "turn this into a template", "analyze this style", or drops a video file and wants to recreate that format repeatedly.

日本語の概要は準備中です。原文の説明を表示しています。

novoads/agent-skills232026年10月8日 更新

Overlays silent b-roll cutaway clips onto a finished base video — the base audio keeps running underneath while the picture cuts away and returns, and the final duration always equals the base duration. Use when the user asks to add b-roll, add cutaways, or overlay clips on a video: "add b-roll to this", "cut away to a product shot here", "overlay these clips on my UGC ad". Entered from an approved base video plus its transcript, which comes from POST /v1/transcripts and needs no local install; it never generates the base itself and it never extends a video.

日本語の概要は準備中です。原文の説明を表示しています。

novoads/agent-skills232026年10月8日 更新

Burn timed, styled captions into a finished video on the local machine, without re-rendering the source. This is the manual fallback to the API's captioning endpoint, POST /v1/captions, which stays the default path: come here when the style the user wants is outside the API's presets, when the wording has to be hand-corrected before it is burned into the pixels, or when the source was rendered with audio disabled and the API refuses it. Transcribes the audio with Whisper, groups words into reading phrases, renders the captions in a real browser via HyperFrames, and composites them over the source with ffmpeg using a real alpha channel. Use when the user has an MP4 with speech and asks to add captions, subtitles, burned-in text, TikTok-style captions or word-by-word text to it, and the API path has been ruled out. Runs out of band, so it costs no credits and works on any video file whoever generated it. Not for generating video (use the video skills) and not for a separate .srt/.vtt sidecar file.

日本語の概要は準備中です。原文の説明を表示しています。

novoads/agent-skills232026年10月8日 更新

Replaces the voice in a video or audio file with one from the Novoads voice catalog, over the REST API. Converts the SPEECH in the source to a voice you pick, keeps the original timing so lip-sync survives, and returns audio that gets muxed back over the untouched picture locally. Casts by MEASURING the source voice against auditioned candidates instead of reading labels, refuses a source with no speech before anything is charged, fences sound effects and music so they survive from the original track, and verifies the finished file by transcribing it. Use when an actor's voice sounds robotic, flat, thin or simply wrong, and for "change the voice", "voice swap", "swap the voice on this ad", "re-voice my ad", "the actor's voice sounds bad", "make him sound human", "different voice for this video", "speech to speech", "same video better voice". Not for narrating a silent clip (that is a voice-over), not translation, and it changes neither pronunciation nor accent.

日本語の概要は準備中です。原文の説明を表示しています。

novoads/agent-skills232026年10月8日 更新

Generate one or more standalone Meta image-ad creatives via ChatGPT Image 2 (gpt-image-2) through the Novoads API. Locks the model, auto-strips platform chrome, enforces edge-safe layouts and glyph-safety inside body text. Use when the user asks for a "gpt-image-2 ad", "ChatGPT Image ad", "Image 2 ad creative", "make a static image ad with GPT", or anchors on a need for typography-heavy / dense-text / UI-mimicry ad creatives (chat threads, comparison tables, fake search results, iOS dialogs, Slack snapshots, ChatGPT-conversation ads, Apple Notes lists). Does NOT trigger on Nano Banana cues — use nano-banana-image-ad for those.

日本語の概要は準備中です。原文の説明を表示しています。

novoads/agent-skills232026年10月8日 更新

Builds a hand-sculpted stop-motion CLAY ad on the Novoads REST API as a STORYBOARD: five to eight beats, each rendered from its own key frame, a storyteller narration laid into the gaps, a music bed, captions burned on, assembled locally with ffmpeg. Carries the genre's arc (named protagonist, inciting moment, social beat, quiet despair, sculpted clay infographic, discovery, transformation, resolution card), and also recreates a found clay ad by reading the reference video locally with ffmpeg and Whisper. Use for ANY clay or stop-motion ask at ANY length: "claymation ad", "stop-motion ad", "clay ad", "a quick clay ad", "plasticine characters", "make an ad like this clay one", or a reference video with sculpted clay characters in it. There is no one-call tier here, so ffmpeg is required. Not for the smooth 3D animated look (use pixar-ad, which covers every Pixar-style length), talking-head UGC (novoads-api), or a static image ad.

日本語の概要は準備中です。原文の説明を表示しています。

novoads/agent-skills232026年10月8日 更新

novoads のスキルをすべて見る

このスキルの問題を報告する