Important: This documentation covers Yarn 1 (Classic).
For Yarn 2+ docs and migration guide, see yarnpkg.com.

Package detail

youtube-dl

przemyslawpluta8.9kMITdeprecated3.5.0TypeScript support: definitely-typed

node-youtube-dl is deprecated. use npm.im/youtube-dl-exec instead.

youtube-dl driver for node

download, video, youtube

readme

youtube-dl

Build Status npm version

Download videos from youtube in node.js using youtube-dl.

If you're only interested in downloading only from youtube, you should consider using pure Javascript youtube downloading module.

Installation

With npm do:

npm install youtube-dl

Usage

Downloading videos

const fs = require('fs')
const youtubedl = require('youtube-dl')

const video = youtubedl('http://www.youtube.com/watch?v=90AiXO1pAiA',
  // Optional arguments passed to youtube-dl.
  ['--format=18'],
  // Additional options can be given for calling `child_process.execFile()`.
  { cwd: __dirname })

// Will be called when the download starts.
video.on('info', function(info) {
  console.log('Download started')
  console.log('filename: ' + info._filename)
  console.log('size: ' + info.size)
})

video.pipe(fs.createWriteStream('myvideo.mp4'))

It will produce an output that looks like the following when ran.

Got video info
saving to T-ara - Number Nine - MV - 티아라-Seku9G1kT0c.mp4
100.00%

Resuming partially downloaded videos

const youtubedl = require('youtube-dl')
const fs = require('fs')
const output = 'myvideo.mp4'

let downloaded = 0

if (fs.existsSync(output)) {
  downloaded = fs.statSync(output).size
}

const video = youtubedl('https://www.youtube.com/watch?v=179MiZSibco',

  // Optional arguments passed to youtube-dl.
  ['--format=18'],

  // start will be sent as a range header
  { start: downloaded, cwd: __dirname })

// Will be called when the download starts.
video.on('info', function(info) {
  console.log('Download started')
  console.log('filename: ' + info._filename)

  // info.size will be the amount to download, add
  let total = info.size + downloaded
  console.log('size: ' + total)

  if (downloaded > 0) {
    // size will be the amount already downloaded
    console.log('resuming from: ' + downloaded)

    // display the remaining bytes to download
    console.log('remaining bytes: ' + info.size)
  }
})

video.pipe(fs.createWriteStream(output, { flags: 'a' }))

// Will be called if download was already completed and there is nothing more to download.
video.on('complete', function complete(info) {
  'use strict'
  console.log('filename: ' + info._filename + ' already downloaded.')
})

video.on('end', function() {
  console.log('finished downloading!')
})

It will produce an output that looks like the following when ran.

Output:

[~/nodejs/node-youtube-dl/example]$ node resume.js
Download started
filename: 1 1 1-179MiZSibco.mp4
size: 5109213
^C
[~/nodejs/node-youtube-dl/example]$ node resume.js
Download started
filename: 1 1 1-179MiZSibco.mp4
size: 5109213
resuming from: 917504
remaining bytes: 4191709
finished downloading

Getting video information

const youtubedl = require('youtube-dl')

const url = 'http://www.youtube.com/watch?v=WKsjaOqDXgg'
// Optional arguments passed to youtube-dl.
const options = ['--username=user', '--password=hunter2']

youtubedl.getInfo(url, options, function(err, info) {
  if (err) throw err

  console.log('id:', info.id)
  console.log('title:', info.title)
  console.log('url:', info.url)
  console.log('thumbnail:', info.thumbnail)
  console.log('description:', info.description)
  console.log('filename:', info._filename)
  console.log('format id:', info.format_id)
})

Running that will produce something like

