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

How to download audio?

Open 4e576rt8uh9ij9okp opened this issue 1 year ago • 6 comments

From what the docs say this should work but it doesn't.

const fs = require('fs')
const ytdl = require('ytdl-core')

async function download(link){
    const info = await ytdl.getInfo(link)

    let audioFormats = ytdl.filterFormats(info.formats, 'audioonly')

    let format = ytdl.chooseFormat(audioFormats, {quality: 'highestaudio'})

    console.log(format)

    ytdl.downloadFromInfo(format)
}

let link = 'https://music.youtube.com/watch?v=7EJbFg_LxjY'

download(link)
throw Error('Cannot use `ytdl.downloadFromInfo()` when called ' +
      ^

Error: Cannot use `ytdl.downloadFromInfo()` when called with info from `ytdl.getBasicInfo()`
    at ytdl.downloadFromInfo (/home/Idiot/Github/musicSync/node_modules/ytdl-core/lib/index.js:207:11)
    at downloadSong (/home/Idiot/Github/musicSync/index.js:13:10)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)

4e576rt8uh9ij9okp avatar Apr 18 '23 19:04 4e576rt8uh9ij9okp

Disclaimer: I would like to explain that my sever sleep depravation 😪 does its work and if any part of my message comes out to you as rude etc. please just ignore that feeling as nothing from this message is meant to sound rude etc.

As name of function suggests, well, it requires you to pass in info, so the result of ytdl.getInfo(link) and then, the second parameter, is for options, in there you go with them, image

list of options (sorry for being lazy) image

Hakunek avatar Apr 22 '23 21:04 Hakunek

Hello @Hakunek , Is the below correct way to download audio from an YouTube video?

const fs = require('fs');
const ytdl = require('ytdl-core');

/**
 * Download mp3 audio from an YouTube URL.
 * 
 * @param {String} ytUrl YouTube video URL.
 * @param {String} filePath Absolute filepath where audio file should be saved.
 */
async function downloadAsAudio(ytUrl, filePath) {
    return new Promise(async (resolve) => {
        ytdl(ytUrl, {
            filter: 'audioonly',
            quality: 'highestaudio',
        }).pipe(fs.createWriteStream(filePath)).on('finish', () => resolve());
    });
}

await downloadAsAudio(<yt URL>, 'audio.mp3');
console.log('File is downloaded');

rdp1414 avatar Apr 27 '23 14:04 rdp1414

Hello @Hakunek , Is the below correct way to download audio from an YouTube video?

const fs = require('fs');
const ytdl = require('ytdl-core');

/**
 * Download mp3 audio from an YouTube URL.
 * 
 * @param {String} ytUrl YouTube video URL.
 * @param {String} filePath Absolute filepath where audio file should be saved.
 */
async function downloadAsAudio(ytUrl, filePath) {
    return new Promise(async (resolve) => {
        ytdl(ytUrl, {
            filter: 'audioonly',
            quality: 'highestaudio',
        }).pipe(fs.createWriteStream(filePath)).on('finish', () => resolve());
    });
}

await downloadAsAudio(<yt URL>, 'audio.mp3');
console.log('File is downloaded');

besides small problem with the code, like await before downloadAsAudio outside of asynchronous function using .then(()=>console.log("...")) would've get the job done without the need of await, also I recommend setting somehting as param for resolve even stupid true or false

as for the main part of the code you are not guaranteed to receive a stream of MP3 encoded audio, it may be AAC, or something else

I would recommend using something like ffmpeg to make sure that in the end you have that file as propper mp3 if you need that file in mp3 format

PS. please include the disclaimer from my previous comment in here, as in those 5 days since that comment I got only 5 hours of sleep ^-^"

Hakunek avatar Apr 28 '23 07:04 Hakunek

Disclaimer: I would like to explain that my sever sleep depravation sleepy does its work and if any part of my message comes out to you as rude etc. please just ignore that feeling as nothing from this message is meant to sound rude etc.

As name of function suggests, well, it requires you to pass in info, so the result of ytdl.getInfo(link) and then, the second parameter, is for options, in there you go with them, image

list of options (sorry for being lazy) image

Thanks for the reply, I lack also some sleep so I understand and no you wasn't rude. Does selecting highestaudio ensures the highes audio or are yt videos really streaming at 128bps?

4e576rt8uh9ij9okp avatar May 14 '23 21:05 4e576rt8uh9ij9okp

@4e576rt8uh9ij9okp highestaudio option at least to my understanding, selects the best audio quality available for that video and what is the highest audio quality depends on the format the video was uploaded to yt in as we can't really upscale video/audio without problems

(if there is someone smarter than me, please correct me, as I'm not a guru in terms of audio quality and youtube)

Hakunek avatar May 15 '23 07:05 Hakunek

Posting here in case someone is curious how to auto detect the extension for the audio file.


  const videoID = await ytdl.getVideoID(
    "https://www.youtube.com/watch?v=H14bBuluwB8"
  );
  let info = await ytdl.getInfo(videoID);
  let audioFormats = ytdl.filterFormats(info.formats, "audioonly");
  const format = ytdl.chooseFormat(audioFormats, { quality: "highestaudio" });
  const fileName = `video.${format.container}`;
  await ytdl
    .downloadFromInfo(info, { format })
    .pipe(fs.createWriteStream(fileName));