diff --git a/.gitignore b/.gitignore index ed177fa..c404b55 100644 --- a/.gitignore +++ b/.gitignore @@ -5,5 +5,4 @@ *.m4a .DS_Store node_modules -test bin diff --git a/LICENSE b/LICENSE index b351ee8..808d690 100644 --- a/LICENSE +++ b/LICENSE @@ -16,4 +16,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. +THE SOFTWARE. diff --git a/README.md b/README.md index ca7188f..91a9a80 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,7 @@ video.on('info', function(info) { video.pipe(fs.createWriteStream('myvideo.mp4')); ``` -A similar example can be found in the _example_ folder, and will produce an output that looks like the following when ran. +It will produce an output that looks like the following when ran. ```bash Got video info @@ -97,7 +97,7 @@ video.on('end', function() { }); ``` -The example can be found in the _example_ folder (`resume.js`), and will produce an output that looks like the following when ran. +It will produce an output that looks like the following when ran. **Output:** @@ -191,6 +191,50 @@ youtubedl.getSubs(url, options, function(err, 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 + +``` js + +var path = require('path'); +var fs = require('fs'); +var ytdl = require('youtube-dl'); + +function playlist(url) { + + 'use strict'; + var video = ytdl(url); + + video.on('error', function error(err) { + console.log('error 2:', err); + }); + + var size = 0; + video.on('info', function(info) { + size = info.size; + var output = path.join(__dirname + '/', size + '.mp4'); + video.pipe(fs.createWriteStream(output)); + }); + + var pos = 0; + video.on('data', function data(chunk) { + pos += chunk.length; + // `size` should not be 0 here. + if (size) { + var 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'); + +``` + ### Getting the list of extractors ``` js diff --git a/example/playlist.js b/example/playlist.js index ee45171..ec1b693 100644 --- a/example/playlist.js +++ b/example/playlist.js @@ -30,9 +30,7 @@ function playlist(url) { } }); - video.on('next', function next(data) { - playlist(data); - }); + video.on('next', playlist); } diff --git a/example/resume.js b/example/resume.js index c1c34b3..c7d397b 100644 --- a/example/resume.js +++ b/example/resume.js @@ -1,11 +1,11 @@ -var youtubedl = require('..'); +var ytdl = require('..'); var fs = require('fs'); var output = 'myvideo.mp4'; var downloaded = 0; if (fs.existsSync(output)) { downloaded = fs.statSync(output).size; } -var video = youtubedl('https://www.youtube.com/watch?v=179MiZSibco', +var video = ytdl('https://www.youtube.com/watch?v=179MiZSibco', // Optional arguments passed to youtube-dl. ['--format=18'], diff --git a/test/playlist.js b/test/playlist.js new file mode 100644 index 0000000..c908f08 --- /dev/null +++ b/test/playlist.js @@ -0,0 +1,80 @@ +var vows = require('vows'); +var ytdl = require('..'); +var fs = require('fs'); +var path = require('path'); +var assert = require('assert'); +var video1 = 'https://www.youtube.com/playlist?list=PLEFA9E9D96CB7F807'; + +vows.describe('download playlist').addBatch({ + 'from a youtube playlist': { + 'topic': function() { + 'use strict'; + + var cb = this.callback; + var details = []; + var count = 0; + + function playlist(url) { + var dl = ytdl(url); + + dl.on('error', cb); + + dl.on('info', function(info) { + var pos = 0; + var progress; + + dl.on('data', function(data) { + pos += data.length; + progress = pos / info.size; + }); + + dl.on('end', function() { + details.push({progress: progress, data: info}); + count = count + 1; + if (count === 2) { return cb(null, details); } + }); + + dl.on('next', playlist); + + var filepath = path.join(__dirname, info._filename); + dl.pipe(fs.createWriteStream(filepath)); + }); + } + + playlist(video1); + + }, + 'data returned': function(err, data) { + 'use strict'; + if (err) { throw err; } + assert.equal(data.length, 2); + assert.isArray(data); + assert.isObject(data[0]); + assert.isObject(data[1]); + }, + 'files downloaded': function(err, data) { + 'use strict'; + if (err) { throw err; } + assert.equal(data[0].progress, 1); + assert.equal(data[0].data._filename, 'Amy Castle - The Original Cuppycake Video-12Z6pWhM6TA.webm'); + assert.equal(data[1].progress, 1); + assert.equal(data[1].data._filename, 'LA REGAÑADA DEL MILENIO.wmv-SITuxqDUjPI.mp4'); + + function fileExists(data) { + var filepath = path.join(__dirname, data._filename); + var exists = fs.existsSync(filepath); + + if (exists) { + // Delete file after each test. + fs.unlinkSync(filepath); + } else { + assert.isTrue(exists); + } + } + + fileExists(data[0].data); + fileExists(data[1].data); + + } + } +}).export(module);