sound (versão completa)
Ferramenta completa para dar som a vídeos, três linhas de capacidade:
- Seleção de efeitos sonoros — pesquisa em múltiplas fontes, filtragem por sinais de feedback humano, download, medição.
- BGM (música de fundo) — duas abordagens: síntese offline de música que se repete perfeitamente, ou recuperação de áudio longo de bancos de素材.
- Voz e mixagem — redução de ruído/EQ/de-esser/compressão, ducking side-chain, mixagem estática, normalização de loudness em duas passagens.
Ambiente: apenas Python 3 + FFmpeg (ffmpeg / ffprobe no PATH). Biblioteca padrão pura, sem pacotes de terceiros, sem chave de API, sem login.
Todas as capacidades desta skill são implementadas em código aberto neste repositório (licença MIT): todos os comandos, regras e parâmetros estão na documentação abaixo e em references/, podendo ser livremente modificados e distribuídos.
Após a instalação, defina as variáveis de acordo com o local real. Abaixo, assume-se a instalação dentro do projeto:
S=.claude/skills/sound/scripts/sfx.py # Pesquisa / Download / Análise
V=.claude/skills/sound/scripts/vocal.py # Voz / Mixagem
C=.claude/skills/sound/scripts/compose.py # Síntese offline de BGM
Para instalação global, substitua .claude/skills/sound/ por ~/.claude/skills/sound/.
1. Seleção de efeitos sonoros
Fluxo de trabalho
- Converta as ações da cena em palavras-chave em inglês ("cartão voando" →
short whoosh, "alternar interruptor" →soft click). - Use
allpara pesquisar em várias fontes; se necessário, pesquise em uma única fonte complementar; forneça--urlspara links de audição. - Primeiro julgue se combina com a cena, depois veja a popularidade; apresente candidatos e justificativas, não trate números como "eu ouvi isso".
- Determine a licença de acordo com o uso, baixe e use
analyzepara verificar duração e distribuição de energia. - Ao entregar, mantenha a URL de origem, autor e licença; para materiais não CC0, complete a atribuição.
python3 $S all "short whoosh" --license cc0 -n 10 --urls
python3 $S freesound "paper slide" --license by -n 5 --sort short
python3 $S commons "bell" -n 5 --json
python3 $S mixkit "whoosh" -n 5
python3 $S kenney "impact" -n 5
python3 $S get sfx/ fs:167563 wm:131079817 mk:1489
python3 $S analyze sfx/*.mp3 --loudness --silence --json
Regras de seleção (seguindo sinais de feedback humano)
- Número de avaliadores > Média:
★4.4(380)é uma evidência mais forte do que★4.9(6). - Descrição do uploader mais próxima da audição: a presença de "built-in mic" / "made with my mouth" indica baixa fidelidade; menção a gravadores (Zoom, Sound Devices) e fonte sonora clara ("cork from a wine bottle") indica controle. Se a fonte sonora na descrição não corresponder à cena, descarte, mesmo que seja popular.
- Popularidade não significa adequação: o "thud" mais baixado pode ser um rugido grave de filme de 3 segundos. É preciso ver a duração, usar
analyzepara ver onde a energia está e quanto tempo dura a cauda, e então decidir se corta. - Apresente candidatos antes de baixar: se o usuário quiser ouvir, adicione
--urls, não decida por ele. - Sinais disponíveis variam por fonte: Freesound tem número de downloads e avaliadores; Commons tem duração real e licença; Mixkit tem duração mas sem popularidade; Kenney são pacotes completos. Não trate campos ausentes como nota zero.
Regras de licenciamento (rigorosas, não flexibilizar)
| Parâmetro | Permitido | Uso típico |
|---|---|---|
--license cc0 | Apenas CC0 / PDM | Comercial, sem se preocupar com atribuição |
--license by | CC0 / PDM / BY / BY-SA | Atribuição aceitável (exclui BY-NC, BY-NC-SA, BY-ND) |
--license any | Tudo, mas o resultado ainda marca a licença | Apenas para ver candidatos |
- BY-NC nunca é usado para fins comerciais; o script já exclui em
cc0/by; emany, você precisa julgar. - Mixkit usa sua própria "Mixkit Free License" (na prática, comercial sem atribuição), mas não pertence ao sistema de tags CC0/BY, portanto é excluído em
cc0/by. Se precisar dele, use explicitamente--license anye mencione o nome da licença na entrega. - Para materiais não CC0,
getimprime o autor e um aviso de licença; isto é apenas uma pista; na entrega, mantenha a fonte e o texto original da licença. - Kenney é totalmente CC0, mas o download é de pacotes zip completos, não de efeitos individuais; é preciso descompactar e selecionar os arquivos.
Distribuição de fontes
| Fonte | Pontos fortes | Limitações |
|---|---|---|
| Freesound | Única com número de downloads/avaliadores | Baixa apenas MP3 de pré-visualização, não o arquivo original; conexão única ~80 KB/s |
| Wikimedia Commons | Duração real + campos de licença completos, gravações ambientais/sinos/áudio longo | Combina por descrição do arquivo; palavras-chave estranhas podem não encontrar; sem popularidade |
| Mixkit | Comercial sem atribuição, qualidade consistente de efeitos de interface | Estrutura de página para解析; sem popularidade; duração marcada em segundos inteiros |
| Kenney | Pacotes de efeitos de jogo/interface CC0 | Pacote zip completo, sem duração individual |
Detalhes do método de captura e mapeamento de tags de licença em references/sources.md.
2. BGM: Síntese ou base
Primeiro, determine se o usuário quer "ter música" ou "compor uma faixa que combine com a emoção":
| Cenário | Abordagem | Comando |
|---|---|---|
| Quer música cíclica, sem dependências, emoção controlável, sem risco de direitos autorais | Síntese offline | compose.py |
| Quer instrumentos reais/voz/ambiente | Recuperação como base | sfx.py music |
| Já tem um BGM curto e quer preencher a cena | Loop/corte | vocal.py loop / trim |
Síntese offline (recomendado, verdadeiramente "síntese de BGM")
python3 $C bgm.wav --style ambient --duration 30 --bpm 90 --key Am
python3 $C bgm.wav --style lofi --duration 30 --bpm 85 --key C
python3 $C bgm.wav --style upbeat --duration 30 --bpm 120 --key G
ambient: pads lentos (acordes de base), sem bateria, ideal para narração/demonstração de produto;lofi: chorus desafinado + kick/hat relaxados + ruído de fita;upbeat: acordes curtos e brilhantes + kick de quatro no chão + linha de baixo.- Saída: WAV 44.1 kHz / 16-bit / estéreo, alinhamento de fase entre início e fim + crossfade em anel de acordes, permitindo loop sem emendas.
- A duração será arredondada para o compasso inteiro mais próximo (ex.: 30s @ 90 BPM na verdade 29.333s); para segundos exatos, use BPM divisível por 4 (ex.: 120).
- O script imprime um valor sugerido de
--bgm-gain(em dB) que pode ser copiado diretamente, consistente com os parâmetros devocal.py. --seedgarante saída idêntica para os mesmos parâmetros, facilitando o gerenciamento de versões.
Recuperação como base
python3 $S music "ambient" --duration long --max-seconds 600 -n 8 --urls --json
python3 $S get bgm/ wm:123456
python3 $V trim bgm/xxx.ogg bed.wav --start 0 --end 30
musicusafiletype:audiono Commons;--duration longpadrão ≥30 segundos, duração desconhecida é excluída por padrão (para permitir, adicione--allow-unknown).- Commons frequentemente retorna gravações de campo/livros de áudio de horas; ao usar como base, adicione sempre
--max-seconds 600, caso contrário, baixará centenas de MB. - Após baixar áudio longo, geralmente é necessário
trimpara extrair um trecho, oulooppara preencher a duração da cena com um trecho curto.
3. Limpeza de voz e mixagem
Fluxo padrão
# 1. Voz: Redução de ruído → Filtro passa-alta → (De-esser) → Compressão → Dupla normalização de loudness → Fade in/out
python3 $V clean voice.wav clean.wav --deesser
# Alvo padrão -16 LUFS; para não normalizar, adicione --no-loudnorm
# 2. Ajustar BGM à duração da cena (escolha uma)
python3 $V loop bgm.wav bed.wav --duration 30 # Preenche com material curto, crossfade real na emenda
python3 $V trim bgm.wav bed.wav --start 0 --end 30
# 3. Mixagem: Abaixa automaticamente o BGM quando há fala (ducking side-chain)
python3 $V duck clean.wav bed.wav mixed.wav --bgm-gain -12 --threshold -30 --ratio 8
# Sem voz / apenas ambiente: use mixagem estática
python3 $V mix bed.wav clean.wav mixed.wav --bgm-gain -18
# 4. Verificação / normalização de loudness final
python3 $V report mixed.wav
python3 $V loudnorm mixed.wav final.wav --target-lufs -16
Regras de parâmetros
| Parâmetro | Padrão | Quando ajustar |
|---|---|---|
--bgm-gain | duck -12 / mix -18 dB | Use o valor sugerido por compose.py; se o BGM cobrir a voz, reduza mais 3~6 dB |
--threshold | -30 dB | O threshold do side-chain é threshold de nível, não detecção de fala; se a voz estiver muito baixa, ajuste para -36; se o BGM estiver muito alto, aumente |
--ratio | 8 | Se o ducking for muito óbvio/sensação de respiração forte, reduza para 4 |
--target-lufs | -16 LUFS | Para narração/vídeo, use -16; para streaming de música, -14; para podcasts, pode ser -16 |
--true-peak | -1.5 dBTP | Altere de acordo com o limite explícito da plataforma |
--fade | duck 0.3 / clean 0.05 segundos | Para início/fim de cena, emendas de loop |
- Não confunda unidades:
Ié LUFS (loudness integrada),TPé dBTP (pico verdadeiro),LRAé LU (faixa de loudness);mean_volumeé nível médio em dBFS, ereportirá rotulá-lo claramente; não o trate como LUFS. duck/mixambas as vias complementam comapad(silêncio para preencher) e usamduration=longest; se o BGM for mais curto que a voz, não será cortado;--durationpode especificar o comprimento final.- A medição dupla de loudnorm em
cleané executada após toda a cadeia de pré-processamento, e a medição I/TP/LRA é exatamente igual à segunda passagem; o fade in/out é colocado antes do loudnorm, garantindo que o sinal medido e a entrada normalizada sejam os mesmos; caso contrário,measured_*não corresponderá. - A medição interna do
loudnormpode diferir doebur128em cerca de 1 LU; o script fará uma verificação de fechamento de loop e compensará com um ganho adicional após o produto final, imprimindo "Compensação de fechamento de loop ±X.X dB" no resumo; esta é uma etapa necessária para atingir a precisão, não a remova. - Para materiais muito curtos / quase silenciosos que não produzem LUFS válidos, o script reduzirá automaticamente para uma única passagem de loudnorm e escreverá claramente "passagem única" na saída; neste caso, o fechamento de loop é automaticamente ignorado, não aplicando ganho excessivo ao silêncio.
O texto original da cadeia de filtros, o princípio do loudnorm de duas passagens e a tabela de ajuste de parâmetros estão em references/mixing.md.
4. Receitas comuns
A. Demonstração de produto de 30 segundos (totalmente offline, sem素材)
python3 $C bgm.wav --style ambient --duration 30 --bpm 120 --key Am
python3 $V clean voice.wav clean.wav --deesser
python3 $V duck clean.wav bgm.wav mixed.wav --bgm-gain -13
python3 $V loudnorm mixed.wav final.wav --target-lufs -16
python3 $S all "soft whoosh" --license cc0 -n 6 --urls
B. Adicionar ambiente real a uma narração existente
python3 $S music "rain ambience" --duration long --max-seconds 600 --license by -n 6 --urls
python3 $S get bgm/ wm:xxx
python3 $V trim bgm/xxx bed.wav --start 10 --end 40
python3 $V clean voice.wav clean.wav
python3 $V duck clean.wav bed.wav mixed.wav --bgm-gain -18
C. Apenas um som de transição e que possa ser usado comercialmente
python3 $S all "paper slide" --license cc0 -n 8 --sort short --urls
python3 $S get sfx/ fs:xxx
python3 $S analyze sfx/*.mp3 --loudness --silence --json
D. Envelope de volume que acompanha a cena (renderização Remotion)
O master final do produto usa o pipeline FFmpeg acima; fades quadro a quadro / ajuste de volume em pontos específicos deve ser feito durante a renderização no Remotion, veja references/remotion-audio.md.