fent / node-ytdl-core

YouTube video downloader in javascript.
MIT License
4.46k stars 784 forks source link

Readable Stream Does Not Emit 'finish' or 'end' Event Causing Code to Not Terminate #1287

Open UltronOne opened 3 months ago

UltronOne commented 3 months ago

Description

I am experiencing an issue with the ytdl-core package where the readable stream does not emit the 'finish' or 'end' event, causing the code execution to hang and not terminate as expected.

Details

I have used the ytdl-core for downloading the audio stream from a YouTube video and piping it to a writable stream to save as an MP3 file. However, it seems that the events ('finish' and 'end') that signify the completion of the streaming are not being emitted, leading to an indefinite wait state.

Here's a minimal reproducible example:

import fs from "fs";
import ytdl from "ytdl-core";

// Video ID to download
const videoId = "4WEQtgnBu0I";

// Destination file for audio
const outputFilePath = "output/audio.mp3";

// Ensure the directory exists
fs.mkdirSync("output", { recursive: true });

console.log("YTDL Start");

async function downloadAsAudio(ytUrl: string, filePath: string) {
  return new Promise(async (resolve) => {
    ytdl(ytUrl, {
      filter: "audioonly",
      quality: "highestaudio",
    })
      .pipe(fs.createWriteStream(filePath))
      .on("finish", () => resolve("Downloaded"));
  });
}

await downloadAsAudio(
  `https://www.youtube.com/watch?v=${videoId}`,
  outputFilePath
);

Expected Behavior

Actual Behavior

Additional Information

I appreciate your help in resolving this issue.

Thank you!

mtripg6666tdr commented 2 months ago

It seems you piped the ytdl stream to a fs stream, so it is the fs stream that doesn't emit either 'finish' or 'end' event. If you'd like to attach an event handler to the fs stream, which is called when finishing the stream, you can listen 'close' event, rathar than 'finish' or 'end' iirc.