如何使用discord.py实现歌曲直接下载至用户本地设备的功能?
核心逻辑限制说明
Discord 机器人的所有代码逻辑均运行在你部署服务的服务器/托管设备上,受浏览器及 Discord 平台的安全策略限制,机器人没有权限直接读写用户的本地存储,也无法主动将文件直接推送至用户的手机内存、本地硬盘等存储位置,不存在完全跳过服务端交互、直接将资源从源站写入用户本地的实现方案。
可行的替代实现方案
下面两种方案可以满足你的需求,均不需要长期占用服务器存储资源:
方案1:服务端临时缓存后发送给用户(用户无需额外操作)
该方案会先将音频文件临时下载到服务器,发送给用户后立即删除临时文件,不会长期占用服务器存储空间:
- 优先使用目前仍在维护的
yt-dlp替代已停止更新的youtube_dl,功能兼容性更强 - 示例实现逻辑:
import discord from discord.ext import commands import yt_dlp import os bot = commands.Bot(command_prefix='!', intents=discord.Intents.all()) @bot.command(name='download') async def download_song(ctx, *, song_name): # yt-dlp配置,仅下载最高质量音频 ydl_opts = { 'format': 'bestaudio/best', 'postprocessors': [{ 'key': 'FFmpegExtractAudio', 'preferredcodec': 'mp3', 'preferredquality': '192', }], 'outtmpl': 'temp_%(id)s.%(ext)s', 'quiet': True } async with ctx.typing(): try: with yt_dlp.YoutubeDL(ydl_opts) as ydl: # 搜索歌曲并下载 info = ydl.extract_info(f"ytsearch:{song_name}", download=True)['entries'][0] temp_file = f"temp_{info['id']}.mp3" # 发送文件给用户 await ctx.send(file=discord.File(temp_file, filename=f"{info['title']}.mp3")) # 发送完成后立即删除临时文件 if os.path.exists(temp_file): os.remove(temp_file) except Exception as e: await ctx.send("歌曲下载失败,请检查关键词后重试") bot.run("你的BOT_TOKEN")
- 注意:Discord 普通服务器单文件上传上限为8MB,服务器开通 Nitro 后可提升至50MB/100MB,常规192kbps的3-5分钟音频文件均符合大小要求。
方案2:返回音频直链给用户自行下载(完全不占用服务器带宽/存储)
该方案不会在服务端下载任何文件,仅提取音频的源站直链返回给用户,用户点击链接即可自行将文件下载到本地,完全符合你不需要服务端存储的需求:
- 调整yt-dlp配置为仅提取信息不下载,示例配置:
ydl_opts = { 'format': 'bestaudio/best', 'quiet': True, 'skip_download': True, }
- 提取到音频的
url字段后直接发送给用户即可,用户点击链接会直接从源站开始下载到本地设备。
注意事项
- 请严格遵守你爬取的音视频平台的版权政策,违规下载传播受版权保护的内容可能导致机器人被平台封禁,甚至面临法律风险
- 音视频平台的直链通常存在有效期限制,一般为几小时,过期后无法继续下载
内容的提问来源于stack exchange,提问作者Aananda Giri
相关产品推荐
相关产品推荐

