You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Discord.py中FFmpeg进程异常终止无音频播放问题求助

修复Discord音乐机器人在Replit上的FFmpeg返回码-9问题

错误原因分析

返回码-9对应SIGKILL信号,说明FFmpeg进程被系统强制终止。在Replit环境下,核心原因是平台内存/CPU资源限制,加上代码里的低效转码、阻塞逻辑进一步加剧了资源消耗,触发了平台的进程查杀机制。

具体修复步骤

1. 替换低效转码方式,弃用MoviePy

MoviePy封装层级高,转码时资源占用大,直接用FFmpeg命令行转码更轻量化:

# 替换原download函数中的MoviePy代码,改用subprocess调用FFmpeg
import subprocess

def download(yt):
    print("DOWNLOADING STREAM TO AUDIO.WEBM")
    stream = yt.streams.filter(only_audio=True, mime_type="audio/webm", abr="160kbps").order_by("abr").first()
    stream.download(filename="audio.webm")
    print("EXPORTING TO MP3")
    # 直接调用FFmpeg转码,参数优化资源占用
    subprocess.run(["./ffmpeg", "-i", "audio.webm", "-vn", "-acodec", "libmp3lame", "-q:a", "2", "audio.mp3"], check=True)
    os.remove("audio.webm")
    print("DONE")

2. 优化异步逻辑,避免线程阻塞

原代码中thread.start()后立刻thread.join()等于同步执行,没有发挥线程优势,改用Discord.py适配的异步任务:

import asyncio

# 把download改成异步函数,用asyncio.to_thread执行阻塞操作
async def download(yt):
    print("DOWNLOADING STREAM TO AUDIO.WEBM")
    stream = yt.streams.filter(only_audio=True, mime_type="audio/webm", abr="160kbps").order_by("abr").first()
    await asyncio.to_thread(stream.download, filename="audio.webm")
    print("EXPORTING TO MP3")
    await asyncio.to_thread(subprocess.run, ["ffmpeg", "-i", "audio.webm", "-vn", "-acodec", "libmp3lame", "-q:a", "2", "audio.mp3"], check=True)
    os.remove("audio.webm")
    print("DONE")

# 在play命令中直接调用异步函数
await download(yt)

3. 修复语音频道连接逻辑

原代码在已连接时未正确获取现有客户端,且ctx.send遗漏await:

try:
    channel = ctx.author.voice.channel
    vc = ctx.voice_client
    if not vc:
        vc = await channel.connect()
    else:
        # 若已在其他频道,自动移动过去
        if vc.channel != channel:
            await vc.move_to(channel)
        await ctx.send("已在语音频道,准备播放")
except AttributeError:
    await ctx.send("你需要先加入一个语音频道!")
    return
except Exception as e:
    await ctx.send(f"连接语音频道出错:{str(e)}")
    return

4. 给FFmpeg添加资源限制参数

播放时限制FFmpeg的线程数和日志输出,降低资源占用:

vc.play(discord.FFmpegPCMAudio(
    source="audio.mp3",
    executable="./ffmpeg",
    options="-threads 1 -loglevel error"
))

5. 修复错误捕获逻辑

去掉全局屏蔽错误的try/except,打印具体错误信息便于排查:

# 替换原外层空except
except Exception as e:
    print(f"播放出错:{str(e)}")
    await ctx.send(f"播放出错:{str(e)}")

6. Replit环境额外优化

在Replit的replit.nix文件中添加FFmpeg系统依赖,无需本地副本:

{ pkgs }: {
  deps = [
    pkgs.python310
    pkgs.ffmpeg
  ];
}

之后代码中executable直接写"ffmpeg"即可,使用系统自带版本更稳定。

优化后的核心代码片段

@bot.command()
async def play(ctx, arg):
    await ctx.send("Downloading...")
    try:
        yt = pytube.YouTube(arg)
        print("STREAM: "+str(yt.streams.filter(only_audio=True,mime_type="audio/webm",type="audio",abr="160kbps")))
        
        async def download(yt):
            print("DOWNLOADING STREAM TO AUDIO.WEBM")
            stream = yt.streams.filter(only_audio=True, mime_type="audio/webm", abr="160kbps").order_by("abr").first()
            await asyncio.to_thread(stream.download, filename="audio.webm")
            print("EXPORTING TO MP3")
            await asyncio.to_thread(subprocess.run, ["ffmpeg", "-i", "audio.webm", "-vn", "-acodec", "libmp3lame", "-q:a", "2", "audio.mp3"], check=True)
            os.remove("audio.webm")
            print("DONE")
        
        await download(yt)
        
        try:
            channel = ctx.author.voice.channel
            vc = ctx.voice_client
            if not vc:
                vc = await channel.connect()
            else:
                if vc.channel != channel:
                    await vc.move_to(channel)
                await ctx.send("已在语音频道,准备播放")
        except AttributeError:
            await ctx.send("你需要先加入一个语音频道!")
            return
        except Exception as e:
            await ctx.send(f"连接语音频道出错:{str(e)}")
            return
        
        vc.play(discord.FFmpegPCMAudio(
            source="audio.mp3",
            options="-threads 1 -loglevel error"
        ))
        await ctx.send(f"正在播放:{yt.title}")
    except Exception as e:
        print(f"整体出错:{str(e)}")
        await ctx.send(f"出错了:{str(e)}")

内容的提问来源于stack exchange,提问作者Bummbumm6

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 08:59:17