如何在用户所在的不和谐语音通道中播放gtts mp3文件(discord.py)

时间:2020-06-21 04:30:56

标签: python python-3.7 discord.py

像标题一样,我需要在语音通道中播放gtts文件,最简单的方法是什么?我正在使用python 3.7。到目前为止,这是我的代码:

@client.command(name="repeat")
async def repeat(context):
  import gtts, ffmpeg
  from discord.ext import commands
  # grab the user who sent the command
  user = context.message.author
  voice_channel = user.voice.voice_channel
  channel = None
  # only play music if user is in a voice channel
  if voice_channel != None:
    await ctx.send(f"What do you want to say, type cancel to cancel:")
        
    def check(msg):
      return msg.author == ctx.author and msg.channel == ctx.channel
        
    try:
      msg = await client.wait_for("message", check=check, timeout=120)
  
    except asyncio.TimeoutError:
      await ctx.send("Sorry, you didn't reply in time!")
      
    if(msg.content == 'cancel'):
      return
    
    tts = gtts.gTTS(str(msg.content), lang="en")
    tts.save("text.mp3")
    
    # grab user's voice channel
    channel = voice_channel.name
    await client.say('User is in channel: '+ channel)
    # create StreamPlayer
    vc = await client.join_voice_channel(voice_channel)
    player = vc.create_ffmpeg_player('text.mp3', after=lambda: print('done'))
    player.start()
    while not player.is_done():
      await asyncio.sleep(1)
      # disconnect after the player has finished
      player.stop()
      await vc.disconnect()
    else:
      await client.say('User is not in a channel.')

我对在不和谐的机器上制作机器人还是陌生的,所以我的代码看起来像垃圾箱,我目前正在修复/压缩我的代码。再次使用python 3.7

1 个答案:

答案 0 :(得分:1)

因此,首先,您应该将任何导入文件放在文件的开头(导入不和谐的区域相同)

现在进入代码,我将简化一下。我的代码不要求用户输入文本,而是该代码使用命令后调用的输入。即!repeat Hello将在语音通道中说出hello

首先,这是一些连接到语音通道的代码。为此,我们将其分开。这是一些不错的代码,比我将尝试的gtts代码要好一些。

@bot.command()
async def connect(ctx, *, channel: discord.VoiceChannel=None):
    """
    Connect to a voice channel
    This command also handles moving the bot to different channels.

    Params:
    - channel: discord.VoiceChannel [Optional]
        The channel to connect to. If a channel is not specified, an attempt to join the voice channel you are in
        will be made.
    """
    if not channel:
        try:
            channel = ctx.author.voice.channel
        except AttributeError:
            raise InvalidVoiceChannel('No channel to join. Please either specify a valid channel or join one.')

    vc = ctx.voice_client

    if vc:
        if vc.channel.id == channel.id:
            return
        try:
            await vc.move_to(channel)
        except asyncio.TimeoutError:
            raise VoiceConnectionError(f'Moving to channel: <{channel}> timed out.')
    else:
        try:
            await channel.connect()
        except asyncio.TimeoutError:
            raise VoiceConnectionError(f'Connecting to channel: <{channel}> timed out.')

    await ctx.send(f'Connected to: **{channel}**', delete_after=20)

很酷,现在我们可以连接到频道了。因此,这实际上是我做些gtts工作的方法。我不会谈论太多,所有评论。但是,如果有问题,请发表评论:)

以下是必需的导入from gtts import gTTS

@bot.command()
async def repeat(ctx, *, text=None):
    """
    A command which saves `text` into a speech file with
    gtts and then plays it back in the current voice channel.

    Params:
     - text [Optional]
        This will be the text we speak in the voice channel
    """
    if not text:
        # We have nothing to speak
        await ctx.send(f"Hey {ctx.author.mention}, I need to know what to say please.")
        return

    vc = ctx.voice_client # We use it more then once, so make it an easy variable
    if not vc:
        # We are not currently in a voice channel
        await ctx.send("I need to be in a voice channel to do this, please use the connect command.")
        return

    # Lets prepare our text, and then save the audio file
    tts = gTTS(text=text, lang="en")
    tts.save("text.mp3")

    try:
        # Lets play that mp3 file in the voice channel
        vc.play(discord.FFmpegPCMAudio('text.mp3'), after=lambda e: print(f"Finished playing: {e}"))

        # Lets set the volume to 1
        vc.source = discord.PCMVolumeTransformer(vc.source)
        vc.source.volume = 1

    # Handle the exceptions that can occur
    except ClientException as e:
        await ctx.send(f"A client exception occured:\n`{e}`")
    except TypeError as e:
        await ctx.send(f"TypeError exception:\n`{e}`")
    except OpusNotLoaded as e:
        await ctx.send(f"OpusNotLoaded exception: \n`{e}`")

现在,要退出当前的语音通道,您可以执行以下操作

@bot.command()
async def disconnect(ctx):
    """
    Disconnect from a voice channel, if in one
    """
    vc = ctx.voice_client

    if not vc:
        await ctx.send("I am not in a voice channel.")
        return

    await vc.disconnect()
    await ctx.send("I have left the voice channel!")