Greasy Fork is available in English.
Download music from music.163.com
当前为
// ==UserScript==
// @name Simple 163 Music Dl Helper
// @namespace org.jixun.music.163
// @version 1.0
// @description Download music from music.163.com
///
// 火狐匹配地址
// @include http://music.163.com/#*
///
// TamperMonkey 匹配地址
// @include http://music.163.com/
///
// @copyright 2014+, Jixun.Moe, 2015+, X-Ryl669
// @run-at document-start
// @grant GM_download
// ==/UserScript==
(function () {
// I love prototype.
String.prototype.format = function () {
var $arg = arguments,
$len = $arg.length;
return this.replace (/\{(\d+)\}/g, function (z, num) {
num = parseInt (num);
if (num < $len) {
return $arg[num];
} else {
return z;
}
});
};
var $bank = {};
var $dlBtn = document.createElement ('a');
$dlBtn.setAttribute ('target', '_blank');
$dlBtn.setAttribute ('style', 'font-size:small;width:3em;left:initial;right:40px');
$dlBtn.className = 'lytit';
$dlBtn.textContent = 'down';
$dlBtn.addEventListener ('click', function (e) {
var $addr = this.getAttribute ('href');
GM_download($addr, this.getAttribute('download') + ".mp3");
e.preventDefault();
e.stopPropagation ();
}, false);
var $blob = 0;
var _updDownloadUrl = function (songId) {
var $song = $bank[songId.toString()];
var $info = '{0}.[{1}] {2} - {3}'.format (("0" + $song.index).slice(-2), $song.album, $song.artist, $song.name);
console.info ('%s\n%s', $info, $song.url);
$dlBtn.setAttribute ('title', 'Song: ' + $info);
$dlBtn.setAttribute ('download', $info+'.mp3');
$dlBtn.setAttribute ('href', $song.url);
};
var _addBank = function (songObj) {
$bank[songObj.id.toString()] = {
name: songObj.name,
album: songObj.album.name,
artist: songObj.artists.map(function (artist) {
return artist.name;
}).join ('& '),
url: songObj.mp3Url,
index: (Object.keys($bank).indexOf(songObj.id) == -1 ? Object.keys($bank).length : Object.keys($bank).indexOf(songObj.id)) + 1
};
};
window.XMLHttpRequest.prototype.oldOpen = window.XMLHttpRequest.prototype.open;
window.XMLHttpRequest.prototype.open = function (method, url) {
console.info ('[REQ] %s: %s', method, url);
if (!url.indexOf('/api/song/media') || !url.indexOf('/api/song/lyric')) {
console.log ('Check $bank...');
var $id = url.indexOf('/api/song/media') === 0 ? url.match (/\d+/)[0] : url.match(/id=(\d+)/)[1];
if ($bank.hasOwnProperty($id)) {
_updDownloadUrl ($id);
} else {
// First, search through local cache.
var cacheSongObj;
try {
cacheSongObj = JSON.parse(localStorage['track-queue']).filter (function (s) {
_addBank (s);
return $id == s.id.toString();
});
} catch (err) { }
if (cacheSongObj) {
console.info ('Music found from cache.');
_updDownloadUrl (cacheSongObj.id);
} else {
console.info ('Requesting song information...');
var $http = new window.XMLHttpRequest ();
var $args = [].slice.apply(arguments);
$http.onreadystatechange = new Function ();
$args[1] = '/api/song/detail/?id=' + $id + '&ids=%5B' + $id + '%5D&csrf_token=' + url.match(/csrf_token=([^&]*)/)[1];
$http.open.apply ($http, $args);
$http.send ();
}
}
} else if (-1 != url.indexOf('/api/song/detail')) {
try {
var $this = this;
var bkReadystatechange = this.onreadystatechange;
this.onreadystatechange = function (e) {
if ($this.readyState === 4) {
JSON.parse($this.responseText.trim()).songs.forEach(function (e) {
_addBank (e);
_updDownloadUrl (e.id);
});
}
return bkReadystatechange.apply (this, arguments);
};
} catch (err) {
console.error (err);
}
}
return this.oldOpen.apply(this, arguments);
};
(function () {
var $t;
var vv = setInterval (function () {
if (!($t = document.querySelector ('.lytit')))
return ;
clearInterval (vv);
$t.style.maxWidth = '302px';
$t.parentNode.insertBefore ($dlBtn, $t.nextElementSibling);
}, 200);
})();
})();