Example #1
0
async def hivivek(ctx):
    """Says hi vivek in the nearest voice channel"""
    try:
        await ctx.message.delete()



        ## now nav to parent group (if there is one, then first active voice channel)
        categoryid = ctx.channel.category_id
        category = ctx.guild.get_channel(categoryid)



        await ctx.send("@vivek hi")


        for channel in category.voice_channels:
            print('got channel', channel.name)
            voicething = await channel.connect()
            print('connected')
            tcardaudio = discord.PCMAudio(open("./hivivek/hivivek.wav", "rb"))
            print('setup sound')
            print('opus loaded')
            voicething.play(tcardaudio)
            print('playeded')
            while voicething.is_playing():
                time.sleep(1)
            await voicething.disconnect()


    except Exception as e:
        print('hivivek exception',type(e),e)
Example #2
0
    async def change_channel(self):
        try:
            selection = self.channels.currentData()
            self.mute.setText("Mute")
            self.setEnabled(False)

            if selection is not None:
                not_connected = (
                    self.voice is None
                    or self.voice is not None
                    and not self.voice.is_connected()
                )

                if not_connected:
                    self.voice = await selection.connect(timeout=10)
                else:
                    await self.voice.move_to(selection)

                not_playing = (
                    self.devices.currentData() is not None
                    and not self.voice.is_playing()
                )

                if not_playing:
                    self.voice.play(discord.PCMAudio(self.stream))

            else:
                if self.voice is not None:
                    await self.voice.disconnect()

        except Exception:
            logging.exception("Error on change_channel")

        finally:
            self.setEnabled(True)
Example #3
0
    async def generate_source(
            self, message: discord.Message,
            user_preference: UserVoicePreference,
            english_dict: dict) -> Optional[discord.PCMAudio]:
        read_name = all(
            (True if self.least_user != message.author.id else False,
             self.guild_preference.read_name))
        text = message.clean_content
        text = code_block_compiled.sub("", text)
        if read_name:
            if self.guild_preference.read_nick:
                text = message.author.display_name + "、" + text
            else:
                text = message.author.name + "、" + text
        text = self.escape_dictionary(text)
        sentences = english_compiled.findall(text)
        for sentence in sentences:
            if sentence.upper() in english_dict.keys():
                text = text.replace(sentence, english_dict[sentence.upper()])
        if len(text) > self.guild_preference.limit:
            text = text[:self.guild_preference.limit] + "、以下略"
        if not text:
            return None

        async with self.jtalk_lock:
            # async with self.voice_event_lock:
            self.jtalk.set_speed(user_preference.speed)
            self.jtalk.set_tone(user_preference.tone)
            self.jtalk.set_intone(user_preference.intone)
            self.jtalk.set_volume(user_preference.volume)
            r = await self.loop.run_in_executor(self.executor,
                                                partial(self.get_source, text))
            self.least_user = message.author.id
            return discord.PCMAudio(r)
Example #4
0
    async def change_channel(self):
        try:
            s_name = self.sv.get()
            c_name = self.cv.get()

            if c_name != 'None':
                guild = discord.utils.find(
                    lambda s: s.id == self.server_map[s_name].id,
                    self.bot.guilds)
                channel = discord.utils.find(
                    lambda c: c.id == self.channel_map[c_name].id,
                    guild.channels)

                self.disable_ui()

                if self.voice is None or self.voice is not None and not self.voice.is_connected(
                ):
                    self.voice = await channel.connect(timeout=10)
                else:
                    await self.voice.move_to(channel)

                if self.dv.get() != 'None' and not self.voice.is_playing():
                    self.voice.play(discord.PCMAudio(self.stream))

            else:
                if self.voice is not None:
                    await self.voice.disconnect()
                    self.voice = None

        except Exception:
            logging.exception('Error on change_channel')

        finally:
            self.enable_ui()
