fent / node-ytdl-core

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

How to download audio? #1212

Open 4e576rt8uh9ij9okp opened 1 year ago

4e576rt8uh9ij9okp commented 1 year ago

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)
Hakunek commented 1 year ago

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

rdp1414 commented 1 year ago

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');
Hakunek commented 1 year ago

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 ^-^"

4e576rt8uh9ij9okp commented 1 year ago

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?

Hakunek commented 1 year ago

@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)

intergalacticspacehighway commented 3 months ago

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));