Пример #1
0
    def play_song(self, client: VoiceClient, url):
        if not client.is_connected():
            return
        song_there = os.path.isfile("song.mp3")
        try:
            if song_there:
                os.remove("song.mp3")
        except PermissionError:
            print('error')
            return
        print("Someone wants to play music let me get that ready for them...")
        ydl_opts = {
            'format': 'bestaudio/best',
            'postprocessors': [{
                'key': 'FFmpegExtractAudio',
                'preferredcodec': 'mp3',
                'preferredquality': '192',
            }],
        }
        with youtube_dl.YoutubeDL(ydl_opts) as ydl:
            ydl.download([url])
        for file in os.listdir("./"):
            if file.endswith(".mp3"):
                os.rename(file, 'song.mp3')

        def after_playing(err):
            song = self.get_next_song()
            print(song, self.playlist)
            self.play_song(client, song)

        client.play(discord.FFmpegPCMAudio("song.mp3"), after=after_playing)
        client.volume = 100
Пример #2
0
async def play_forever(vc: discord.VoiceClient):
    event = asyncio.Event()
    while vc.is_connected():
        audio = discord.FFmpegPCMAudio('resources/shame.mp3')
        vc.play(audio, after=lambda _: event.set())
        await event.wait()
        event.clear()
Пример #3
0
 def callback(self, client: discord.VoiceClient,
              queue: collections.deque) -> None:
     """Handle callbacks after the voice client finishes playing."""
     if not client.is_connected():
         queue.clear()
     elif queue:
         now = queue.popleft()
         client.play(now, after=lambda e: self.callback(client, queue))
Пример #4
0
    async def play_with(self, voice_client: discord.VoiceClient):
        fname = self.get_filename()
        source = await discord.FFmpegOpusAudio.from_probe(fname)
        voice_client.play(source)

        print(f"Played {self.sound_name} ({fname}) in "
              f"{voice_client.channel.name} ({voice_client.guild.name})")

        return fname
Пример #5
0
async def _stream_media(voice_client: discord.VoiceClient, loop: asyncio.BaseEventLoop, source: YTDLSource):
    """Method which starts the streaming and playback of the provided URL.

    Args:
        voice_client (discord.VoiceClient): The voice client used by the bot.
        source (YTDLSource): Audio source which contains the audio stream.
    """

    future = loop.create_future() if loop else asyncio.get_event_loop().create_future()
    voice_client.play(source, after=lambda e: future.set_result(e))

    try:
        await asyncio.wait_for(future, timeout=None)
        error = future.result()
        if error:
            log.error("Player error: %s", error)
    except asyncio.TimeoutError:
        log.error("Player error: Timeout for song playback has been reached.")
Пример #6
0
    async def next_track(self, voice_client: VoiceClient):
        """Play next track"""

        if voice_client is None:
            self.cleanup()
            return

        if not voice_client.is_connected():
            self.cleanup()
            return

        if voice_client.is_connected() and self.queue:
            source = self.queue.pop(0)
            await source.load_source()
            voice_client.play(source,
                              after=lambda error: self.on_track_end(
                                  source, error, voice_client))
            self.on_track_start(audio_source=source)
Пример #7
0
 async def play(self, voice_channel:discord.VoiceClient, channel:discord.VoiceChannel):
     while len(self.playlist[channel.id]) != 0:
         file = self.playlist[channel.id][0]
         if not voice_channel.is_connected():
             await voice_channel.connect(reconnect=True)
         self.playing[channel.id] = voice_channel
         voice_channel.play(discord.FFmpegPCMAudio(executable=self.ffmpeg, source=file),
                             after=None)
         while voice_channel.is_playing():
             if self.playing[channel.id] == None:
                 voice_channel.stop()
                 await voice_channel.disconnect()
                 self.playlist[channel.id].clear()
                 return
             await asyncio.sleep(0.05)
         if file[:3] == 'tmp':
             fileManager.delete_file(file)
         self.playlist[channel.id].pop(0)
     self.playing[channel.id] = None