Example #5
0
async def play_audio(stream, channel_id):
    voice_channel = bot.get_channel(channel_id)
    print(f'- Dispatch audio to \'{voice_channel}\'')

    last_song_cache[str(channel_id)] = io.BytesIO(stream.getvalue())

    try:
        voice_client = await voice_channel.connect()
    except discord.ClientException:
        print(f'Cannot connect to channel {voice_channel}')
        return

    if voice_client.is_playing():
        print(f'Channel {voice_channel} is busy')
        return
    else:
        buffer = discord.PCMAudio(stream)
        voice_client.play(buffer)

        # this loop can probably be removed by using the 'after=' kwarg
        # of play() that is called when it finishes. however, that seems
        # to be very hard to get to work with async functions
        while voice_client.is_playing():
            await asyncio.sleep(1)

        await voice_client.disconnect()
Example #6
0
    async def change_channel(self):
        try:
            s_name = self.sv.get()
            c_name = self.cv.get()

            if (c_name != 'None'):
                guild = discord.utils.find(
                    lambda s: s.id == self.server_map[s_name].id,
                    self.bot.guilds)
                channel = discord.utils.find(
                    lambda c: c.id == self.channel_map[c_name].id,
                    guild.channels)

                if (self.voice is None):
                    self.voice = await channel.connect()
                else:
                    await self.voice.move_to(channel)

                if (self.dv.get() != 'None' and not self.voice.is_playing()):
                    self.voice.play(discord.PCMAudio(self.stream))

            else:
                if (self.voice is not None):
                    await self.voice.disconnect()
                    self.voice = None

        except:
            logging.exception('Error on change_channel')
Example #7
0
async def stream_to(voice_client, url, ctx):
    resp = requests.get(url, stream=True)

    # Gather information about stream
    station_name = resp.headers.get("icy-name", "unknown station")
    genre = resp.headers.get("icy-genre")
    stream_fmt = resp.headers.get("Content-Type")
    bitrate = int(resp.headers.get("icy-br", 0))
    samplerate = int(resp.headers.get("icy-sr", 0))
    audio_info = resp.headers.get("ice-audio-info")
    metaint = int(resp.headers.get("icy-metaint", 0))

    # Send information about stream
    desc = ""
    for category, value in zip(
        ["Genre", "Format", "Bitrate", "Samplerate", "Audio Info"],
        [genre, stream_fmt, bitrate, samplerate, audio_info]):
        if value:
            desc += f"{category}: {value}\n"

    embed = discord.Embed(title="Radio information:",
                          description=desc,
                          colour=ctx.author.colour.value or 0xff0)
    embed.set_author(name=f"Streaming from {station_name}",
                     icon_url=voice_client.user.avatar_url)
    await ctx.send(embed=embed)

    converter = (ffmpeg.input(url, re=None, loglevel="quiet").output(
        "pipe:1", format="s16le", ar='48k').run_async(pipe_stdout=True))
    voice_client.play(discord.PCMAudio(converter.stdout))
Example #8
0
 def play_empty(self):
     """Play blank audio to let Discord know we're still here"""
     if self.vclient:
         try:
             if self.vclient:
                 self.vclient.volume = 0
             self.vclient.play(discord.PCMAudio("\n".encode()))
         except discord.ClientException:
             pass
Example #9
0
 async def generate_default_source(self, text: str) -> discord.PCMAudio:
     async with self.voice_event_lock:
         self.jtalk.set_speed(1.0)
         self.jtalk.set_tone(0)
         self.jtalk.set_intone(1.0)
         self.jtalk.set_volume(-3.0)
         r = await self.loop.run_in_executor(self.executor,
                                             partial(self.get_source, text))
         self.least_user = None
         return discord.PCMAudio(r)
