From 77a99e57b0ff0dc859e3ac2e805f85930a16898a Mon Sep 17 00:00:00 2001 From: Roly Fentanes Date: Fri, 5 Aug 2011 05:53:06 -0700 Subject: [PATCH] when finished downloading, statistics data will be passed --- README.md | 8 +++- example/download.js | 11 ++++-- example/info.js | 2 +- lib/youtube-dl.js | 85 +++++++++++++++++++++++++++++++++++++++---- package.json | 2 +- src/youtube-dl.coffee | 81 +++++++++++++++++++++++++++++++++++++---- test/download.coffee | 2 +- test/info.js | 13 ------- 8 files changed, 168 insertions(+), 36 deletions(-) delete mode 100644 test/info.js diff --git a/README.md b/README.md index 0cdb15e..7447c73 100755 --- a/README.md +++ b/README.md @@ -20,14 +20,18 @@ Usage // will be called during download progress of a video function(data) { - console.log(data.eta + ' ' + data.percent + '% at ' + data.speed); + process.stdout.write(data.eta + ' ' + data.percent + '% at ' + data.speed + '\r'); }, // called when youtube-dl finishes - function(err) { + function(err, data) { if (err) throw err; console.log('Download finished!') + console.log('Time Taken: ' + data.timeTaken); + console.log('Time Taken in ms: ' + data.timeTakenms); + console.log('Average Speed: ' + data.averageSpeed); + console.log('Average Speed in Bytes: ' + data.averageSpeedBytes); }, // optional arguments passed to youtube-dl diff --git a/example/download.js b/example/download.js index b0792fe..0e0cb77 100755 --- a/example/download.js +++ b/example/download.js @@ -1,4 +1,5 @@ -youtubedl = require('youtube-dl'); +youtubedl = require('./../lib/youtube-dl'); + // will be called when a state changes stateChange = function(state, data) { @@ -10,14 +11,16 @@ stateChange = function(state, data) { // will be called during download progress of a video progress = function(data) { - console.log(data.eta + ' ' + data.percent + '% at ' + data.speed); + process.stdout.write(data.eta + ' ' + data.percent + '% at ' + data.speed + '\r'); } // called when youtube-dl finishes -finished = function(err) { +finished = function(err, data) { if (err) throw err; - console.log('Download finished!') + console.log('\nDownload finished!'); + console.log('Time Taken: ' + data.timeTaken); + console.log('Average Speed: ' + data.averageSpeed); }, youtubedl.download('http://www.youtube.com/watch?v=90AiXO1pAiA', './', diff --git a/example/info.js b/example/info.js index cc0f972..0d1f2db 100755 --- a/example/info.js +++ b/example/info.js @@ -1,4 +1,4 @@ -youtube = require('youtube-dl'); +youtube = require('./../lib/youtube-dl'); youtube.info('http://www.youtube.com/watch?v=WKsjaOqDXgg', diff --git a/lib/youtube-dl.js b/lib/youtube-dl.js index b47d9fe..97afea6 100644 --- a/lib/youtube-dl.js +++ b/lib/youtube-dl.js @@ -1,5 +1,5 @@ (function() { - var badArgs, cmd, file, fs, hasArg, parseOpts, path, spawn; + var badArgs, file, fs, getHumanSize, getHumanTime, hasArg, parseOpts, path, regex, round, spawn, toBytes, units; spawn = require('child_process').spawn; fs = require('fs'); path = require('path'); @@ -38,16 +38,73 @@ }); } }); - cmd = file; + round = function(num, n) { + var dec; + dec = Math.pow(10, n); + return Math.round(num * dec + 0.1) / dec; + }; + toBytes = function(s) { + var speed; + speed = parseFloat(s.substring(0, s.length - 3)); + switch (s.substr(-3, 1).toLowerCase()) { + case 'b': + return speed; + case 'k': + return speed * 1024; + case 'm': + return speed * 1024 * 1024; + case 'g': + return speed * 1024 * 1024 * 1024; + } + }; + units = ' KMGTPEZYXWVU'; + getHumanSize = function(bytes) { + var t2; + if (bytes <= 0) { + return 0; + } + t2 = Math.min(Math.floor(Math.log(bytes) / Math.log(1024)), 12); + return (Math.round(bytes * 100 / Math.pow(1024, t2)) / 100) + units.charAt(t2).replace(' ', '') + 'B'; + }; + getHumanTime = function(ms) { + var d, h, m, s, set, str, x; + x = ms / 1000; + ms %= 1000; + s = Math.round(x % 60); + x /= 60; + m = Math.round(x % 60); + x /= 60; + h = Math.round(x % 24); + d = Math.round(x / 24); + str = ''; + if (d > 0) { + str += "" + d + " day" + (d > 1 ? 's' : void 0) + ", "; + set = true; + } + if (set || h > 0) { + str += "" + h + " hour" + (h > 1 ? 's' : void 0) + ", "; + set = true; + } + if (set || m > 0) { + str += "" + m + " minute" + (m > 1 ? 's' : void 0) + ", "; + set = true; + } + if (set || s > 0) { + str += "" + s + " second" + (s > 1 ? 's' : void 0) + ", "; + } + return "" + str + ms + " ms"; + }; + regex = /(\d+\.\d)% of (\d+\.\d+\w) at\s+([^\s]+) ETA ((\d|-)+:(\d|-)+)/; module.exports.download = function(url, dest, stateChange, download, callback, args) { - var err, regex, size, state, video, youtubedl; + var err, size, speed, start, state, video, youtubedl; args = parseOpts(args); args.push(url); - youtubedl = spawn(cmd, args, { + youtubedl = spawn(file, args, { cwd: dest }); + speed = []; + start = new Date().getTime(); err = video = size = state = false; - regex = /(\d+\.\d)% of (\d+\.\d+\w) at\s+([^\s]+) ETA ((\d|-)+:(\d|-)+)/; youtubedl.stdout.on('data', function(data) { var pos, result; data = data.toString(); @@ -59,6 +116,7 @@ size: size = result[2] }); } + speed.push(toBytes(result[3])); return download({ percent: result[1], speed: result[3], @@ -81,7 +139,20 @@ return err = data.substring(7, data.length - 1); }); return youtubedl.on('exit', function(code) { - return callback(err); + var averageSpeed, i, timeTaken, _i, _len; + averageSpeed = 0; + for (_i = 0, _len = speed.length; _i < _len; _i++) { + i = speed[_i]; + averageSpeed += i; + } + averageSpeed /= speed.length; + timeTaken = new Date().getTime() - start; + return callback(err, { + timeTakenms: timeTaken, + timeTaken: getHumanTime(timeTaken), + averageSpeedBytes: round(averageSpeed, 2), + averageSpeed: getHumanSize(averageSpeed) + '/s' + }); }); }; module.exports.info = function(url, callback, args) { @@ -89,7 +160,7 @@ args = parseOpts(args); args = ['--get-url', '--get-title', '--get-thumbnail', '--get-description'].concat(args); args.push(url); - youtubedl = spawn(cmd, args); + youtubedl = spawn(file, args); err = info = false; youtubedl.stdout.on('data', function(data) { data = data.toString().split("\n"); diff --git a/package.json b/package.json index f05e288..ab02122 100755 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "youtube-dl", "description": "youtube-dl driver for node", "keywords": ["youtube", "download"], - "version": "1.0.3", + "version": "1.0.4", "homepage": "https://github.com/fent/node-youtube-dl", "repository": { "type": "git", diff --git a/src/youtube-dl.coffee b/src/youtube-dl.coffee index 8232680..e025dc5 100755 --- a/src/youtube-dl.coffee +++ b/src/youtube-dl.coffee @@ -1,5 +1,5 @@ # module dependencies -spawn = require('child_process').spawn +{spawn} = require 'child_process' fs = require 'fs' path = require 'path' @@ -46,21 +46,75 @@ fs.stat file, (err, stats) -> throw new Error 'youtube-dl file does not exist. tried to download it but failed.' -# command to be called -cmd = file +# rounds a number to n decimal places +round = (num, n) -> + dec = Math.pow 10, n + Math.round(num * dec + 0.1) / dec + + +# converts from bytes, kb, mb, and gb to bytes +toBytes = (s) -> + speed = parseFloat(s.substring 0, s.length - 3) + switch s.substr(-3, 1).toLowerCase() + when 'b' + speed + when 'k' + speed * 1024 + when 'm' + speed * 1024 * 1024 + when 'g' + speed * 1024 * 1024 * 1024 + + +# converts bytes to human readable unit +# thank you Amir from StackOverflow +units = ' KMGTPEZYXWVU' +getHumanSize = (bytes) -> + return 0 if bytes <= 0 + t2 = Math.min(Math.floor(Math.log(bytes) / Math.log(1024)), 12) + (Math.round(bytes * 100 / Math.pow(1024, t2)) / 100) + + units.charAt(t2).replace(' ', '') + 'B' + + +# converts ms to human readable time +getHumanTime = (ms) -> + x = ms / 1000 + ms %= 1000 + s = Math.round(x % 60) + x /= 60 + m = Math.round(x % 60) + x /= 60 + h = Math.round(x % 24) + d = Math.round(x / 24) + + str = '' + if d > 0 + str += "#{d} day#{if d > 1 then 's'}, " + set = true + if set or h > 0 + str += "#{h} hour#{if h > 1 then 's'}, " + set = true + if set or m > 0 + str += "#{m} minute#{if m > 1 then 's'}, " + set = true + if set or s > 0 + str += "#{s} second#{if s > 1 then 's'}, " + "#{str}#{ms} ms" # main download function +regex = /(\d+\.\d)% of (\d+\.\d+\w) at\s+([^\s]+) ETA ((\d|-)+:(\d|-)+)/ module.exports.download = (url, dest, stateChange, download, callback, args) -> # setup settings args = parseOpts args args.push url # call youtube-dl - youtubedl = spawn cmd, args, { cwd: dest } + youtubedl = spawn file, args, { cwd: dest } + speed = [] + start = new Date().getTime() err = video = size = state = false - regex = /(\d+\.\d)% of (\d+\.\d+\w) at\s+([^\s]+) ETA ((\d|-)+:(\d|-)+)/ youtubedl.stdout.on 'data', (data) -> data = data.toString() @@ -73,6 +127,8 @@ module.exports.download = (url, dest, stateChange, download, callback, args) -> stateChange state, video: video size: size = result[2] + + speed.push toBytes result[3] download percent: result[1] speed: result[3] @@ -97,7 +153,18 @@ module.exports.download = (url, dest, stateChange, download, callback, args) -> err = data.substring 7, data.length - 1 youtubedl.on 'exit', (code) -> - callback err + averageSpeed = 0 + for i in speed + averageSpeed += i + averageSpeed /= speed.length + + timeTaken = new Date().getTime() - start + + callback err, + timeTakenms: timeTaken + timeTaken: getHumanTime timeTaken + averageSpeedBytes: round averageSpeed, 2 + averageSpeed: getHumanSize(averageSpeed) + '/s' # gets info from a video @@ -113,7 +180,7 @@ module.exports.info = (url, callback, args) -> args.push url # call youtube-dl - youtubedl = spawn cmd, args + youtubedl = spawn file, args err = info = false diff --git a/test/download.coffee b/test/download.coffee index 4044636..d62b9da 100755 --- a/test/download.coffee +++ b/test/download.coffee @@ -7,7 +7,7 @@ youtube.download process.argv[2], './', ((state, data) -> if data console.log 'data: ' + data ), ((data) -> - console.log "Downloading: #{data.percent}%, #{data.speed}, #{data.eta}" + process.stdout.write "Downloading: #{data.percent}%, #{data.speed}, #{data.eta}\r" ), ((err) -> if err console.log 'error: ' + err diff --git a/test/info.js b/test/info.js deleted file mode 100644 index 2487372..0000000 --- a/test/info.js +++ /dev/null @@ -1,13 +0,0 @@ -(function() { - var youtube; - youtube = require('youtube-dl'); - youtube.info(process.argv[2], function(err, info) { - if (err) { - throw err; - } - console.log('title: ' + info.title); - console.log('url: ' + info.url); - console.log('thumbnail: ' + info.thumbnail); - return console.log('description: ' + info.description); - }); -}).call(this);