Discord bot audio playback issue: 'source' argument missing in VoiceClient.play()

Hey everyone!

I’m having trouble with my Discord bot’s audio playback function. I’m using discord.py along with app_commands. When I try to play an audio file, I encounter the following error:

TypeError: VoiceClient.play() missing 1 required positional argument: 'source'

Here is a snippet of my code:

from discord import Intents, Client, Message, app_commands
from discord.voice_client import VoiceClient

@tree.command(
    name='play_tune',
    description='Play a local audio file',
    guild=discord.Object(id=123456789)
)
async def play_tune_command(interaction):
    audio_source = discord.PCMVolumeTransformer(discord.FFmpegPCMAudio('tune.mp3'))
    VoiceClient.play(audio_source)

I’ve verified the FFmpeg encoding, but the error persists. Any suggestions on what I might be doing wrong? Thanks in advance!

I’ve dealt with this issue in my own Discord bot projects. The key here is understanding how voice clients work in discord.py. You’re trying to call play() on the VoiceClient class itself, which won’t work.

Instead, you need to get the voice client instance for your guild and call play() on that. Here’s how I’d modify your code:

@tree.command(
    name='play_tune',
    description='Play a local audio file',
    guild=discord.Object(id=123456789)
)
async def play_tune_command(interaction):
    if not interaction.guild.voice_client:
        if interaction.user.voice:
            await interaction.user.voice.channel.connect()
        else:
            await interaction.response.send_message('Join a voice channel first!')
            return
    
    voice_client = interaction.guild.voice_client
    audio_source = discord.PCMVolumeTransformer(discord.FFmpegPCMAudio('tune.mp3'))
    voice_client.play(audio_source)
    await interaction.response.send_message('Now playing the tune!')

This should solve your issue and get your audio playing. Remember to handle exceptions and disconnect the bot when it’s done playing!

I’ve encountered a similar issue before. The problem lies in how you’re calling the play() method. VoiceClient.play() is an instance method, not a class method. You need to call it on the voice client instance connected to your guild’s voice channel.

Try modifying your code like this:

@tree.command(
    name='play_tune',
    description='Play a local audio file',
    guild=discord.Object(id=123456789)
)
async def play_tune_command(interaction):
    if interaction.guild.voice_client is None:
        await interaction.user.voice.channel.connect()
    voice_client = interaction.guild.voice_client
    audio_source = discord.PCMVolumeTransformer(discord.FFmpegPCMAudio('tune.mp3'))
    voice_client.play(audio_source)

This should resolve the ‘source’ argument error you’re experiencing. Make sure you’re in a voice channel when running the command.

hey there! i had this problem too. make sure ur bot is actually in a voice channel first. then use the voice client for that specific guild, not the general VoiceClient class. try this:

voice_client = interaction.guild.voice_client
if voice_client:
    audio_source = discord.PCMVolumeTransformer(discord.FFmpegPCMAudio('tune.mp3'))
    voice_client.play(audio_source)

that should fix it for ya. good luck!