Example #10
0
async def tcard(ctx):
    """Raises a t-card in the current channel"""
    try:
        await ctx.message.delete()

        embedTcard = discord.Embed.from_dict({
        })
        embedTcard.set_image(url='http://geas.org.uk/wp-content/uploads/2020/08/tcard-1-e1597167776966.png')


        ## now nav to parent group (if there is one, then first active voice channel)
        categoryid = ctx.channel.category_id
        category = ctx.guild.get_channel(categoryid)

        ## try to find relevant role to @ rather than the @here cos on our server that gets the admins too, who are sick of it!
        atRole = None
        for role in category.changed_roles:
            if '@' in role.name:
                continue
            elif ' ' not in role.name:
                # make the wild assumption the relevant has a space in it
                continue
            elif not atRole or len(role.name)> len(atRole.name):
                # make the wild assuptiion that the role we want is the longest one, and has a space in it
                atRole = role


        if not atRole:
            atRole = '@here'
        else:
            atRole = atRole.mention





        await ctx.send("{} **T CARD T CARD T CARD T CARD**".format(atRole), embed=embedTcard)


        for channel in category.voice_channels:
            print('got channel', channel.name)
            voicething = await channel.connect()
            print('connected')
            tcardaudio = discord.PCMAudio(open("tcard.wav", "rb"))
            print('setup sound')
            print('opus loaded')
            voicething.play(tcardaudio)
            print('playeded')
            while voicething.is_playing():
                time.sleep(1)
            await voicething.disconnect()


    except Exception as e:
        print('tcard exception',type(e),e)
Example #11
0
    async def speak_content_in_channel(self, member, content):
        if member.voice is None or member.voice.channel is None:
            return

        voice_channel = member.voice.channel
        voices_in_guild = [x for x in self.bot.voice_clients if x.guild == voice_channel.guild]

        if len(voices_in_guild) > 0:
            voice_client = voices_in_guild[0]

            if voice_client.channel != voice_channel:
                await voice_client.disconnect()
                voice_client = await voice_channel.connect()

        else:
            voice_client = await voice_channel.connect()

        old_guild_document = await self.tts_db.settings.find_one({"_id": member.guild.id})

        if old_guild_document is None:
            old_guild_document = {"_id": member.guild.id, "speed": 1.0, "lang": "en", "tld": "com"}
            await self.bot.mongo.force_insert(self.tts_db.settings, old_guild_document)

        lang = old_guild_document.get("lang")
        speed = old_guild_document.get("speed")
        tld = old_guild_document.get("tld")

        with concurrent.futures.ProcessPoolExecutor() as pool:
            output = await self.bot.loop.run_in_executor(pool, partial(get_speak_file, content,
                                                                       lang, speed, tld))
        if member.guild.id not in self.guild_queues:
            async with self.queue_change_lock:
                self.guild_queues[member.guild.id] = []

        async with self.queue_change_lock:
            our_uid = self.uid
            self.uid += 1
            self.guild_queues[member.guild.id].append(our_uid)

        while voice_client.is_playing():
            await asyncio.sleep(0.05)

        while self.guild_queues[member.guild.id][0] != our_uid:
            await asyncio.sleep(0.05)

        try:
            voice_client.play(discord.PCMAudio(output))
        except discord.errors.ClientException:
            pass

        while voice_client.is_playing():
            await asyncio.sleep(0.05)

        self.guild_queues[member.guild.id].pop(0)
        return True
Example #12
0
 async def source(self, session):
     data = await fetch_voice_data(
         session=session,
         token=self.google_cloud_token,
         text=self.text,
         language_code=self.language,
         name=self.voice_setting.voice[self.language],
         rate=self.voice_setting.speed,
         pitch=self.voice_setting.pitch,
     )
     return discord.PCMAudio(io.BytesIO(audioop.tostereo(data, 2, 1, 1)))
Example #13
0
    def change_device(self, options, dv):
        try:
            if dv.get() != 'None':
                if self.voice is not None:
                    self.voice.stop()
                    self.stream.change_device(options.get(dv.get()))
                    self.voice.play(discord.PCMAudio(self.stream))
                else:
                    self.stream.change_device(options.get(dv.get()))

        except Exception:
            logging.exception('Error on change_device')
Example #14
0
 async def source(self, session):
     data = await fetch_voice_data(
         session=session,
         token=self.bot.google_cloud_token,
         text=self.text,
         language_code=LANGUAGES[self.language],
         name=convert_voice_name(LANGUAGES[self.language],
                                 self.voice_setting.voice[self.language]),
         rate=self.voice_setting.speed,
         pitch=self.voice_setting.pitch,
     )
     source = discord.PCMAudio(io.BytesIO(audioop.tostereo(data, 2, 1, 1)))
     return discord.PCMVolumeTransformer(source, volume=0.4)