id: WKsjaOqDXgg
title: Ace Rimmer to the Rescue
url: http://r5---sn-p5qlsn7e.c.youtube.com/videoplayback?ms=au&ip=160.79.125.18&cp=U0hWTFVQVl9FTENONl9NSlpDOjgtU1VsODlkVmRH&id=58ab2368ea835e08&source=youtube&expire=1377558202&factor=1.25&key=yt1&ipbits=8&mt=1377534150&itag=34&sver=3&upn=-rGWz2vYpN4&fexp=912306%2C927900%2C919395%2C926518%2C936203%2C913819%2C929117%2C929121%2C929906%2C929907%2C929922%2C929127%2C929129%2C929131%2C929930%2C925726%2C925720%2C925722%2C925718%2C929917%2C906945%2C929919%2C929933%2C912521%2C932306%2C913428%2C904830%2C919373%2C930803%2C908536%2C904122%2C938701%2C936308%2C909549%2C900816%2C912711%2C904494%2C904497%2C900375%2C906001&sparams=algorithm%2Cburst%2Ccp%2Cfactor%2Cid%2Cip%2Cipbits%2Citag%2Csource%2Cupn%2Cexpire&mv=m&burst=40&algorithm=throttle-factor&signature=ABD3A847684AD9B39331E567568D3FA0DCFA4776.7895521E130A042FB3625A17242CE3C02A4460B7&ratebypass=yes
thumbnail: https://i1.ytimg.com/vi/WKsjaOqDXgg/hqdefault.jpg
description: An old Red Dwarf eposide where Ace Rimmer saves the Princess Bonjella.
filename: Ace Rimmer to the Rescue-WKsjaOqDXgg.flv
format id: 34

You can use an array of urls to produce an array of response objects with matching array index (e.g. the 1st response object will match the first url etc...)

const youtubedl = require('youtube-dl')

const url1 = 'http://www.youtube.com/watch?v=WKsjaOqDXgg'
const url2 = 'https://vimeo.com/6586873'

youtubedl.getInfo([url1, url2], function(err, info) {
  if (err) throw err

  console.log('title for the url1:', info[0].title)
  console.log('title for the url2:', info[1].title)
})

Using a proxy

const youtubedl = require('youtube-dl')

