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

Discord机器人发送YouTube MP4文件时触发413请求实体过大错误

Discord机器人发送YouTube MP4报错413 Payload Too Large的解决方法

错误原因

你遇到的413 Payload Too Large错误,本质是要发送的MP4文件大小超过了Discord的上传限制:

  • 普通服务器频道的文件上传上限为8MB
  • Nitro用户的服务器频道上限为50MB
    而你的代码默认下载YouTube最高分辨率的MP4流,这类文件体积很容易超出上述限制。

解决方案

1. 下载更低分辨率的视频流

修改代码中的流筛选逻辑,指定下载更小分辨率的MP4,确保文件体积在Discord限制内。比如优先下载720p,没有则降级到480p:

@client.command()
async def downloadmp4(ctx, link):
    yt = pytube.YouTube(link)
    # 先尝试获取720p的MP4流
    video = yt.streams.filter(progressive=True, file_extension='mp4', resolution='720p').first()
    # 如果没有720p,降级到480p
    if not video:
        video = yt.streams.filter(progressive=True, file_extension='mp4', resolution='480p').first()
    # 若仍无匹配,取所有可用progressive流中分辨率最低的
    if not video:
        video = yt.streams.filter(progressive=True, file_extension='mp4').order_by('resolution').asc().first()
    
    out_file = video.download(output_path='C:\\Users\\Ethan\\PycharmProjects\\YoutubeBot')
    await ctx.channel.send(file=discord.File(out_file))
    os.remove(out_file)

注:原代码中的重命名步骤是多余的,因为progressive=True且file_extension='mp4'的流,下载后本身就是MP4格式,无需额外重命名。

2. 压缩视频文件

如果需要保留较高分辨率,可以用FFmpeg对下载后的视频进行压缩,降低文件体积后再发送。需要先安装FFmpeg并配置到系统环境变量中:

import subprocess
import os

@client.command()
async def downloadmp4(ctx, link):
    yt = pytube.YouTube(link)
    video = yt.streams.filter(progressive=True, file_extension='mp4').order_by('resolution').desc().first()
    out_file = video.download(output_path='C:\\Users\\Ethan\\PycharmProjects\\YoutubeBot')
    
    # 压缩视频:CRF值越高体积越小(范围18-28,28为平衡值),音频码率设为128k
    compressed_file = os.path.splitext(out_file)[0] + '_compressed.mp4'
    subprocess.run([
        'ffmpeg', '-i', out_file,
        '-vcodec', 'libx264', '-crf', '28',
        '-acodec', 'aac', '-b:a', '128k',
        compressed_file
    ], check=True)
    
    await ctx.channel.send(file=discord.File(compressed_file))
    # 删除临时文件
    os.remove(out_file)
    os.remove(compressed_file)

3. 拆分长视频(针对时长较长的视频)

如果视频本身时长过长,即使压缩后仍超限制,可以用FFmpeg将视频拆分为多个片段,分别发送:

import subprocess
import os

@client.command()
async def downloadmp4(ctx, link):
    yt = pytube.YouTube(link)
    video = yt.streams.filter(progressive=True, file_extension='mp4').order_by('resolution').desc().first()
    out_file = video.download(output_path='C:\\Users\\Ethan\\PycharmProjects\\YoutubeBot')
    
    # 每10分钟拆分一个片段(600秒)
    segment_duration = 600
    subprocess.run([
        'ffmpeg', '-i', out_file,
        '-c', 'copy', '-map', '0',
        '-segment_time', str(segment_duration),
        '-f', 'segment',
        os.path.join(os.path.dirname(out_file), 'part_%03d.mp4')
    ], check=True)
    
    # 发送所有拆分后的片段
    for part in sorted(os.listdir(os.path.dirname(out_file))):
        if part.startswith('part_') and part.endswith('.mp4'):
            part_path = os.path.join(os.path.dirname(out_file), part)
            await ctx.channel.send(file=discord.File(part_path))
            os.remove(part_path)
    
    os.remove(out_file)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 02:50:32