bgm-music
Crea música de fondo que esté en la tonalidad correcta, al tempo adecuado, con el volumen apropiado, sin ser estridente, y con la duración exacta; luego demuéstralo con mediciones antes de entregarla.
Los scripts residen en scripts/ junto a este archivo (resuélvelos usando el directorio del skill, normalmente ~/.claude/skills/bgm-music/scripts). Solo necesita Python 3 + numpy + ffmpeg.
Límites honestos - léelos primero
- No puedes escuchar audio. "Bueno" aquí significa medido como bueno: tonalidad, tempo, volumen, balance espectral, aspereza, dinámica, uniones. La escucha humana sigue siendo el juez final.
- El compositor procedural genera música de producción limpia, de buen gusto y genérica: pads, plectros, baterías simples, una melodía pegadiza de 4 compases. No sonará como una pista de Suno. Es ideal para BGM bajo voz/UI, que es la mayor parte del trabajo en video.
- Para música más rica y "producida", usa el nivel neural (ACE-Step 1.5, opcional, instalación de ~17 GB, 6-8 GB de VRAM). Consulta
references/neural-tier.mdpara la configuración. Pregunta siempre antes de descargar.
Ruta rápida: musicalizar un video (úsala primero)
S=~/.claude/skills/bgm-music/scripts
python $S/score_video.py --video out/video.mp4 [--voice vo.wav] --brief "<qué es>" --out out/final.mp4
python $S/score_video.py --frames 900 --fps 30 --brief "<qué es>" --audio-out public/bgm.mp3 # Remotion
El estado de ánimo (mood) se deduce de la descripción, la duración es exacta, las secciones se ajustan a los cortes de escena detectados (--cuts 6,14 para definirlos), se elige la mejor de 4 semillas según la evaluación, se atenúa bajo la narración, y se genera un informe JSON (código de salida 2 si nada alcanza 85). El skill de video y el skill gsap-remotion lo llaman automáticamente. El flujo manual que sigue es para control personalizado.
Flujo de trabajo
- Descripción. Obtén: estado de ánimo/género, duración total (que coincida con la longitud del video), loop o una sola vez, si hay locución superpuesta, puntos de sincronización exactos (opcional). Por defecto, elige el mood que encaje con el contenido (demo de producto ->
corporate/uplifting, tutorial ->calm/lofi, trailer ->cinematic, bug/terror/alerta ->tense, infantil/juego ->playful). - Componer.
El tempo se ajusta para que los compases llenen la duración exactamente (seguro para duración de video). Misma semilla = misma pista; cambiapython scripts/bgm.py --mood corporate --duration 45 --out bgm.wav # una sola vez con cola python scripts/bgm.py --mood lofi --duration 32 --loop --out loop.wav # loop sin fisuras python scripts/bgm.py --mood uplifting --duration 30 --key D --seed 4 --lufs -20 --out bgm.mp3--seedpara una melodía diferente,--key/--scale/--bpmal gusto. - Evaluar - obligatorio. Pasa los mismos datos con los que compusiste:
Luego lee el PNG: busca paredes verticales/horizontales sólidas y brillantes por encima de ~8 kHz (siseo), huecos o secciones planas. Las métricas pasan por alto cosas que la imagen muestra.python scripts/evaluate.py bgm.wav --mood corporate --key G --scale major --bpm 104 \ --spectrogram bgm.png [--loop] - Iterar. Si la puntuación < 85 o alguna línea es DÉBIL/MALO, aplica la corrección indicada junto a ella (ver tabla), re-renderiza, re-evalúa. Detente al alcanzar >= 85 sin ningún MALO, o después de ~4 rondas y explica qué queda pendiente. Nunca afirmes calidad que no hayas medido.
- Entregar / mezclar.
La música se atenúa ~12 dB bajo el habla, con fundidos de entrada/salida, normalizada a -16 LUFS.python scripts/mix_under_voice.py --voice vo.wav --music bgm.wav --out mixed.wav python scripts/mix_under_voice.py --video clip.mp4 --voice vo.wav --music bgm.wav --out final.mp4 python scripts/mix_under_voice.py --video clip.mp4 --music bgm.wav --out scored.mp4
Para Remotion: renderiza bgm.mp3 en public/, usa <Audio src={staticFile('bgm.mp3')} volume={0.35} loop />; el archivo generado ya está gestionado en volumen.
Nivel neural (ACE-Step) uso rápido
cd ~/ace-step-1.5 && .venv/Scripts/python ~/.claude/skills/bgm-music/scripts/ace_generate.py --prompt "uplifting corporate pop, plucked synth arpeggio, warm pad, soft kick" --duration 30 --bpm 113 --key "C major" --n 3 --out bgm_ace.wav
Renderiza N semillas, post-procesa (recorta silencio final, suaviza agudos, funde, -18 LUFS), evalúa cada una y se queda con la mejor. Aproximadamente 1-2 min por semilla después de la primera carga del modelo. Medido en una RTX 3050 8 GB: la salida es 2-5 s más corta de lo solicitado y la calidad varía mucho según la semilla (74-96 con el mismo prompt), por lo que siempre hay que quedarse con la mejor de N y dejar que mix_under_voice.py haga loop/recorte. Prefiere el procedural cuando importen la duración exacta, las uniones de loop o la tonalidad garantizada; prefiere ACE cuando importen un timbre más rico y un arreglo más elaborado y un humano vaya a escuchar para confirmar.
Qué comprueba el evaluador (y la corrección)
| Criterio | Aprobado se ve como | Corrección típica |
|---|---|---|
| volumen | -21..-15 LUFS | --lufs -18 |
| margen dinámico | pico <= -1 dBFS, sin recorte | bajar --lufs |
| brillo | 6-16 kHz está 38-62 dB por debajo de 250-2k | sombreros/ruido demasiado alto: bajar ganancia de ruido de batería, bajar tone_hz en master() |
| espectro | bandas compartidas dentro del rango (sin barro, sin retumbo) | cambiar registro del pad / ganancia de graves / cantidad de reverberación en el mood |
| tonalidad | >= 90% de la energía tonal en la escala | tonalidad/escala incorrecta pasada, o notas de melodía fuera de escala |
| ritmo | tempo coincide, pulso claro | subir batería/arpegio; ambiental/tranquilo/cinematográfico pueden tener pulso débil |
| dinámica | rango de nivel 2-9 dB en toda la pieza | demasiado plano: más contraste entre secciones; demasiado saltón: menos |
| variedad | no congelado, no caótico | cambiar --seed, duración más larga añade secciones |
| estéreo | correlación L/R 0.25-0.97 | demasiado mono: desafinar/panear; con fase: reducir anchura de reverberación |
| finales | fundido de salida / unión de loop inaudible | usar --loop para loops; la cola es automática |
Un fallo crítico (tonalidad incorrecta, recorte, volumen muy desviado, siseo) limita la puntuación a 55-100 proporcionalmente, por lo que un desastre no puede esconderse detrás de los promedios.
Banco de regresión
Después de editar bgm.py, ejecuta python scripts/bench.py <directorio_de_salida>. Renderiza cada mood (además de un loop y un corte de 15 s), imprime las puntuaciones y escribe PNGs de espectrograma. Línea base cuando se escribió este skill: media 97.5, mínima 89.9 (ambient; el pulso es intencionalmente débil). Controles negativos que el evaluador debe seguir fallando: ruido blanco (~41), seno recortado (~41), notas aleatorias (~60), tonalidad incorrecta (limitado).
Ampliación
- Nuevo mood = un diccionario en
MOODS(escala, bpm, progresión de 4 acordesprogcomo grados de la escala, nombre del patrón de batería, voz de teclas/plomo, reverberación, brillo). Las rejillas de batería viven enDRUMS(16 pasos/compás;xgolpe). - Lecciones ya pagadas: la percusión de ruido debe pasar un filtro paso bajo antes de la reverberación o la pista silba (descubierto solo mediante espectrograma); las voces de los acordes deben tener conducción de voz o los pads saltan; la melodía usa notas del acorde en los tiempos fuertes con una forma de frase A-A-B-A'; la anchura estéreo proviene de voces de pad desafinadas y una IR de reverberación parcialmente correlacionada.
- Ideas aún no implementadas: modulación tonal para el último estribillo, variantes de bajo ambulante, puntos de sincronización precisos a nivel de muestra (
--hit-at), exportación de pistas por sección.