def after_play(error): if loop == 'loop' and not self._stop_loop: try: ctx.message.guild.voice_client.play( discord.FFmpegOpusAudio(song), after=after_play) except: pass elif self._playlist: try: next_song = self.music_path + self._playlist[0] coroutine = self.changestatus(ctx, self._playlist[0][:-5]) run_coroutine_threadsafe(coroutine, self.client.loop).result() self._playlist.pop(0) ctx.message.guild.voice_client.play( discord.FFmpegOpusAudio(next_song), after=after_play) except: print('Error in playlist') elif not self.is_stopped: coroutine = self.stop(ctx) future = run_coroutine_threadsafe(coroutine, self.client.loop) try: future.result() except: print( f'Disconnect has failed. Run {self.prefix}stop manually', error)
async def get(self): if self.downloaded: return discord.FFmpegOpusAudio(os.path.join(self.path, self.filename + ".opus")) else: await self._run_ytdl() if self._file_exists(): return discord.FFmpegOpusAudio(os.path.join(self.path, self.filename + ".opus")) raise RuntimeError("Failed to download.")
def create_source(self, vid): # create audio source logger.info('Creating audio source') if vid['acodec'] == 'opus': source = discord.FFmpegOpusAudio(vid['url'], codec='copy') else: source = discord.FFmpegOpusAudio(vid['url']) return source
async def playurl(ctx,url): voice_channel = ctx.author.voice.channel if voice_channel != None: await ctx.reply(f"Playing `{url}`") vc = await voice_channel.connect() if "youtube.com" in url or "youtu.be" in url: ytdlpopen = subprocess.Popen(["youtube-dl","--quiet","-o","-",url],stdout=subprocess.PIPE) vc.play(discord.FFmpegOpusAudio(ytdlpopen.stdout,pipe=True)) else: vc.play(discord.FFmpegOpusAudio(url)) while vc.is_playing(): await asyncio.sleep(0.1) await vc.disconnect()
async def play(self, message, url, called_internally=False): if message.channel.id != self.music_text_channel_id: return await message.channel.send( f'{message.author.mention}, {DISALLOW_MESSAGE}') data = None with youtube_dl.YoutubeDL({}) as ydl: data = ydl.extract_info(url, download=False) await self.bot.change_presence( activity=discord.Activity(type=discord.ActivityType.listening, name=data['title'], url=url, small_image_url=data['thumbnail'])) # If this was called by a normal user, add the song to the queue, and bail if we're currently playing if not called_internally: self.queue.append(QueueItem(message, url, data)) if len(self.queue) > 1: return await message.channel.send("Song added to the queue.") await asyncio.get_event_loop().run_in_executor(None, self._download, url) channel = discord.utils.find( lambda channel: channel.id == self.music_voice_channel_id, message.guild.voice_channels) try: await channel.connect() except discord.errors.ClientException: pass def finish_playing(error): # It's possible that we interrupted playing, and that this hook still gets called if self.queue: self.queue.pop(0) try: os.remove(SONG_FILENAME) except: pass if self.queue: coro = self.play(self.queue[0].message, self.queue[0].url, called_internally=True) asyncio.run_coroutine_threadsafe(coro, self.bot.loop) else: coro = voice.disconnect() asyncio.run_coroutine_threadsafe(coro, self.bot.loop) coro = self.bot.change_presence(status=discord.Status.online, activity=None) asyncio.run_coroutine_threadsafe(coro, self.bot.loop) voice = discord.utils.get(self.bot.voice_clients, guild=message.guild) voice.play(discord.FFmpegOpusAudio(SONG_FILENAME, bitrate=128), after=finish_playing) voice.is_playing() return await message.reply( f"😸 🎵 **Now playing:** *{data['title']}* 🎵")
def playlistLoop(self): server_id = self.ctx.guild.id logger.info( f'Server: {server_id}. Start playing thread: {threading.current_thread().getName()}' ) def my_after(error): self.eventNextTrack.set() while not self.stopSignal: self.eventStartLoop.wait() logger.debug(f'Server: {server_id}. Start loop') while not self.stopSignal and self.playlist.getLength( ) > 0 and self.voice.is_connected(): mi = self.playlist.next() self.eventNextTrack.clear() self.voice.play(discord.FFmpegOpusAudio(mi.filepath), after=my_after) asyncio.run_coroutine_threadsafe( self.ctx.send(embed=Server.generate_embed(mi)), Server_loop).result() self.eventNextTrack.wait() logger.debug(f'Server: {server_id}. Next track') logger.debug(f'Server: {server_id}. Stop loop') self.eventStartLoop.clear() logger.info(f'Server: {server_id}. Playing thread died')
async def play_audio(self, ctx, audio_file, queue_message=True): def update_queue(): if self.audio_queue: try: if not self.audio_repeat: self.audio_queue.pop(0) else: self.audio_queue.append(self.audio_queue.pop(0)) audio_source = discord.FFmpegOpusAudio( self.audio_queue[0][0]) print(f'playing {self.audio_queue[0][1]}') ctx.voice_client.play(audio_source, after=lambda e: update_queue()) except: print('queue is now empty') if not ctx.voice_client: await self.join_voice(ctx) self.audio_queue.append(audio_file) if not ctx.voice_client.is_playing() and len(self.audio_queue) == 1: audio_source = discord.FFmpegOpusAudio(audio_file[0]) await ctx.channel.send(f'Playing {audio_file[1]}') ctx.voice_client.play(audio_source, after=lambda e: update_queue()) elif queue_message: await ctx.channel.send(f'adding {audio_file[1]} to queue')
async def play_next(self): # Plays the next song in the queue # Get next song from queue try: self.playing = self.queue.get_nowait() except asyncio.QueueEmpty: # Nothing in queue, no need to play next self.playing = None await self.disconnect_from_voice() return if not self._voice_client: connected = await self.connect_to_voice(self.playing.channel) elif self._voice_client.channel != self.playing.channel: # Switch channel to new one await self.disconnect_from_voice() connected = await self.connect_to_voice(self.playing.channel) else: # Already connected to old channel connected = True # Create audio stream, then play it on voice client if connected: stream = discord.FFmpegOpusAudio(self.playing.path, options=self.playing.ffmpegopts) self._voice_client.play(stream, after=self.song_ended) else: # Couldn't play song, so treat as if song has ended self.song_ended()
async def regex_interrupt(self, path): # Pause current stream, store it in a stack, play regex self._voice_client.pause() self._prev_source.append(self._voice_client.source) new_source = discord.FFmpegOpusAudio(_AUDIO_DIR + path) self._voice_client.source = new_source self._voice_client.resume()
async def play(ctx, url: str): ''' Проигрывание аудиодорожки с использование youtube ''' song = os.path.isfile('song.webm') try: if song: os.remove('song.webm') except PermissionError: await ctx.send('Дождитесь окончания текущий аудиодорожки, или используйте команду $stop') return voiceChannel = discord.utils.get(ctx.guild.voice_channels, name='Основной') await voiceChannel.connect() voice = discord.utils.get(bot.voice_clients, guild=ctx.guild) ydl_opts ={ 'format': '249/250/251', 'key': 'FFmpegExtractAudio', 'preferredcodec': 'webm', 'preferredquality': '192', } with youtube_dl.YoutubeDL(ydl_opts) as ydl: ydl.download([url]) for file in os.listdir("./"): if file.endswith(".webm"): os.rename(file, "song.webm") voice.play(discord.FFmpegOpusAudio("song.webm"))
async def play(self, ctx, *args): if ctx.voice_client: if args: try: await download_youtube.download(args[0], DOWNLOAD_PATH, ctx.guild) except Exception as e: await ctx.send(f'Error: {e}') return # Might use this later if I add a volume command # source = discord.PCMVolumeTransformer( # discord.FFmpegPCMAudio( # f'{DOWNLOAD_PATH}/{ctx.guild}.webm', # options='-vn' # ) # ) ctx.voice_client.play( discord.FFmpegOpusAudio(f'{DOWNLOAD_PATH}/{ctx.guild}.webm'), # source, after=lambda e: ctx.voice_client.stop()) else: if ctx.voice_client.is_paused(): ctx.voice_client.resume() else: await ctx.send('You must provide a Youtube URL')
def play_next(self, e, filename): os.remove(filename) if self.queue: filename = self.queue.pop(0) self.vc.play(discord.FFmpegOpusAudio(filename), after=lambda e: self.play_next(e, filename)) if self.loop: self.queue.append(filename)
def nightcoreify(rate, link): ydl_opts = { "format": "bestaudio", "postprocessors": [ { "key": "FFmpegExtractAudio", "preferredcodec": "opus", "preferredquality": "128", } ], } with tempfile.NamedTemporaryFile(dir=TEMP_DIR) as t: filename = str(t.name) + "_ytdl.opus" ydl_opts = {"format": "bestaudio", "outtmpl": filename} with youtube_dl.YoutubeDL(ydl_opts) as ydl: ydl.download([link]) source = discord.FFmpegOpusAudio( filename, options=f"-filter_complex [0:a:0]volume=0.15,asetrate={rate}*48k,aresample=resampler=soxr:precision=24:osf=s32:tsf=s32p:osr=48k[out] -map [out]", ) return source, filename
async def playURL(ctx, url: str): if not ctx.message.author.voice: await ctx.send("You need to be in a voice channel to do this.") return else: channel = ctx.message.author.voice.channel song_there = os.path.isfile("song.webm") try: if song_there: os.remove("song.webm") except PermissionError: await ctx.send("Permission Error!") return voiceChannel = discord.utils.get(ctx.guild.voice_channels, name=channel.name) voice = discord.utils.get(client.voice_clients, guild=ctx.guild) if not (voice and voice.is_connected()): await voiceChannel.connect() RV = discord.utils.get(client.voice_clients, guild=ctx.guild) ydl_opts = {'format': '249/250/251'} with youtube_dl.YoutubeDL(ydl_opts) as ydl: ydl.download([url]) for file in os.listdir("./"): if file.endswith(".webm"): os.rename(file, "song.webm") try: RV.play(discord.FFmpegOpusAudio("song.webm")) except: await ctx.send( "Please wait for the song to finish, or use the clear command to clear the bot. This bot can only take 1 song at a time for now. Queue is on the to-do list." ) return
async def _play_music(message, voice_client, guild_state, skip=False): if guild_state.requested_skip: guild_state.requested_skip = False return if len(guild_state.playlist) == 0: await stop_bot(voice_client, message.guild.id) return guild_state.requested_skip = skip music = guild_state.playlist.pop(0) guild_state.now_playing = music source = discord.FFmpegOpusAudio( music.stream_url, codec=music.acodec, before_options= "-reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 5", ) def after_finished(err): # TODO: Fix non stopping bug. asyncio.run_coroutine_threadsafe( _play_music(message, voice_client, guild_state), voice_client.loop) embed = music.get_embed() # embed.remove_field(1) await message.channel.send("Now Playing", embed=embed) if voice_client.is_playing(): voice_client.stop() voice_client.play(source, after=after_finished)
async def play(ctx, arg): global queue_map if discord.utils.get(bot.voice_clients, guild=ctx.guild) is None: await join(ctx) q = queue_map.get(discord.utils.get(bot.voice_clients, guild=ctx.guild)) # try: # os.remove('song.m4a') # except FileNotFoundError: # pass name = ''.join(choices(string.ascii_uppercase + string.digits, k=6)) params = { 'outtmpl': 'song_' + name + '.m4a', 'format': 'bestaudio/best', 'postpreocessors': [{ 'key': 'FFmpegExtractAudio', 'preferredcodec': 'opus', 'prefferedquality': 128, }], } title = yt.YoutubeDL(params).extract_info(arg, download=False).get( "title", None) yt.YoutubeDL(params).download([arg]) filename = 'song_' + name + '.m4a' if len(q) == 0: q.append([filename, title]) voice = discord.utils.get(bot.voice_clients, guild=ctx.guild) audio = discord.FFmpegOpusAudio(filename, bitrate=160) voice.play(audio) await ctx.send("Now playing: " + title) else: await ctx.send("Added " + title + " to the queue!") q.append([filename, title])
def play_MP3(message, inputText, file_name): if not inputText: return creat_MP3(inputText, file_name) source = discord.FFmpegOpusAudio(file_name) message.guild.voice_client.play(source) time.sleep(MP3(file_name).info.length + 0.5)
async def write_countdown_msg(self, msg, text_channel, voice_client, is_last=False): """ TODO: Find a way how to load single strema into memory and then reuse it. instead of loading it from file every time. """ dirname = os.path.dirname(__file__) audio_source = discord.FFmpegOpusAudio( os.path.join( dirname, 'media/high_pitch.mp3' if is_last else 'media/low_pitch.mp3')) if not (msg is None or msg == ''): await text_channel.send(content=msg) if voice_client.is_playing(): voice_client.stop() voice_client.play(audio_source) await asyncio.sleep(1) audio_source.cleanup()
async def VoicePlay(self, ctx, audiopath): if (ctx.message.channel.type is discord.ChannelType.private): embed=discord.Embed(title="Error!", description="This command only works on servers!", color=0xff0000) return await ctx.message.channel.send(embed=embed) guild = ctx.guild author = ctx.message.author voice_channel = author.voice.channel try: vc = await voice_channel.connect() except: vc = guild.voice_client audio_source = discord.FFmpegOpusAudio(audiopath) if not vc.is_playing(): vc.play(audio_source, after=None) else: embed=discord.Embed(title="Error!", description="Something is already playing, please wait!", color=0xff0000) return await ctx.message.channel.send(embed=embed) while vc.is_playing(): await asyncio.sleep(1) await vc.disconnect()
async def play(ctx, *arg): if ctx.message.author.voice: print("play") query = "" for word in arg: query += word + " " query = query.rstrip() print("searching for " + query + ", ", end="") s = Search(query) yt = s.results[0] print("found " + str(s.results[0]) + ", ", end="") stream = yt.streams.get_audio_only() stream.download(filename="music.mp4") print("downloaded " + str(stream)) channel = ctx.message.author.voice.channel vc = await channel.connect() url = "https://www.youtube.com/watch?v=" + str(yt)[41:-1] await ctx.send("playing: " + url) vc.play(discord.FFmpegOpusAudio(source="music.mp4")) await asyncio.sleep(yt.length) await vc.disconnect()
async def on_message(self, message: discord.Message): """You know what it is""" channel: discord.TextChannel = message.channel if ( simple_message_compare(message, "everybody") or simple_message_compare(message, "rock your body") or simple_message_compare(message, "am I original?") or simple_message_compare(message, "am I the only one?") or simple_message_compare(message, "am I sexual?") ): await channel.send("yeaaaaaaahh :raised_hands:") return if simple_message_compare( message, "backstreet's back" ) or simple_message_compare(message, "backstreet's back alright"): message_futures = asyncio.gather( channel.send("ALRIGHT!!!"), channel.send( "https://tenor.com/view/backstreet-boys-bsb-dance-gif-15271760" ), ) # they're not in a voice channel, just await the messages, since we have no where to play music to if message.author.voice is None: await message_futures return # create a voice client if it doesn't exist vc: Optional[discord.VoiceClient] = discord.utils.find( lambda vc: vc.channel == message.author.voice.channel, self.bot.voice_clients, ) if vc is None: vc = await message.author.voice.channel.connect() # play!!! also the song shouldn't restart if it's already playing, so people can sing along :) if not vc.is_playing(): vc.play( discord.FFmpegOpusAudio(BACKSTREET_BOYS_OPUS_PATH), after=after_disconnect_voice_client(vc, loop=self.bot.loop), ) # and don't forget to wait the messages! I didn't await earlier, because I want it all triggers ASAP await message_futures return # if anyone in the channel says stop, then stop playing music! if ( simple_message_compare(message, "stop") or simple_message_compare(message, "stop please") or simple_message_compare(message, "please stop") ): for vc in self.bot.voice_clients: if vc.is_playing(): vc.stop() await asyncio.gather(*(vc.disconnect() for vc in self.bot.voice_clients)) return
async def play(self, ctx, name): if ctx.guild.voice_client is not None and ctx.author.voice is not None: if ctx.author.voice.channel == ctx.guild.voice_client.channel: b = ctx.voice_client c = self.ytdl.extract_info(url=name, download=False) if 'entries' in c: c = c['entries'][0] if b.is_playing() or b.is_paused(): b.stop() b.play(discord.FFmpegOpusAudio(c['url']), after=lambda e: print('Player error: %s' % e) if e else None) await self.embed_maker(ctx=ctx, ytdl_info=c) else: print(ctx.voice_client.channel) await ctx.voice_client.move_to(ctx.author.voice.channel) # Seems like the `await` doesn't actually wait until it finishes before calling stuff below, oddly. # This `sleep` line ensures that the bot will move before b is defined and all the other stuff happens. # I mean, its not like Discord bots need to be *that* fast, right? await asyncio.sleep(2) b = ctx.voice_client # b = discord.utils.get(self.client.voice_clients, guild=ctx.guild) print(b.channel) c = self.ytdl.extract_info(url=name, download=False) if 'entries' in c: c = c['entries'][0] if b.is_playing() or b.is_paused(): b.stop() b.play(discord.FFmpegOpusAudio(c['url']), after=lambda e: print('Player error: %s' % e) if e else None) await self.embed_maker(ctx=ctx, ytdl_info=c) elif ctx.author.voice is not None: b = await ctx.author.voice.channel.connect() await self.embed_maker( ctx=ctx, ytdl_info=self.ytdl.extract_info(url=name, download=False) if 'entries' not in self.ytdl.extract_info(url=name, download=False) else self.ytdl.extract_info(url=name, download=False)['entries'][0]) b.play(discord.FFmpegOpusAudio( self.ytdl.extract_info(url=name, download=False)['url']), after=lambda e: print('Player error: %s' % e) if e else None) else: await ctx.reply('You are not connected to a voice channel')
def play(self): if self.queue[0]['format']['format_name'] == 'opus': self._voice.play(discord.FFmpegOpusAudio(self.queue[0]['path'], **self.options), after=self.next) else: self._voice.play(discord.FFmpegPCMAudio(self.queue[0]['path'], **self.options), after=self.next)
async def queue_sound(ctx: Context, *search_terms: str): search_url = "https://freesound.org/apiv2/search/text/" terms = [] for term in search_terms: terms.append(re.sub(r'[\W]', '', term)) if not terms: return query_params = { 'query': f'"{" ".join(terms)}"', 'filter': 'duration:[5 TO 10]', 'page_size': '50', 'fields': 'previews', 'token': os.getenv('FREESOUND_TOKEN'), 'sort': 'rating_desc', } try: async with aiohttp.ClientSession() as session: async with session.get(search_url, params=query_params) as response: if response.status == 401: await ctx.send( "Freesound doesn't like your token. Too bad! 😿") return response.raise_for_status() response_json = await response.json() count = response_json['count'] if not count: await ctx.send( "That's so sad. There is no good sound for this 😿") return sound_index = random.randint(0, min(count, 20) - 1) sound_url = response_json['results'][sound_index]['previews'][ 'preview-lq-mp3'] # passing the URL directly results in a delay between the bot joining and sound playing async with aiohttp.ClientSession() as session: async with session.get(sound_url) as response: response.raise_for_status() sound_data = await response.read() sound_file = TemporaryFile(dir=sounds_dir.name) sound_file.write(sound_data) sound_file.seek(0) source = discord.FFmpegOpusAudio(source=sound_file, pipe=True, options='-filter:a loudnorm') player = SoundPlayer.get_or_create(ctx.guild) await player.play(source, ctx.author.voice.channel) except requests.RequestException: await ctx.send("Sorry, I'm having troubles doing what you asked 😿") return
def play_dir(self, path: str): files = [os.path.abspath(p) for p in glob.glob(path + "/*")] for fp in files: print("fp: ", fp) self.vc.play(discord.FFmpegOpusAudio( source=fp, options='-filter:a "volume=-10dB"'), after=lambda e: print('done', e)) while self.vc.is_playing() or self.vc.is_paused(): time.sleep(1)
async def play(ctx, audio_file, pitchFactor=1.0, speedFactor=1.0): os.system("process.py {} {} {}".format(audio_file, pitchFactor, speedFactor)) guild = ctx.guild existing_client = discord.utils.get(bot.voice_clients, guild=guild) if not existing_client: existing_client = connect(ctx) audio_source = discord.FFmpegOpusAudio("out.mp3") await existing_client.play(audio_source)
def on_voice_activity(self): try: roll = random.randint(1, self.probability) logging.debug(f'rolled a {roll}') if roll == 1: herm_num = random.randint(1, self.num_herms) self.voice_client.play( discord.FFmpegOpusAudio(f'herms/{herm_num}.ogg')) except Exception as e: logging.error(e, exc_info=True)
async def play_song(self, song_info, server, filename=None): #creates file if filename == None: filename = await YTDLSource.from_url(song_info['url'], loop=self.bot.loop) #plays file server.voice_client.play( discord.FFmpegOpusAudio(executable="ffmpeg.exe", source=f"{filename}")) #adds filename to currently_playing so it can be deleted later self.currently_playing[server] = filename
def play_all(self, path: str): files = [os.path.abspath(p) for p in glob.glob(path + "/*")] last = files.pop(-1) print(last) befor = "-i " + " -i ".join(files) print(befor) self.vc.play(discord.FFmpegOpusAudio( source=last, before_options=befor, options='-filter:a "volume=-10dB"'), after=lambda e: print('done', e))
async def _handle_play(self, item, client): future = asyncio.Future() loop = asyncio.get_event_loop() def after(*args): loop.call_soon_threadsafe(future.set_result, args) client.play(discord.FFmpegOpusAudio(os.path.expanduser(item)), after=after) callback_args = await future return callback_args