GithubHelp home page GithubHelp logo

Comments (10)

fent avatar fent commented on May 12, 2024

ytld.getInfo() is NOT synchronous, it needs to travel to youtube servers to get video info.

ytdl.getInfo('https://www.youtube.com/watch?v=rHLbd3nvu88', { downloadURL: true }, function(err, songInfo) {
  if (err) throw err;
  ytdl.downloadFromInfo(songInfo, { filter: 'audioonly' }).pipe(res);
});

ytdl() is synchronous because it returns a readable stream, but its data isn't immediately available.

from node-ytdl-core.

johnRivs avatar johnRivs commented on May 12, 2024

I see.. My knowledge on node is crippling me at the moment. This is what I'm ultimately trying:

var app      = require('express')(),
    ytdl     = require('ytdl-core'),
    ffmpeg   = require('fluent-ffmpeg'),
    archiver = require('archiver'),
    async    = require('async');

app.get('/', function(req, res) {
    var archive = archiver.create('zip', {});

    ytdl.getInfo('https://www.youtube.com/watch?v=rHLbd3nvu88', { downloadURL: true }, function(err, songInfo) {
        archive.append(
            ffmpeg(
                ytdl('https://www.youtube.com/watch?v=rHLbd3nvu88', { filter: 'audioonly' })
            ).format('mp3').pipe(), {
                name: Date.now() + '.mp3'
            }
        );
    });

    res.setHeader('Content-disposition', 'attachment; filename=u2fy_' + Date.now() + '.zip');
    res.setHeader('Content-type', 'application/zip');

    archive.finalize().pipe(res);
});

When I do this without getInfo(), it works perfectly; the user recieves a zip file with the audio without it being created on the server. However, when I perform the same thing inside the callback function, I get an error by archiver: append: queue closed. Passing songInfo to ytdl() doesn't seem to work for me either.

Any hint?

from node-ytdl-core.

fent avatar fent commented on May 12, 2024

That sounds like it might be an error with ytdl, but why do you need to call ytdl.getInfo() if you're not using songInfo?

You could also listen for the info event on the stream it returns.

var video = ytdl('https://www.youtube.com/watch?v=rHLbd3nvu88', { filter: 'audioonly' });
video.on('info', function() {
});

from node-ytdl-core.

johnRivs avatar johnRivs commented on May 12, 2024

I couldn't get that work, because of said [Error: append: queue closed] from archiver. Switched to:

ffmpeg(
    ytdl.downloadFromInfo(songInfo, { filter: 'audioonly' })
)

Same thing though.

About the info event, would that work in my case? Because I need to pass a stream to ffmpeg(). How would that look like if I was to use the info event callback?

from node-ytdl-core.

fent avatar fent commented on May 12, 2024

do you need the info?

from node-ytdl-core.

johnRivs avatar johnRivs commented on May 12, 2024

Oh I forgot, I used Date.now() instead of the actual thing I'm supposed to use, which is the title of the video. Sorry about that confusion :P

from node-ytdl-core.

fent avatar fent commented on May 12, 2024

Oh, then something like

var video = ytdl('https://www.youtube.com/watch?v=rHLbd3nvu88', { filter: 'audioonly' });
video.on('info', function(info) {
  archive.append(ffmpeg(video).format('mp3').pipe(), { name: info.title});
});

from node-ytdl-core.

johnRivs avatar johnRivs commented on May 12, 2024

No luck :( Seems like archive.append() doesn't like being inside a callback.

from node-ytdl-core.

johnRivs avatar johnRivs commented on May 12, 2024

Ok, I've gone a different direction. My guess is, archive.finalize() gets piped to the response way to early, the queue closes and no more appends can happen.

So now I'm returning the archive but only finalizing it when everything is in:

var archive = archiver.create('zip', {}),
    songs   = [
        'https://www.youtube.com/watch?v=vK_3AS2gavY'
    ],
    entries = 0;

var video = ytdl(songs[0], { filter: 'audioonly' });

video.on('info', function(info) {
    archive.append(ffmpeg(video).format('mp3').pipe(), { name: info.title + '.mp3'});
});

archive.on('entry', function(data) {
    entries++;

    if (songs.length === entries) {
        archive.finalize();
    }
});

res.setHeader('Content-disposition', 'attachment; filename=u2fy_' + Date.now() + '.zip');
res.setHeader('Content-type', 'application/zip');

archive.pipe(res);

It works, however, I can't figure out a way to make a loop in order to download more than 1 video. If I was able to apply the listener to ytdl instead of a specific var video = ytdl(songs[0], { filter: 'audioonly' });, I wouldn't have this problem I guess. Or if ytdl accepted an array of URLs so the info event can be triggered more than once.

By the way, the entry event gets triggered once an entry has been processed.

from node-ytdl-core.

fent avatar fent commented on May 12, 2024

I don't understand why this wouldn't work for more than 1 video.

wouldn't you just loop for the list of video urls and append for each?

from node-ytdl-core.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.