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

discord.py调用FFmpeg播放音频时出现输入/输出错误求助

问题:Discord.py机器人在线播放音频中途出现I/O错误

代码实现

async def direct(self, interaction: discord.Interaction, link: str):
    voice_client = get(self.bot.voice_clients, guild=interaction.guild)
    if voice_client is None:
        return await interaction.response.send_message("❌ Connect to a channel first.")

    await interaction.response.send_message("Using direct link.")
    voice_client.play(discord.FFmpegPCMAudio(link))
    return

错误信息

[tls @ 0x557c73a19d00] Error in the pull function.
https://cdn.discordapp.com/attachments/1109998398150545410/1112473248505004142/portradio-_1_.ogg: Input/output error
2023-05-28 13:29:11 INFO     discord.player ffmpeg process 1458408 successfully terminated with return code of 0.

已尝试的FFmpeg参数

ffmpeg_options = {'options': '-vn -dn -sn -ignore_unknown -fflags +discardcorrupt'}

该参数解决了"corrupt input packet"错误,但I/O问题仍存在。

需求

无需将音频文件本地存储,直接在线播放到Discord语音频道。


解决思路

1. 优化FFmpeg网络相关参数

针对网络流不稳定的问题,添加缓存、超时和自动重连参数,增强流的稳定性:

ffmpeg_options = {
    'before_options': '-reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 5',
    'options': '-vn -dn -sn -ignore_unknown -fflags +discardcorrupt -buffer_size 1024k -timeout 5000000'
}

参数说明:

  • -reconnect 1:允许FFmpeg在连接断开时自动重连
  • -reconnect_streamed 1:对流式传输启用重连逻辑
  • -reconnect_delay_max 5:设置最大重连延迟为5秒
  • -buffer_size 1024k:增大输入缓存,缓解网络波动导致的断流
  • -timeout 5000000:设置5秒超时,避免无限等待无效连接

调用时传入参数:

voice_client.play(discord.FFmpegPCMAudio(link, **ffmpeg_options))

2. 模拟浏览器请求头

Discord CDN可能会拦截非浏览器的请求,添加用户代理头伪装成浏览器访问:

ffmpeg_options = {
    'before_options': '-user_agent "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36" -reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 5',
    'options': '-vn -dn -sn -ignore_unknown -fflags +discardcorrupt -buffer_size 1024k'
}

3. 检查网络与CDN限制

  • 测试其他公开音频链接,确认是否是当前Discord CDN链接的临时限制
  • 确保机器人所在服务器的网络可以稳定访问Discord CDN,无防火墙、代理或带宽限制导致的中断

4. 基于aiohttp的流式中转

如果FFmpeg直接拉流仍不稳定,可用aiohttp先获取音频流再传给FFmpeg(适合中小文件):

import aiohttp

async def direct(self, interaction: discord.Interaction, link: str):
    voice_client = get(self.bot.voice_clients, guild=interaction.guild)
    if voice_client is None:
        return await interaction.response.send_message("❌ Connect to a channel first.")

    await interaction.response.send_message("Using direct link.")
    
    async with aiohttp.ClientSession() as session:
        async with session.get(link, headers={'User-Agent': 'Mozilla/5.0'}) as resp:
            if resp.status != 200:
                return await interaction.followup.send("Failed to fetch audio.")
            # 边读边传,适配大文件
            voice_client.play(discord.FFmpegPCMAudio(resp.content, **ffmpeg_options))

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 10:08:17