mirror of
https://github.com/Cog-Creators/Red-DiscordBot.git
synced 2025-11-06 19:28:54 -05:00
commit
00d8fe1d23
139
cogs/audio.py
139
cogs/audio.py
@ -49,6 +49,7 @@ class Audio:
|
|||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
self.music_player = EmptyPlayer()
|
self.music_player = EmptyPlayer()
|
||||||
|
self.sfx_player = EmptyPlayer()
|
||||||
self.settings = fileIO("data/audio/settings.json", "load")
|
self.settings = fileIO("data/audio/settings.json", "load")
|
||||||
self.queue_mode = False
|
self.queue_mode = False
|
||||||
self.queue = []
|
self.queue = []
|
||||||
@ -86,7 +87,8 @@ class Audio:
|
|||||||
self.playlist = []
|
self.playlist = []
|
||||||
self.queue.append(link)
|
self.queue.append(link)
|
||||||
self.music_player.paused = False
|
self.music_player.paused = False
|
||||||
if self.music_player.is_playing(): self.music_player.stop()
|
if not self.sfx_player.is_done(): self.sfx_player.stop()
|
||||||
|
if not self.music_player.is_done(): self.music_player.stop()
|
||||||
await self.bot.say("Playing requested link...")
|
await self.bot.say("Playing requested link...")
|
||||||
else:
|
else:
|
||||||
self.playlist = []
|
self.playlist = []
|
||||||
@ -147,6 +149,8 @@ class Audio:
|
|||||||
self.music_player.stop()
|
self.music_player.stop()
|
||||||
else:
|
else:
|
||||||
await self.vote_skip(msg)
|
await self.vote_skip(msg)
|
||||||
|
elif self.sfx_player.is_playing():
|
||||||
|
self.sfx_player.stop()
|
||||||
|
|
||||||
async def vote_skip(self, msg):
|
async def vote_skip(self, msg):
|
||||||
v_channel = msg.server.me.voice_channel
|
v_channel = msg.server.me.voice_channel
|
||||||
@ -209,6 +213,70 @@ class Audio:
|
|||||||
else:
|
else:
|
||||||
await self.bot.say("There are no valid playlists in the localtracks folder.\nIf you're the owner, see {}".format(help_link))
|
await self.bot.say("There are no valid playlists in the localtracks folder.\nIf you're the owner, see {}".format(help_link))
|
||||||
|
|
||||||
|
@commands.command(pass_context=True, no_pm=True)
|
||||||
|
async def sfx(self, ctx, *, name : str):
|
||||||
|
"""Plays a local sound file
|
||||||
|
|
||||||
|
For bot's owner:
|
||||||
|
audio files must be placed in the data/audio/sfx folder.
|
||||||
|
Supported files are mp3, flac, wav"""
|
||||||
|
#sound effects default enabled
|
||||||
|
server = ctx.message.server
|
||||||
|
if server.id not in self.settings["SERVER_SFX_ON"]:
|
||||||
|
self.settings["SERVER_SFX_ON"][server.id] = True
|
||||||
|
if not self.settings["SERVER_SFX_ON"][server.id]:
|
||||||
|
await self.bot.say("Sound effects are not enabled on this server")
|
||||||
|
return
|
||||||
|
|
||||||
|
msg = ctx.message
|
||||||
|
localsfx = self.get_local_sfx()
|
||||||
|
if localsfx and ("data/audio/sfx/" not in name and "\\" not in name):
|
||||||
|
if name in localsfx.keys():
|
||||||
|
file = "data/audio/sfx/{}{}".format(name,localsfx[name])
|
||||||
|
|
||||||
|
if await self.check_voice(msg.author, ctx.message):
|
||||||
|
try:
|
||||||
|
if self.music_player.is_playing():
|
||||||
|
self.music_player.paused = True
|
||||||
|
self.music_player.pause()
|
||||||
|
|
||||||
|
if self.sfx_player.is_playing():
|
||||||
|
self.sfx_player.stop()
|
||||||
|
|
||||||
|
self.sfx_player = self.bot.voice.create_ffmpeg_player(file, options='''-filter:a "volume={}"'''.format(self.settings["VOLUME"]))
|
||||||
|
self.sfx_player.start()
|
||||||
|
while self.sfx_player.is_playing():
|
||||||
|
await asyncio.sleep(.5)
|
||||||
|
|
||||||
|
if not self.music_player.is_playing():
|
||||||
|
self.music_player.paused = False
|
||||||
|
self.music_player.resume()
|
||||||
|
except AttributeError:
|
||||||
|
#music_player not used yet. Still an EmptyPlayer.
|
||||||
|
#better to ask for forgiveness?
|
||||||
|
pass
|
||||||
|
except Exception as e:
|
||||||
|
print(e)
|
||||||
|
|
||||||
|
else:
|
||||||
|
await self.bot.say("There is no sound effect with that name.")
|
||||||
|
else:
|
||||||
|
await self.bot.say("There are no valid sound effects in the `data/audio/sfx` folder.")
|
||||||
|
|
||||||
|
def get_local_sfx(self):
|
||||||
|
filenames = {}
|
||||||
|
files = os.listdir("data/audio/sfx/")
|
||||||
|
#only reason why these are the only supported ext is cause I haven't tried any others
|
||||||
|
supported = [".mp3",".flac",".wav"]
|
||||||
|
for f in files:
|
||||||
|
item = os.path.splitext(f)
|
||||||
|
if item[1] in supported:
|
||||||
|
filenames[item[0]] = item[1]
|
||||||
|
if filenames != {}:
|
||||||
|
return filenames
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
@commands.command(pass_context=True, no_pm=True)
|
@commands.command(pass_context=True, no_pm=True)
|
||||||
async def loop(self, ctx):
|
async def loop(self, ctx):
|
||||||
"""Loops single song
|
"""Loops single song
|
||||||
@ -260,7 +328,7 @@ class Audio:
|
|||||||
"""Stops audio activity
|
"""Stops audio activity
|
||||||
"""
|
"""
|
||||||
msg = ctx.message
|
msg = ctx.message
|
||||||
if self.music_player.is_playing():
|
if self.music_player.is_playing() or self.sfx_player.is_playing():
|
||||||
if await self.is_alone_or_admin(msg):
|
if await self.is_alone_or_admin(msg):
|
||||||
await self.close_audio()
|
await self.close_audio()
|
||||||
else:
|
else:
|
||||||
@ -272,7 +340,8 @@ class Audio:
|
|||||||
self.queue = []
|
self.queue = []
|
||||||
self.playlist = []
|
self.playlist = []
|
||||||
self.current = -1
|
self.current = -1
|
||||||
if self.music_player.is_playing(): self.music_player.stop()
|
if not self.music_player.is_done(): self.music_player.stop()
|
||||||
|
if not self.sfx_player.is_done(): self.sfx_player.stop()
|
||||||
await asyncio.sleep(1)
|
await asyncio.sleep(1)
|
||||||
if self.bot.voice: await self.bot.voice.disconnect()
|
if self.bot.voice: await self.bot.voice.disconnect()
|
||||||
|
|
||||||
@ -355,7 +424,9 @@ class Audio:
|
|||||||
@commands.command()
|
@commands.command()
|
||||||
async def resume(self):
|
async def resume(self):
|
||||||
"""Resumes paused song."""
|
"""Resumes paused song."""
|
||||||
if not self.music_player.is_playing():
|
if self.sfx_player.is_playing():
|
||||||
|
self.sfx_player.stop()
|
||||||
|
elif not self.music_player.is_playing():
|
||||||
self.music_player.paused = False
|
self.music_player.paused = False
|
||||||
self.music_player.resume()
|
self.music_player.resume()
|
||||||
await self.bot.say("Resuming song.")
|
await self.bot.say("Resuming song.")
|
||||||
@ -397,6 +468,30 @@ class Audio:
|
|||||||
else:
|
else:
|
||||||
await self.bot.say("There are no local playlists.")
|
await self.bot.say("There are no local playlists.")
|
||||||
|
|
||||||
|
@_list.command(name="sfx", pass_context=True)
|
||||||
|
async def list_sfx(self, ctx):
|
||||||
|
msgs = ["Available local sound effects: \n\n```\n"]
|
||||||
|
files = self.get_local_sfx()
|
||||||
|
m = 0
|
||||||
|
maxm = 1980
|
||||||
|
if files:
|
||||||
|
for i, d in enumerate(files.keys()):
|
||||||
|
if len(d) < maxm: #how did you get a filename this large?
|
||||||
|
if len(msgs[m]) + len(d) > maxm:
|
||||||
|
msgs[m] += "```"
|
||||||
|
m += 1
|
||||||
|
msgs.append("```\n")
|
||||||
|
if i % 4 == 0 and i != 0:
|
||||||
|
msgs[m] += d + "\n"
|
||||||
|
else:
|
||||||
|
msgs[m] += d + "\t"
|
||||||
|
msgs[m] += "```"
|
||||||
|
for msg in msgs:
|
||||||
|
await self.bot.send_message(ctx.message.author, msg)
|
||||||
|
await asyncio.sleep(1)
|
||||||
|
else:
|
||||||
|
await self.bot.say("There are no local sound effects.")
|
||||||
|
|
||||||
@_list.command(name="queue", pass_context=True)
|
@_list.command(name="queue", pass_context=True)
|
||||||
async def list_queue(self, ctx):
|
async def list_queue(self, ctx):
|
||||||
queue_list = await self.queue_titles()
|
queue_list = await self.queue_titles()
|
||||||
@ -427,10 +522,14 @@ class Audio:
|
|||||||
async def audioset(self, ctx):
|
async def audioset(self, ctx):
|
||||||
"""Changes audio module settings"""
|
"""Changes audio module settings"""
|
||||||
if ctx.invoked_subcommand is None:
|
if ctx.invoked_subcommand is None:
|
||||||
|
server = ctx.message.server
|
||||||
await send_cmd_help(ctx)
|
await send_cmd_help(ctx)
|
||||||
msg = "```"
|
msg = "```"
|
||||||
for k, v in self.settings.items():
|
for k, v in self.settings.items():
|
||||||
msg += str(k) + ": " + str(v) + "\n"
|
if type(v) is dict and server.id in v:
|
||||||
|
msg += str(k) + ": " + str(v[server.id]) + "\n"
|
||||||
|
else:
|
||||||
|
msg += str(k) + ": " + str(v) + "\n"
|
||||||
msg += "```"
|
msg += "```"
|
||||||
await self.bot.say(msg)
|
await self.bot.say(msg)
|
||||||
|
|
||||||
@ -471,6 +570,22 @@ class Audio:
|
|||||||
else:
|
else:
|
||||||
await self.bot.say("Volume must be between 0 and 1. Example: 0.40")
|
await self.bot.say("Volume must be between 0 and 1. Example: 0.40")
|
||||||
|
|
||||||
|
@audioset.command(name="sfx", pass_context=True, no_pm=True)
|
||||||
|
async def _sfx(self, ctx):
|
||||||
|
"""Enables/Disables sound effects usage in the server"""
|
||||||
|
#default on.
|
||||||
|
server = ctx.message.server
|
||||||
|
if server.id not in self.settings["SERVER_SFX_ON"]:
|
||||||
|
self.settings["SERVER_SFX_ON"][server.id] = True
|
||||||
|
else:
|
||||||
|
self.settings["SERVER_SFX_ON"][server.id] = not self.settings["SERVER_SFX_ON"][server.id]
|
||||||
|
#for a toggle, settings should save here in case bot fails to send message
|
||||||
|
fileIO("data/audio/settings.json", "save", self.settings)
|
||||||
|
if self.settings["SERVER_SFX_ON"][server.id]:
|
||||||
|
await self.bot.say("Sound effects are now enabled on this server.")
|
||||||
|
else:
|
||||||
|
await self.bot.say("Sound effects are now disabled on this server.")
|
||||||
|
|
||||||
@audioset.command()
|
@audioset.command()
|
||||||
@checks.is_owner()
|
@checks.is_owner()
|
||||||
async def maxcache(self, size : int):
|
async def maxcache(self, size : int):
|
||||||
@ -537,7 +652,12 @@ class Audio:
|
|||||||
await asyncio.sleep(1)
|
await asyncio.sleep(1)
|
||||||
if self.downloader["ID"]:
|
if self.downloader["ID"]:
|
||||||
try:
|
try:
|
||||||
if self.music_player.is_playing(): self.music_player.stop()
|
# sfx_player should only ever get stuck as much as music_player does
|
||||||
|
# when it happens to music_player, the reponsibility is put on the user to !stop
|
||||||
|
# so we'll do the same with sfx_player. a timeout could be placed here though.
|
||||||
|
while self.sfx_player.is_playing():
|
||||||
|
await asyncio.sleep(.5)
|
||||||
|
if not self.music_player.is_done(): self.music_player.stop()
|
||||||
self.music_player = self.bot.voice.create_ffmpeg_player(path + self.downloader["ID"], options='''-filter:a "volume={}"'''.format(self.settings["VOLUME"]))
|
self.music_player = self.bot.voice.create_ffmpeg_player(path + self.downloader["ID"], options='''-filter:a "volume={}"'''.format(self.settings["VOLUME"]))
|
||||||
self.music_player.paused = False
|
self.music_player.paused = False
|
||||||
self.music_player.start()
|
self.music_player.start()
|
||||||
@ -815,6 +935,9 @@ class EmptyPlayer(): #dummy player
|
|||||||
def is_playing(self):
|
def is_playing(self):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
def is_done(self):
|
||||||
|
return True
|
||||||
|
|
||||||
class MaximumLength(Exception):
|
class MaximumLength(Exception):
|
||||||
def __init__(self, m):
|
def __init__(self, m):
|
||||||
self.message = m
|
self.message = m
|
||||||
@ -822,7 +945,7 @@ class MaximumLength(Exception):
|
|||||||
return self.message
|
return self.message
|
||||||
|
|
||||||
def check_folders():
|
def check_folders():
|
||||||
folders = ("data/audio", "data/audio/cache", "data/audio/playlists", "data/audio/localtracks")
|
folders = ("data/audio", "data/audio/cache", "data/audio/playlists", "data/audio/localtracks", "data/audio/sfx")
|
||||||
for folder in folders:
|
for folder in folders:
|
||||||
if not os.path.exists(folder):
|
if not os.path.exists(folder):
|
||||||
print("Creating " + folder + " folder...")
|
print("Creating " + folder + " folder...")
|
||||||
@ -830,7 +953,7 @@ def check_folders():
|
|||||||
|
|
||||||
def check_files():
|
def check_files():
|
||||||
|
|
||||||
default = {"VOLUME" : 0.5, "MAX_LENGTH" : 3700, "QUEUE_MODE" : True, "MAX_CACHE" : 0, "SOUNDCLOUD_CLIENT_ID": None, "TITLE_STATUS" : True}
|
default = {"VOLUME" : 0.5, "MAX_LENGTH" : 3700, "QUEUE_MODE" : True, "MAX_CACHE" : 0, "SOUNDCLOUD_CLIENT_ID": None, "TITLE_STATUS" : True, "SERVER_SFX_ON" : {}}
|
||||||
settings_path = "data/audio/settings.json"
|
settings_path = "data/audio/settings.json"
|
||||||
|
|
||||||
if not os.path.isfile(settings_path):
|
if not os.path.isfile(settings_path):
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user