Discord.js: playFile/playStream fails to play short (<1 sec) files

Created on 23 Sep 2016  路  20Comments  路  Source: discordjs/discord.js

My bot has a soundboard command where the bot joins a voice channel, plays a simple mp3 file, then leaves.

On 8.x I had no trouble but I couldn't figure out why some mp3s weren't launching on 9.x and I narrowed it down to the ones that were that short(less than 1 second long).

I've tested it on 3 different mp3s and none of them work, however other mp3s longer than this seem to work correctly.

vc
    .join()
    .then(conn => {
        console.log(fileName);
        const intent = conn.playFile(fileName, {volume: Config.AudioVolume});
        intent.on('debug', i => {
            console.log(i);
        });
        intent.on('start', () => {
            console.log("playing " + fileName);
        });
        intent.once('end', () => {
            //intent usually ends before it's acutally done outputting to the websocket
            setTimeout(function() {
                message
                    .delete()
                    .catch(merr => {
                        console.log("Deleted message after voice: " + merr);
                    }
                );
                conn.channel.leave();
            }, 800);
        });
        intent.once('error', errWithFile => {
            console.log("err with file: " + errWithFile);
            util.botReply(message, "There was an error playing your soundbite.");
            conn.channel
                .leave()
                .catch(function(e) {
                    console.log("err leaving voice channel: " + e);
                }
            );
        });
    })
    .catch(e => {
        console.log("err joining voice: " + e);
    }
);

In this code example, normal mp3s play and then the bot leaves the channel.
Printing out something like

/some/path/potg.mp3
playing /some/path/potg.mp3
Triggered terminal state end - stream is now dead

However with <1s mp3, I get only

/some/path/short.mp3

And nothing follows, the music intent never fires "start".

I can't upload mp3s here, I can gladly link the ones that I have tested(with permission to do so).

high voice bug

Most helpful comment

Really happy to announced this is _finally_ fixed on the indev-prism branch! 馃帀

While this isn't completely ready for release, it's fairly stable and it simplifies a lot of voice internals. It uses prism-media which moves a lot of the audio transcoding code that used to exist in discord.js into a separate module. It has a significant performance improvement when streaming from files, and should also allow streaming from URLs!

Anyway, I'll close this issue once the fix is released :)

All 20 comments

What discord.js version are you running?

| Module | Version |
| --- | --- |
| discord.js | 9.2.0 |
| node.js | 6.6.0(also tried 6.0.0 and 6.5.0) |
| ffmpeg | 3.0.2-4 |
| node-opus | 0.2.1 |

I just saw 9.3.0 is released, should I try that?

EDIT: 9.3.0 doesn't seem to have changed anything related to StreamDispatcher anyway, tested it and no apparent changes.

Not sure how helpful this is, but I'm running into what I believe to be this issue too.

I set up something like the following:

channel.join().then(connection => {
  connection.on('speaking', (user, speaking) => {
    const dispatcher = connection.playFile('clip.mp3');
    dispatcher.on('end', () => connection.disconnect());
  });
});

After attaching a ton of debug code, what I noticed is if someone speaks the first time the clip doesn't play, but the end event doesn't trigger either. If someone says something a second time, the clip "plays" again but I get Triggered terminal state end - stream is now dead and the dispatcher fires the end event. The audio clip doesn't play either time, but the event emitter seems to think it does the second time at least.

Sorry if this isn't helpful!

Hacky walkaround: was able to play 1 sec audio by remove {end:false} flag here, and and move unpipe events content to end event.

no event will fire when {end:false} is set for 1 sec audio, I am not sure why.

Go ahead and give it a try on the latest indev - the voice code was improved dramatically.

Doesn't seem like it does - I also no longer get any on('speaking') events. I swapped the opus library along with the update, so I'm gonna poke around with that a bit more

Edit - should mention I swapped Opus library because I got this error after upgrading:

/node_modules/discord.js/src/client/voice/opus/OpusEngineList.js:23
  throw new Error('Couldn\'t find an Opus engine.');

Assuming that's just part of the changes, and put it into peer dependencies

This should be fixed in the indev branch, as we no longer do anything to try and kill the real input stream; instead we let it end gracefully.

Could you please try your code under the indev branch? There are some breaking changes towards presences, but nothing breaking about voice.

As I mentioned above, when tested against the indev branch it still fails to play. Longer clips work without issue, but the ~1s clip never triggers.

I ran into this as well. I had bunch of .wavs and .mp3s that a v8 bot would have no trouble with but v9 would not emit any sound for. I made the same observation: files that were longer than 1 second would play with v9, shorter files would not. Like @IanMitchell mentioned, switching to indev made no difference.

I ended up encoding every file to opus and v9 would play those without any issues, even the files under 1 second. This is obviously far from ideal.

I used to run my bot on my windows 8 pc and never had this problem. I'm running it on a debian jessie server now and ran into this problem as well. Might be coincidence but maybe this information could be of use.

Can confirm @juhokuu. Works perfectly fine with v8.2, but neither with v9 nor v10.

@schwifty-space @markokajzer are you guys on indev?

Nope! I just used ^10.0.0. Shall I try with indev?

Yes, I'm on the indev branch. Last pulled ~a week ago.

Taking another look at voice soon, should have this fixed soon :)

The voice rewrite may take some time and I don't want to delay the v11 release any further (it has a _lot_ of bug fixes) so I'm going to bump it to v11.1.0, which will mainly be an update for voice fixes and improvements, should drop in January (hopefully!)

Really happy to announced this is _finally_ fixed on the indev-prism branch! 馃帀

While this isn't completely ready for release, it's fairly stable and it simplifies a lot of voice internals. It uses prism-media which moves a lot of the audio transcoding code that used to exist in discord.js into a separate module. It has a significant performance improvement when streaming from files, and should also allow streaming from URLs!

Anyway, I'll close this issue once the fix is released :)

Awesome to hear, thank you!

Thanks! I can confirm it works perfectly now!

This is fixed in the indev-prism branch, which will be a part of the next version of discord.js.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Alipoodle picture Alipoodle  路  3Comments

LLamaFTL picture LLamaFTL  路  3Comments

Lombra picture Lombra  路  3Comments

ghost picture ghost  路  3Comments

PassTheMayo picture PassTheMayo  路  3Comments