Create a Discord Radio Bot in python under Debian

211 Views Asked by At

I'm trying to create a simple discord bot in python that would broadcast my webradio in a voice channel. I found this topic (How to create a discord bot that streams online radio in Python), but using the given code, I get the following error:

python radio.py
Traceback (most recent call last):
  File "/home/radio.py", line 11, in <module>
    client = Bot(command_prefix=list(PREFIX))
TypeError: 'NoneType' object is not iterable

Here is the code I've used:

import os

from discord import FFmpegPCMAudio
from discord.ext.commands import Bot
from dotenv import load_dotenv

load_dotenv()
TOKEN = os.getenv('DISCORD_TOKEN')
PREFIX = os.getenv('DISCORD_PREFIX')

client = Bot(command_prefix=list(PREFIX))


@client.event
async def on_ready():
    print('Music Bot Ready')


@client.command(aliases=['p', 'pla'])
async def play(ctx, url: str = 'http://stream.radioparadise.com/rock-128'):
    channel = ctx.message.author.voice.channel
    global player
    try:
        player = await channel.connect()
    except:
        pass
    player.play(FFmpegPCMAudio('http://stream.radioparadise.com/rock-128'))


@client.command(aliases=['s', 'sto'])
async def stop(ctx):
    player.stop()


client.run(TOKEN)

Being a beginner, I'm stuck on this error, how can I solve it?

EDIT: I followed Puncher's recommendation and now I'm getting this error:

Music Bot Ready
pla
Ignoring exception in command play:
Traceback (most recent call last):
  File "/usr/local/lib/python3.10/site-packages/discord/ext/commands/core.py", line 85, in wrapped
    ret = await coro(*args, **kwargs)
  File "/home/radio.py", line 27, in play
    player.play(FFmpegPCMAudio('https://rdx.kaed-tzo.com/listen/orx_radio/radio.mp3'))
NameError: name 'player' is not defined

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/usr/local/lib/python3.10/site-packages/discord/ext/commands/bot.py", line 939, in invoke
    await ctx.command.invoke(ctx)
  File "/usr/local/lib/python3.10/site-packages/discord/ext/commands/core.py", line 863, in invoke
    await injected(*ctx.args, **ctx.kwargs)
  File "/usr/local/lib/python3.10/site-packages/discord/ext/commands/core.py", line 94, in wrapped
    raise CommandInvokeError(exc) from exc
discord.ext.commands.errors.CommandInvokeError: Command raised an exception: NameError: name 'player' is not defined
3

There are 3 best solutions below

0
H.LK On BEST ANSWER

Learning from its mistakes, here is a working simple code. Hope this saves others some time.

import discord
from discord.ext import commands
import asyncio

bot = commands.Bot(command_prefix='!')

@bot.command()
async def radio(ctx):

    url = 'https://your-url.com/streamfile.mp3'
    if ctx.author.voice.channel.id == chanel-ID:
        voice = await ctx.author.voice.channel.connect()
        voice.play(discord.FFmpegPCMAudio(url))
        await ctx.send("confirmation message")
    else:
        await ctx.send("You must be in the 'Radio' audio channel to use this command")

bot.run('token')
4
puncher On

The problem in your code is client = Bot(command_prefix=list(PREFIX)). You're trying to convert PREFIX to a list, but PREFIX returns None, that's why this error occurs.

The reason why it returns None is, that it can't find the env variable DISCORD_PREFIX in your .env. Make sure that .env and the env variable exists.

0
Eric Jin On

It raises an exception. (Which is also ignored. This is why it's generally a bad idea to bare except.)

You probably don't want to be using global player anyway, because each instance of the command should probably have its own player.

@client.command(aliases=['p', 'pla'])
async def play(ctx, url: str = 'http://stream.radioparadise.com/rock-128'):
    channel = ctx.message.author.voice.channel
    global player
    try:
        player = await channel.connect()
    except Exception as e:
        await ctx.send(f"Sorry, I was unable to connect to the channel. Error details: {e}")
        return
    player.play(FFmpegPCMAudio('http://stream.radioparadise.com/rock-128'))

If you intended for everything to have its own player, simply except when you try to reference the player:

try:
    player.play(FFmpegPCMAudio('http://stream.radioparadise.com/rock-128'))
except NameError:
    await ctx.send('No earlier player found and I wasn't able to connect to the channel.')