Discord.js: Unable to play music file with either of recommended libraries

Created on 13 Feb 2020  路  9Comments  路  Source: discordjs/discord.js

Please describe the problem you are having in as much detail as possible:
I am simply unable to play any music as every attempt to results in an error. I've tested each one of the recommended libraries and none of them seems to be working. I've been trying to reinstall those libraries and always keep only one library installed at the time, however it didn't change anything.

Include a reproducible code sample here, if possible:

VoiceChannel.join().then(connection => {
    const path = './musicfile.mp3';
    //const path = '/home/myuser/musicfile.mp3'; // Not working either...
    //const path = '~/musicfile.mp3'; // Not working either...
    connection.play(path, {
        volume: false,
        bitrate: 'auto'
    });
}).catch(console.error);

While using either @discordjs/opus or node-opus I get this:

Error: Could not find an Opus module! Please install @discordjs/opus, node-opus or opusscript.
    at new OpusStream (/srv/discord/node_modules/prism-media/src/opus/Opus.js:42:13)
    at new Encoder (/srv/discord/node_modules/prism-media/src/opus/Opus.js:130:5)
    at AudioPlayer.playPCMStream (/srv/discord/node_modules/discord.js/src/client/voice/player/BasePlayer.js:64:33)
    at AudioPlayer.playUnknown (/srv/discord/node_modules/discord.js/src/client/voice/player/BasePlayer.js:59:17)
    at VoiceConnection.play (/srv/discord/node_modules/discord.js/src/client/voice/util/PlayInterface.js:70:28)
    at /srv/discord/laura.js:269:35
    at processTicksAndRejections (internal/process/task_queues.js:94:5)

And while using opusscript I get this instead:

TypeError: Cannot convert "null" to int
/srv/dis/node_modules/opusscript/build/opusscript_native_wasm.js:8
var Module=typeof Module!=="undefined"?Module:{};var moduleOverrides={};var key;for(key in Module){if(Module.hasOwnProperty(key)){moduleOverrides[key]=Module[key]}}Module["arguments"]=[];Module["thisProgram"]="./this.program";Module["quit"]=function(status,toThrow){throw toThrow};Module["preRun"]=[];Module["postRun"]=[];var ENVIRONMENT_IS_WEB=false;var ENVIRONMENT_IS_WORKER=false;var ENVIRONMENT_IS_NODE=false;var ENVIRONMENT_HAS_NODE=false;var ENVIRONMENT_IS_SHELL=false;ENVIRONMENT_IS_WEB=typeof window==="object";ENVIRONMENT_IS_WORKER=typeof importScripts==="function";ENVIRONMENT_HAS_NODE=typeof process==="object"&&typeof process.versions==="object"&&typeof process.versions.node==="string";ENVIRONMENT_IS_NODE=ENVIRONMENT_HAS_NODE&&!ENVIRONMENT_IS_WEB&&!ENVIRONMENT_IS_WORKER;ENVIRONMENT_IS_SHELL=!ENVIRONMENT_IS_WEB&&!ENVIRONMENT_IS_NODE&&!ENVIRONMENT_IS_WORKER;var scriptDirectory="";function locateFile(path){if(Module["locateFile"]){retur

Further details:

  • discord.js version: Master (commit: a36f386)
  • Node.js version: 12.15.0
  • Operating system: Debian GNU/Linux 9.12
  • Priority: Low. Apparently it's a rather uncommon problem.
  • ffmpeg version: 3.2.14-1
  • [x] I have also tested the issue on latest master, commit hash: a36f386
dependencies voice bug

Most helpful comment

prism-media v1.2.2 has been released with a fix for this issue :)

All 9 comments

I would like to do a little followup on this issue. I think it's safe to say that ffmpeg is totally irrelevant for this problem since I am getting exactly the same error when using createReadStream that is claimed by documentation to bypass ffmpeg altogether.

VoiceChannel.join().then(connection => {
    const path = './musicfile.ogg';
    //const path = '/home/myuser/musicfile.ogg'; // Not working either...
    //const path = '~/musicfile.ogg'; // Not working either...
    connection.play(fs.createReadStream(path), {
        type: 'ogg/opus'
    });
}).catch(console.error);

The only time I've had those kind of issues is when the node version that my bot was executing on was different than the node version that I installed node-opus with. Otherwise you'd probably wanna join the Discord for more direct support

I've tried reaching out on discord but no one seems to know what might be the reason.
However, I found out that playing mp3 files works just fine on my personal machine. I still have no clue what might be causing those problems on my VPS. I think I've checked everything:

  • Same version of npm - Checked
  • Same version of node - Checked
  • Same version of all npm libraries - Checked
  • Same version of ffmpeg - Checked
  • Same folder structure - Checked

I am really confused about this issue.

After playing around with the code I've decided to make some changes directly in /prism-media/src/opus/Opus.js file to find something more about the issue. Thanks to that I have found out the reason why @discordjs/opus and node-opus were "invisible" for DiscordJS:

@discordjs/opus : Error: Cannot find module '/srv/discord/node_modules/@discordjs/opus/prebuild/node-v79-linux-x64/opus.node'
I've checked deeper and indeed, there is not even such folder as prebuild in the first place. I guess it's important to note that npm install worked just fine and there were no errors during installation.

node-opus : Error: Could not locate the bindings file.
I haven't investigated this one more.

opusscript : The biggest surprise here - it worked. I've changed my code back and forth few times but apparently the cause of this library error is located in loader function.

Original loader function:

function loader(requireData, objMap = {}) {
  for (const [name, reqFn] of requireData) {
    try {
      const dep = require(name);
      const fn = reqFn ? reqFn(dep) : dep;
      return {
        [objMap.module || 'module']: dep,
        [objMap.name || 'name']: name,
        [objMap.fn || 'fn']: fn,
      };
    } catch (e) { }
  }
  return {};
};

My custom loader function:

function myloader(requireData, objMap = {}) {
  for (const [name, reqFn] of requireData) {
    try {
      const dep = require(name);
      const fn = reqFn ? reqFn(dep) : dep;
      return {
        [objMap.fn || 'fn']: fn,
      };
    } catch (e) { 
      console.error("Loading of " + name + " failed!");
    }
  }
  return {};
};

After this change, running my bot and playing the file worked like a charm without any error. However, I would still love to find a way to fix it so I can use @discordjs/opus, like recommended by the docs.

Can you set up a test repo for this?

Hello,

I'm also experiencing this error. Today I converted all my MP3s to OGG to minimize FFMPEG usage. After changing my code according to documentation, the bot doesn't start playing audio and instead instantly jumps to leaving the channel.

Relevant code:

function playAudio(voiceChannel, file, textChannel) {
    // check for permissions first
    if (!voiceChannel.permissionsFor(client.user.id).has("CONNECT")) {
        textChannel.send("No permission to join this channel.")
        return;
    };
    if (!voiceChannel.permissionsFor(client.user.id).has("SPEAK")) {
        textChannel.send("No permission to speak in this channel.")
        return;
    };

    voiceChannel.join().then(connection => {

        logger.log(client.shard.ids, "Queuing " + file);

        // file -> "./audio/xxx/audio.ogg"
        connection.play(fs.createReadStream(file), { type: 'ogg/opus' }).on("finish", () => {
            voiceChannel.leave();
        });

    }).catch(error => {
    logger.log(client.shard.ids, JSON.stringify(error));
    });
  }

The issue is reproducible in my project and can be tested: https://github.com/Blogshot/trump-bot

I encountered both issues mentioned above yesterday.

FFMpeg is innocent in that, however I suggest to use the apt version in favour of the snap installation on Ubuntu. I had some bad experience inside of an LXD container as snap doesn't have the same amount of permissions.

  1. @discordjs/opus you can probably spot the problem after starting node and typing in require("@discordjs/node"). In my setup (Focal Fossa) the problem is that my version of libc6 is newer than the one supported by the package. I reported it over here.

  2. opusscript throws an error that is caused by prism-media passing a null argument to opusscript. I found out how to hack it by editing one of the files in the node_packages... well atemporary solution that works. Follow the details in my StackOverflow answer. It would be of course the best if a proper fix would be integrated to prism-media, so here is the issue to follow.

@tiritto Your fix basically avoided prism-media to recognize opusscript by name, so the problematic name === 'opusscript' ? null : frameSize jumped to the false branch providing a vaild int instead of a null.

prism-media v1.2.2 has been released with a fix for this issue :)

Was this page helpful?
0 / 5 - 0 ratings

Related issues

iCrawl picture iCrawl  路  3Comments

xCuzImPro picture xCuzImPro  路  3Comments

kvn1351 picture kvn1351  路  3Comments

tiritto picture tiritto  路  3Comments

Alipoodle picture Alipoodle  路  3Comments