Browse Source

fixed most of the bugs in voice hopefully. Deleted some useless functions and moved some stuff. Refresh rate upped to help queuing when it gets stuck. This should make it better for actually starting the next song. Bumping the refreshrate from 2Hz to 60Hz.

tags/v2.0.0
Roxie Gibson 5 years ago
parent
commit
00cf5b1707
1 changed files with 30 additions and 40 deletions
  1. +30
    -40
      roxbot/cogs/voice.py

+ 30
- 40
roxbot/cogs/voice.py View File

@@ -44,6 +44,21 @@ def _clear_cache():
os.remove("roxbot/cache/{}".format(file))


def _format_duration(duration):
"""Static method to turn the duration of a file (in seconds) into something presentable for the user"""
if not duration:
return duration
hours = duration // 3600
minutes = (duration % 3600) // 60
seconds = duration % 60
format_me = {"second": int(seconds), "minute": int(minutes), "hour": int(hours)}
formatted = datetime.time(**format_me)
output = "{:%M:%S}".format(formatted)
if formatted.hour >= 1:
output = "{:%H:}".format(formatted) + output
return output


def volume_perms():
def predicate(ctx):
gs = guild_settings.get(ctx.guild)
@@ -65,7 +80,6 @@ def volume_perms():
# Suppress noise about console usage from errors
youtube_dl.utils.bug_reports_message = lambda: ''


ytdl_format_options = {
'format': 'bestaudio/best',
'outtmpl': './roxbot/cache/%(extractor)s-%(id)s-%(title)s.%(ext)s',
@@ -133,6 +147,7 @@ class Voice:

# Setup variables and then add dictionary entries for all guilds the bot can see on boot-up.
self.bot = bot
self.refresh_rate = 1/60 # 60hz
self._volume = {}
self.playlist = {} # All audio to be played
self.skip_votes = {}
@@ -147,34 +162,26 @@ class Voice:
self.now_playing[guild.id] = None
self.queue_logic[guild.id] = None

@staticmethod
def _format_duration(duration):
"""Static method to turn the duration of a file (in seconds) into something presentable for the user"""
if not duration:
return duration
hours = duration // 3600
minutes = (duration % 3600) // 60
seconds = duration % 60
format_me = {"second": int(seconds), "minute": int(minutes), "hour": int(hours)}
formatted = datetime.time(**format_me)
output = "{:%M:%S}".format(formatted)
if formatted.hour >= 1:
output = "{:%H:}".format(formatted) + output
return output
async def on_guild_join(self, guild):
"""Makes sure that when the bot joins a guild it won't need to reboot for the music bot to work."""
self.playlist[guild.id] = []
self.skip_votes[guild.id] = []
self.am_queuing[guild.id] = False
self.now_playing[guild.id] = None
self.queue_logic[guild.id] = None

async def _queue_logic(self, ctx):
"""Background task designed to help the bot move on to the next video in the queue"""
sleep_for = 0.5
try:
while ctx.voice_client.is_playing() or ctx.voice_client.is_paused():
await asyncio.sleep(sleep_for)
await asyncio.sleep(self.refresh_rate)
except AttributeError:
pass # This is to stop any errors appearing if the bot suddenly leaves voice chat.
self.now_playing[ctx.guild.id] = None
self.skip_votes[ctx.guild.id] = []
if self.playlist[ctx.guild.id] and ctx.voice_client:
player = self.playlist[ctx.guild.id].pop(0)
await ctx.invoke(self.play, url=player, stream=player.get("stream", False), from_queue=True, queue_by=player.get("queued_by", None))
await ctx.invoke(self.play, url=player, stream=player.get("stream", False), from_queue=True, queued_by=player.get("queued_by", None))

def _queue_song(self, ctx, video, stream):
"""Fuction to queue up a video into the playlist."""
@@ -186,8 +193,8 @@ class Voice:
def _generate_np_embed(self, guild, playing_status):
np = self.now_playing[guild.id]
title = "{0}: '{1.title}' from {1.host}".format(playing_status, np)
duration = self._format_duration(np.duration)
time_played = self._format_duration(np.source.timer/1000)
duration = _format_duration(np.duration)
time_played = _format_duration(np.source.timer/1000)

embed = discord.Embed(title=title, colour=roxbot.EmbedColours.pink, url=np.webpage_url)
embed.description = "Uploaded by: [{0.uploader}]({0.uploader_url})\nURL: [Here]({0.webpage_url})\nDuration: {1}\nQueued by: {0.queued_by}".format(np, duration)
@@ -196,14 +203,6 @@ class Voice:
embed.set_footer(text="{}/{} | Volume: {}%".format(time_played, duration, int(self.now_playing[guild.id].volume*100)))
return embed

async def on_guild_join(self, guild):
"""Makes sure that when the bot joins a guild it won't need to reboot for the music bot to work."""
self.playlist[guild.id] = []
self.skip_votes[guild.id] = []
self.am_queuing[guild.id] = False
self.now_playing[guild.id] = None
self.queue_logic[guild.id] = None

@roxbot.checks.is_admin_or_mod()
@commands.command()
async def join(self, ctx, *, channel: discord.VoiceChannel = None):
@@ -222,14 +221,6 @@ class Voice:
await channel.connect()
return await ctx.send("Joined {0.name} :ok_hand:".format(channel))

@commands.command(hidden=True, enabled=False)
async def play_local(self, ctx, *, query):
"""Plays a file from the local filesystem."""
source = discord.PCMVolumeTransformer(discord.FFmpegPCMAudio(query))
ctx.voice_client.play(source, after=lambda e: print('Player error: %s' % e) if e else None)

await ctx.send('Now playing: {}'.format(query))

@commands.cooldown(1, 0.5, commands.BucketType.guild)
@commands.command(aliases=["yt"])
async def play(self, ctx, *, url, stream=False, from_queue=False, queued_by=None):
@@ -257,7 +248,7 @@ class Voice:
data = dict(video)
video = data["entries"].pop(0)
for entry in data["entries"]:
await self._queue_song(ctx, entry, stream)
self._queue_song(ctx, entry, stream)
elif 'entries' in video and video.get("extractor_key") == "YoutubeSearch":
video = video["entries"][0]

@@ -286,11 +277,11 @@ class Voice:
await ctx.send(embed=embed)
else:
# Queue the song as there is already a song playing or paused.
await self._queue_song(ctx, video, stream)
self._queue_song(ctx, video, stream)

# Sleep because if not, queued up things will send first and probably freak out users or something
while self.am_queuing[guild.id] is True:
await asyncio.sleep(0.5)
await asyncio.sleep(self.refresh_rate)
embed = discord.Embed(description='Added "{}" to queue'.format(video.get("title")), colour=roxbot.EmbedColours.pink)
await ctx.send(embed=embed)

@@ -303,7 +294,6 @@ class Voice:

@play.before_invoke
@stream.before_invoke
@play_local.before_invoke
async def ensure_voice(self, ctx):
"""Ensures the bot is in a voice channel before continuing and if it cannot auto join, raise an error."""
if ctx.voice_client is None:

Loading…
Cancel
Save