async def preload_song(self, ctx: commands.Context) -> None: """ Preload of the next song. :param ctx: :return: """ try: if self.guilds[ctx.guild.id].song_queue.qsize() == 0: return i = 0 for item in self.guilds[ctx.guild.id].song_queue.queue: item: Song if item.stream: continue backup_title: str = str(item.title) if item.link is not None: try: type_of_source = Url.determine_source(item.link) if type_of_source == Url.youtube_url: youtube_dict = await self.parent.youtube.youtube_url( item.link, ctx.guild.id) elif type_of_source == Url.soundcloud_track: youtube_dict = await self.parent.soundcloud.soundcloud_track( item.link) else: continue except BasicError: self.parent.log( logging_manager.debug_info(traceback.format_exc())) continue youtube_dict.user = item.user else: if item.title: continue try: youtube_dict = await self._search_song(ctx, item) except BasicError: continue youtube_dict.user = item.user j: int = 0 for _song in self.guilds[ctx.guild.id].song_queue.queue: _song: Song if _song.title != backup_title: j += 1 continue self.guilds[ ctx.guild.id].song_queue.queue[j] = Song.copy_song( youtube_dict, self.guilds[ctx.guild.id].song_queue.queue[j], ) break break i += 1 except IndexError: pass except AttributeError: traceback.print_exc()
def test_song_copy(self): """ Test Song Copy @return: """ a = Song(title="Test1", image_url="fest1", duration=1) b = Song(image_url="kalb53") c = Song.copy_song(a, b) self.assertEqual(c.title, "Test1") self.assertEqual(c.image_url, "kalb53") self.assertEqual(c.duration, 1)
async def preload_song(self, ctx): """ Preload of the next song. :param ctx: :return: """ try: if self.parent.guilds[ctx.guild.id].song_queue.qsize() > 0: i = 0 for item in self.parent.guilds[ctx.guild.id].song_queue.queue: item: Song if item.stream is None: backup_title: str = str(item.title) if item.link is not None: youtube_dict = await self.parent.youtube.youtube_url( item.link, ctx.guild.id) youtube_dict.user = item.user else: if item.title is not None: youtube_dict = await self.parent.youtube.youtube_term( item) else: youtube_dict = await self.parent.youtube.youtube_term( item) youtube_dict.user = item.user j: int = 0 for _song in self.parent.guilds[ ctx.guild.id].song_queue.queue: _song: Song if _song.title == backup_title: self.parent.guilds[ ctx.guild. id].song_queue.queue[j] = Song.copy_song( youtube_dict, self.parent.guilds[ ctx.guild.id].song_queue.queue[j], ) break j -= -1 break i += 1 except IndexError: pass except AttributeError as e: traceback.print_exc()
async def player(self, ctx, small_dict): if isinstance(small_dict, Error): error_message = small_dict.reason await self.parent.send_error_message(ctx, error_message) if error_message in (Errors.no_results_found, Errors.default): await self.parent.guilds[ ctx.guild.id].now_playing_message.message.delete() return small_dict = Song.copy_song( await self.parent.youtube.youtube_url(small_dict.link, ctx.guild.id), small_dict, ) if isinstance(small_dict, Error): self.parent.log.error(small_dict.reason) await self.parent.send_error_message(ctx, small_dict.reason) return try: self.parent.guilds[ctx.guild.id].now_playing = small_dict if self.parent.guilds[ctx.guild.id].voice_client is None: return volume = getattr( self.parent.guilds[ctx.guild.id], "volume", await self.parent.mongo.get_volume(ctx.guild.id), ) if small_dict.codec == "opus": self.parent.log.debug("Using OPUS Audio.") # source = await FFmpegOpusAudioB.from_probe( # small_dict.stream, # volume=volume, # before_options="-reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 5", # commented, because of spamming messages of failed reconnects. # ) else: # only used for backup soundcloud atm self.parent.log.debug("Using PCM Audio.") # source = PCMVolumeTransformerB( # FFmpegPCMAudioB( # small_dict.stream, # before_options="-reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 5", # ), # volume=volume, # ) try: small_dict.guild_id = ctx.guild.id self.parent.guilds[ctx.guild.id].voice_client.play( small_dict # source, # after=lambda error: self.song_conclusion(ctx, error=error), ) self.parent.guilds[ctx.guild.id].voice_client.set_after( self.song_conclusion, ctx, error=None) except discord.ClientException: if ctx.guild.voice_client is None: if (self.parent.guilds[ctx.guild.id].voice_channel is not None): self.parent.guilds[ ctx.guild. id].voice_client = await self.parent.guilds[ ctx.guild.id ].voice_channel.connect(timeout=10, reconnect=True) small_dict.guild_id = ctx.guild.id self.parent.guilds[ctx.guild.id].voice_client.play( small_dict, # after=lambda error: self.song_conclusion( # ctx, error=error # ), ) self.parent.guilds[ ctx.guild.id].voice_client.set_after( self.song_conclusion, ctx, error=None) full, empty = await self.parent.mongo.get_chars(ctx.guild.id) self.parent.guilds[ ctx.guild.id].now_playing_message = NowPlayingMessage( ctx=ctx, message=self.parent.guilds[ ctx.guild.id].now_playing_message.message, song=self.parent.guilds[ctx.guild.id].now_playing, full=full, empty=empty, discord_music=self.parent, voice_client=self.parent.guilds[ctx.guild.id].voice_client, ) await self.parent.guilds[ctx.guild.id].now_playing_message.send() except (Exception, discord.ClientException) as e: self.parent.log.debug( logging_manager.debug_info(traceback.format_exc(e)))
async def pre_player(self, ctx, bypass=None): if (self.parent.guilds[ctx.guild.id].song_queue.qsize() > 0 or bypass is not None): if bypass is None: small_dict = await self.parent.guilds[ctx.guild.id ].song_queue.get() else: small_dict = bypass self.parent.guilds[ ctx.guild.id].now_playing_message = NowPlayingMessage( message=await self.parent.send_embed_message(ctx=ctx, message=" Loading ... ", delete_after=None), ctx=ctx, ) if small_dict.stream is None: if small_dict.link is not None: # url _type = Url.determine_source(small_dict.link) if _type == Url.youtube: youtube_dict = Song.copy_song( await self.parent.youtube.youtube_url( small_dict.link, ctx.guild.id), small_dict, ) elif _type == Url.soundcloud: youtube_dict = Song.copy_song( await self.parent.soundcloud.soundcloud_track( small_dict.link), small_dict, ) else: self.parent.log.warning("Incompatible Song Type: " + _type) return else: if small_dict.title is None: self.parent.log.warning(small_dict) # term youtube_dict = Song.copy_song( await self.parent.youtube.youtube_term(small_dict), small_dict, ) if isinstance(youtube_dict, Error): if youtube_dict.reason != Errors.error_please_retry: await self.parent.send_error_message( ctx, youtube_dict.reason) await self.parent.guilds[ ctx.guild.id].now_playing_message.message.delete() await self.pre_player(ctx) return await self.parent.guilds[ ctx.guild.id].now_playing_message.message.delete() await self.pre_player(ctx, bypass=small_dict) return youtube_dict.user = small_dict.user youtube_dict.image_url = small_dict.image_url await self.player(ctx, youtube_dict) if hasattr(youtube_dict, "title"): asyncio.ensure_future( self.parent.mongo.append_most_played( youtube_dict.title)) if hasattr(youtube_dict, "loadtime"): asyncio.ensure_future( self.parent.mongo.append_response_time( youtube_dict.loadtime)) else: await self.player(ctx, small_dict) if hasattr(small_dict, "title"): asyncio.ensure_future( self.parent.mongo.append_most_played(small_dict.title)) if hasattr(small_dict, "loadtime"): asyncio.ensure_future( self.parent.mongo.append_response_time( small_dict.loadtime)) asyncio.ensure_future(self.preload_song(ctx=ctx))
async def pre_player(self, ctx: commands.Context, bypass=None) -> None: """ Routine called before a song gets played. @param ctx: @param bypass: @return: """ guild_id = ctx.guild.id if self.guilds[guild_id].song_queue.qsize() > 0 or bypass is not None: if bypass is None: small_dict = await self.guilds[ctx.guild.id].song_queue.get() else: small_dict = bypass if small_dict.stream is None: try: if small_dict.link is not None: # url _type = Url.determine_source(small_dict.link) if _type == Url.youtube: youtube_dict = Song.copy_song( await self.parent.youtube.youtube_url( small_dict.link, ctx.guild.id), small_dict, ) elif _type == Url.soundcloud: youtube_dict = Song.copy_song( await self.parent.soundcloud.soundcloud_track( small_dict.link), small_dict, ) else: self.parent.log.warning( f"Incompatible Song Type: {_type}") return else: if small_dict.title is None: self.parent.log.warning(small_dict) # term youtube_dict = Song.copy_song( await self._search_song(ctx, small_dict), small_dict) except NoResultsFound: await self.parent.send_error_message( ctx, Errors.no_results_found) self.guilds[guild_id].unlock_queue() await self.pre_player(ctx) return except SongExtractionException: await self.parent.send_error_message( ctx, Errors.youtube_video_not_available) self.guilds[guild_id].unlock_queue() await self.pre_player(ctx) return except (BasicError, asyncio.TimeoutError) as basic_error: if str(basic_error) != Errors.error_please_retry: await self.parent.send_error_message( ctx, str(basic_error)) self.guilds[guild_id].unlock_queue() await self.pre_player(ctx) return return await self.pre_player(ctx, bypass=small_dict) youtube_dict.user = small_dict.user youtube_dict.image_url = small_dict.image_url await self.player(ctx, youtube_dict) # add stats to website if hasattr(youtube_dict, "title"): asyncio.ensure_future( self.parent.mongo.append_most_played( youtube_dict.title)) if hasattr(youtube_dict, "loadtime"): asyncio.ensure_future( self.parent.mongo.append_response_time( youtube_dict.loadtime)) else: await self.player(ctx, small_dict) if hasattr(small_dict, "title"): asyncio.ensure_future( self.parent.mongo.append_most_played(small_dict.title)) if hasattr(small_dict, "loadtime"): asyncio.ensure_future( self.parent.mongo.append_response_time( small_dict.loadtime)) asyncio.ensure_future(self.preload_song(ctx=ctx))