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

Discord.js音乐机器人断开后无法删除播放中MP3文件求助

Discord音乐机器人删除播放中文件EPERM错误解决

问题根源

  1. 文件被播放器占用:调用player.stop()后,播放器不会立刻释放MP3文件的句柄,此时执行删除操作会触发系统文件锁定保护,返回EPERM错误。
  2. 同步删除的无效回调:fs.unlinkSync是同步方法,不支持传入回调函数,你代码里的删除后日志逻辑完全不会执行。
  3. 轮询状态逻辑不可靠:依赖autopaused状态判断播放器是否停止,可能和实际播放器状态不匹配,导致player.stop()没有被正确触发。

解决方案

1. 确保播放器彻底释放资源

优先通过播放器的stop事件监听触发删除操作,或者短时间延迟等待资源释放,避免在播放器还占用文件时执行删除。

2. 改用异步删除+重试机制

异步删除配合重试逻辑,可以在文件暂时被占用时,等待一段时间后再次尝试删除,避免直接报错。

3. 修正代码错误

去掉同步删除的无效回调,使用fs.promises.unlink进行异步文件操作,代码更简洁且支持错误处理。

修改后的代码示例

const fs = require('fs').promises;
const { join } = require('path');

eventEmitter.on("leave", async () => {
    // 停止播放器并清空队列
    player.stop();
    queueOfSongs.length = 0;

    // 方案一:如果播放器支持stop事件,优先用事件监听(推荐)
    // player.once("stop", async () => {
    //     await handleFileDeletion();
    // });

    // 方案二:如果没有stop事件,用短延迟等待资源释放
    await new Promise(resolve => setTimeout(resolve, 1000)); // 延迟1秒,可根据实际调整
    await handleFileDeletion();
});

// 封装文件删除逻辑
async function handleFileDeletion() {
    let musics;
    try {
        musics = await fs.readdir(pahtForMusic); // 注意:检查变量是否拼写错误,正确应为pathForMusic
    } catch (err) {
        console.error("Failed to read music folder:", err);
        return;
    }

    if (musics.length === 0) {
        console.log("No music to delete, folder is empty");
        return;
    }

    // 带重试的文件删除函数
    async function deleteFileWithRetry(filePath, retries = 3) {
        try {
            await fs.unlink(filePath);
            console.log(`Deleted: ${filePath}`);
        } catch (err) {
            if (retries > 0 && err.code === "EPERM") {
                console.log(`File in use, retrying... (${retries} attempts left)`);
                await new Promise(resolve => setTimeout(resolve, 500));
                return deleteFileWithRetry(filePath, retries - 1);
            }
            console.error(`Failed to delete ${filePath}:`, err);
        }
    }

    // 批量删除文件
    for (const music of musics) {
        const filePath = join(pahtForMusic, music);
        await deleteFileWithRetry(filePath);
    }
}

额外提示

  • 检查变量pahtForMusic是否为拼写错误,正确应为pathForMusic,避免路径错误。
  • 查看你使用的Discord音乐播放器库(如discord-player、erela.js等)的官方文档,确认播放器停止后的事件触发机制,用事件监听代替延迟会更可靠。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 18:42:44