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

os.remove("roxbot/cache/{}".format(file)) 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 volume_perms():
def predicate(ctx): def predicate(ctx):
gs = guild_settings.get(ctx.guild) gs = guild_settings.get(ctx.guild)
# Suppress noise about console usage from errors # Suppress noise about console usage from errors
youtube_dl.utils.bug_reports_message = lambda: '' youtube_dl.utils.bug_reports_message = lambda: ''



ytdl_format_options = { ytdl_format_options = {
'format': 'bestaudio/best', 'format': 'bestaudio/best',
'outtmpl': './roxbot/cache/%(extractor)s-%(id)s-%(title)s.%(ext)s', 'outtmpl': './roxbot/cache/%(extractor)s-%(id)s-%(title)s.%(ext)s',


# Setup variables and then add dictionary entries for all guilds the bot can see on boot-up. # Setup variables and then add dictionary entries for all guilds the bot can see on boot-up.
self.bot = bot self.bot = bot
self.refresh_rate = 1/60 # 60hz
self._volume = {} self._volume = {}
self.playlist = {} # All audio to be played self.playlist = {} # All audio to be played
self.skip_votes = {} self.skip_votes = {}
self.now_playing[guild.id] = None self.now_playing[guild.id] = None
self.queue_logic[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): async def _queue_logic(self, ctx):
"""Background task designed to help the bot move on to the next video in the queue""" """Background task designed to help the bot move on to the next video in the queue"""
sleep_for = 0.5
try: try:
while ctx.voice_client.is_playing() or ctx.voice_client.is_paused(): 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: except AttributeError:
pass # This is to stop any errors appearing if the bot suddenly leaves voice chat. pass # This is to stop any errors appearing if the bot suddenly leaves voice chat.
self.now_playing[ctx.guild.id] = None self.now_playing[ctx.guild.id] = None
self.skip_votes[ctx.guild.id] = [] self.skip_votes[ctx.guild.id] = []
if self.playlist[ctx.guild.id] and ctx.voice_client: if self.playlist[ctx.guild.id] and ctx.voice_client:
player = self.playlist[ctx.guild.id].pop(0) 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): def _queue_song(self, ctx, video, stream):
"""Fuction to queue up a video into the playlist.""" """Fuction to queue up a video into the playlist."""
def _generate_np_embed(self, guild, playing_status): def _generate_np_embed(self, guild, playing_status):
np = self.now_playing[guild.id] np = self.now_playing[guild.id]
title = "{0}: '{1.title}' from {1.host}".format(playing_status, np) 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 = 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) embed.description = "Uploaded by: [{0.uploader}]({0.uploader_url})\nURL: [Here]({0.webpage_url})\nDuration: {1}\nQueued by: {0.queued_by}".format(np, duration)
embed.set_footer(text="{}/{} | Volume: {}%".format(time_played, duration, int(self.now_playing[guild.id].volume*100))) embed.set_footer(text="{}/{} | Volume: {}%".format(time_played, duration, int(self.now_playing[guild.id].volume*100)))
return embed 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() @roxbot.checks.is_admin_or_mod()
@commands.command() @commands.command()
async def join(self, ctx, *, channel: discord.VoiceChannel = None): async def join(self, ctx, *, channel: discord.VoiceChannel = None):
await channel.connect() await channel.connect()
return await ctx.send("Joined {0.name} :ok_hand:".format(channel)) 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.cooldown(1, 0.5, commands.BucketType.guild)
@commands.command(aliases=["yt"]) @commands.command(aliases=["yt"])
async def play(self, ctx, *, url, stream=False, from_queue=False, queued_by=None): async def play(self, ctx, *, url, stream=False, from_queue=False, queued_by=None):
data = dict(video) data = dict(video)
video = data["entries"].pop(0) video = data["entries"].pop(0)
for entry in data["entries"]: 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": elif 'entries' in video and video.get("extractor_key") == "YoutubeSearch":
video = video["entries"][0] video = video["entries"][0]


await ctx.send(embed=embed) await ctx.send(embed=embed)
else: else:
# Queue the song as there is already a song playing or paused. # 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 # 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: 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) embed = discord.Embed(description='Added "{}" to queue'.format(video.get("title")), colour=roxbot.EmbedColours.pink)
await ctx.send(embed=embed) await ctx.send(embed=embed)




@play.before_invoke @play.before_invoke
@stream.before_invoke @stream.before_invoke
@play_local.before_invoke
async def ensure_voice(self, ctx): 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.""" """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: if ctx.voice_client is None:

Loading…
Cancel
Save