From 1056fb2cd20340fef5397d24133395b78c46ef10 Mon Sep 17 00:00:00 2001 From: liam4 Date: Thu, 20 Jul 2017 22:31:48 -0300 Subject: YouTube playlist downloader --- man/http-music-crawl-http.1 | 2 +- man/http-music-crawl-itunes.1 | 2 +- man/http-music-crawl-youtube.1 | 13 +++++++++++ man/http-music.1 | 4 ++++ package.json | 3 ++- src/cli.js | 1 + src/crawl-http.js | 1 - src/crawl-youtube.js | 49 ++++++++++++++++++++++++++++++++++++++++++ todo.txt | 3 +++ 9 files changed, 74 insertions(+), 4 deletions(-) create mode 100644 man/http-music-crawl-youtube.1 create mode 100644 src/crawl-youtube.js diff --git a/man/http-music-crawl-http.1 b/man/http-music-crawl-http.1 index 003e8f7..62bbc24 100644 --- a/man/http-music-crawl-http.1 +++ b/man/http-music-crawl-http.1 @@ -5,7 +5,7 @@ http-music-crawl-http - create a playlist file using an HTTP-based directory lis .SH SYNOPSIS .B http-music-crawl-http -\fIdownloadURL\fR + [opts...] .SH DESCRIPTION diff --git a/man/http-music-crawl-itunes.1 b/man/http-music-crawl-itunes.1 index e1f39d5..383c80d 100644 --- a/man/http-music-crawl-itunes.1 +++ b/man/http-music-crawl-itunes.1 @@ -5,7 +5,7 @@ http-music-crawl-itunes - create a playlist file using an iTunes library .SH SYNOPSIS .B http-music crawl-itunes -[libraryPath] +[library path] .SH DESCRIPTION \fBhttp-music-crawl-itunes\fR is a command line utility used to generate a diff --git a/man/http-music-crawl-youtube.1 b/man/http-music-crawl-youtube.1 new file mode 100644 index 0000000..58a03f5 --- /dev/null +++ b/man/http-music-crawl-youtube.1 @@ -0,0 +1,13 @@ +.TH HTTP-MUSIC-CRAWL-YOUTUBE 1 + +.SH NAME +http-music-crawl-youtube - create a playlist file from a YouTube playlist URL + +.SH SYNOPSIS +.B http-music crawl-youtube + + +.SH DESCRIPTION +\fBhttp-music-crawl-youtube\fR is a simple utility that creates a playlist file from a YouTube playlist, given its URL. +It requires the \fByoutube-dl\fR command line utility to download tracks. +(It's also necessary to have youtube-dl to play them.) diff --git a/man/http-music.1 b/man/http-music.1 index 12970bc..634f014 100644 --- a/man/http-music.1 +++ b/man/http-music.1 @@ -41,6 +41,10 @@ Creates a playlist from a directory on the local machine. .BR crawl-itunes Creates a playlist from the iTunes Shared Library. +.TP +.BR crawl-youtube +Creates a playlist from a YouTube playlist URL. + .TP .BR download-playlist Downloads each item in a playlist into a directory. diff --git a/package.json b/package.json index c66f894..57ef8aa 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,8 @@ "./man/http-music.1", "./man/http-music-play.1", "./man/http-music-crawl-http.1", - "./man/http-music-crawl-itunes.1" + "./man/http-music-crawl-itunes.1", + "./man/http-music-crawl-youtube.1" ], "dependencies": { "cheerio": "^1.0.0-rc.1", diff --git a/src/cli.js b/src/cli.js index d88ddc0..4bc64ab 100755 --- a/src/cli.js +++ b/src/cli.js @@ -18,6 +18,7 @@ async function main(args) { case 'crawl-http': script = require('./crawl-http'); break case 'crawl-local': script = require('./crawl-local'); break case 'crawl-itunes': script = require('./crawl-itunes'); break + case 'crawl-youtube': script = require('./crawl-youtube'); break case 'download-playlist': script = require('./download-playlist'); break default: diff --git a/src/crawl-http.js b/src/crawl-http.js index 29c59d2..e776b9c 100755 --- a/src/crawl-http.js +++ b/src/crawl-http.js @@ -142,7 +142,6 @@ function getHTMLLinks(text) { async function main(args) { if (args.length === 0) { console.log("Usage: crawl-http http://.../example/path/ [opts]") - process.exit(1) return } diff --git a/src/crawl-youtube.js b/src/crawl-youtube.js new file mode 100644 index 0000000..823fef7 --- /dev/null +++ b/src/crawl-youtube.js @@ -0,0 +1,49 @@ +'use strict' + +const { spawn } = require('child_process') +const promisifyProcess = require('./promisify-process') + +async function crawl(url) { + const ytdl = spawn('youtube-dl', [ + '-j', // Output as JSON + '--flat-playlist', + url + ]) + + const items = [] + + ytdl.stdout.on('data', data => { + const lines = data.toString().trim().split('\n') + + items.push(...lines.map(JSON.parse)) + }) + + // Don't show logging. + await promisifyProcess(ytdl, false) + + return { + items: items.map(item => { + return { + name: item.title, + downloaderArg: 'https://youtube.com/watch?v=' + item.id + } + }) + } +} + +async function main(args) { + // TODO: Error message if none is passed. + + if (args.length === 0) { + console.error("Usage: crawl-youtube ") + } else { + console.log(JSON.stringify(await crawl(args[0]), null, 2)) + } +} + +module.exports = main + +if (require.main === module) { + main(process.argv.slice(2)) + .catch(err => console.error(err)) +} diff --git a/todo.txt b/todo.txt index 4382526..52c2a94 100644 --- a/todo.txt +++ b/todo.txt @@ -225,3 +225,6 @@ TODO: Make iTunes crawler prefer album artist over artist. (Done!) TODO: Make iTunes crawler take into account track numbers. + +TODO: Make a YouTube playlist crawler. + (Done!) -- cgit 1.3.0-6-gf8a5