Bots do Discord podem fazer mais do que enviar mensagens de texto e reproduzir arquivos de áudio. Você pode criar um bot que escuta um canal de voz e processa áudio em tempo real. Isso é útil para reconhecimento de fala, transcrição de áudio, análise musical ou moderação de voz ao vivo. Pycord é um wrapper moderno da API do Discord para Python que inclui um recurso chamado sinks. Sinks permitem que seu bot receba e manipule dados de áudio conforme eles chegam dos canais de voz. Este artigo explica como configurar o Pycord, criar um cliente de voz e usar sinks para transmitir áudio em tempo real de canais de voz do Discord.
Principais Conclusões: Pycord Sinks para Transmissão de Áudio em Tempo Real
- Classes de sink do Pycord: Classes integradas como
PCMAudioeFFmpegPCMAudiopermitem que seu bot receba e processe áudio sem salvar arquivos no disco. - Método
voice_client.listen(): Inicia a escuta de um canal de voz e envia dados de áudio PCM brutos para uma função de callback que você define. - Parâmetro
afteremcreate_ffmpeg_player: Aciona uma função após a reprodução de áudio terminar, útil para encadear ações de escuta e reprodução.
O Que São Pycord Sinks e Por Que Você Precisa Deles
Pycord é um fork mantido do discord.py que suporta a API de voz do Discord. Um sink é um mecanismo que captura dados de áudio de um canal de voz e os entrega ao seu código em pedaços. Sem sinks, seu bot só pode reproduzir áudio ou enviar arquivos de áudio. Com sinks, seu bot pode processar áudio ao vivo para conversão de fala em texto, detecção de som ou comandos personalizados acionados por voz.
O conceito central é simples. Quando seu bot entra em um canal de voz, ele cria um objeto VoiceClient. Chamar voice_client.listen() inicia um sink que recebe dados de áudio de cada usuário falando no canal. Os dados chegam como quadros PCM brutos. Você escreve uma função de callback que recebe cada quadro. Dentro dessa função, você pode analisar o áudio, salvá-lo ou encaminhá-lo para outro serviço.
Pycord fornece dois tipos principais de sink. A classe PCMAudio funciona para dados PCM brutos sem transcodificação. A classe FFmpegPCMAudio usa FFmpeg para converter formatos de áudio dinamicamente. Para transmissão em tempo real, PCMAudio é a melhor escolha porque evita a sobrecarga de codificação e decodificação. Você precisa ter o FFmpeg instalado no servidor ou na máquina local se planeja usar FFmpegPCMAudio.
Pré-requisitos para Transmitir Áudio em Tempo Real
Antes de escrever qualquer código, verifique se estes itens estão em ordem:
- Python 3.8 ou superior instalado no sistema.
- Biblioteca Pycord instalada via pip:
pip install py-cord[voice]. O extra[voice]instala as dependências de áudio necessárias, comopynacleaudioop. - FFmpeg instalado e adicionado ao PATH do sistema. Baixe de ffmpeg.org e coloque o executável em uma pasta que esteja na variável de ambiente PATH.
- Um token de bot do Discord. Crie um bot no Portal do Desenvolvedor do Discord, ative as intenções Server Members Intent e Message Content Intent, e convide o bot para um servidor com as permissões
connectespeak. - Um canal de texto onde o bot possa enviar mensagens ou um canal de voz dedicado para testes.
Passos para Criar um Bot que Transmite Áudio em Tempo Real
Os passos a seguir criam um bot simples que entra em um canal de voz, escuta todo o áudio e imprime o tamanho dos dados de áudio no console. Você pode substituir o callback pela sua própria lógica de processamento.
- Crie o script do bot
Abra um novo arquivo Python chamadovoice_sink_bot.py. Importe os módulos necessários:discord,asyncioediscord.ext.commands. Defina uma instância do bot com a classecommands.Bote defina o prefixo de comando como!. - Defina a classe de callback do sink
Crie uma classe que herda dediscord.Sink. Sobrescreva o método__init__para inicializar um buffer. Sobrescreva o métodowrite. O métodowriterecebe dois argumentos:data(um objeto bytes de áudio PCM) euser(um objetodiscord.Useroudiscord.Member). Dentro dewrite, processe os dados de áudio. Neste exemplo, imprima o comprimento dos dados e o nome do usuário. - Crie o comando join
Adicione um comando chamadojoinque recebe um parâmetroctx. Verifique se o autor está em um canal de voz. Se não estiver, envie uma mensagem de erro. Useawait ctx.author.voice.channel.connect()para fazer o bot entrar no canal. Armazene ovoice_clientpara uso posterior. - Crie o comando listen
Adicione um comando chamadolisten. Dentro do comando, obtenha ovoice_clientdectx.voice_client. Se o bot não estiver conectado, envie uma mensagem pedindo para o usuário executar!joinprimeiro. Instancie sua classe de sink personalizada. Chamevoice_client.listen(sink_instance)para iniciar a escuta. Envie uma mensagem de confirmação. - Crie o comando stop
Adicione um comando chamadostop. Chamevoice_client.stop_listening()para parar o sink. Envie uma mensagem informando que a escuta foi interrompida. - Execute o bot
No final do script, adicionebot.run('SEU_TOKEN_DO_BOT'). SubstituaSEU_TOKEN_DO_BOTpelo token real do seu bot. Execute o script compython voice_sink_bot.py.
Exemplo de Código Completo
Aqui está o script completo funcional para um bot que transmite áudio em tempo real e imprime os tamanhos dos dados:
import discord
from discord.ext import commands
import asyncio
class AudioSink(discord.Sink):
def __init__(self):
super().__init__()
self.buffer = b''
def write(self, data, user):
self.buffer += data
print(f"Recebidos {len(data)} bytes de {user}")
bot = commands.Bot(command_prefix='!')
@bot.command()
async def join(ctx):
if ctx.author.voice:
channel = ctx.author.voice.channel
await channel.connect()
await ctx.send(f"Entrou em {channel.name}")
else:
await ctx.send("Você não está em um canal de voz")
@bot.command()
async def listen(ctx):
voice = ctx.voice_client
if not voice:
await ctx.send("O bot não está em um canal de voz. Use !join primeiro")
return
sink = AudioSink()
voice.listen(sink)
await ctx.send("Escutando áudio...")
@bot.command()
async def stop(ctx):
voice = ctx.voice_client
if voice and voice.is_listening():
voice.stop_listening()
await ctx.send("Escuta interrompida")
else:
await ctx.send("O bot não está escutando no momento")
bot.run('SEU_TOKEN_DO_BOT')
Erros Comuns e Limitações ao Usar Pycord Sinks
O Bot Não Responde a Comandos de Voz
Se o bot entrar no canal mas não receber áudio, verifique se você ativou a Server Members Intent no Portal do Desenvolvedor do Discord. Sem essa intenção, o bot não consegue ver quem está falando. Verifique também se o bot tem a permissão speak no canal de voz. Sem ela, o bot não pode receber áudio.
Dados de Áudio Chegam em Pequenos Pedaços
Pycord envia dados de áudio em quadros de 20 milissegundos. Isso é normal para transmissão em tempo real. Se você precisar de buffers maiores para processamento, acumule os dados no método write do seu sink até ter amostras suficientes. Use um temporizador ou um contador de quadros para liberar o buffer periodicamente.
O Bot Trava Quando Vários Usuários Falam Simultaneamente
O método write é chamado separadamente para cada usuário. Sua classe sink recebe áudio de todos os falantes. Se sua lógica de processamento for lenta, use asyncio.create_task dentro de write para delegar o trabalho a uma corrotina separada. Isso evita bloquear o fluxo de áudio.
Erro FFmpeg Não Encontrado
Se você usar FFmpegPCMAudio e receber um FileNotFoundError, o FFmpeg não está instalado ou não está no PATH. Baixe a versão correta para seu sistema operacional de ffmpeg.org, extraia o executável e adicione a pasta à variável de ambiente PATH do sistema. Reinicie o terminal ou IDE após fazer a alteração.
O Bot Desconecta Após Reproduzir Áudio
O cliente de voz do Pycord desconecta automaticamente se nenhum áudio for reproduzido ou escutado por um período. Para manter o bot conectado, inicie o sink imediatamente após entrar ou use voice_client.play(discord.PCMAudio(silent_pcm_data)) para reproduzir uma faixa silenciosa. A faixa silenciosa mantém a conexão ativa sem produzir ruído audível.
Tipos de Pycord Sink: PCMAudio vs FFmpegPCMAudio
| Item | PCMAudio | FFmpegPCMAudio |
|---|---|---|
| Formato de entrada | Áudio PCM bruto (não comprimido) | Qualquer formato suportado pelo FFmpeg (MP3, AAC, OGG, etc.) |
| Sobrecarga de transcodificação | Nenhuma | Uso adicional de CPU para decodificação |
| Requisito de instalação | Nenhum além do Pycord | FFmpeg deve estar instalado e no PATH |
| Adequação para transmissão em tempo real | Melhor para processamento de baixa latência | Adequado quando você precisa receber áudio em um codec diferente |
| Caso de uso | Detecção de atividade de voz, reconhecimento de fala, análise personalizada | Gravação de áudio em arquivos, reprodução de música, conversão de formato |
Agora você tem um bot funcional que transmite áudio em tempo real de um canal de voz do Discord usando Pycord sinks. O próximo passo é substituir a instrução print no método write do sink pela lógica real de processamento de áudio. Por exemplo, você pode alimentar os dados PCM para uma biblioteca de reconhecimento de fala como speech_recognition ou uma biblioteca de análise de som como pydub. Lembre-se de manipular os dados de áudio em pedaços para manter o bot responsivo. Para uso avançado, explore a documentação da classe discord.Sink do Pycord para aprender sobre parâmetros personalizados de sink e o callback after para encadear ações de escuta e reprodução.