Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

unblock-netease-music

Package Overview
Dependencies
Maintainers
1
Versions
59
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

unblock-netease-music - npm Package Compare versions

Comparing version 0.1.4 to 0.2.2

middleware/index.js

20

app.js
var express = require('express');
var favicon = require('serve-favicon');
var logger = require('morgan');
var bodyParser = require('body-parser');
var proxy = require('./middleware')

@@ -14,2 +14,3 @@ var routes = require('./routes/index');

}));
app.use(proxy);

@@ -26,19 +27,4 @@ app.use('/', routes);

// error handlers
// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.send({
message: err.message,
error: err
});
});
}
// production error handler
// no stacktraces leaked to user
app.use(function(err, req, res, next) {
console.error(err);
res.status(err.status || 500);

@@ -45,0 +31,0 @@ res.send({

{
"name": "unblock-netease-music",
"version": "0.1.4",
"version": "0.2.2",
"scripts": {

@@ -12,6 +12,4 @@ "start": "node ./bin/www"

"async": "^2.0.0-rc.2",
"base-64": "^0.1.0",
"body-parser": "~1.13.2",
"colors": "^1.1.2",
"cookie-parser": "~1.3.5",
"debug": "~2.2.0",

@@ -21,5 +19,3 @@ "express": "~4.13.1",

"morgan": "~1.6.1",
"python-shell": "^0.4.0",
"request": "^2.69.0",
"serve-favicon": "~2.3.0"
"request": "^2.69.0"
},

@@ -26,0 +22,0 @@ "description": "A proxy server for Netease Music...",

@@ -7,4 +7,3 @@ # UnblockNeteaseMusic

1. Python 2.7 installed and added to path.
2. Node.js 4.x+
1. Node.js 4.x+

@@ -11,0 +10,0 @@ # How to use

@@ -5,80 +5,48 @@ var express = require('express');

var colors = require('colors');
var request = require('request');
var waterfall = require("async/waterfall");
var utils = new Utils();
router.get('/*', function(req, res) {
var url = req.originalUrl;
if(!/^http/.test(url)){
url = "http://223.252.199.7" + url;
}
var options = {
url: url,
headers: req.headers,
method: 'get'
};
request(options)
.on('error', function(err) {
console.error(err)
})
.pipe(res);
});
router.post('/*', function(req, res, next) {
if (/mp3$|flac$/.test(req.originalUrl)) {
return request.get(req.originalUrl).pipe(res);
}
utils.defaultPost(req.headers, req.body, req.originalUrl, function(err, headers, body) {
if (err) {
return console.error(err);
} else {
// console.log(body);
// console.log(utils);
next();
}
});
});
router.post('/eapi/v3/song/detail', function(req, res, next) {
utils.modifyDetailApi();
res.defaultBody = utils.netease.modifyDetailApi(res.defaultBody);
next();
});
router.post('/eapi/v3/playlist/detail', function(req, res, next) {
utils.modifyDetailApi();
res.defaultBody = utils.netease.modifyDetailApi(res.defaultBody);
next();
});
router.post('/eapi/v1/album/*', function(req, res, next) {
utils.modifyDetailApi();
res.defaultBody = utils.netease.modifyDetailApi(res.defaultBody);
next();
});
router.post('/eapi/batch', function(req, res, next) {
utils.modifyDetailApi();
res.defaultBody = utils.netease.modifyDetailApi(res.defaultBody);
next();
});
router.post('/eapi/cloudsearch/pc', function(req, res, next) {
utils.modifyDetailApi();
res.defaultBody = utils.netease.modifyDetailApi(res.defaultBody);
next();
});
router.post('/eapi/v1/artist', function(req, res, next) {
utils.modifyDetailApi();
res.defaultBody = utils.netease.modifyDetailApi(res.defaultBody);
next();
});
router.post('/eapi/batch', function(req, res, next) {
utils.modifyDetailApi();
res.defaultBody = utils.netease.modifyDetailApi(res.defaultBody);
next();
});
router.post('/eapi/v1/search/get', function(req, res, next) {
utils.modifyDetailApi();
res.defaultBody = utils.netease.modifyDetailApi(res.defaultBody);
next();
});
router.post('/eapi/song/enhance/privilege', function(req, res, next) {
utils.modifyDetailApi();
res.defaultBody = utils.netease.modifyDetailApi(res.defaultBody);
next();
});
router.post('/eapi/v1/discovery/new/songs', function(req, res, next) {
utils.modifyDetailApi();
res.defaultBody = utils.netease.modifyDetailApi(res.defaultBody);
next();
});
router.post('/eapi/v1/play/record', function(req, res, next) {
utils.modifyDetailApi();
res.defaultBody = utils.netease.modifyDetailApi(res.defaultBody);
next();

@@ -88,7 +56,44 @@ });

router.post('/eapi/song/enhance/player/url', function(req, res, next) {
if (utils.getPlaybackReturnCode() != 200 || utils.getPlaybackBitrate() < 320000) {
utils.modifyPlayerApi(function(err) {
if (err) {
return console.error(err.red);
} else {
if (utils.netease.getPlaybackReturnCode(res.defaultBody) != 200 || utils.netease.getPlaybackBitrate(res.defaultBody) < 320000) {
waterfall([
function(callback) {
var songId = utils.netease.getPlaybackSongId(res.defaultBody);
callback(null, songId);
},
function(songId, callback) {
utils.netease.getSongDetail(songId, function(err, detail) {
if (err) {
console.error(err);
} else {
callback(null, detail);
}
});
},
function(detail, callback) {
var songName = utils.netease.getSongName(detail);
var artist = utils.netease.getArtistName(detail);
utils.kugou.search(songName, artist, function(err, hash, bitrate) {
if (err) {
console.error(err);
} else {
callback(null, hash, bitrate);
}
});
},
function(hash, bitrate, callback) {
utils.kugou.getUrl(hash, function(err, url) {
if (err) {
console.error(err);
} else {
callback(null, url, bitrate);
}
});
}
], function(err, url, bitrate) {
if(err) {
console.error(err);
res.status = 500;
res.send();
}else{
res.defaultBody = utils.netease.modifyPlayerApiCustom(url, bitrate, res.defaultBody);
next();

@@ -98,3 +103,3 @@ }

} else {
console.log('Playback bitrate is not changed. The song URL is '.green + utils.getPlaybackUrl().green);
console.log('Playback bitrate is not changed. The song URL is '.green + utils.netease.getPlaybackUrl(res.defaultBody).green);
next();

@@ -105,7 +110,44 @@ }

router.post('/eapi/song/enhance/download/url', function(req, res, next) {
if (utils.getDownloadReturnCode() != 200 || utils.getDownloadBitrate() < 320000) {
utils.modifyDownloadApi(function(err) {
if (err) {
return console.error(err.red);
} else {
if (utils.netease.getDownloadReturnCode(res.defaultBody) != 200 || utils.netease.getDownloadBitrate(res.defaultBody) < 320000) {
waterfall([
function(callback) {
var songId = utils.netease.getDownloadSongId(res.defaultBody);
callback(null, songId);
},
function(songId, callback) {
utils.netease.getSongDetail(songId, function(err, detail) {
if (err) {
console.error(err);
} else {
callback(null, detail);
}
});
},
function(detail, callback) {
var songName = utils.netease.getSongName(detail);
var artist = utils.netease.getArtistName(detail);
utils.kugou.search(songName, artist, function(err, hash, bitrate) {
if (err) {
console.error(err);
} else {
callback(null, hash, bitrate);
}
});
},
function(hash, bitrate, callback) {
utils.kugou.getUrl(hash, function(err, url) {
if (err) {
console.error(err);
} else {
callback(null, url, bitrate);
}
});
}
], function(err, url, bitrate) {
if(err) {
console.error(err);
res.status = 500;
res.send();
}else{
res.defaultBody = utils.netease.modifyDownloadApiCustom(url, bitrate, res.defaultBody);
next();

@@ -115,3 +157,3 @@ }

} else {
console.log('Download bitrate is not changed. The song URL is '.green + utils.getPlaybackUrl().green);
console.log('Download bitrate is not changed. The song URL is '.green + utils.netease.getDownloadUrl(res.defaultBody).green);
next();

@@ -123,7 +165,6 @@ }

// console.log(utils.headers);
// console.log(utils.body);
res.set(utils.headers);
res.send(utils.body);
// console.log(res.defaultBody);
res.send(res.defaultBody);
});
module.exports = router;

@@ -1,292 +0,10 @@

var request = require('request');
var md5 = require('md5');
var base64 = require('base-64');
var PythonShell = require('python-shell');
var waterfall = require("async/waterfall");
var colors = require('colors');
var netease = require('./netease');
var kugou = require('./kugou');
var baseUrl = "http://223.252.199.7";
var utils = function() {
this.body = '';
this.headers = '';
this.netease = new netease();
this.kugou = new kugou();
}
utils.prototype.defaultPost = function(headers, body, url, callback) {
var _this = this;
_this.post(headers, body, url, function(err, headers, body) {
if (err) {
console.error(err);
return callback(err);
} else {
_this.body = body;
_this.headers = headers;
delete _this.headers['content-encoding'];
callback(null, headers, body);
}
})
}
utils.prototype.post = function(headers, body, url, callback) {
// console.log(headers);
var _this = this;
body = new Buffer(body);
if(!/^http/.test(url)) {
url = baseUrl + url;
}
// console.log(url);
var options = {
url: url,
headers: headers,
method: 'post',
body: body,
gzip: true
};
request(options, function(err, res, body) {
if (err) {
console.error(err);
return callback(err);
} else {
// console.log(res.headers);
callback(null, res.headers, body);
}
});
}
utils.prototype.get = function(headers, url, callback) {
var _this = this;
if(!/^http/.test(url)) {
url = baseUrl + url;
}
// console.log(url);
var options = {
url: url,
headers: headers,
method: 'get',
gzip: true
};
request(options, function(err, res, body) {
if (err) {
console.error(err);
return callback(err);
} else {
// console.log(res.headers);
// console.log(body);
callback(null, res.headers, body);
}
});
}
utils.prototype.getPlaybackBitrate = function() {
// console.log(this.body);
var body = JSON.parse(this.body);
return body["data"][0]["br"];
}
utils.prototype.getPlaybackReturnCode = function() {
var body = JSON.parse(this.body);
return body["data"][0]["code"];
}
utils.prototype.getPlaybackUrl = function() {
var body = JSON.parse(this.body);
return body["data"][0]["url"];
}
utils.prototype.getDownloadBitrate = function() {
// console.log(this.body);
var body = JSON.parse(this.body);
return body["data"]["br"];
}
utils.prototype.getDownloadReturnCode = function() {
var body = JSON.parse(this.body);
return body["data"]["code"];
}
utils.prototype.getDownloadUrl = function() {
var body = JSON.parse(this.body);
return body["data"]["url"];
}
utils.prototype.getEncId = function(dfsId, callback) {
// var magicBytes = new Buffer('3go8&$8*3*3h0k(2)2');
// var songId = new Buffer(dfsId.toString());
// for (var i = 0; i < songId.length; i++) {
// songId[i] = songId[i] ^ magicBytes[i % magicBytes.length];
// }
// // console.log(songId);
// var hash = md5(songId.toString());
// return base64.encode(hash)
// .replace('/', '_')
// .replace('+', '-');
var options = {
mode: 'text',
args: [dfsId]
};
PythonShell.run('./utils/get_enc_id.py', options, function(err, results) {
if (err) {
console.error(err.red);
return callback(err);
} else {
callback(null, results[0]);
}
});
}
utils.prototype.generateUrl = function(dfsId, callback) {
var s = (new Date()).getSeconds() % 2 + 1;
this.getEncId(dfsId, function(err, encId) {
if (err) {
console.error(err.red);
return callback(err);
} else {
var url = "http://m" + s + ".music.126.net/" + encId + "/" + dfsId + ".mp3";
callback(null, url)
}
});
}
utils.prototype.getDfsId = function(pageContent) {
var body = JSON.parse(pageContent);
// Downgrade if we don't have higher quality...
var nQuality = 'h';
if (nQuality == "h" && !!!body["songs"][0]["h"]) {
nQuality = "m";
}
if (nQuality == "m" && !!!body["songs"][0]["m"]) {
nQuality = "l";
}
if (nQuality == "l" && !!!body["songs"][0]["l"]) {
nQuality = "b";
}
if (nQuality == "b" && !!!body["songs"][0]["b"]) {
console.log('Song url not found.'.red)
}
return body["songs"][0][nQuality]["fid"];
}
utils.prototype.getUrl = function(songId, callback) {
var _this = this;
waterfall([
function(cb) {
// Make post data
var data = [{
id: songId,
v: 0
}];
data = "c=" + JSON.stringify(data);
cb(null, data);
},
function(data, cb) {
// Make post header
var header = {
'host': 'music.163.com',
'cookie': 'os=pc',
'content-length': data.length,
'content-type': 'application/x-www-form-urlencoded'
};
cb(null, header, data);
},
function(header, data, cb) {
// Do post and get dfsId
_this.post(header, data, "/api/v2/song/detail", function(err, res, body) {
if (err) {
console.error(err.red);
return cb(err);
} else {
var dfsId = _this.getDfsId(body);
return cb(null, dfsId);
}
});
},
function(dfsId, cb) {
// Generate url
_this.generateUrl(dfsId, function(err, url) {
if (err) {
console.error(err.red);
return cb(err);
} else {
cb(null, url);
}
})
}
], function(err, url) {
if (err) {
console.error(err.red);
return callback(err);
} else {
callback(null, url);
}
});
}
utils.prototype.modifyDetailApi = function() {
console.log("Song Detail API Injected".green);
this.body = this.body
.replace(/\"pl\":\d+/g, '"pl":320000')
.replace(/\"dl\":\d+/g, '"dl":320000')
.replace(/\"st\":-?\d+/g, '"st":0')
.replace(/\"subp\":\d+/g, '"subp":1');
// console.log(this.body);
}
utils.prototype.modifyPlayerApi = function(callback) {
console.log("Player API Injected".green);
var _this = this;
var body = JSON.parse(_this.body);
var songId = body["data"][0]["id"];
_this.getUrl(songId, function(err, newUrl) {
if (err) {
console.error(err.red);
return callback(err);
} else {
var newUrl = newUrl;
console.log("New URL is ".green + newUrl.green);
body["data"][0]["url"] = newUrl;
body["data"][0]["br"] = 320000;
body["data"][0]["code"] = "200";
_this.body = JSON.stringify(body);
callback(null);
}
});
}
utils.prototype.modifyDownloadApi = function(callback) {
console.log("Download API Injected".green);
var _this = this;
var body = JSON.parse(_this.body);
var songId = body["data"]["id"];
_this.getUrl(songId, function(err, newUrl) {
if (err) {
console.error(err.red);
return callback(err);
} else {
var newUrl = newUrl;
console.log("New URL is ".green + newUrl.green);
body["data"]["url"] = newUrl;
body["data"]["br"] = 320000;
body["data"]["code"] = "200";
_this.body = JSON.stringify(body);
callback(null);
}
});
}
module.exports = utils;

@@ -1,6 +0,29 @@

var utils = new(require('./index'));
var netease = new(require('./netease'));
utils.getUrl('399953237', function(err, url){
netease.getMusicDetail('589979', function(err, detail){
console.log(err);
console.log(url);
console.log(detail['songs'][0]);
});
// var kugou = new(require('./kugou'));
//
// kugou.getUrl('efba483eb717cc872436075748bcfcf8', function(err, url){
// console.log(url);
// });
// var request = require('request');
//
// var options = {
// url: 'http://media.store.kugou.com/v1/get_res_privilege',
// method: 'post',
// body: '{"appid":1001,"behavior":"play","clientver":"8043","relate":1,"resource":[{"album_id":"544828","hash":"c70b75dd07aabe2ae76b0cdaff007057","id":0,"name":"刘瑞琦 - 晴天.flac","type":"audio"}],"token":"","userid":87549184,"vip":1}',
// gzip: true
// };
// request(options, function(err, res, body) {
// if (err) {
// console.error(err);
// } else {
// // console.log(res.headers);
// console.log(body);
// }
// });
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc