-
-
Save carlos8f/57d07c4bf4ab56e9164b to your computer and use it in GitHub Desktop.
ripper
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
.DS_Store | |
node_modules | |
npm-debug.log | |
db |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module.exports = function (app) { | |
app.require('modeler'); | |
return app.modeler; | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var youtubedl = require('youtube-dl'); | |
module.exports = function (app) { | |
return function (url, args, cb) { | |
var video = youtubedl(url, args); | |
var errored = false; | |
function done (err) { | |
if (errored) return; | |
if (err) { | |
errored = true; | |
return cb(err); | |
} | |
cb(null, video); | |
} | |
video.on('info', function (info) { | |
video.info = info; | |
video.size = info.size; | |
done(null, video); | |
}); | |
video.once('error', done); | |
}; | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var ffmpegPath = require('ffmpeg-bin').ffmpeg | |
, spawn = require('child_process').spawn | |
module.exports = function (app) { | |
return function (args, opts) { | |
return spawn(ffmpegPath, args, opts); | |
}; | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
ripper is: | |
a media library | |
free | |
offline | |
access the raw files forever | |
no subscription | |
no waiting for licenses deals and record companies | |
basically it saves streamed content, for later. | |
features: | |
rip from youtube | |
media browser | |
media server | |
library search | |
create "mixtapes" of any series of media, save to .rmx file | |
export mixtapes for sharing | |
encrypt mixtapes for specific identities | |
standard container format for sharing: | |
- RMT, Ripper Mixtape | |
- manifest | |
- ordered media | |
- examples: photos, videos, documents, emails, mp3's, csv's, blobs (use at your own risk) | |
- progressive download | |
- figure out security scan for all these types | |
TBD: | |
cloud sync (sftp, dropbox, s3) | |
rip from cd or dvd? | |
bittorrent? p2p? | |
mobile? | |
hosted? | |
three.js | |
theoretical: | |
download ripper, install, open. | |
auto-creates RIP KEYRING and keypair | |
prompt with search box. what do you want to rip? | |
search youtube for results, display thumbnails like album covers, animated gif cache? | |
click on one, add to queue. | |
see progress bar as the thing downloads. | |
auto-rip mp3 in background (preference) | |
ANY type of streaming would be awesome | |
upon rip, a RIP KEY is created for the file | |
having the rip key "unlocks" that file | |
files can be distributed without rip keys. filenames might not matter | |
if data is hidden | |
when you friend someone, you choose to merge rip keys | |
(in a way that can't be traced to either ID?) | |
your library inherits all their stuff | |
you can download files from them at will | |
you can generate any number of anonymous IDs (hashes) that people can access | |
for your library list with | |
you can pay bitcoin for a rip key | |
verification through checksums - recognized "good sums" for certain things | |
enter someone's RIP ID on ripnet | |
(optional: confirmation question. | |
auto-generated questions and answer security questions, | |
picked at random. fails after 3 tries) | |
see a list of RMT ID's | |
IDs correspond to public RMT cover art and track listing | |
some may be locked | |
request a key | |
request pops up on owner's RipDeck, with requester's rip ID | |
a secret phrase is shown, which requester needs to unlock the key | |
the secret phrase is tweeted by the requestee | |
requester finds the tweet and runs it? | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var path = require('path'); | |
module.exports = function (app) { | |
var dir; | |
app.require('mkdirp'); | |
if (process.env.HOME) dir = path.join(process.env.HOME, app.conf.id); | |
else dir = app.conf.id; | |
app.mkdirp.sync(dir, 0700); | |
return dir; | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var spawn = require('child_process').spawn | |
, path = require('path') | |
, wrap = require('word-wrap') | |
, colors = require('colors') | |
module.exports = function (app) { | |
app.require('media', 'commander', 'pkg', 'library'); | |
var cmd = app.commander | |
.version(app.pkg.version) | |
.usage('[options] <url>\n\n rip a video webpage (i.e. YouTube) to local mp3 file\n\n Alternate Usage: ripper search <keywords>\n\n search YouTube and list results') | |
.option('--no-mp3', 'just keep the video') | |
.option('--library <path>', 'location of your media library (default: ~/Ripper)') | |
.option('--both', 'keep video and mp3 files') | |
.option('--open', 'open after downloading (OSX)') | |
cmd.on('--help', function () { | |
console.log(' Examples:'); | |
console.log(''); | |
console.log(' $ ripper --open dQw4w9WgXcQ'); | |
console.log(' $ ripper https://www.youtube.com/watch?v=ho9rZjlsyYY'); | |
console.log(' $ ripper search "dog the bounty hunter song"'); | |
console.log(''); | |
}); | |
cmd.parse(process.argv); | |
if (cmd.library) app.library = cmd.library; | |
if (!cmd.args[0]) { | |
app.commander.outputHelp(); | |
app.close(); | |
} | |
else if (cmd.args[0].match(/^(https?:\/\/|[a-zA-Z0-9-_]{11}$)/)) { | |
if (cmd.args[0].match(/^[a-zA-Z0-9-_]{11}$/)) { | |
cmd.args[0] = 'https://www.youtube.com/watch?v=' + cmd.args[0]; | |
} | |
app.media.create({url: cmd.args[0], mp3: cmd.mp3, both: cmd.both, manualFilename: cmd.args[1]}, function (err, media) { | |
if (err) throw err; | |
console.log('downloaded ' + media.fulltitle.green + '!'); | |
if (cmd.open) { | |
spawn('open', [media.path]) | |
.on('exit', function () { | |
app.close(); | |
}) | |
} | |
else app.close(); | |
}); | |
} | |
else { | |
switch (cmd.args[0]) { | |
case 'search': | |
app.require('request'); | |
var query = encodeURIComponent(cmd.args.slice(1).join(' ')); | |
app.request({ | |
uri: 'https://www.googleapis.com/youtube/v3/search?part=id%2Csnippet&key=AIzaSyCHg7AtcfUj82AeXNoPpYQTMaagDcn2Rcg&maxResults=25&q=' + query, | |
json: true | |
}, function (err, resp, body) { | |
if (err) throw err; | |
if (!body) { | |
console.error('resp code: ' + resp.statusCode); | |
return app.close(); | |
} | |
if (!body.items) { | |
console.error('invalid body: ' + JSON.stringify(body, null, 2)); | |
return app.close(); | |
} | |
if (!body.items.length) { | |
console.log('\nno results.\n'); | |
return app.close(); | |
} | |
var idx = body.items.length; | |
body.items.reverse(); | |
body.items.forEach(function (e) { | |
console.log( | |
idx + '.', | |
e.snippet.title.cyan, | |
'\n\n Uploader: '.blue, | |
e.snippet.channelTitle.grey, | |
'\n URL:'.blue, | |
('https://www.youtube.com/watch?v=' + e.id.videoId).grey, | |
'\n Description:'.blue, | |
'\n\n' + wrap(e.snippet.description, {width: 40, indent: ' '}).grey, | |
'\n' | |
); | |
idx--; | |
}); | |
app.require('prompt'); | |
app.prompt('Enter a number to rip: ', function (num) { | |
if (!num || !num.match(/^[0-9]{1,3}\.?$/)) return app.close(); | |
num = parseInt(num, 10); | |
if (num > body.items.length) throw new Error('Number must be within range.'); | |
num = body.items.length - num; | |
var e = body.items[num]; | |
if (!e) throw new Error('number not in range!'); | |
var u = 'https://www.youtube.com/watch?v=' + e.id.videoId; | |
console.log('ripper', u); | |
var proc = spawn(path.join(__dirname, 'ripper'), [u]); | |
proc.stdout.pipe(process.stdout); | |
proc.stderr.pipe(process.stderr); | |
proc.on('exit', function () { | |
app.close(); | |
}); | |
}); | |
app.close(); | |
}); | |
break; | |
default: | |
throw new Error('command not supported'); | |
} | |
} | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var fs = require('fs') | |
, path = require('path') | |
, Progress = require('progress') | |
module.exports = function (app) { | |
app.require('collection'); | |
return app.collection({ | |
name: 'media', | |
save: function (media, cb) { | |
app.require('dl', 'ffmpeg', 'mkdirp', 'library'); | |
var basePath = app.library; | |
app.mkdirp(basePath, function (err) { | |
if (err) return cb(err); | |
var args = []; | |
if (media.manualFilename) args.push('-o', media.manualFilename); | |
app.dl(media.url, args, function (err, video) { | |
if (err) return cb(err); | |
var bar = new Progress(':bar', { total: video.size, width: 80 }); | |
var destPath = media.videoPath = path.join(basePath, media.manualFilename || video.info._filename); | |
var errored = false; | |
video.on('data', function (buf) { | |
bar.tick(buf.length); | |
}); | |
function done (err) { | |
if (errored) return; | |
if (err) { | |
errored = true; | |
return cb(err); | |
} | |
Object.keys(video.info).forEach(function (k) { | |
if (!k.match(/^(url)$/i)) media[k] = video.info[k]; | |
}); | |
if (!media.mp3) { | |
media.path = media.videoPath; | |
return cb(null, media); | |
} | |
media.songPath = destPath.replace(/\.[^\.]+$/, '') + '.mp3'; | |
var stderr = ''; | |
console.log('Processing raw video...'.green); | |
var ffmpeg = app.ffmpeg(['-y', '-i', destPath, '-vn', '-f', 'mp3', media.songPath]) | |
.on('exit', function (code) { | |
if (code !== 0) return done(new Error('Error ripping audio: ' + stderr)); | |
if (media.both) { | |
media.path = media.songPath; | |
return cb(null, media); | |
} | |
fs.unlink(destPath, function (err) { | |
if (err) return done(err); | |
media.path = media.songPath; | |
cb(null, media); | |
}); | |
}); | |
ffmpeg.stderr.on('data', function (data) { | |
stderr += data; | |
}); | |
//ffmpeg.stdout.pipe(process.stdout); | |
//ffmpeg.stderr.pipe(process.stderr); | |
} | |
video | |
.pipe(fs.createWriteStream(destPath)) | |
.once('finish', function () { | |
console.log('Done!'.green); | |
done(); | |
}) | |
.once('error', done) | |
video.once('error', done) | |
}); | |
}); | |
} | |
}); | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
id: Ripper | |
minimal: true | |
collections: "*_collection.js" | |
plugins: "*_plugin.js" | |
title: Ripper |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"name": "ripper", | |
"version": "0.4.2", | |
"description": "rip videos and songs from the interwebs", | |
"bin": "./ripper", | |
"repository": { | |
"type": "git", | |
"url": "git@gist.github.com:/57d07c4bf4ab56e9164b.git" | |
}, | |
"author": "Carlos Rodriguez <carlos@s8f.org> (http://s8f.org/)", | |
"license": "MIT", | |
"dependencies": { | |
"colors": "^0.6.2", | |
"ffmpeg-bin": "0.0.1", | |
"motley": "^1.4.1", | |
"progress": "^1.1.8", | |
"word-wrap": "^0.1.3", | |
"youtube-dl": "^1.5.10" | |
}, | |
"scripts": {} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env node | |
require('motley')('motley.yml', __dirname) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment