Youtube-dl and Ffmpeg - python

i have made a music bot with discord.py, but i get this info thing and it doesnt work anymore error [youtube] QxYdBvB8sOY: Downloading webpage 985104597242773505 [2022-06-25 07:45:51] [INFO ] discord.player: Preparing to terminate ffmpeg process 37580. [2022-06-25 07:45:51] [INFO ] discord.player: ffmpeg process 37580 has not terminated. Waiting to terminate... [2022-06-25 07:45:51] [INFO ] discord.player: ffmpeg process 37580 should have terminated with a return code of 1. this is my code
import discord
import os
import asyncio
import youtube_dl
from discord import *
token = "token is here"
prefix = "j!"
blocked_words = ["blocked words are here"]
voice_clients = {}
yt_dl_opts = {'format': 'bestaudio/best'}
ytdl = youtube_dl.YoutubeDL(yt_dl_opts)
ffmpeg_options = {'options': "-vn"}
intents = discord.Intents.default()
intents.message_content = True
client = discord.Client(intents=intents)
programmer_role = "987018590152699964"
#client.event
async def on_ready():
print(f"Bot logged in as {client.user}")
#client.event
async def on_message(msg):
if msg.author != client.user:
if msg.content.lower().startswith(f"{prefix}info"):
await msg.channel.send(f"Hi, Im JoksysBot Made By Joksy!")
for text in blocked_words:
if text in str(msg.content.lower()):
await msg.delete()
await msg.channel.send("Hey, Dont Say That!")
return
if msg.content.startswith(f"{prefix}play"):
try:
voice_client = await msg.author.voice.channel.connect()
voice_clients[voice_client.guild.id] = voice_client
except:
print("error")
try:
url = msg.content.split()[1]
loop = asyncio.get_event_loop()
data = await loop.run_in_executor(None, lambda: ytdl.extract_info(url, download=False))
song = data['url']
player = discord.FFmpegPCMAudio(song, **ffmpeg_options, executable="C:\\Users\\jonas\\Documents\\ffmpeg-2022-06-16-git-5242ede48d-full_build\\ffmpeg-2022-06-16-git-5242ede48d-full_build\\bin\\ffmpeg.exe")
voice_clients[msg.guild.id].play(player)
except Exception as err:
print(err)
if msg.content.startswith(f"{prefix}pause"):
try:
voice_clients[msg.guild.id].pause()
except Exception as err:
print(err)
if msg.content.startswith(f"{prefix}resume"):
try:
voice_clients[msg.guild.id].resume()
except Exception as err:
print(err)
if msg.content.startswith(f"{prefix}stop"):
try:
voice_clients[msg.guild.id].stop()
await voice_clients[msg.guild.id].disconnect()
except Exception as err:
print(err)
client.run(token)
its weird since all the other code in my bot works fine like the !info command, so it must be an error with either youtube-dl or ffmpeg. But then again it doesnt join the voice call in the first place so that might be the error. i added ffmpeg to path but i still wrote the path to it here player = discord.FFmpegPCMAudio(song, **ffmpeg_options, executable="C:\\Users\\jonas\\Documents\\ffmpeg-2022-06-16-git-5242ede48d-full_build\\ffmpeg-2022-06-16-git-5242ede48d-full_build\\bin\\ffmpeg.exe"). i followed this tutorial for the bot https://www.youtube.com/watch?v=Q8wxin72h50&t=1040s i did everything he did but it didnt work. My discord.py version is 2.0.0 my Python version is 3.10.5 and my youtube_dl version is 2021.12.17 my ffmpeg download is ffmpeg-2022-06-16-git-5242ede48d-full_build. I tested it on discord.py 1.73 and it worked fine. This was in intellij though whilst my main program is in Visual Studio Code but i couldnt see it making any big difference so it could be the intents that makes the program not work.I couldnt see any mistakes in the code but im new to discord.py, youtube_dl and ffmpeg stuff so unless visual studio code showed me what i did wrong, i wouldnt notice. But what did i do wrong and how can i fix it?

So for anybody having this issue here ya go: So the issue was connecting to the voice call. Make sure you have these intents
intents = discord.Intents.default()
intents.message_content = True
intents.voice_states = True
if it still doesnt work make sure you have PyNaCl installed. you can do it in a terminal with this code pip install pynacl you need to have python installed for this though. and that should be the fix

Related

Why is the ffmpeg process in discordpy terminating without playing anything?

I'm making a discord bot for playing music (ik very unoriginal) and everytime I try to play music, it gives this error:
2023-02-18 12:31:54 INFO discord.player ffmpeg process 4024 has not terminated. Waiting to terminate...
2023-02-18 12:31:54 INFO discord.player ffmpeg process 4024 should have terminated with a return code of -9.
It is in the voice chat and didn't play anything. Here's my code if you need it:
print("defining functions")
import discord, pytube, os, threading
from moviepy import editor
from discord.ext.commands import Bot
intents=discord.Intents.default()
intents.message_content = True
intents.voice_states = True
bot = Bot("b!",intents=intents)
check = False
token = "redacted"
#bot.command()
async def play(ctx, arg):
await ctx.send("Downloading...")
try:
yt = pytube.YouTube(arg)
print("STREAM: "+str(yt.streams.filter(only_audio=True,mime_type="audio/webm",type="audio",abr="160kbps")))
def download(yt):
print("DOWNLOADING STREAM TO AUDIO.WEBM")
yt.streams.filter(only_audio=True,mime_type="audio/webm",type="audio",abr="160kbps").order_by("abr").first().download(filename="audio.webm")
print("EXPORTING TO MP3")
editor.AudioFileClip("audio.webm").write_audiofile("audio.webm"[:-5] + ".mp3")
os.remove("audio.webm")
print("DONE")
thread = threading.Thread(target=download, args=(yt,))
thread.start()
thread.join()
try:
channel = ctx.author.voice.channel
try:
vc = await channel.connect()
except Exception:
ctx.send("already in vc, one sec")
except Exception:
pass
vc.play(discord.FFmpegPCMAudio(source="audio.mp3", executable="./ffmpeg"))
except Exception:
pass
bot.run(token)
It worked on my computer in VS Code, but I wanted to test it on Replit and only there I got the error. I tried:
Reinstalling discord, pynacl, even pytube and moviepy.
Using a local copy of ffmpeg on replit, see line 36.
Adding the intents that were described in a different thread.
One thing that always happens is the exit code being -9 but the process number changing (ofc). I saw a GitHub Issue about this too which is not showing a fix so how do I fix that?

Nextcord (discord.py fork) - How can I return to Discord that a command is currently running?

I have a Discord bot with a command that take some time to be completed (about 5 seconds).
When the command take too much time to complete without any responses to Discord servers, I've seen that Discord make the command crash, and delete the Context, so when I send a response, it raises an error to say that the Context does not exists.
MEE6 by example, when executing a command, Discord returns:
Sending command...
And when MEE6 receive the command, it says:
MEE6 is thinking...
But my bot does not.
How can I do like MEE6, return to Discord that my command is still running ?
Im using Nextcord (a discord.py fork) so discord.py anwsers will works too.
Minimal reproductible code:
import requests, nextcord
from nextcord.ext import commands
bot = commands.Bot(intents=nextcord.Intents.all()) # be sure to enable every discord intents in the discord dev portal
#bot.slash_command(name='axolotl')
async def axolotl(ctx): # do things that take a lot of time
r = requests.get('https://axolotlapi-test.kirondevcoder.repl.co/reddit?nsfw=0', timeout=2)
if r.status_code == 200:
data = r.json()['data'][0]
embed = nextcord.Embed(title='Axolotl !', description=data['text'] or 'No text content.')
medias = ""
for media in data['media']:
embed.set_image(media)
await ctx.send('', embed=embed)
else:
await ctx.send('', embed=nextcord.Embed(title='Axolotl !', description='There was an error while contacting the API.'))
bot.run('your token here')
I know that the ctx object is not a nextcord.Context object but a nextcord.interaction.Interaction object and I think the API docs of this class can be found at https://docs.nextcord.dev/en/stable/api.html#nextcord.Interaction but im not sure.
I allready tried to make the bot typing on the channel, but it does not change anything:
#bot.slash_command(name='axolotl')
async def axolotl(ctx):
async with ctx.channel.typing():
r = requests.get('https://axolotlapi-test.kirondevcoder.repl.co/reddit?nsfw=0', timeout=2)
if r.status_code == 200:
data = r.json()['data'][0]
embed = nextcord.Embed(title='Axolotl !', description=data['text'] or 'No text content.')
medias = ""
for media in data['media']:
embed.set_image(media)
await ctx.send('', embed=embed)
else:
await ctx.send('', embed=nextcord.Embed(title='Axolotl !', description='There was an error while contacting the API.'))
(I only provided the command code, else its the same code as the minimal reproductible code)
Can someone help please ?
If your commands take a while to execute then you can defer() to tell discord that your commands are going to take a while (and get the "Bot is thinking..." message).
So add await ctx.response.defer() at the start of your command. You can then use the followup attribute to send a message and "respond" to the slash command.
#bot.slash_command(name='axolotl')
async def axolotl(ctx):
await ctx.response.defer()
async with ctx.channel.typing():
r = requests.get('https://axolotlapi-test.kirondevcoder.repl.co/reddit?nsfw=0', timeout=2)
if r.status_code == 200:
data = r.json()['data'][0]
embed = nextcord.Embed(title='Axolotl !', description=data['text'] or 'No text content.')
medias = ""
for media in data['media']:
embed.set_image(media)
await ctx.followup.send('', embed=embed)
else:
await ctx.followup.send('', embed=nextcord.Embed(title='Axolotl !', description='There was an error while contacting the API.'))

