first-commit
ci / Validate workspace (push) Has been cancelled
landing-page-ci / Validate landing page (push) Has been cancelled
landing-page-deploy / Deploy landing page (push) Has been cancelled
github-metrics / Generate repository metrics SVG (push) Has been cancelled
refresh-contributors-wall / Refresh contributors wall cache bust (push) Waiting to run
ci / Validate workspace (push) Has been cancelled
landing-page-ci / Validate landing page (push) Has been cancelled
landing-page-deploy / Deploy landing page (push) Has been cancelled
github-metrics / Generate repository metrics SVG (push) Has been cancelled
refresh-contributors-wall / Refresh contributors wall cache bust (push) Waiting to run
This commit is contained in:
@@ -0,0 +1,132 @@
|
||||
---
|
||||
name: audio-jingle
|
||||
description: |
|
||||
Audio generation skill — jingles, beds, voiceover, and sound effects.
|
||||
Routes music requests to Suno V5 / Udio / Lyria, speech to MiniMax
|
||||
TTS / FishAudio / ElevenLabs V3, and SFX to ElevenLabs SFX or
|
||||
AudioCraft. Output is one MP3/WAV file saved to the project folder.
|
||||
triggers:
|
||||
- "music"
|
||||
- "jingle"
|
||||
- "bed"
|
||||
- "voiceover"
|
||||
- "tts"
|
||||
- "sound effect"
|
||||
- "音乐"
|
||||
- "配音"
|
||||
- "音效"
|
||||
od:
|
||||
mode: audio
|
||||
surface: audio
|
||||
scenario: marketing
|
||||
preview:
|
||||
type: html
|
||||
entry: example.html
|
||||
design_system:
|
||||
requires: false
|
||||
example_prompt: |
|
||||
A 30-second upbeat indie-pop jingle for a coffee shop launch — warm
|
||||
electric piano lead, brushed drums, gentle bass, a single sun-soaked
|
||||
"ahhh" choir on the chorus. No vocals. Loop-friendly tail.
|
||||
---
|
||||
|
||||
# Audio Jingle Skill
|
||||
|
||||
Three sub-modes. The active project's `audioKind` decides which one
|
||||
runs:
|
||||
|
||||
| `audioKind` | Models we route to | Plan focus |
|
||||
|---|---|---|
|
||||
| `music` | Suno V5 (default), Udio, Lyria 2 | genre + tempo + instrumentation |
|
||||
| `speech` | MiniMax TTS (default), Fish, ElevenLabs V3 | script + voice + pacing |
|
||||
| `sfx` | ElevenLabs SFX (default), AudioCraft | texture + impact + duration |
|
||||
|
||||
## Resource map
|
||||
|
||||
```
|
||||
audio-jingle/
|
||||
├── SKILL.md
|
||||
└── example.html
|
||||
```
|
||||
|
||||
## Workflow
|
||||
|
||||
### Step 0 — Read the project metadata
|
||||
|
||||
`audioKind`, `audioModel`, `audioDuration` (seconds), and (for speech)
|
||||
`voice`. Branch by `audioKind` and use the values verbatim — no
|
||||
clarifying form unless something is marked `(unknown — ask)`.
|
||||
|
||||
Important: `voice` is provider-specific. For `minimax-tts`, `--voice`
|
||||
must be a valid MiniMax `voice_id` (for example `male-qn-qingse`), not
|
||||
a natural-language description. If you only have a prose voice brief
|
||||
("warm female narrator", "neutral Mandarin"), keep that in your plan
|
||||
but omit `--voice` so the daemon's default voice id applies, or ask the
|
||||
user to choose a specific id.
|
||||
|
||||
### Step 1 — Plan
|
||||
|
||||
**Music**
|
||||
- Genre + reference artists (1-2)
|
||||
- Tempo (BPM) + key
|
||||
- Instrumentation (3-5 instruments max)
|
||||
- Vocals: yes / no / hummed / choir
|
||||
- Mood arc (intro → chorus → outro)
|
||||
|
||||
**Speech**
|
||||
- Script (final, not draft — TTS runs verbatim)
|
||||
- Voice target + pacing
|
||||
For MiniMax this means a real `voice_id`, not prose in `--voice`
|
||||
- Pronunciation hints for proper nouns / acronyms
|
||||
|
||||
**SFX**
|
||||
- Texture (impact / whoosh / ambience / foley)
|
||||
- Duration + envelope (sharp attack vs. gentle swell)
|
||||
- Layering note (single hit vs. stacked)
|
||||
|
||||
State the plan in 2-3 sentences before dispatching.
|
||||
|
||||
### Step 2 — Compose the prompt
|
||||
|
||||
Use the format the upstream model prefers. Bind `audioDuration` to the
|
||||
API parameter directly; never put "make it 30 seconds" in prose.
|
||||
|
||||
### Step 3 — Dispatch via the media contract
|
||||
|
||||
Use the unified dispatcher — do **not** call provider APIs by hand:
|
||||
|
||||
```bash
|
||||
node "$OD_BIN" media generate \
|
||||
--project "$OD_PROJECT_ID" \
|
||||
--surface audio \
|
||||
--audio-kind "<music|speech|sfx>" \
|
||||
--model "<audioModel from metadata>" \
|
||||
--duration <audioDuration seconds> \
|
||||
[--voice "<provider voice id (speech only)>"] \
|
||||
--output "<short-slug>-<duration>s.mp3" \
|
||||
--prompt "<assembled prompt from Step 2 — for speech, the literal script>"
|
||||
```
|
||||
|
||||
The command prints one line of JSON: `{"file": {"name": "...", ...}}`.
|
||||
The bytes land in the project; the FileViewer renders the audio
|
||||
transport controls automatically.
|
||||
|
||||
### Step 4 — Hand off
|
||||
|
||||
Reply with: plan summary, the filename returned by the dispatcher, and
|
||||
one sentence on what to try if the user wants a variation (e.g. "swap
|
||||
tempo from 92 to 108 BPM" rather than "make it different").
|
||||
|
||||
## Hard rules
|
||||
|
||||
- TTS runs your script **literally**. Proof it before dispatching —
|
||||
even one stray comma changes the cadence.
|
||||
- MiniMax TTS rejects free-form voice prose in `--voice`. Use a real
|
||||
MiniMax `voice_id` (for example `male-qn-qingse`) or omit the flag
|
||||
and let the daemon's default voice apply.
|
||||
- Music: under 30s = single section; 30–90s = intro + body; 90s+ =
|
||||
full arc. Don't try to fit a 3-act song into 15 seconds.
|
||||
- SFX: prefer one well-described layer over a paragraph of "make it
|
||||
cool" — generators reward specific texture words.
|
||||
- Save the file every turn. The audio viewer shows transport controls
|
||||
the moment the file lands.
|
||||
@@ -0,0 +1,128 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>Audio jingle — example</title>
|
||||
<style>
|
||||
:root {
|
||||
--bg: #f5efe5;
|
||||
--panel: #ffffff;
|
||||
--ink: #1c1b1a;
|
||||
--muted: #8b8579;
|
||||
--accent: #c96442;
|
||||
--grid: #e6dfd1;
|
||||
}
|
||||
* { box-sizing: border-box; }
|
||||
html, body { margin: 0; padding: 0; background: var(--bg); color: var(--ink);
|
||||
font-family: 'Iowan Old Style', 'Charter', Georgia, serif; }
|
||||
body { min-height: 100dvh; display: grid; place-items: center; padding: 32px; }
|
||||
.card {
|
||||
width: min(640px, 92vw);
|
||||
background: var(--panel);
|
||||
border-radius: 8px;
|
||||
padding: 26px 28px 22px;
|
||||
box-shadow: 0 16px 40px rgba(28,27,26,0.10), 0 1px 2px rgba(28,27,26,0.05);
|
||||
border: 1px solid rgba(28,27,26,0.06);
|
||||
}
|
||||
.row1 { display: flex; align-items: center; gap: 14px; margin-bottom: 18px; }
|
||||
.icon {
|
||||
width: 44px; height: 44px; border-radius: 50%;
|
||||
background: var(--accent); color: #fff;
|
||||
display: grid; place-items: center;
|
||||
box-shadow: 0 6px 18px rgba(201, 100, 66, 0.35);
|
||||
}
|
||||
.icon svg { width: 22px; height: 22px; }
|
||||
.title { margin: 0; font-size: 20px; line-height: 1.2; }
|
||||
.sub { font-family: ui-monospace, 'SF Mono', Menlo, monospace;
|
||||
font-size: 11px; color: var(--muted); letter-spacing: 0.14em; text-transform: uppercase; margin-top: 2px; }
|
||||
|
||||
.wave {
|
||||
display: flex; align-items: end; gap: 3px;
|
||||
height: 96px; padding: 0 4px;
|
||||
border-top: 1px dashed var(--grid);
|
||||
border-bottom: 1px dashed var(--grid);
|
||||
}
|
||||
.wave span {
|
||||
flex: 1; background: linear-gradient(180deg, var(--accent), #a4502f);
|
||||
border-radius: 2px;
|
||||
animation: bob 2s ease-in-out infinite;
|
||||
animation-delay: var(--d, 0s);
|
||||
}
|
||||
@keyframes bob {
|
||||
0%, 100% { height: var(--h, 30%); }
|
||||
50% { height: calc(var(--h, 30%) * 1.6); }
|
||||
}
|
||||
|
||||
.transport {
|
||||
margin-top: 14px;
|
||||
display: grid; grid-template-columns: auto 1fr auto auto; gap: 12px;
|
||||
align-items: center;
|
||||
}
|
||||
.play {
|
||||
width: 36px; height: 36px; border-radius: 50%;
|
||||
background: var(--ink); color: #fff;
|
||||
display: grid; place-items: center;
|
||||
}
|
||||
.timeline {
|
||||
height: 4px; border-radius: 2px;
|
||||
background: linear-gradient(90deg, var(--accent) 0 32%, var(--grid) 32% 100%);
|
||||
}
|
||||
.time {
|
||||
font-family: ui-monospace, 'SF Mono', Menlo, monospace;
|
||||
font-size: 11px; color: var(--muted);
|
||||
letter-spacing: 0.08em;
|
||||
}
|
||||
.badge {
|
||||
font-family: ui-monospace, 'SF Mono', Menlo, monospace;
|
||||
font-size: 10px; color: var(--accent);
|
||||
letter-spacing: 0.18em; text-transform: uppercase;
|
||||
padding: 4px 8px; border-radius: 999px;
|
||||
background: rgba(201, 100, 66, 0.1);
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="card">
|
||||
<div class="row1">
|
||||
<div class="icon" aria-hidden>
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M9 18V5l12-2v13"/><circle cx="6" cy="18" r="3"/><circle cx="18" cy="16" r="3"/></svg>
|
||||
</div>
|
||||
<div>
|
||||
<h1 class="title">A 30s coffee-shop launch jingle.</h1>
|
||||
<div class="sub">suno-v5 · 92 BPM · loop-friendly tail</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="wave" aria-hidden>
|
||||
<span style="--h:24%;--d:0s"></span>
|
||||
<span style="--h:38%;--d:.05s"></span>
|
||||
<span style="--h:52%;--d:.1s"></span>
|
||||
<span style="--h:64%;--d:.15s"></span>
|
||||
<span style="--h:48%;--d:.2s"></span>
|
||||
<span style="--h:70%;--d:.25s"></span>
|
||||
<span style="--h:42%;--d:.3s"></span>
|
||||
<span style="--h:58%;--d:.35s"></span>
|
||||
<span style="--h:36%;--d:.4s"></span>
|
||||
<span style="--h:62%;--d:.45s"></span>
|
||||
<span style="--h:26%;--d:.5s"></span>
|
||||
<span style="--h:50%;--d:.55s"></span>
|
||||
<span style="--h:34%;--d:.6s"></span>
|
||||
<span style="--h:46%;--d:.65s"></span>
|
||||
<span style="--h:58%;--d:.7s"></span>
|
||||
<span style="--h:30%;--d:.75s"></span>
|
||||
<span style="--h:44%;--d:.8s"></span>
|
||||
<span style="--h:54%;--d:.85s"></span>
|
||||
<span style="--h:28%;--d:.9s"></span>
|
||||
<span style="--h:48%;--d:.95s"></span>
|
||||
</div>
|
||||
<div class="transport">
|
||||
<div class="play" aria-hidden>
|
||||
<svg viewBox="0 0 24 24" width="14" height="14" fill="currentColor"><path d="M6 4v16l14-8z"/></svg>
|
||||
</div>
|
||||
<div class="timeline" aria-hidden></div>
|
||||
<span class="time">00:09 / 00:30</span>
|
||||
<span class="badge">MP3</span>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user