node-ytdl-core icon indicating copy to clipboard operation
node-ytdl-core copied to clipboard

ytdl stop stream after few minute

Open Nyako01 opened this issue 3 years ago • 22 comments

i am using ytdl to stream youtube video on my discord bot. after few minute ytdl stop streaming with error

Error: aborted
    at connResetException (node:internal/errors:691:14)
    at TLSSocket.socketCloseListener (node:_http_client:407:19)
    at TLSSocket.emit (node:events:406:35)
    at node:net:672:12
    at TCP.done (node:_tls_wrap:580:7) {
  code: 'ECONNRESET'
}

I think the error is caused by my slow internet connection. so I try to run my bot on hosting [heroku]. but still got the same error

i am using ytdl v4.9.1, discordJs v13.1.0 and nodeJs v16.6.1

here the code i use to start streaming

const option = {
        filter: "audioonly",
        highWaterMark: 1048576 / 4,
    };
const stream = await ytdl(streamUrl, option);

and here the code i use to play stream in bot with discordJs v13.1.0 and discordJs/voice v0.6.0

const player = createAudioPlayer();
const resource = createAudioResource(stream);

player.play(resource);
const connection = await joinVoiceChannel({ channelId: song.voiceChannel.id, guildId: song.voiceChannel.guild.id, adapterCreator: song.voiceChannel.guild.voiceAdapterCreator });
try {
        await entersState(connection, VoiceConnectionStatus.Ready, 30_000);
        connection.subscribe(player);
    } catch (error) {
        connection.destroy();
        throw error;
    }

Nyako01 avatar Aug 16 '21 16:08 Nyako01

We think this issue is caused by recent versions of NodeJS. We're trying to find a fix. Can someone determine if this is a duplicate ticket?

redbrain avatar Aug 16 '21 19:08 redbrain

#902 Is at least a related Bug.

GaryCraft avatar Aug 16 '21 20:08 GaryCraft

i just updated my nodejs to the latest version which is 16.6.2 and tried to test ytdl again but as an mp3 downloader. here the code i used to test

const ytdl = require('ytdl-core')
const fs = require('fs')
const streamUrl = 'http://www.youtube.com/watch?v=05s6wxQS6Ag'
const idvideo = streamUrl.slice(streamUrl.indexOf('v=') + 2)
const option = {
      filter: "audioonly",
      highWaterMark: 1048576 / 4,
    };

const stream = ytdl(streamUrl, option);
stream.on("error", (err) => {
      console.log("ytdl error\n", err);
    });
stream.pipe(fs.createWriteStream(`./song_temp_cache/${idvideo}.mp3`));

is work fine. but still getting the same error when used for discord music bot

I also tried the discordjs/voice to play directly from the mp3 file url and the local mp3 file. and the result is works fine

do i have to download the youtube audio first in mp3 format. then stream to my discord bot?

*sorry for my bad english

Nyako01 avatar Aug 17 '21 16:08 Nyako01

I'm having the same issue with Discord music bots, but for some reason, I receive this Error: aborted every day around 7 AM (in Brazil). This regularity probably is related to Heroku dyno restart system of my application or something like that.

I'm using node-ytdl for a few months and this thing only appeared when I migrated to Node V16. I can still play some music, but sometimes the stream suddenly ends without throwing any visible errors

InfiniteMarcus avatar Aug 19 '21 13:08 InfiniteMarcus

i try to find solution on discordjs/voice/issue. and i found this

the developer said. the error is from ytdl-core. and he suggested using youtube-dl for stream audio data to discord bot so i try using youtube-dl-exec based on example here (line 47). and it works. until streaming is over here my code

const yt-dl = require('youtube-dl-exec').raw
const stream = yt-dl(streamUrl, {
    o: '-',
    q: '',
    f: 'bestaudio[ext=webm+acodec=opus+asr=48000]/bestaudio',
    r: '100K',
  }, { stdio: ['ignore', 'pipe', 'ignore'] })

const player = createAudioPlayer();
const connection = await joinVoiceChannel({
      channelId: song.voiceChannel.id,
      guildId: song.voiceChannel.guild.id,
      adapterCreator: song.voiceChannel.guild.voiceAdapterCreator,
    });
const resource = createAudioResource(stream.stdout);
player.play(resource);

try {
    await entersState(connection, VoiceConnectionStatus.Ready, 30_000);
    connection.subscribe(player);
  } catch (error) {
    connection.destroy();
    throw error;
  }

maybe for now we should use youtube-dl-exec to stream audio data to discord bot (only on discordjs v13). until ytdl can fix this problem

Error: aborted
    at connResetException (node:internal/errors:691:14)
    at TLSSocket.socketCloseListener (node:_http_client:407:19)
    at TLSSocket.emit (node:events:406:35)
    at node:net:672:12
    at TCP.done (node:_tls_wrap:580:7) {
  code: 'ECONNRESET'
}

Nyako01 avatar Aug 26 '21 16:08 Nyako01

@Oky12 that works great thanks! However, do you know if it's possible to play age-restricted videos? Like in ytdl we had the cookies option, I can't seem to find anything in youtube-dl-exec

MrPedrinho avatar Aug 26 '21 19:08 MrPedrinho

@MrPedrinho I have no idea about that. and because "youtube-dl-exec" is a simple Node.js wrapper for youtube-dl. so maybe only the essentials of youtube-dl are available in "youtube-dl-exec". btw i found a github repository issue that talking about youtube-dl cookies. maybe it will help you

Nyako01 avatar Aug 26 '21 23:08 Nyako01

can you provide full example code to test / reproduce the problem? i can ofc fill in voicechannel id's + bot token myself

TimeForANinja avatar Aug 27 '21 12:08 TimeForANinja

can reproduce it (without discord.js library) by piping it to ffmpeg and opus encoder through pipeline to convert into ogg/opus format Example: https://github.com/mtripg6666tdr/ytdl-test/blob/d130f03679f628d692760be27694eedd22c3a9c4/src/index.js#L33 An error will occur in about 30-40 minutes later after starting playing (and this is the same way to use Readable stream in @discordjs/voice)

mtripg6666tdr avatar Aug 27 '21 12:08 mtripg6666tdr

This might be related to audio bitrate, try to use quality: 'lowestaudio'. Discord channels default to 32 bitrate, if your video exceeds this limit it will close your connection and return an error.

const stream = await ytdl(song.url, {
              filter: 'audioonly',
              quality: 'lowestaudio',
              requestOptions: {
                headers: {
                  cookie: process.env.YOUTUBE_LOGIN_COOKIE,
                },
              },
            });

AkatGabrielGoncalves avatar Sep 04 '21 02:09 AkatGabrielGoncalves

It depends on actual data size in PassThrough. When quality set lower, the audio stored in buffer becomes long By setting actually quality low or setting highWaterMark high help to be longer to when the error occurs in addition to that, this error will occur also without discord.js

mtripg6666tdr avatar Sep 04 '21 03:09 mtripg6666tdr

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

stale[bot] avatar Dec 09 '21 00:12 stale[bot]

This error is unresolved also on node.js v17

mtripg6666tdr avatar Dec 09 '21 10:12 mtripg6666tdr

@Nyako01 i've been battling this issue with Error: aborted all day until I saw your suggestion to try youtube-dl-exec. however, I can't get it to work either as when using .raw it complains of not being a function

 const youtubedl = require("youtube-dl-exec").raw;
  const stream = youtubedl(
    data.queue[0].url,
    {
      o: "-",
      q: "",
      f: "bestaudio[ext=webm+acodec=opus+asr=48000]/bestaudio",
      r: "100K",
    },
    { stdio: ["ignore", "pipe", "ignore"] }
  )

"youtubedl is not a function"

Trying without, i get a promise but i cant use the then() scope due to it seeming to never be reached

What am i missing here?

PatricNox avatar Apr 04 '22 10:04 PatricNox

@PatricNox Try using exec instead of raw.

import { exec as ytdlexec } from 'youtube-dl-exec';

const stream = ytdlexec(
  url,
  {
    output: '-',
    format:
      'bestaudio[ext=webm+acodec=opus+tbr>100]/bestaudio[ext=webm+acodec=opus]/bestaudio/best',
    limitRate: '1M',
    rmCacheDir: true,
    verbose: true,
  },
  { stdio: ['ignore', 'pipe', 'ignore'] }
);

const audioResource = createAudioResource(stream.stdout!);
this.player.play(audioResource);

It is an example with typescript but you get the idea and you don't actually need to await if you are going to create a stream from it.

I have the whole code from my example here, its a mess but if it can help you its good enough 😂

AkatGabrielGoncalves avatar Apr 04 '22 15:04 AkatGabrielGoncalves

Same problem here here's the full code I tested

// Install discord.js, ffmpeg, node-opus and ytdl-core before running this!

const ytdl = require('ytdl-core');
const {
    StreamType,
    createAudioResource,
    NoSubscriberBehavior,
    AudioPlayerStatus,
    createAudioPlayer,
    joinVoiceChannel,
    VoiceConnectionStatus,
    entersState,
} = require('@discordjs/voice');


const fluentffmpeg = require('fluent-ffmpeg')
const { Client, GatewayIntentBits, Partials } = require('discord.js');
const url = 'https://www.youtube.com/watch?v=uvwCf4jkgrs';
const clientToken = 'token';

const client = new Client({
    intents: [GatewayIntentBits.Guilds,
        GatewayIntentBits.GuildMessages,
        GatewayIntentBits.GuildMessageReactions,
        GatewayIntentBits.GuildVoiceStates,
        GatewayIntentBits.MessageContent
    ],
    partials: [Partials.Channel],

    disableMentions: 'everyone',
});
client.on('ready', () => {
    console.log('discord.js client ready');
});

client.on('messageCreate', async message => {

    console.log('in Event');
    if (!message.content.startsWith('++play')) return;

    console.log('Got a song request!');
    const voiceChannel = message.member.voice.channel;
    if (!voiceChannel) {
        message.reply('Please be in a voice channel first!');
        return;
    }
    play(message);

});

function play(message) {
    const player = createAudioPlayer({
        behaviors: {
            noSubscriber: NoSubscriberBehavior.Pause,
        },
    });
    const connection = joinVoiceChannel({
        channelId: message.member.voice.channel.id,
        guildId: message.guild.id,
        adapterCreator: message.guild.voiceAdapterCreator,
    })

    const subscribe = connection.subscribe(player);
    const stream = ytdl(url);
    player.once('error', (error) => {
        console.log("Catched:" + error + error.resource.playbackDuration)
        play(message);
    });

    //const ffmpeg_audio_stream = fluentffmpeg({ source: stream }).toFormat('wav');

    const audio_resauce = createAudioResource(stream, { inputType: StreamType.Arbitrary });

    player.play(audio_resauce);
}

client.login(clientToken);

here's how console looks like

PS D:\PD_maid> node test.js
discord.js client ready
in Event
Got a song request!
in Event
Catched:Error: aborted165700
Catched:Error: aborted140740
in Event
Catched:Error: aborted135720
in Event
Catched:Error: aborted140740
Catched:Error: aborted130740
in Event
Catched:Error: aborted160700

here are my dependencies

"dependencies": {
    "@appland/appmap-agent-js": "^12.0.0",
    "@discordjs/voice": "^0.13.0",
    "avconv": "^3.1.0",
    "cli-progress": "^3.11.2",
    "discord-api-types": "^0.36.1",
    "discord-rich-presence": "^0.0.8",
    "discord.js": "^14.6.0",
    "ffmpeg": "^0.0.4",
    "fluent-ffmpeg": "^2.1.2",
    "html-metadata-parser": "^2.0.4",
    "libsodium-wrappers": "^0.7.10",
    "node-ffprobe": "^3.0.0",
    "ws": "^8.8.0",
    "ytdl-core": "^4.11.2",
    "ytpl": "^2.3.0"

now I using error.resource.playbackDuration and ffmpeg to hadle the error, because the begin option in ytdl is not working well https://github.com/DanielBUBU/PD_maid

DanielBUBU avatar Dec 07 '22 16:12 DanielBUBU

Can confirm the issue, experiencing it myself.

richiedevs avatar Dec 16 '22 12:12 richiedevs

Same problem, input stream aborted

eugabrielsilva avatar Mar 06 '23 19:03 eugabrielsilva

Have a look at https://github.com/fent/node-ytdl-core/issues/902#issuecomment-1460991438 in case you are getting an aborted error.

0xAnakin avatar Mar 08 '23 22:03 0xAnakin

can reproduce in NodeJS v19...

LeGeek01 avatar Apr 02 '23 13:04 LeGeek01

I had the same problem with my discord bot. After some testing I reduced the LiveBuffer down to 2 sec witch solved the problem. My guess is that the error occurs because the buffer gets too big for some default or hardcoded limit of nodeJS.

const stream = ytdl(song.url, {filter: 'audioonly', liveBuffer: 2000, highWaterMark: 1 << 25});
const resource = createAudioResource(stream);
player.play(resource);

luca-naujoks avatar Apr 27 '24 16:04 luca-naujoks

yeah good job it works now! @Nyako01 can you try it out? @redbrain any news on a fix?

LeGeek01 avatar Apr 28 '24 13:04 LeGeek01