Exception mechanism doesn't work after some times

I've created a Discord bot in Python using the discord.py library. This is the pseudo-code of my bot :
import discord
client = discord.Client()
async def test_func():
return "This is a test"
async def error_func():
raise Exception
text_to_func = {"test": test_func, "error": error_func}
#client.event
async def on_message(message):
if message.content.startswith("$"):
command = message.content[1:]
try:
func = text_to_func[command]
answer = await func()
except Exception:
answer = "Error !"
await message.reply(answer)
client.run("<TOKEN>")
When a message is received by the bot, the on_message function is executed. It checks if the message starts with "$", which is the prefix of my bot, and execute the function associated with the command in a try/except block.
I run this script on a ubuntu server using an ssh connection.
Now if I send "$test" on my discord server, the bot will reply with "This is a test" and if I send "$error", it will reply with "Error !". The thing is, after a certain amount of time (can be from 6 hours to 2 days), the "$error" command won't work anymore. The bot doesn't reply to the command, while it still does for "$test".
Does someone know what's going on there ? Thank you for your help.
I'm not 100% sure what you're trying to accomplish, but if you're actually just trying to react to errors, I recommend just using:
#client.event
async def on_error(event, args, kwargs):
#what you want to happen in the event of an error
instead of putting everything you do in a try...except block.
Here are the official docs for the on_error event listener.

Command raised an exception: OpusNotLoaded:

I just started programming a discord bot with discord.py and everything is perfect.
Except one thing: I can't let the bot play music.
Here is my code:
#client.command(pass_context=True)
async def yt(ctx, url):
author = ctx.message.author
voice_channel = author.voice_channel
vc = await client.join_voice_channel(voice_channel)
player = await vc.create_ytdl_player(url)
player.start()
My error:
discord.ext.commands.errors.CommandInvokeError:
Command raised an exception:
OpusNotLoaded:
Why is it happening?
You need to use discord.opus.load_opus to load the Opus library.

Why is my discord bot only executing my command one time and one time only?

I'm in the process of finishing a simple sound clip Discord bot I made by recycling a basic music bot example in python. All I want the bot to do is enter the voice channel of the user who called the command (!womble), play a random sound clip from a folder of sound clips, then leave the voice channel.
"Simple, right?" Of course it isn't, not with this API apparently.
After a BUNCH of trial and error, looking to at least 3 API revisions I got the bot to actually perform the command.....one time. Any further prompts of the command are met with crickets. I can do a !summon and it bring the bot into the channel, but the !womble command no longer works.
def bot_leave(self, ctx):
state = self.get_voice_state(ctx.message.server)
coro = state.voice.disconnect()
fut = asyncio.run_coroutine_threadsafe(coro, state.voice.loop)
try:
fut.result()
except:
# an error happened sending the message
pass
#commands.command(pass_context=True, no_pm=True)
async def womble(self, ctx):
state = self.get_voice_state(ctx.message.server)
opts = {
'default_search': 'auto',
'quiet': True,
}
if state.voice is None:
success = await ctx.invoke(self.summon)
if not success:
return
try:
random_clip = clip_dir + "\\" + random.choice(os.listdir(clip_dir))
player = state.voice.create_ffmpeg_player(random_clip, after=lambda: self.bot_leave(ctx))
player.start()
except Exception as e:
fmt = 'An error occurred while processing this request: ```py\n{}: {}\n```'
await self.bot.send_message(ctx.message.channel, fmt.format(type(e).__name__, e))
I have tried going into the python chat is the Discord API server, but much like my bot, I'm met with crickets. (Guess that's what I get trying to seek support from a chat that already has 4 conversations going.)
I'm guessing you might not need help anymore but just in case you should try removing the coroutine.result() and run it directly. I.e change:
def bot_leave(self, ctx):
state = self.get_voice_state(ctx.message.server)
coro = state.voice.disconnect()
fut = asyncio.run_coroutine_threadsafe(coro, state.voice.loop)
try:
fut.result()
except:
# an error happened sending the message
pass
to:
def bot_leave(self, ctx):
state = self.get_voice_state(ctx.message.server)
coro = state.voice.disconnect()
try:
asyncio.run_coroutine_threadsafe(coro, state.voice.loop)
except:
# an error happened sending the message
pass
That's the only thing I could think of seeing your code snippet, but the problem may lie elsewhere in the code.

Categories