Пример #8
0
def player_play(vc: discord.VoiceClient, m: str):

    global nc
    global mQueue
    global isPlay

    ret = ""

    if m == "#play" or m == "#p":

        # 再開
        if vc.is_paused():
            vc.resume()
            ret = "Resuming!"

    # キュー追加
    elif m.find("https://www.nicovideo.jp/watch/") >= 0:

        ret = "add `{0}`".format(mQueue.addQueue(m.split(" ")[1]))

        # 新規再生
        if not vc.is_playing():

            if mQueue.popQueue() == mQueue.notPlaying:
                return
            src = nc.getVideo(mQueue.nowPlaying["url"])

            while os.path.getsize(src) < 256:
                pass

            vc.play(discord.FFmpegPCMAudio(src))
            vc.source = discord.PCMVolumeTransformer(vc.source)
            vc.source.volume = 0.1

            if not isPlay:
                isPlay = True
                t1 = threading.Thread(target=playcheck, args=(vc, 0))
                t1.start()

            ret = "Play {0}".format(mQueue.now())

    return ret
Пример #9
0
def playcheck(vc: discord.VoiceClient, dummy):
    global isPlay
    global nc
    global mQueue

    if isPlay:
        print("start")

    while isPlay:
        if vc.is_paused() == False:
            time.sleep(0.5)
            if vc.is_playing() == False:
                if mQueue.popQueue() != mQueue.notPlaying:
                    src = nc.getVideo(mQueue.nowPlaying["url"])
                    while os.path.getsize(src) < 128:
                        pass

                    vc.play(discord.FFmpegPCMAudio(src))
                    vc.source = discord.PCMVolumeTransformer(vc.source)
                    vc.source.volume = 0.1
                    isPlay = True
Пример #10
0
    def play_song(self,
                  voice_client: discord.VoiceClient,
                  channel: discord.VoiceChannel = None) -> None:
        """
        Plays the first song in the playlist queue.

        :param voice_client: The discord VoiceClient that the bot should play into.
        :param channel: A channel to connect to if the bot is currently not in one.
        :return: None
        """
        try:
            print(self.playlist)
            source = discord.FFmpegOpusAudio(
                self.playlist[0],
                options={'use_wallclock_as_timestamps': True})
            voice_client.play(source, after=self.play_after)
            self.playlist.pop(0)
            self.current_song_playing = self.playlist_data.pop(0)
            self.song_started_at = datetime.datetime.now()
        except discord.errors.ClientException as e:
            if 'Not connected to voice' in str(e):
                channel.connect()
Пример #11
0
 async def create_player(self, voice_client: discord.VoiceClient):
     await self.download()
     if self.location:
         audio_source = discord.FFmpegPCMAudio(self.location)
         if not voice_client.is_playing():
             voice_client.play(audio_source)