const video = youtubedl('http://www.youtube.com/watch?v=90AiXO1pAiA',
  // Optional arguments passed to youtube-dl.
  ['--proxy', 'http://ip:port'],

Downloading subtitles

const youtubedl = require('youtube-dl')
const url = 'https://youtu.be/PizwcirYuGY'

const options = {
  // Write automatic subtitle file (youtube only)
  auto: false,
  // Downloads all the available subtitles.
  all: false,
  // Subtitle format. YouTube generated subtitles
  // are available ttml or vtt.
  format: 'ttml',
  // Languages of subtitles to download, separated by commas.
  lang: 'en',
  // The directory to save the downloaded files in.
  cwd: __dirname,
}

youtubedl.getSubs(url, options, function(err, files) {
  if (err) throw err

  console.log('subtitle files downloaded:', files)
})

Downloading thumbnails

const youtubedl = require('youtube-dl')
const url = 'https://youtu.be/PizwcirYuGY'

const options = {
  // Downloads available thumbnail.
  all: false,
  // The directory to save the downloaded files in.
  cwd: __dirname,
}

youtubedl.getThumbs(url, options, function(err, files) {
  if (err) throw err

  console.log('thumbnail file downloaded:', files)
})

For more usage info on youtube-dl and the arguments you can pass to it, do youtube-dl -h or go to the youtube-dl documentation.

Downloading playlists


const path = require('path')
const fs   = require('fs')
const youtubedl = require('youtube-dl')

function playlist(url) {

  'use strict'
  const video = youtubedl(url)

  video.on('error', function error(err) {
    console.log('error 2:', err)
  })

  let size = 0
  video.on('info', function(info) {
    size = info.size
    let output = path.join(__dirname + '/', size + '.mp4')
    video.pipe(fs.createWriteStream(output))
  })

  let pos = 0
  video.on('data', function data(chunk) {
    pos += chunk.length
    // `size` should not be 0 here.
    if (size) {
      let percent = (pos / size * 100).toFixed(2)
      process.stdout.cursorTo(0)
      process.stdout.clearLine(1)
      process.stdout.write(percent + '%')
    }
  })

  video.on('next', playlist)
}

playlist('https://www.youtube.com/playlist?list=PLEFA9E9D96CB7F807')

Note node-youtube-dl does not currently support playlist urls with the "list" format:

https://www.youtube.com/watch?v=<video-id>&list=<playlist id>

Please use instead the equivalent "playlist" format as the example below:

https://www.youtube.com/playlist?list=<playlist id>

The following snippet could be of use when making this format conversion.

function toSupportedFormat(url) {
    if (url.includes("list=")) {
        var playlistId = url.substring(url.indexOf('list=') + 5);
        return "https://www.youtube.com/playlist?list=" + playlistId;
    }
    return url;
}

var url = "https://www.youtube.com/watch?v=shF8Sv-OswM&list=PLzIUZKHPb1HbqsPMIFdE0My54iektZrNU"
url = toSupportedFormat(url);
console.log(url) // "https://www.youtube.com/playlist?list=PLzIUZKHPb1HbqsPMIFdE0My54iektZrNU"

Getting the list of extractors

const youtubedl = require('youtube-dl')

youtubedl.getExtractors(true, function(err, list) {
  console.log('Found ' + list.length + ' extractors')

  for (let i = 0 i < list.length i++) {
    console.log(list[i])
  }
})

Will print something like

Found 521 extractors
1up.com
220.ro
24video
3sat

Getting the binary path

const youtubedl = require('youtube-dl')

console.log(youtubedl.getYtdlBinary())

Changing the binary path

const path = require('path')
const youtubedl = require('youtube-dl')

const customBinaryPath = path.resolve('custom/path/to-binary')

youtubedl.setYtdlBinary(customBinaryPath)

Call the youtube-dl binary directly

This module doesn't have youtube-dl download the video. Instead, it uses the url key from the --dump-json CLI option to create a node stream. That way, it can be used like any other node stream.

If that, or none of the above support your use case, you can use youtubedl.exec() to call youtube-dl however you like.

const youtubedl = require('youtube-dl')

youtubedl.exec(url, ['-x', '--audio-format', 'mp3'], {}, function(err, output) {
  if (err) throw err

  console.log(output.join('\n'))
})

Update

Since the youtube-dl binary is updated regularly, you can run npm run update to check for and download any updates for it. You can also require youtube-dl/lib/downloader in your app if you'd like to place youtube-dl binary in a specific directory and control when it gets updates.

const downloader = require('youtube-dl/lib/downloader')

downloader('path/to-binary', function error(err, done) {
  'use strict'
  if (err) throw err

  console.log(done)
})

This script parses a couple of flags from argv:

  • --platform=windows forces downloading the Windows version of youtube-dl.
  • --overwrite overwrites the existing youtube-dl executable if it exists.

Update (promise version)

If you are using promises there's now a promise version, if you don't pass a function as second argument:

const downloader = require('youtube-dl/lib/downloader')

downloader('path/to-binary')
.then((message) => {
    console.log(message);
}).catch((err) => {
    console.log("err", err);
    exit(1);
});

Environment Variables

Youtube-dl looks for certain environment variables to aid its operations. If Youtube-dl doesn't find them in the environment during the installation step, a lowercased variant of these variables will be used from the npm config or yarn config.

  • YOUTUBE_DL_DOWNLOAD_HOST - overwrite URL prefix that is used to download the binary file of Youtube-dl. Note: this includes protocol and might even include path prefix. Defaults to https://yt-dl.org/downloads/latest/youtube-dl.

Tests

Tests are written with vows

npm test

License

MIT

changelog

3.5.0 (2021-02-21)

  • feat: ensure python is available on the machine (102de70)

3.4.1 (2021-02-20)

3.4.0 (2021-02-18)

  • build: remove unnecessary dependency (375ae5e)
  • build: update dependencies (abedf17)
  • refactor: sort (9d36ad5)
  • chore: update got to v11 (4def2dd)
  • fix(test): youtube service webp images instead of jpg and youtube-dl doesn't have a switch (645964f)
  • Replace Request with Got (c9670e3)

3.3.0 (2021-02-18)

3.2.0 (2021-02-18)

  • fix: get binary url from github releases (173c5fa)

3.1.0 (2021-01-10)

  • build: add contributors (c01efab)
  • build: remove git add from git pre hooks (8f779b7)
  • build: update dependencies (ea20196)
  • ci: update node builds (9b87bad)
  • Execa function may not pass stdout in callback function if run it with the { stdio: 'inherit' } op (a85b449)
  • fix #320: webp and not jpeg (bae7c99), closes #320
  • handles overwriting (a3551d1)
  • promise version of downloader (e11831a)
  • promise when there's no argument (d6133fc)
  • README documentation for #271 (2ab626e), closes #271

3.0.2 (2020-01-31)

  • fix: don't fail on videos when ytdl returns filesize null (8f6235b)

3.0.1 (2020-01-16)

3.0.0 (2020-01-13)

  • ci: drop node8 support (333fb7a)
  • always add range header on data request (4bd8904)
  • test: adding download large audio (871382f)
  • test: fix failure due to latest server data (4f5e44b)

2.3.0 (2019-12-15)

  • Update get-binary.js (b98425a)
  • refactor: log warning instead of an error if the binary is not found (1ecca38)
  • refactor: only log missing binary error if debug is enabled (3535e36)
  • fix: log error if the youtube-dl binary does not exist (1898e8c)

2.2.0 (2019-12-12)

  • Update downloader.js (952826a)
  • Update README.md (341882f)
  • fix: access to download binary from mirror sites (7751e65)

2.1.0 (2019-10-29)

  • build: add execa dependency (ffddb6f)
  • build: update contributors (00dcf5e)
  • fix: avoid destructure under error (8fb0e20)
  • Add a timeout to close connection if its idle. (51963bd)
  • Update youtube-dl.js (9195b44)

2.0.2 (2019-10-25)

  • fix: add access to ChildProcess from outside (0c10ce5)
  • docs: Add undocumented getYtdlBinary & setYtdlBinary functions (3e91ebf)
  • docs: normalize youtubedl require statements and remove semicolons (28373a0)

2.0.1 (2019-08-10)

2.0.0 (2019-05-22)

  • build: be possible setup downloader for windows (8111957)
  • build: improve workflow (5ce37dd)
  • build: improve workflow (9ff909e)
  • build: setup node version (41f0a80)
  • build: setup properly release message (8f7a11b)
  • build: take end on consideration (66e1324)
  • refactor: remove dead code (1a74f06)

1.13.5 (2019-05-22)

  • Fix non-json outputs (cfff104)
  • Fix typo in comments (e968072)
  • New has() method that replaces arr.indexOf where applicable (5ec1f87)
  • Removed package-lock.json (56cbc63)
  • Replace typeof === "string" with util.isString globally (e3f4a9d)
  • Fix: Checking if we have args before testing them (113ed2a)

1.13.4 (2019-05-18)

1.13.3 (2019-05-16)

  • test: update (fd31af8)
  • fix: fix a regression caused by previous refactorings (dfed31a), closes #230
  • Enable option to select subtitle formats (4bc1caa)

1.13.2 (2019-03-29)

  • Send header because gets 403 if cookie is needed (91f3f69)

1.13.1 (2019-02-04)

  • Fixed typo & removed redundant line (156bbd5)

1.13.0 (2019-01-25)

  • build: add release process (8cc1b05)
  • test: update snapshots (65fb75e)
  • add editorconfig (8a92f0b)
  • add hms to duration, twitch test (9ea3ff1)
  • add sensible execFile good defaults (2524d75), closes #173
  • Adding dashes before the video ID (da8f4dd)
  • changed to _filename in line 33 readme (87d3891)
  • Consider copyright videos as not available in order to continue on error (e19d8d1)
  • Consider not made available videos as not available in order to continue on error (ae7ea3b)
  • Correct extension in playlist.js (5d77436)
  • Correct test with correct video info (0ee2609)
  • Disable non-functional test (ca1aa42)
  • download best and combine is ffmpeg available (2193220)
  • Download correct binary for windows systems (3874a88)
  • drop tests for 4,5 and version bump (3634c67)
  • Fix encoding issue on windows (d65114d)
  • Get and set path from youtube-dl (161ed2a)
  • handle thumbnails download (a0832dc)
  • hms and raw duration (eb0e9de)
  • meta tweaks (f685ad7)
  • minor typo (429b1f7)
  • missing ; (05f8f62)
  • remove dead code (4b1ba39)
  • remove deprecated badge (19a7b33)
  • remove lock (0131daf)
  • Remove size from download test, not relevant (e22ee14)
  • remove vimeo tests (1f717cc)
  • update dependencies (bf28967)
  • update snapshot (70ec50a)
  • Update test about twitch (twitch id are not anymore the video title) (b9f0317)
  • update travis builds (efe313c)
  • Updated test case since video title changed on twitch's end (7c22361)
  • use const over var (6ed5a1c)

1.12.1 (2017-09-28)

1.11.1 (2016-04-06)

1.11.0 (2016-03-25)

  • add getFormats example (d9b2925)
  • add node 4 & 5 for testing (8683ac1)
  • adding ability to continue partially downloaded files. (e9e540a)
  • allow for external bin but keep details internally (f35daab)
  • As requested, I was trying to make the code as readable as possible (38884d1)
  • callback err (f49128c)
  • change bin permissions (957172b)
  • check for datadir existence (1817160)
  • choose bin location (1123d33)
  • cleanup (12eb585)
  • cleanup (1a8b2f0)
  • cleanup .gitignore (bf5b974)
  • dependencies bump (f131dca)
  • document ytdl.exec() with audio example (2b8333f)
  • extract downloader (f27c45a)
  • fix bin path (6f9ef39)
  • fix license meta in pacakge.json (3d2f168)
  • fix resolution or audio (d2a3269)
  • handle playlists (acb1571)
  • install module before download (f3e0ac7)
  • missing dependency (f56cb24)
  • move bin path to datadir (7ef58ef)
  • no longer maintaining (1aa9076)
  • package postinstall (c1f052f)
  • permission change on bin (c061caa)
  • permission change on bin cleanup test (6912150)
  • preventing options being created if it doesn't exist (894e215)
  • remove unused module (6fc3f02)
  • resolve to .exe on win (2c5467e)
  • skip over not available videos during playlist download (45ee26b)
  • store example videos in dir to keep things cleaner (e7cc0d5)
  • update (4da180b)
  • update (60a0cf4)
  • update path (b9992cf)
  • update readme (c159427)
  • update readme (a41b965)
  • update README (1565229)
  • update tests (7be149d)
  • Updating comment block for inline quotes, replacing double quotes with single quotes (1646cec)

1.10.5 (2015-05-07)

1.10.4 (2015-05-07)

1.10.3 (2015-04-19)

  • 1.10.3 (a70895e)
  • Fix the broken Host HTTP Header for Dailymotion && Fix Test (9657b8c)

1.10.2 (2015-03-24)

1.10.1 (2015-02-26)

  • 1.10.1 (498e288)
  • add io.js and 0.12 to test matrix (17ce70b)
  • call binary with python instead of directly, fixes #66 (833d281), closes #66
  • dont test on node v0.8 (5c1c182)
  • quote iojs (47d1485)
  • update packages (413cf53)
  • use container based environment (4947618)

1.10.0 (2015-02-19)

  • 1.10.0 (d3018e5)
  • Multiple URL support (array param) for getInfo() (1afab0b)

1.9.0 (2015-02-13)

  • 1.9.0 (e3be488)
  • add warnings for using deprecated fields (d2c53ae)
  • Call getInfo from getFormats (4ecda89)
  • document how to keep youtube-dl binary up to date. fixes #61 (a8eface), closes #61
  • dont check each individual format object (50c113f)
  • fix getting playlist info (cdb37fe)
  • Move formatDuration to util.js (c309c24)
  • remove unused old functions (e4689a6)
  • Return the full info provided by youtube-dl (ace1b11)
  • Use the '--dump-json' option for extracting the video information (b3a9fcd)
  • Use the '--dump-json' option for getFormats (e93a8b9)

1.8.0 (2015-01-15)

  • 1.8.0 (ab8b3df)
  • Added extractor API incl. tests and example code (d2b3983)
  • dont download video when downloading subtitles (3cfa382)
  • put try/catch around unlinking subtitle file (a3f5202)

1.7.0 (2015-01-08)

  • 1.7.0 (777619e)
  • added more cli args to ignore (8edbd1e)
  • get duration. fixes #53 (fd7d7c9), closes #53
  • make args passed to youtube-dl actually optional (413d0ab)

1.6.0 (2014-11-23)

1.5.16 (2014-10-24)

1.5.15 (2014-09-25)

1.5.14 (2014-09-24)

  • 1.5.14 (c7d7c08)
  • expose call function with empty default args as exec (e12b538)
  • ignore any errors after successful download. fixes #43 (58558d8), closes #43

1.5.13 (2014-09-07)

1.5.12 (2014-09-04)

1.5.11 (2014-08-24)

  • 1.5.11 (09d2951)
  • support non-youtube (speificially vimeo) videos. fixes #39 (cd6938b), closes #39

1.5.10 (2014-08-05)

1.5.9 (2014-08-02)

  • 1.5.9 (303fb12)
  • Add more entries to badArgs (a6821b5)
  • fix for failed download with no subtitles (36fd75a)
  • fix for failed download with no subtitles when requested (69166bf)
  • fix for failed download with no subtitles when requested (aeab2dd)
  • fix for failed download with no subtitles when requested (038b1fd)
  • fix for failed download with no subtitles when requested (19c13af)
  • fix for failed download with no subtitles when requested (82a48a4)
  • only notify on build changes (3cf3363)
  • update request to v2.37.0 (11757f3)

1.5.8 (2014-07-04)

1.5.6 (2014-06-14)

1.5.5 (2014-05-02)

  • can pass execFile options to download (2986447)
  • dont parse options twice on download (67eb88d)
  • v1.5.5 (20c3cd2)

1.5.4 (2014-05-01)

1.5.3 (2014-04-26)

1.5.2 (2014-04-25)

  • Add a second var (76d3468)
  • Fix "Cannot call method 'split' of undefined" bug with last version of youtube-dl (2014.04.21.6) (864a526)
  • Remove commented old code (9804155)
  • Remove the extra space (11aabf9)
  • Save the regexp in the outer scope so it's not compiled every time this function runs (585c526)
  • v1.5.2 (88be6d7)

1.5.1 (2014-04-08)

1.5.0 (2014-04-08)

1.4.0 (2014-03-14)

1.3.6 (2014-02-15)

1.3.5 (2014-02-15)

  • Fix - win handling getInfo & getFormats (19ccc54)
  • Fix - win handling getInfo & getFormats (7655ea1)
  • v1.3.5 (6f4eb9c)

1.3.4 (2014-02-14)

  • Fix - Incorrect youtube video URL (954df15)
  • Fix - Incorrect youtube video URL (17c4214)
  • Fix - Incorrect youtube video URL (12dea04)
  • Fix - Incorrect youtube video URL (1b10dff)
  • Fix - Incorrect youtube video URL (408e2b1)
  • Fix - Incorrect youtube video URL (c161fa6)
  • Fix - Incorrect youtube video URL (753ae6b)
  • Fix - Incorrect youtube video URL (04f4aaa)
  • Fix - Incorrect youtube video URL (a5eeb09)
  • Fix - Incorrect youtube video URL (28dd461)
  • only write version to file if downloaded successfully (091f425)
  • v1.3.4 (6825c7b)

1.3.3 (2014-02-12)

1.3.2 (2013-10-22)

  • improve regexp to download latest version (9040f81)
  • removed check for query.v that breaks soundcloud functionality (11da4f7)
  • version bump (60cce67)

1.3.1 (2013-10-15)

  • always download latest version of youtube-dl (c7de217)
  • fix reading download state (174743a)
  • formats change :/ (e6f172d)
  • make sure to delete downloaded file (be74d80)
  • only download if new version (1c8211c)
  • specify format to download (429687c)
  • v1.3.1 (23128d7)

1.3.0 (2013-09-13)

1.2.12 (2013-08-27)

1.2.11 (2013-08-23)

  • add id, itag, and resolution to info() (11c7f68)
  • version bump (c5fc896)

1.2.10 (2013-08-04)

1.2.9 (2013-08-04)

1.2.8 (2013-05-17)

1.2.7 (2012-08-19)

1.2.6 (2012-08-01)

  • buffer info call (c46a993)
  • make sure to delete downloaded file (5247bdb)
  • separate youtubedl stdout by line (a1b7294)
  • version bump (4f30db8)

1.2.5 (2012-07-07)

1.2.4 (2012-03-10)

1.2.3 (2012-03-04)

  • used __dirname instead of ./ to save download (b5fb4bf)
  • used path.join to make it more cross-platform (05c2ba3)

1.2.2 (2012-02-06)

1.2.1 (2012-01-04)

1.2.0 (2011-09-16)

  • added filename to data returned (49909ca)
  • added tests (1377915)
  • fixed installation issue (d05b14c)
  • fixed symlink installation issue (68199c0)

1.1.0 (2011-08-27)

1.0.4 (2011-08-07)