Search code examples
javascriptnode.jsyoutubestreampipe

pipe works on localhost but not on remote nodejs


I'm trying to use ytdl-core module in order to download youtube audio to my local disk (some path on my computer).

I created an API to which I can call with the requested youtube url and the destination folder in which I want the file to be saved.

app.get('/api/downloadYoutubeVideo', function (req, res) {  
var videoUrl = req.query.videoUrl;  
var destDir = req.query.destDir;    

ytdl.getInfo(videoUrl, function(err, info){
        var videoName = info.title.replace('|','').toString('ascii');       

        var stream = ytdl(videoUrl, { filter: 'audioonly'})
                       .pipe(fs.createWriteStream(destDir + '\\' + videoName + '.mp3'));

        stream.on('finish', function() {
            res.writeHead(204);
            res.end();
        });             
    });         
}); 

The problem is that when I call the api on my localhost (example: localhost:11245/api/downloadYoutubeVideo?videoUrl=https://www.youtube.com/watch?v=E5kJDWQSBUk&destDir=C:\test) it works and the file indeed downloads to "C:\test".

But when I call to the api on my remote (example: http://sometest.cloudno.de/api/downloadYoutubeVideo?videoUrl=https://www.youtube.com/watch?v=02BAlrAkuCE&destDir=C:\test)

it doesnt create the file in the directory...

I have searched the answer but haven't found one...


Solution

  • Does C:\test already exist on your remote? If not you can't use fs.createWriteStream() until the directory has been created, it will not create the directory for you implicitly. Since you're not listening for an 'error' event, you wouldn't even know that was the problem since you're not capturing it.

    The below code sample will check for the existence of destDir and if it doesn't exist will create it before proceeding.

    const fs = require('fs');
    const sep = require('path').sep;
    
    function checkAndMakeDir(dir, cb) {
      fs.access(dir, (err) => {
        if (err)
          fs.mkdir(dir, (err) => {
            if (err)
              return cb(err);
    
            return cb();
          });
        else
          return cb();
      });
    }
    
    app.get('/api/downloadYoutubeVideo', function (req, res) {
      let videoUrl = req.query.videoUrl;
      let destDir = req.query.destDir;
    
      checkAndMakeDir(destDir, (err) => {
        if (err) {
          res.writeHead(500);
          return res.end();
        }
    
        ytdl.getInfo(videoUrl, function (err, info) {
          let videoName = info.title.replace('|', '').toString('ascii');
          let saveStream = fs.createWriteStream(`${destDir}${sep}${videoName}.mp3`);
    
          saveStream.once('error', (err) => {
            console.log(err);
            res.writeHead(500);
    
            return res.end();
          });
    
          saveStream.once('finish', () => {
            res.writeHead(204);
            return res.end();
          });
    
          ytdl(videoUrl, {filter: 'audioonly'})
            .once('error', (err) => {
              console.log('Read Stream Error', err);
    
              res.writeHead(500);
              return res.end();
            })
            .pipe(saveStream);
        });
      });
    });