Example #15
0
    async def _play(self, song):
        if song.stream is None:
            song.fetch_buffer()
        await self._join_channel(song.channel)
        await asyncio.sleep(2)
        source = discord.PCMVolumeTransformer(discord.PCMAudio(song.stream))
        source.volume = song.volume / 100
        song.channel.guild.voice_client.play(
            source,
            after=lambda e: self.bot.log.error("Player error: %s" % e) if e else None,
        )

        self.lastPlayed[song.channel.guild.id] = datetime.now()
Example #16
0
    async def create_source(
            self, attachment: discord.Attachment) -> discord.AudioSource:
        """
        Attachmentからdiscord.PCMAudioを作成します。

        :param attachment: 変換するアタッチメント
        :return: 出力するPCMAudio
        """
        raw = await attachment.read()

        data = await self.to_pcm(
            raw, "mp3" if attachment.filename.endswith(".mp3") else "wav")

        return discord.PCMVolumeTransformer(discord.PCMAudio(data), volume=0.8)
    async def _say(self, text: str, context: Union[commands.Context, SlashContext], voice_channel, language, text_to_speech_input=None):

        # Get text-to-speech data
        text_to_speech_bytes = await self._get_text_to_speech(text_to_speech_input, language=language)

        # Check if we got valid text-to-speech data
        if text_to_speech_bytes.getbuffer().nbytes <= 0:
            await context.send('There was a problem generating the text-to-speech!')
            return

        # Join the voice channel
        try:
            await self._guild_locks[context.guild].acquire()
            voice_client = await self._join_voice_channel(voice_channel)
        except InsufficientPermissionsException as e:
            self._guild_locks[context.guild].release()
            await context.send(
                f'I don\'t have permission to join your voice channel! Please grant me the following permissions: ' + ', '.join(f'`{x}`' for x in e.permissions) + '.')
            return

        # Temporary fix for (https://github.com/TychoTheTaco/Discord-Dictionary-Bot/issues/1)
        await asyncio.sleep(2.5)

        # Send text chat reply
        await context.send(text)

        # Create a callback to be invoked when the bot is finished playing audio
        def after(error):

            # A nested async function is used here to ensure that the bot leaves the voice channel before releasing the associated locks
            async def after_coroutine(error):

                if error is not None:
                    logger.error(f'An error occurred while playing audio: {error}')

                # Update voice channel map
                self._voice_channels[voice_channel] -= 1

                # Disconnect from the voice channel if we don't need it anymore
                if self._voice_channels[voice_channel] <= 0:
                    await self._leave_voice_channel(voice_channel)

                self._guild_locks[context.guild].release()

            asyncio.run_coroutine_threadsafe(after_coroutine(error), self._bot.loop)

        # Speak
        voice_client.play(discord.PCMAudio(text_to_speech_bytes), after=after)
Example #18
0
    def change_device(self):
        try:
            selection = self.devices.currentData()
            self.mute.setText("Mute")

            if self.voice is not None:
                self.voice.stop()
                self.stream.change_device(selection)

                if self.voice.is_connected():
                    self.voice.play(discord.PCMAudio(self.stream))

            else:
                self.stream.change_device(selection)

        except Exception:
            logging.exception("Error on change_device")
Example #19
0
    async def tts(self, message, stripped, server):
        # command: espeak --stdout "hello world" | ffmpeg -i pipe:0 out.ogg
        caller = message.author
        guild = message.guild

        if 'off' not in server.roles and not caller.guild_permissions.manage_guild:
            for role in caller.roles:
                if role.id in server.roles:
                    break
            else:
                await channel.send(
                    'You aren\'t allowed to do this. Please tell a moderator to do `{}roles` to set up permissions'
                    .format(server.prefix))
                return

        if caller.voice is None:
            await channel.send('You aren\'t in a voice channel.')

        elif not caller.voice.channel.permissions_for(guild.me).connect:
            await channel.send('No permissions to connect to channel.')

        else:
            try:
                voice = await caller.voice.channel.connect()
            except discord.errors.ClientException:
                voice = [
                    v for v in self.voice_clients if v.channel.guild == guild
                ][0]
                if voice.channel != caller.voice.channel:
                    await voice.disconnect()
                    voice = await caller.voice.channel.connect()

            if voice.is_playing():
                voice.stop()

            s = subprocess.Popen(
                ['pico2wave', '-w', 'stdout.wav', '"{}"'.format(stripped)],
                stdout=subprocess.PIPE)
            s2 = subprocess.Popen([
                'ffmpeg', '-i', '-', '-f', 's16le', '-ar', '48000', '-ac', '2',
                '-loglevel', 'warning', 'pipe:1'
            ],
                                  stdin=s.stdout,
                                  stdout=subprocess.PIPE)

            voice.play(discord.PCMAudio(s2.stdout))
Example #20
0
async def connect(bot, stream, device_id, channel_id, token):
    try:
        print('Connecting...')
        await bot.wait_until_ready()
        print(f'Logged in as {bot.user.name}')

        channel = bot.get_channel(channel_id)
        stream.change_device(device_id)

        voice = await channel.connect()
        voice.play(discord.PCMAudio(stream))

        print(f'Playing audio in {channel.name}')

    except Exception:
        logging.exception('Error on cli connect')
        sys.exit(1)
Example #21
0
async def on_voice_state_update(member, old_state, new_state):
    # Don't send messages about ourself!
    if member.id == client.user.id:
        return

    # Has the user moved channel?
    new_channel = new_state.channel
    old_channel = old_state.channel
    if old_channel == new_channel:
        return

    # Check if the bot needs to change channel.
    guild = (old_channel and old_channel.guild) or (new_channel
                                                    and new_channel.guild)
    assert (guild)
    await update_bot_channel(guild)
    if not guild.voice_client:
        return

    voice_client = guild.voice_client

    # Build a message based on the change.
    message = None
    lang = None
    if new_channel == voice_client.channel:
        lang, hello = get_synonym('Hello', member.display_name)
        message = f'{hello} {member.display_name}!'
        if member.display_name == 'James':
            message = message + ' I was so worried!'
    elif old_channel == voice_client.channel:
        lang, goodbye = get_synonym('Goodbye', member.display_name)
        message = f'{goodbye} {member.display_name}!'

    # Send the text-to-speech message, or queue it if the bot is already speaking.
    if message:
        stream = BytesIO(text_to_pcm(message, lang))
        stream.seek(
            64
        )  # Hack: skip the first couple of frames to fix an audible pop...
        audio_stream = discord.PCMAudio(stream)
        if voice_client.is_playing():
            message_queue.append(audio_stream)
        else:
            voice_client.play(audio_stream,
                              after=partial(after_play_finished, guild))
Example #22
0
async def connect(bot, device_id, channel_id):
    try:
        print("Connecting...")
        await bot.wait_until_ready()
        print(f"Logged in as {bot.user.name}")

        stream = sound.PCMStream()
        channel = bot.get_channel(channel_id)
        stream.change_device(device_id)

        voice = await channel.connect()
        voice.play(discord.PCMAudio(stream))

        print(f"Playing audio in {channel.name}")

    except Exception:
        logging.exception("Error on cli connect")
        sys.exit(1)
Example #23
0
    async def loop(self):
        try:
            while not self.bot.is_closed():
                req = await self.queue.get()

                if not await self.bot.firestore.spend_char(
                        req.guild.id, len(req.text)):
                    await self.text_channel.send(
                        "申し訳ございません。今月の利用可能文字数を超えてしまいました。"
                        "\nまだご利用になりたい場合は、公式サイトより文字数を購入してください。")
                    await self.close(force=True)
                    return

                await req.convert_username(self.before_user_id)
                data = await request_tts(self.bot.access_token, self.session,
                                         req)
                self.before_user_id = req.message.author.id
                while self.voice_client.is_playing():
                    await asyncio.sleep(0.5)
                await asyncio.sleep(0.2)

                source = discord.PCMAudio(
                    io.BytesIO(audioop.tostereo(data, 2, 1, 1)))
                self.voice_client.play(source)

        except asyncio.exceptions.CancelledError:
            pass

        except audioop.error as e:
            import traceback
            traceback.print_exc()
            await self.bot.error(e)
            await self.text_channel.send('内部エラーが発生しました。再接続してください。')
            await self.close(force=True)

        except Exception as e:
            import traceback
            traceback.print_exc()
            await self.bot.error(e)
            await self.text_channel.send('内部エラーが発生しました。再接続してください。')
            await self.close(force=True)
Example #24
0
async def on_voice_state_update(member, old_state, new_state):
    # Don't send messages about ourself or any other bots!
    if member.bot:
        return

    # Has the user moved channel?
    new_channel = new_state.channel
    old_channel = old_state.channel
    if old_channel == new_channel:
        return

    # Check if the bot needs to change channel.
    guild = (old_channel and old_channel.guild) or (new_channel
                                                    and new_channel.guild)
    assert (guild)
    await update_bot_channel(guild)
    if not voice_client:
        return

    # Build a message based on the change. Treat 'afk' channel as if user disconnected.
    message = None
    lang = None
    if new_channel == voice_client.channel:
        lang, hello = get_synonym('Hello')
        message = f'{hello} {member.display_name}!'
    elif old_channel == voice_client.channel:
        lang, goodbye = get_synonym('Goodbye')
        message = f'{goodbye} {member.display_name}!'

    if member.display_name == 'James':
        message = message + ' we were so worried!'

    # Send the text-to-speech message, or queue it if the bot is already speaking.
    if message and voice_client:
        audio_stream = discord.PCMAudio(BytesIO(text_to_pcm(message)))
        if voice_client.is_playing():
            message_queue.append(audio_stream)
        else:
            voice_client.play(audio_stream, after=after_play_finished)
Example #25
0
async def on_voice_state_update(member, old_state, new_state):
    # Don't send messages about ourself or any other bots!
    if member.bot:
        return

    # Has the user moved channel?
    new_channel = new_state.channel
    old_channel = old_state.channel
    if old_channel == new_channel:
        return

    # Check if the bot should go to the new channel.
    guild = (old_channel and old_channel.guild) or (new_channel
                                                    and new_channel.guild)
    assert (guild)
    await update_bot_channel(guild)

    # Build a message based on the change. Treat 'afk' channel as if user disconnected.
    now_in_channel = (new_channel and new_channel != guild.afk_channel)
    was_in_channel = (old_channel and old_channel != guild.afk_channel)
    message = None
    if now_in_channel:
        if was_in_channel:
            message = f'{member.display_name} {get_synonym("moved to")} {new_channel.name}.'
        else:
            message = f'{get_synonym("Hello")} {member.display_name}!'
    elif was_in_channel:
        message = f'{get_synonym("Goodbye")} {member.display_name}!'

    # Send the text-to-speech message, or queue it if the bot is already speaking.
    if message and voice_client:
        audio_stream = discord.PCMAudio(BytesIO(text_to_pcm(message)))
        if voice_client.is_playing():
            message_queue.append(audio_stream)
        else:
            voice_client.play(audio_stream, after=after_play_finished)
Example #26
0
async def plays(ctx, source):
    vc = bot.voice_clients[0]
    audio_src = discord.PCMAudio(
        'C:\\Users\\Francois\\Music\\Downloaded by MediaHuman\\The Black Keys - Little Black Submarines.mp3'
    )
    await vc.play(audio_src)
Example #27
0
 async def __do_play_wav(self, wav, voice_channel):
     return await self.__do_play_source(discord.PCMAudio(open(wav, "r+b")),
                                        voice_channel)
 def __set_src__(self):
     self._file = open(self.path, "rb")
     self._src = discord.PCMVolumeTransformer(discord.PCMAudio(self._file),
                                              volume=self.default_vol)
Example #29
0
 async def play(self, ctx, song):
     ctx.voice_client.play(discord.PCMAudio(f'music/{song}'))
     await ctx.send(ctx.voice_client.is_playing())