提问者:小点点

Python不和谐音乐机器人停止播放任何歌曲几分钟


我试图把一个Python的不和谐音乐机器人作为一个有趣的小项目。在所需的不和谐库之外,我目前正在使用YouTubeAPI搜索视频并解析URL(代码中未显示),yt-dlp,这是一个yt_download的分支,仍然保持从YTURL获取信息,FFMPEG通过机器人播放从yt-dlp获得的歌曲。我的play命令似乎可以作为第一个YT视频结果开始播放,但大约30-90秒后,它停止播放。我在控制台中得到了这条消息:

2023-02-23 14:54:44INdiscord.player ffmpeg进程4848成功终止,返回代码为0。

所以我没有错误可以关闭。我已经包含了下面控制台的完整输出…

-----------------------------------
groovy-jr#6741 is up and running
-----------------------------------
2023-02-23 14:53:23 INFO     discord.voice_client Connecting to voice...
2023-02-23 14:53:23 INFO     discord.voice_client Starting voice handshake... (connection attempt 1)
2023-02-23 14:53:24 INFO     discord.voice_client Voice handshake complete. Endpoint found us-south1655.discord.media
2023-02-23 14:54:44 INFO     discord.player ffmpeg process 4848 successfully terminated with return code of 0.  <= AUDIO STOPS

我目前正在Windows 11机器上开发这个项目,但我也在我的Ubuntu机器上运行它时遇到了问题。我只是直接从VSCode终端托管机器人进行开发。

我一直在尝试研究这个问题,问题是我找不到很多关于这个问题的最新信息。还有一篇文章谈到了一个类似的问题,并有一个答案建议使用以下FFMPEG选项,但我试图无济于事。

FFMPEG_OPTIONS = {
                    'before_options': '-reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 5',
                    'options': '-vn',
                 }

我将在下面包含问题文件:

import discord
from discord.ext import commands
from discord import FFmpegPCMAudio
import responses
import youtubeSearch as YT
import yt_dlp

async def send_message(message, user_message, is_private = False):
    try:
        response = responses.handle_response(user_message)
        await message.author.send(response) if is_private else await message.channel.send(response)
    except Exception as e:
        print(e)

def run_discord_bot():
    intents = discord.Intents.default()
    intents.message_content = True

    TOKEN = 'xxxxxx'
    client = commands.Bot(command_prefix = '-', intents=intents)

    @client.event
    async def on_ready():
        print('-----------------------------------')
        print(f'{client.user} is up and running')
        print('-----------------------------------')

    @client.command(name='play', aliases=['p'], pass_context = True)
    async def play(ctx, *, search_term:str = None):
        if ctx.author.voice:
            voice = None
            if search_term == None:
                await ctx.send('No song specified.')
                return
            if not ctx.voice_client:
                channel = ctx.message.author.voice.channel
                voice = await channel.connect()
            else:
                voice = ctx.guild.voice_client
            
            url = YT.singleSearch(search_term)
            
            YTDLP_OPTIONS = {
                'format': 'bestaudio/best',
                'extractaudio': True,
                'audioformat': 'mp3',
                'outtmpl': '%(extractor)s-%(id)s-%(title)s.%(ext)s',
                'restrictfilenames': True,
                'noplaylist': True,
                'nocheckcertificate': True,
                'ignoreerrors': False,
                'logtostderr': False,
                'quiet': True,
                'no_warnings': True,
                'default_search': 'ytsearch',
                'source_address': '0.0.0.0',
            }

 =====>     FFMPEG_OPTIONS = {
                'before_options': '-reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 5',
                'options': '-vn',
            }

            with yt_dlp.YoutubeDL(YTDLP_OPTIONS) as ydl:
                info = ydl.extract_info(url, download=False)
                playUrl = info['url']

            source = FFmpegPCMAudio(playUrl, options=FFMPEG_OPTIONS)
            voice.play(source)
        else:
            await ctx.send('You must be in a voice channel to play a song!')
            return

    @client.command(pass_context = True)
    async def leave(ctx):
        if ctx.voice_client:
            await ctx.guild.voice_client.disconnect()
        else:
            await ctx.send("I'm not in a voice channel!")

    @client.command(pass_context = True)
    async def pause(ctx):
        voice = discord.utils.get(client.voice_clients, guild = ctx.guild)
        if voice.is_playing():
            voice.pause()
        else:
            await ctx.send('No audio playing...')

    @client.command(pass_context = True)
    async def resume(ctx):
        voice = discord.utils.get(client.voice_clients, guild = ctx.guild)
        if voice.is_paused():
            voice.resume()
        else:
            await ctx.send('No audio paused...')

    @client.command(pass_context = True)
    async def stop(ctx):
        voice = discord.utils.get(client.voice_clients, guild = ctx.guild)
        voice.stop()

    client.run(TOKEN)

我很感激我能了解的任何指导!


共2个答案

匿名用户

我也面临着同样的问题。传递下面的选项对我有用

source = FFmpegPCMAudio(source=playUrl,before_options="-reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 5",options="-vn")

匿名用户

它在Ubuntu上运行不正常可能是因为那里的库安装有问题,所以有些包不会正常安装,而是使用wget、curl或brew。可以在这里检查

我注意到的一件事是,经过一定时间后,YouTube可能会阻塞流。这是YouTube流的一个常见问题,因为我认为它们的高级功能可用性不打算长时间连续播放。解决方案是为您的音乐使用不同的源。还有许多其他音乐来源,例如SoundCloud或Spotify,对于流式传输长歌曲可能更可靠,或者可以使用不同的库,如小波。

此外,检查FFMPEG日志是否有任何错误或警告可能会对您有所帮助,这些错误或警告可能会提供有关问题的更详细信息。您可以尝试通过在FFMPEG命令中添加-v选项来增加日志的详细信息。

如果可以修复,您可能需要尝试将FFMPEG安装更新到最新版本以查看是否可以解决问题。