Пример #12
0
    async def queue_task(self, ctx: commands.Context,
                         voice_client: discord.VoiceClient):
        # 왜인지는 모르겠는데 매우 불안정하네요.
        while voice_client.is_connected():
            if ctx.guild.id not in self.queues.keys():
                if voice_client.is_playing():
                    voice_client.stop()
                break
            try:
                is_loop = bool(self.queues[ctx.guild.id]["playing"]["loop"])
                is_shuffle = bool(
                    self.queues[ctx.guild.id]["playing"]["random"])
            except KeyError:
                is_loop = False
                is_shuffle = False
            if not voice_client.is_playing() and not voice_client.is_paused(
            ) and (not is_loop and len(self.queues[ctx.guild.id]) <= 1):
                break
            if voice_client.is_playing() or voice_client.is_paused():
                await asyncio.sleep(1)
                continue
            print(self.queues)
            song_id_list = [
                x for x in self.queues[ctx.guild.id].keys() if x != "playing"
            ]
            next_song_id = (
                sorted(song_id_list)[0] if not is_shuffle else
                random.choice(song_id_list)) if not is_loop else "playing"
            print(next_song_id)
            next_song = self.queues[ctx.guild.id][next_song_id].copy()
            embed = discord.Embed(
                title="유튜브 음악 재생 - 재생 시작",
                description=
                f"업로더: [`{next_song['vid_author']}`]({next_song['vid_channel_url']})\n"
                f"제목: [`{next_song['vid_title']}`]({next_song['vid_url']})",
                color=discord.Color.red(),
                timestamp=datetime.datetime.now(
                    tz=datetime.timezone(datetime.timedelta(hours=9))))
            embed.set_footer(text=str(next_song['req_by']),
                             icon_url=next_song['req_by'].avatar_url)
            embed.set_image(url=next_song['thumb'])
            voice_client.play(
                discord.FFmpegPCMAudio(next_song["tgt_url"],
                                       before_options=get_youtube.before_args))
            voice_client.source = discord.PCMVolumeTransformer(
                voice_client.source)
            voice_client.source.volume = self.queues[
                ctx.guild.id]["playing"]["vol"]

            await ctx.send(embed=embed)

            if not is_loop:
                for k, v in next_song.items():
                    self.queues[ctx.guild.id]["playing"][k] = v
                del self.queues[ctx.guild.id][next_song_id]

            await asyncio.sleep(1)

        if ctx.guild.id in self.queues.keys():
            del self.queues[ctx.guild.id]
        if voice_client.is_connected():
            await voice_client.disconnect()
        await ctx.send(
            f"대기열이 비어있고 모든 노래를 재생했어요. `{voice_client.channel}`에서 나갈께요.")
Пример #13
0
 async def play_next_queued(self, voice_client: discord.VoiceClient):
     if voice_client is None or not voice_client.is_connected():
         return
     await asyncio.sleep(0.5)
     guild_document = await self.guild_document_from_guild(
         voice_client.guild)
     guild_queued = guild_document.get("queue", [])
     if len(guild_queued) == 0:
         # await voice_client.disconnect()
         return
     if guild_document.get("loop", False):
         next_song_url = guild_queued[0]
     else:
         next_song_url = guild_queued.pop(0)
     await self.music_db.songs.update_one({"_id": voice_client.guild.id},
                                          {'$set': {
                                              "queue": guild_queued
                                          }},
                                          upsert=True)
     local_ffmpeg_options = ffmpeg_options.copy()
     resume_from = 0
     if type(next_song_url) == tuple or type(next_song_url) == list:
         next_song_url, resume_from = next_song_url
         local_ffmpeg_options['options'] = "-vn -ss {}".format(resume_from)
     volume_document = await self.bot.mongo.find_by_id(
         self.music_db.volumes, voice_client.guild.id)
     volume = volume_document.get("volume", 0.5)
     if next_song_url is None:
         self.bot.loop.create_task(self.play_next_queued(voice_client))
         return
     next_song_url = await self.transform_single_song(next_song_url)
     if next_song_url is None:
         self.bot.loop.create_task(self.play_next_queued(voice_client))
         return
     data = await YTDLSource.get_video_data(next_song_url, self.bot.loop)
     source = YTDLSource(discord.FFmpegPCMAudio(data["url"],
                                                **local_ffmpeg_options),
                         data=data,
                         volume=volume,
                         resume_from=resume_from)
     if voice_client.guild.id in self.tts_cog.guild_queues:
         while len(self.tts_cog.guild_queues[voice_client.guild.id]) > 0:
             await asyncio.sleep(0.1)
     while voice_client.is_playing():
         await asyncio.sleep(0.1)
     voice_client.play(source,
                       after=lambda e: self.bot.loop.create_task(
                           self.play_next_queued(voice_client)))
     title = await self.title_from_url(next_song_url)
     embed = self.bot.create_completed_embed(
         "Playing next song!",
         "Playing **[{}]({})**".format(title, next_song_url))
     thumbnail_url = await self.thumbnail_from_url(next_song_url)
     if thumbnail_url is not None:
         embed.set_thumbnail(url=thumbnail_url)
     text_channel_id = guild_document.get("text_channel_id", None)
     if text_channel_id is None:
         print("text channel id is none")
         return
     # noinspection PyTypeChecker
     called_channel = self.bot.get_channel(text_channel_id)
     history = await called_channel.history(limit=1).flatten()
     print("sending message")
     if len(history) > 0 and history[0].author.id == self.bot.user.id:
         old_message = history[0]
         if len(old_message.embeds) > 0:
             if old_message.embeds[0].title == "Playing next song!":
                 await old_message.edit(embed=embed)
                 return
     await called_channel.send(embed=embed)
Пример #14
0
 async def _play_stream(self, audio_source: AudioSource,
                        voice_client: VoiceClient):
     voice_client.play(audio_source)
Пример #15
0
async def queue_task(bot: CustomClient, ctx: commands.Context,
                     voice: discord.VoiceClient):
    while True:
        exists = os.path.isfile(f"music/{ctx.guild.id}.json")
        if not exists:
            await ctx.send(f"`{voice.channel}`에서 나갈께요.")
            await voice.disconnect(force=True)
            break
        queue = await get_queue(ctx.guild.id)
        if voice.is_playing() or voice.is_paused():
            await asyncio.sleep(1)
            continue
        elif not voice.is_playing() and len(
                queue.keys()) == 1 and queue["playing"]["loop"] is not True:
            await ctx.send(f"음악이 끝났어요. `{voice.channel}`에서 나갈께요.")
            await voice.disconnect(force=True)
            os.remove(f"music/{ctx.guild.id}.json")
            break
        vol = queue["playing"]["vol"]
        if queue["playing"]["loop"] is True:
            tgt_url = queue["playing"]["tgt_url"]
            voice.play(
                discord.FFmpegPCMAudio(tgt_url,
                                       before_options=get_youtube.before_args))
            voice.source = discord.PCMVolumeTransformer(voice.source)
            voice.source.volume = vol
            await asyncio.sleep(3)
            continue
        if queue["playing"]["random"]:
            queue_keys = [str(x) for x in queue.keys() if not x == "playing"]
            tgt_name = str(random.choice(queue_keys))
            tgt_queue = queue[tgt_name]
        else:
            tgt_name = list(queue.keys())[1]
            tgt_queue = queue[tgt_name]
        vid_url = tgt_queue["vid_url"]
        vid_title = tgt_queue["vid_title"]
        vid_author = tgt_queue["vid_author"]
        vid_channel_url = tgt_queue["vid_channel_url"]
        tgt_url = tgt_queue["tgt_url"]
        thumb = tgt_queue["thumb"]
        req_by = bot.get_user(int(tgt_queue["req_by"]))
        voice.play(
            discord.FFmpegPCMAudio(tgt_url,
                                   before_options=get_youtube.before_args))
        voice.source = discord.PCMVolumeTransformer(voice.source)
        voice.source.volume = vol
        embed = discord.Embed(title="유튜브 음악 재생",
                              color=discord.Colour.from_rgb(255, 0, 0))
        embed.add_field(
            name="재생 시작",
            value=
            f"업로더: [`{vid_author}`]({vid_channel_url})\n제목: [`{vid_title}`]({vid_url})",
            inline=False)
        embed.add_field(name="요청자",
                        value=f"{req_by.mention} (`{req_by}`)",
                        inline=False)
        embed.set_image(url=str(thumb))
        queue["playing"]["vid_url"] = vid_url
        queue["playing"]["vid_title"] = vid_title
        queue["playing"]["vid_author"] = vid_author
        queue["playing"]["vid_channel_url"] = vid_channel_url
        queue["playing"]["thumb"] = thumb
        queue["playing"]["tgt_url"] = tgt_url
        queue["playing"]["req_by"] = tgt_queue["req_by"]
        await ctx.send(embed=embed)
        del queue[tgt_name]
        await update_queue(ctx.guild.id, queue)
        await asyncio.sleep(3)