Last active
October 1, 2015 03:57
-
-
Save mallendeo/876ac5cfb110609a2d6f to your computer and use it in GitHub Desktop.
Get Youtube download URLs
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 request = require('./request') | |
var vm = require('vm') | |
var parseString = require('xml2js').parseString | |
var url = 'https://www.youtube.com/watch?v=si81bIoZRJQ' | |
var html = '' | |
request(url).then(function(body) { | |
html = body | |
var player = body.match(/html5player-([\w\d\-]+)\\\/html5player(.*?).js/g) | |
var playerUrl = 'https://s.ytimg.com/yts/jsbin/' + player[0].replace('\\', '') | |
return request(playerUrl) | |
}).then(function(player) { | |
// get the function name | |
var name = /\.sig\|\|([a-zA-Z0-9$]+)\(/g.exec(player)[1] | |
var regex = 'function ' + name + '\(.+){.*?};' | |
var functionContent = new RegExp(regex, 'g').exec(player)[0] | |
var helperObj = /;([A-Za-z0-9]+?)\./.exec(functionContent)[1] | |
var helperRegex = 'var ' + helperObj + '={.*?};' | |
var helperFunction = new RegExp(helperRegex, 'g').exec(player)[0] | |
var dashmpdUrl = /\"dashmpd\":\"(.*?)\"/g.exec(html)[1] | |
var signature = /\\\/s\\\/([a-fA-F0-9\.]+)/g.exec(dashmpdUrl)[1] | |
signature = signature ? signature : '' | |
var fn = helperFunction + functionContent | |
+ 'var signature = ' + name | |
+ '(\'' + signature + '\')' | |
// eval is evil, so we use a sandbox | |
var sandbox = { signature: signature } | |
vm.runInNewContext(fn, sandbox) | |
dashmpdUrl = dashmpdUrl | |
.replace(/\/s\\\/([a-fA-F0-9\.]+)/, '\/signature\\\/' + sandbox.signature) | |
.replace(/\\/g, '') | |
return request(dashmpdUrl) | |
}).then(function(xml) { | |
parseString(xml, function (err, result) { | |
var mimeTypes = result.MPD.Period[0].AdaptationSet | |
var formatList = [] | |
mimeTypes.forEach(function(mimeType) { | |
mimeType.Representation.forEach(function(format) { | |
formatList.push({ | |
mimeType: mimeType.$.mimeType, | |
itag: format.$.id, | |
codecs: format.$.codecs, | |
audioSamplingRate: format.$.audioSamplingRate || null, | |
url: format.BaseURL[0]._, | |
clen: format.BaseURL[0].$['yt:contentLength'], | |
width: format.$.width || null, | |
height: format.$.height || null, | |
}) | |
}) | |
}) | |
console.log(formatList) | |
}) | |
}) |
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
{ | |
"main": "index.js", | |
"dependencies": { | |
"bluebird": "~2.10.1", | |
"xml2js": "~0.4.12" | |
} | |
} |
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 http = require('http') | |
var https = require('https') | |
var parse = require('url').parse | |
var Promise = require('bluebird') | |
var httpLibs = { 'http:': http, 'https:': https } | |
module.exports = function(url) { | |
var parsed = parse(url) | |
var httpLib = httpLibs[parsed.protocol] | |
return new Promise(function(resolve, reject) { | |
if (!httpLib) { | |
var err = new Error('Invalid URL: ' + url) | |
reject(err) | |
return | |
} | |
var req = httpLib.get(parsed) | |
req.on('response', function(res) { | |
if (res.statusCode !== 200) { | |
reject(new Error('status code ' + res.statusCode)); | |
return | |
} | |
var body = '' | |
res.setEncoding('utf8') | |
res.on('data', function(chunk) { | |
body += chunk | |
}) | |
res.on('end', function() { | |
resolve(body) | |
}) | |
}) | |
req.on('error', reject) | |
}) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment