Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

'write EPIPE -4047' error with some videos #816

Open
AMDBartek opened this issue Dec 9, 2020 · 22 comments
Open

'write EPIPE -4047' error with some videos #816

AMDBartek opened this issue Dec 9, 2020 · 22 comments

Comments

@AMDBartek
Copy link

My friends tried to play this video on my Discord bot and it threw a write EPIPE (warning, it is loud): https://youtu.be/ihmDR7W1P1o

This video also throws a write EPIPE error but not immediately: https://www.youtube.com/watch?v=thW6YPgJm2U
It happens on both Windows and Linux hosts, I could not find the culprit for this issue but it only happens with a few videos, there is a couple of examples above. Is it something to do with the format of the videos?

Error: write EPIPE
    at afterWriteDispatched (node:internal/stream_base_commons:162:15)
    at writeGeneric (node:internal/stream_base_commons:153:3)
    at Socket._writeGeneric (node:net:764:11)
    at Socket._write (node:net:776:8)
    at writeOrBuffer (node:internal/streams/writable:382:12)
    at Socket.Writable.write (node:internal/streams/writable:333:10)
    at PassThrough.ondata (node:internal/streams/readable:715:22)
    at PassThrough.emit (node:events:327:20)
    at PassThrough.Readable.read (node:internal/streams/readable:515:10)
    at flow (node:internal/streams/readable:988:34) {
  errno: -4047,
  code: 'EPIPE',
  syscall: 'write'
}

Sample of my code:

client.on("message", message => {
    
  var ismusicCommand = message.content.toLowerCase().startsWith(config.prefix + "play") || message.content.toLowerCase().startsWith(config.prefix + "skip") || message.content.toLowerCase().startsWith(config.prefix + "stop");
    
  if (message.author.bot) return;
  
  if (!message.channel.guild) {
      if (ismusicCommand == true) {
      message.react("723607808255197244");
      message.channel.send("Music functionality can only be used while in a guild!");
    return;
      }
      return;
  }

  const serverQueue = queue.get(message.guild.id);

  if (message.content.toLowerCase().startsWith(config.prefix + `play`)) {
    message.react("723607808062390363");
    execute(message, serverQueue);
    return;
  } else if (message.content.toLowerCase().startsWith(config.prefix + `skip`)) {
    message.react("723607808062390363");
    skip(message, serverQueue);
    return;
  } else if (message.content.toLowerCase().startsWith(config.prefix + `stop`)) {
    message.react("723607808062390363");
    stop(message, serverQueue);
    return;
  }
});

async function execute(message, serverQueue) {
  const args = message.content.split(" ");

  const voiceChannel = message.member.voice.channel;
  if (!voiceChannel)
    return message.channel.send("You need to be in a voice channel to play audio!");
  const permissions = voiceChannel.permissionsFor(message.client.user);
  if (!permissions.has("CONNECT") || !permissions.has("SPEAK")) {
    return message.channel.send("I need the permissions to join and play audio in your voice channel!");
  }

  const songInfo = await ytdl.getInfo(args[1]);
  const song = {
    title: songInfo.videoDetails.title,
    author: songInfo.videoDetails.author.name,
    url: songInfo.videoDetails.video_url
  };

  if (!serverQueue) {
    const queueContruct = {
      textChannel: message.channel,
      voiceChannel: voiceChannel,
      connection: null,
      songs: [],
      volume: 5,
      playing: true
    };

    queue.set(message.guild.id, queueContruct);

    queueContruct.songs.push(song);

    try {
      var connection = await voiceChannel.join();
      queueContruct.connection = connection;
      play(message.guild, queueContruct.songs[0]);
    } catch (err) {
      console.log(err);
      queue.delete(message.guild.id);
      return message.channel.send(err);
    }
  } else {
    serverQueue.songs.push(song);
    return message.channel.send(`${song.title} **by** ${song.author} has been added to the queue!`);
  }
}

function skip(message, serverQueue) {
  if (!message.member.voice.channel)
    return message.channel.send("You have to be in a voice channel to skip audio!");
  if (!serverQueue)
    return message.channel.send("There is no audio that I could skip!");
  serverQueue.connection.dispatcher.end();
}

function stop(message, serverQueue) {
  if (!message.member.voice.channel)
    return message.channel.send("You have to be in a voice channel to stop audio playback!");
  serverQueue.songs = [];
  serverQueue.connection.dispatcher.end();
  message.channel.send("Successfully stopped audio playback and left voice channel.")
}

function play(guild, song) {
  const serverQueue = queue.get(guild.id);
  if (!song) {
    serverQueue.voiceChannel.leave();
    queue.delete(guild.id);
    return;
  }

  const dispatcher = serverQueue.connection
    .play(ytdl(song.url), {bitrate: 192000 /* 192kbps */})
    .on("finish", () => {
      serverQueue.songs.shift();
      play(guild, serverQueue.songs[0]);
    })
    .on("error", error => console.error(error));
  dispatcher.setVolumeLogarithmic(serverQueue.volume / 5);
  serverQueue.textChannel.send(`Started playing: ${song.title} **by** ${song.author}`);
}
@redbrain
Copy link
Contributor

redbrain commented Dec 9, 2020

Are you at the latest version of ytdl-core? The current latest version is 4.1.4, make sure you upgrade to that.
If an upgrade doesn't work, it's possible that altering or removing the bitrate setting may fix the issue.
I've also noticed that this code snippet closely matches the first Google result for "discord music bot javascript".
I strongly encourage you to learn more about JavaScript and Discord.JS so you can write and debug your own code in the future.

@AMDBartek
Copy link
Author

AMDBartek commented Dec 9, 2020

Removing the bitrate setting didn't work, as for the code I did copy and paste a part for the example. It's probably not the code because going back to ytdl-core 3.4.2 fixes the issue, but that version is a bit unstable and I don't want to have to use a bad work-around. I also am using the latest version of ytdl-core (4.1.4).

@redbrain
Copy link
Contributor

I'm unable to reproduce the error on either version with your code. I'll leave this open in case someone else can help.

@AMDBartek
Copy link
Author

What code did you use to get the video (or how did you download the video), was it streaming through a Discord bot or just downloading and playing back the video? I have been trying to get this working for days, rewrote the code from scratch and it still produced a 'write EPIPE -4047' error, it doesn't happen with all videos only a small percentage of them.

@TimeForANinja
Copy link
Collaborator

🤔 stumbled across the same error earlier today in the example/ffmpeg.js
running it twice produces the error after crashing since the output file already exists
the stack isn't that helpful

@AMDBartek
Copy link
Author

Yep, the first time it does nothing, second time produces a 'write EPIPE -4047' error.

@fent fent added the support label Dec 31, 2020
@zLuisTv
Copy link

zLuisTv commented Jan 19, 2021

I still have the same error

@LangkaWS
Copy link

Hey !
I'm having this error too on some musics, don't really know why.
I tried the 2 musics that AMDBartek gave, these are working with by bot ^^" I have more or less the same code as him.
Maybe this bug comes from discord.js or node and not from ytdl-core package.

@N1C0exe
Copy link

N1C0exe commented May 22, 2021

Hey @AMDBartek have you resolved this issue?

@stale
Copy link

stale bot commented Jul 22, 2021

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 stale bot added the stale Issues that were closed for inactivity label Jul 22, 2021
@stale stale bot closed this as completed Jul 29, 2021
@TimeForANinja TimeForANinja added bug and removed stale Issues that were closed for inactivity labels Jul 30, 2021
@TimeForANinja TimeForANinja reopened this Jul 30, 2021
@AMDBartek
Copy link
Author

Sorry for the (very) late response, I did manage to solve the issue by rewriting my code but I think this issue should be kept open as others seem to be having the same issue.

@redbrain
Copy link
Contributor

redbrain commented Aug 4, 2021

If that's the case, then perhaps this isn't a bug with ytdl but rather improper handling of a stream.
Can you share what you did to fix the issue, if you know?

@AMDBartek
Copy link
Author

Unfortunately, I do not know what specific part of code fixed the issue.

@TimeForANinja
Copy link
Collaborator

If that's the case, then perhaps this isn't a bug with ytdl but rather improper handling of a stream.
Can you share what you did to fix the issue, if you know?

that's what I thought after this find #816 (comment)

that way it is either a ytdl problem or a ytdl-example problem 😂

@CarbonNeuron
Copy link

I am also having this issue after following the ffmpeg example

@Noomaok
Copy link

Noomaok commented Oct 28, 2021

Hi, I recently made a similar implementation and found a way to prevent this error.
I am not sure I works 100% of the time, but so far it worked for me.

Here is the code I used :

let stream = ytdl(song.url, {
        filter : "audioonly",
        opusEncoded : false,
        fmt : "mp3",
        encoderArgs: ['-af', 'bass=g=10,dynaudnorm=f=200'] 
});

const dispatcher = serverQueue.connection
        .play(stream, {type : "unknown"})
        .on("finish", () => {
                //do finish step
        })
        .on("error", error => console.error(error));

