Search code examples
pythonffmpegdiscorddiscord.py

Command raised an exception: NameError: name 'player' is not defined


I finally got myself a hosting for my project, but got into an error and I don't know how to resolve it. I ran command !play to start streaming in vc, but I got this error:

2023-03-19 18:36:04 INFO     discord.client logging in using static token
2023-03-19 18:36:04 INFO     discord.gateway Shard ID None has connected to Gateway (Session ID: f983009c9f2881b87ee119278692efc9).
Eurobeat Radio is running!
2023-03-19 18:36:10 ERROR    discord.ext.commands.bot Ignoring exception in command play
Traceback (most recent call last):
  File "/home/container/.local/lib/python3.10/site-packages/discord/ext/commands/core.py", line 229, in wrapped
    ret = await coro(*args, **kwargs)
  File "/home/container/radio.py", line 44, in play
    player.play(FFmpegPCMAudio('http://stream.eurobeat.xyz'))
NameError: name 'player' is not defined
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
  File "/home/container/.local/lib/python3.10/site-packages/discord/ext/commands/bot.py", line 1350, in invoke
    await ctx.command.invoke(ctx)
  File "/home/container/.local/lib/python3.10/site-packages/discord/ext/commands/core.py", line 1023, in invoke
    await injected(*ctx.args, **ctx.kwargs)  # type: ignore
  File "/home/container/.local/lib/python3.10/site-packages/discord/ext/commands/core.py", line 238, in wrapped
    raise CommandInvokeError(exc) from exc
discord.ext.commands.errors.CommandInvokeError: Command raised an exception: NameError: name 'player' is not defined

I tried running it on my pc and that was without error, but once it was on the hosting it ran in to the error up the page.

Here is the code:

import discord
import urllib.request, json 
from discord import FFmpegPCMAudio
from discord.ext import commands
from discord.ext import tasks
client= commands.Bot(command_prefix="er!", intents=discord.Intents.all(), help_command=None)

@tasks.loop(seconds=10.0)
async def my_background_task():
    """Will loop every 60 seconds and change the bots presence"""
    with urllib.request.urlopen('https://api.laut.fm/station/eurobeat/current_song') as url:
        data = json.load(url)
        global namestatus
        global artiststatus
        namestatus = data['title']
        artiststatus = data['artist']['name']
    await client.change_presence(activity=discord.Activity(type=discord.ActivityType.listening, name="Eurobeat FM"))
    await client.change_presence(activity=discord.Game(name="Para para dancing ~"))
    await client.change_presence(activity=discord.Activity(type=discord.ActivityType.listening, name=f"{namestatus} by {artiststatus}"))


@client.event
async def on_ready():
    print('Eurobeat Radio is running!')
    await client.wait_until_ready()
    my_background_task.start()


@client.event
async def on_voice_state_update(member, prev, cur):
    if client.user in prev.channel.members and len([m for m in prev.channel.members if not m.bot]) == 0:
        channel = discord.utils.get(client.voice_clients, channel=prev.channel)
        await channel.disconnect()

@client.command(aliases=['p', 'pla', 'join', 'j'])
async def play(ctx, url: str = 'http://stream.eurobeat.xyz'): 
    channel = ctx.message.author.voice.channel
    global player
    try:
        player = await channel.connect()
    except:
        pass
    player.play(FFmpegPCMAudio('http://stream.eurobeat.xyz'))
    embedVar = discord.Embed(title="Started Playing!", color=discord.Color.random())
    await ctx.send(embed=embedVar)

Would be very grateful for your help!


Solution

  • Hard to be sure without knowing exactly how you're hosting, but in my experience using global often causes issues, and using global alongside async almost always causes issues.

    The below re-write of your play function may fix this (hopefully):

    @client.command(aliases=['p', 'pla', 'join', 'j'])
    async def play(ctx, url: str = 'http://stream.eurobeat.xyz'): 
        channel = ctx.message.author.voice.channel
        try:
            player = await channel.connect()
        except discord.ClientException as e:
            if str(e) == "Already connected to a voice channel.":
                player = ctx.guild.voice_client
            else:
                await ctx.send("Error: Unable to connect to the voice channel.")
                return
        except Exception as e:
            await ctx.send(f"Error: {e}")
            return
    
        player.play(FFmpegPCMAudio('http://stream.eurobeat.xyz'))
        embedVar = discord.Embed(title="Started Playing!", color=discord.Color.random())
        await ctx.send(embed=embedVar)
    

    If that still doesn't work, or if works but causes another error elsewhere in your code, try re-inserting the global player above the try block, e.g.:

    ...
    async def play(ctx, url: str = 'http://stream.eurobeat.xyz'): 
        channel = ctx.message.author.voice.channel
        global player    # re-insert this
        try:
            player = await channel.connect()
    ...