How to Download multiple Youtube Videos using Nodejs and Show a Progress Bar

March 30, 2021

Introduction

I was trying to download some youtube videos for my kids. As I have a road trip coming. So, instead of downloading manually. I tried writing a script using nodejs.

I have a bunch of youtube videos in a text file, line by line.

Example

https://www.youtube.com/watch?v=MeYm_jj6Fng
https://www.youtube.com/watch?v=QE7HUkHdkW8
https://www.youtube.com/watch?v=R0RCeqBzANo
https://www.youtube.com/watch?v=nU9A9L5kZRU

Nodejs Code to Download Youtube videos

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

const cliProgress = require('cli-progress');
const bar1 = new cliProgress.SingleBar({}, cliProgress.Presets.shades_classic);

const videos = fs.readFileSync('./videos.txt', 'utf8').split(/\r?\n/);

return new Promise((resolve, reject) => {
  async.eachLimit(videos, 1,
      function (url, callback) {
        console.log(url);
        const filename = `./downloaded/${url.split('=')[1]}.mp4`

        let downloadStarted = false;
        ytdl(url)
          .on('progress', (_, totalDownloaded, total) => {
            if (!downloadStarted) {
              bar1.start(total, 0);
              downloadStarted = true;
            }

            bar1.update(totalDownloaded);
          })
          .on('end', (_, totalDownloaded, total) => {
            bar1.stop();
            callback();
          })
          .pipe(fs.createWriteStream(filename));

      }.bind(this),
      function (err) {
          if (err) {
              console.error(err);
              reject(err);
          } else {
              resolve();
          }
      }
  );
});

Explanation to above code

The code is quite small. I’m reading from a file videos.txt where the urls are written line by line.

Let me try to break above code:

Read from file

const fs = require('fs);
const videos = fs.readFileSync('./videos.txt', 'utf8').split(/\r?\n/);

I’m reading and splitting all content by new line character. So, I will have an array of urls.

Library to download Youtube video

Its quite popular library. ytdl-core

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

I’m doing no fancy stuff. Simply downloading by doing a pipe.

ytdl(url)
  .pipe(fs.createWriteStream(filename));

Executing in Syc

This library provides no promise support. So, I used async module.

return new Promise((resolve, reject) => {
  async.eachLimit(videos, 1,
      function (url, callback) {
        
        //operation
        callback();

      }.bind(this),
      function (err) {
          if (err) {
              console.error(err);
              reject(err);
          } else {
              resolve();
          }
      }
  );
});

Note: Above code can run in parallel. I’m running in single way. By providing 2nd parameter as 1.

Progress bar

Another quite popular library: cli-progress

const cliProgress = require('cli-progress');
const bar1 = new cliProgress.SingleBar({}, cliProgress.Presets.shades_classic);

//initialize
bar1.start(total, 0);

//stop
bar1.stop();

Sample Output

https://www.youtube.com/watch?v=rqNxtyZAOhA
 ████████████████████████████████████████ 100% | ETA: 0s | 16069480/16069480
https://www.youtube.com/watch?v=EpuDYZ_g0yg
 ████████████████████████████████████████ 100% | ETA: 0s | 22471833/22471833
https://www.youtube.com/watch?v=31F0laJjyy8
 ████████████████████████████████████████ 100% | ETA: 0s | 19234721/19234721
https://www.youtube.com/watch?v=M8rW-IvX3JM
 ████████████████████████████████████████ 100% | ETA: 0s | 32604186/32604186
https://www.youtube.com/watch?v=Q0gfC1kvYow
 ████████████████████████████████████████ 100% | ETA: 0s | 18743655/18743655
https://www.youtube.com/watch?v=HOQE0bv3_ks
 ████████████████████████████████████████ 100% | ETA: 0s | 37773979/37773979
https://www.youtube.com/watch?v=6zI4_1Blkko
 ████████████████████████████████████████ 100% | ETA: 0s | 45062755/45062755
https://www.youtube.com/watch?v=jCvSEuHms5M
 ████████████████████████████████████████ 100% | ETA: 0s | 140657573/140657573
https://www.youtube.com/watch?v=NQy4MVp1kgw
 ████████████████████████████████████████ 100% | ETA: 0s | 171159978/171159978
https://www.youtube.com/watch?v=dFm-5AxgwEE
 ████████████████████████████████████████ 100% | ETA: 0s | 15894197/15894197
https://www.youtube.com/watch?v=dSi9EeQhpLw
 █████████████████████████████████████░░░ 93% | ETA: 23688s | 273020896/292460792

Hope it will help.


Similar Posts

Latest Posts