I did not tried this code with the ffmpeg example but with my own discord bot

@karfelren
Copy link

Hi, I recently made a similar implementation and found a way to prevent this error. I am not sure I works 100% of the time, but so far it worked for me.

Here is the code I used :

let stream = ytdl(song.url, {
        filter : "audioonly",
        opusEncoded : false,
        fmt : "mp3",
        encoderArgs: ['-af', 'bass=g=10,dynaudnorm=f=200'] 
});

const dispatcher = serverQueue.connection
        .play(stream, {type : "unknown"})
        .on("finish", () => {
                //do finish step
        })
        .on("error", error => console.error(error));

I did not tried this code with the ffmpeg example but with my own discord bot

thanks, this solved my problem about "typeerror: the compressed data passed is corrupted"

@TimeForANinja
Copy link
Collaborator

just wanna let you know that these parameters serve no use with ytdl-core 😉

        opusEncoded : false,
        fmt : "mp3",
        encoderArgs: ['-af', 'bass=g=10,dynaudnorm=f=200'] 

@moonstar-x
Copy link

moonstar-x commented Jan 15, 2022

Hey there, I recently came across this issue myself with the following video:

https://www.youtube.com/watch?v=M_HCA7G9qUQ

Checking the format output for that video using youtube-dl gave out the following:

[youtube] M_HCA7G9qUQ: Downloading webpage
[youtube] M_HCA7G9qUQ: Downloading MPD manifest
[info] Available formats for M_HCA7G9qUQ:
format code  extension  resolution note
139          m4a        audio only DASH audio   50k , m4a_dash container, mp4a.40.5 (22050Hz), 931.23KiB
251          webm       audio only tiny  126k , webm_dash container, opus @126k (48000Hz), 2.36MiB
140          m4a        audio only tiny  129k , m4a_dash container, mp4a.40.2@129k (44100Hz), 2.41MiB
278          webm       256x144    DASH video   95k , webm_dash container, vp9, 30fps, video only
160          mp4        256x144    DASH video  108k , mp4_dash container, avc1.4d400b, 30fps, video only
242          webm       426x240    DASH video  220k , webm_dash container, vp9, 30fps, video only
133          mp4        426x240    DASH video  242k , mp4_dash container, avc1.4d400c, 30fps, video only
243          webm       640x360    DASH video  405k , webm_dash container, vp9, 30fps, video only
134          mp4        640x360    360p  584k , mp4_dash container, avc1.4d401e@ 584k, 30fps, video only, 10.88MiB
244          webm       854x480    DASH video  752k , webm_dash container, vp9, 30fps, video only
135          mp4        854x480    DASH video 1155k , mp4_dash container, avc1.4d400d, 30fps, video only
247          webm       1280x720   DASH video 1505k , webm_dash container, vp9, 30fps, video only
136          mp4        1280x720   720p 2105k , mp4_dash container, avc1.64001f@2105k, 30fps, video only, 39.16MiB
248          webm       1920x1080  DASH video 2646k , webm_dash container, vp9, 30fps, video only
137          mp4        1920x1080  1080p 4166k , mp4_dash container, avc1.640028@4166k, 30fps, video only, 77.50MiB
18           mp4        640x360    360p  658k , avc1.42001E, 30fps, mp4a.40.2 (44100Hz), 12.25MiB (best)

In my case, I'm using the quality: highestaudio option, so it would seem the format 140 would be chosen.

I tried downloading the file manually and then trying to play it directly on discord.js and surprise, it didn't work. However, trying with the format 251downloaded did.

I also tried doing the opposite for a video that worked normally, downloading it in audioonly format with m4a codec also made it fail.

Could it be maybe that the voice support for discord.js cannot handle an m4a stream?

@TimeForANinja
Copy link
Collaborator

Could it be maybe that the voice support for discord.js cannot handle an m4a stream?

depends on how u use it
as far as i know you can decide in the api-calls if it should assume a special encoding or use ffmpeg to just handle whatever you throw at it

@efefurkankarakaya
Copy link

efefurkankarakaya commented May 31, 2023

In my case, I fixed this problem and the reason was the video title.

Some videos have special characters or emojis in their title which are not supported by the most of modern OS' as file name. You should remove all special characters before using title in any I/O operation (except it's a file content).

By the way, if you are a cross-platform developer, do not mix Bash and Powershell in Windows. Some packages can cause conflict during package installation.

@jovolopez
Copy link

I had the same problem when testing my code on Windows. I put it into a Docker container, and I had no more issues. I hope it helps someone else! (I recommend using the docker init command to set up the Dockerfile and compose.yml).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests