Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

organized

  • Loading branch information...
commit aeaf9c8a75a3b279106cf2fa589e21308958aa3b 1 parent 2544054
@fent fent authored
Showing with 270 additions and 0 deletions.
  1. +13 −0 Cakefile
  2. +111 −0 lib/youtube-dl.js
  3. +133 −0 src/youtube-dl.coffee
  4. +13 −0 test/info.js
View
13 Cakefile
@@ -0,0 +1,13 @@
+{spawn, exec} = require('child_process')
+
+task 'build', 'Build project from src/*.coffee to lib/*.js', ->
+ exec 'coffee -o lib -c src', (err, stdout, stderr) ->
+ throw err if err
+ console.log stdout + stderr
+
+task 'watch', 'Build and watch for changes', ->
+ child = spawn 'coffee', ['-w', '-o', 'lib', '-c', 'src']
+ child.stdout.on 'data', (data) ->
+ console.log data.toString().replace /\s+$/, ''
+ child.stderr.on 'data', (data) ->
+ console.log data.toString()
View
111 lib/youtube-dl.js
@@ -0,0 +1,111 @@
+(function() {
+ var badArgs, cmd, file, fs, hasArg, parseOpts, path, spawn;
+ spawn = require('child_process').spawn;
+ fs = require('fs');
+ path = require('path');
+ badArgs = ['-h', '--help', '-v', '--version', '-U', '--update', '-q', '--quiet', '-s', '--simulate', '-g', '--get-url', '-e', '--get-title', '--get-thumbnail', '--get-description', '--get-filename', '--no-progress', '--console-title'];
+ parseOpts = function(args) {
+ var arg, pos, _i, _len;
+ if (args == null) {
+ args = [];
+ }
+ for (_i = 0, _len = badArgs.length; _i < _len; _i++) {
+ arg = badArgs[_i];
+ if ((pos = hasArg(args, arg)) !== -1) {
+ args.splice(pos, 1);
+ }
+ }
+ return args;
+ };
+ hasArg = function(arr, arg) {
+ var a, i, _len;
+ for (i = 0, _len = arr.length; i < _len; i++) {
+ a = arr[i];
+ if ((a.indexOf(arg)) === 0) {
+ return i;
+ }
+ }
+ return -1;
+ };
+ file = path.normalize(__dirname + '/../bin/youtube-dl');
+ fs.stat(file, function(err, stats) {
+ if (err) {
+ require(__dirname + '/../scripts/download');
+ return fs.stat(file, function(err, stat) {
+ if (err) {
+ throw new Error('youtube-dl file does not exist. tried to download it but failed.');
+ }
+ });
+ }
+ });
+ cmd = file;
+ module.exports.download = function(url, dest, stateChange, download, callback, args) {
+ var err, regex, size, state, video, youtubedl;
+ args = parseOpts(args);
+ args.push(url);
+ youtubedl = spawn(cmd, args, {
+ cwd: dest
+ });
+ 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();
+ if (state === 'Downloading video') {
+ if (result = regex.exec(data)) {
+ if (size === false) {
+ stateChange(state, {
+ video: video,
+ size: size = result[2]
+ });
+ }
+ return download({
+ percent: result[1],
+ speed: result[3],
+ eta: result[4]
+ });
+ }
+ } else if ((pos = data.indexOf('[download] ')) === 0) {
+ return state = 'Downloading video';
+ } else if ((pos = data.indexOf(']')) !== -1) {
+ state = data.substring(pos + 2, data.length - 1);
+ if ((pos = state.indexOf(':')) !== -1) {
+ video = state.substring(0, pos);
+ state = state.substring(pos + 2);
+ }
+ return stateChange(state, video);
+ }
+ });
+ youtubedl.stderr.on('data', function(data) {
+ data = data.toString();
+ return err = data.substring(7, data.length - 1);
+ });
+ return youtubedl.on('exit', function(code) {
+ return callback(err);
+ });
+ };
+ module.exports.info = function(url, callback, args) {
+ var err, info, youtubedl;
+ args = parseOpts(args);
+ args = ['--get-url', '--get-title', '--get-thumbnail', '--get-description'].concat(args);
+ args.push(url);
+ youtubedl = spawn(cmd, args);
+ err = info = false;
+ youtubedl.stdout.on('data', function(data) {
+ data = data.toString().split("\n");
+ return info = {
+ title: data[0],
+ url: data[1],
+ thumbnail: data[2],
+ description: data[3]
+ };
+ });
+ youtubedl.stderr.on('data', function(data) {
+ data = data.toString();
+ return err = data.substring(7, data.length - 1);
+ });
+ return youtubedl.on('exit', function(code) {
+ return callback(err, info);
+ });
+ };
+}).call(this);
View
133 src/youtube-dl.coffee
@@ -0,0 +1,133 @@
+# module dependencies
+spawn = require('child_process').spawn
+fs = require 'fs'
+path = require 'path'
+
+
+# arguments we dont want users to use with youtube-dl
+# because they will break this module
+badArgs = [
+ '-h', '--help'
+ '-v', '--version'
+ '-U', '--update'
+ '-q', '--quiet'
+ '-s', '--simulate'
+ '-g', '--get-url'
+ '-e', '--get-title'
+ '--get-thumbnail'
+ '--get-description'
+ '--get-filename'
+ '--no-progress'
+ '--console-title'
+]
+
+# helps parse options used in youtube-dl command
+parseOpts = (args = []) ->
+ for arg in badArgs
+ if (pos = hasArg args, arg) isnt -1
+ args.splice pos, 1
+ args
+
+# returns position if argument is found in array
+hasArg = (arr, arg) ->
+ for a, i in arr
+ if (a.indexOf arg) is 0
+ return i
+ return -1
+
+
+# check that youtube-dl file exists
+file = path.normalize __dirname + '/../bin/youtube-dl'
+fs.stat file, (err, stats) ->
+ if err
+ require __dirname + '/../scripts/download'
+ fs.stat file, (err, stat) ->
+ if err
+ throw new Error 'youtube-dl file does not exist. tried to download it but failed.'
+
+
+# command to be called
+cmd = file
+
+
+# main download function
+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 }
+
+ 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()
+
+ # check if video is uploading so script can start
+ # calling the download progress function
+ if state is 'Downloading video'
+ if result = regex.exec data
+ if size is false
+ stateChange state,
+ video: video
+ size: size = result[2]
+ download
+ percent: result[1]
+ speed: result[3]
+ eta: result[4]
+
+ # about to start downloading video
+ else if (pos = data.indexOf '[download] ') is 0
+ state = 'Downloading video'
+
+ # check if this is any other state
+ else if (pos = data.indexOf ']') isnt -1
+ state = data.substring pos + 2, data.length - 1
+
+ # get video name
+ if (pos = state.indexOf ':') isnt -1
+ video = state.substring 0, pos
+ state = state.substring pos + 2
+ stateChange state, video
+
+ youtubedl.stderr.on 'data', (data) ->
+ data = data.toString()
+ err = data.substring 7, data.length - 1
+
+ youtubedl.on 'exit', (code) ->
+ callback err
+
+
+# gets info from a video
+module.exports.info = (url, callback, args) ->
+ # setup settings
+ args = parseOpts args
+ args = [
+ '--get-url'
+ '--get-title'
+ '--get-thumbnail'
+ '--get-description'
+ ].concat args
+ args.push url
+
+ # call youtube-dl
+ youtubedl = spawn cmd, args
+
+ err = info = false
+
+ youtubedl.stdout.on 'data', (data) ->
+ data = data.toString().split "\n"
+ info =
+ title: data[0]
+ url: data[1]
+ thumbnail: data[2]
+ description: data[3]
+
+ youtubedl.stderr.on 'data', (data) ->
+ data = data.toString()
+ err = data.substring 7, data.length - 1
+
+ youtubedl.on 'exit', (code) ->
+ callback err, info
View
13 test/info.js
@@ -0,0 +1,13 @@
+(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);
Please sign in to comment.
Something went wrong with that request. Please try again.