node-ytdl-core: Stream is terminated 10 - 15 seconds before the end of the video

It’s been 1 month since users have been reporting that YouTube videos are not played entirely.

The bot often stops 10 - 15 seconds before the end of a video. I don’t have any particular error thrown by ytdl nor by discord.js.

When I log the reason of a voice-connection ending is Stream is not generating quickly enough.. I really doubt this is a low bandwidth issue since the bot is hosted on a Google Cloud Platform VM with 400 mbps up/down.

What I’m doing with YTDL:

export function getReadableStream(track: models.Track): Readable {
  return YTDL(track.streamURL, { filter: 'audioonly' });
}

From this code snippet, I store the result of the function and play the stream with discord.js:

guildVoiceConnection.playStream(stream, streamOptions)
	.on('end', (reason) => _onTrackEnd(reason, message));

The bot is open-source if you want to dig-up more code.

I’ve also opened an issue on the repo of the bot.

EDIT : see @COPS2000 answer for a working fix

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Reactions: 20
  • Comments: 55 (11 by maintainers)

Commits related to this issue

Most upvoted comments

This is not a ytdl-core issue. It’s also extremely easy to fix.

So I dont know if you all fixed it on your ends but in my code I put

const dispatcher = serverQueue.connection.playStream(ytdl(song.url, {
		filter: "audioonly",
		highWaterMark: 1<<25
	}))

and that fixed it on the most recent YTDL version. I no longer have any of that happening and my bot is back to working perfectly.

Hi, I’m the author of ytdl-core-discord.

To try and fix these issues, I’ve bypassed downloading the videos with ytdl-core itself and instead obtaining the m3u8 stream URL and providing that to FFmpeg instead. However, this will only affect a very small number of videos, as any WebM Opus videos are downloaded with ytdl-core.

If the issue persists, I will consider doing the same for WebM Opus streams to try and track down where the issue is actually occurring.

Edit: reading above comments, looks like this won’t fix the issue 😕

My best guess with ytdl-core-discord fixing it for some people is that when available the use of the prism encoder for opus streams does not suffer from the same issues as ytdl-core does with using ffmpeg. And while not all yt videos can benefit from prisim, enough do to make the issue seem muted.

I can confirm, I’m also experiencing this issue with my own bot. From what I can tell, is that this started happening without updating anything. So I would suspect that something changed with YouTube and that broke something with ytdl-core. I don’t think the problem lies with youtube-dl itself, as many more people would be complaining about that and I also don’t think the issue lies with discord.js.

please test this on ytdl-core version v0.29.3, just released. it uses an updated version of miniget that handles reconnects a little better.

It’s my understanding that the higher the highWaterMark, the more it downloads, so maybe just double the value. There might be a way to use the info return value to calculate the video size so when you go to download it with the highWaterMark, you can give an accurate value.

is there any solution for this?

using the highWaterMark option 1<<25 or higher on the ytdl stream that has solved it terminating early, comes with the occasional weirdness or stuttering if the connection can’t keep up. I think an “official” fix is still in the works.

So the quick-fix here is to stop in-memory streaming and instead stream from a file (which have been freshly downloaded using ytdl), which I really don’t want to do for performance and storage reasons.

Another thing you could try is increasing the highWaterMark option. The default is 16kb, you can try increasing it to 1<<25 (32mb) for example. With that option, it’ll keep at most 32mb of a song in memory, which is more than enough for most songs.

Normally, discord will throttle the download to go as fast as it’s being played. Which may not play well with youtube, it may not be as responsive to continuing a download or to reconnects if the stream is not actively consumed.

So the quick-fix here is to stop in-memory streaming and instead stream from a file (which have been freshly downloaded using ytdl), which I really don’t want to do for performance and storage reasons.

You can just delete the file after it has been played. It’s a fair quick-fix for now, unless you’re using the bot in a lot of guilds, this shouldn’t impact performance as much.

@TotomInc I have, Initially 1<<25 created some interruptions in the stream, to the point of being unbearable. Tried lowering to 1<<15 and the issue reappeared. I’m currently testing back at 1<<25 after increasing the discord channel bitrate, since I know the VPS I use should have more than sufficient bandwidth. Funny enough long videos (1-2hours) had the least issues and it was the average length (2-3mins) that it would reoccur, but that would usually only be during a queue (after several other average length songs had been played).

Discord.js also has it’s own highWaterMark option for the dispatcher, using that one created a weird situation where a song played 2-3 songs ago would suddenly start replaying, not really relevant just something I found while fiddling. At least by using YTDL’s option the volume can still be changed in realtime.

My best guess with ytdl-core-discord fixing it for some people is that when available the use of the prism encoder for opus streams does not suffer from the same issues as ytdl-core does with using ffmpeg. And while not all yt videos can benefit from prisim, enough do to make the issue seem muted.

sadly cant adjust the volume.

From my testing this issue is not present on 0.24.0 but present on 0.29.x