// ==SiteScript== // @siteName 网易云音楽(music.163.com) // @siteUrl http://music.163.com/ // @author mayan // @authorUrl // @scriptUrl // @description // @date 2017/08/18 // @version 0.2.3 // ==/SiteScript== function CravingSiteScript() { this._initialize(); } CravingSiteScript.prototype = { _xhr: null, _initialize: function() {}, _getXmlHttpRequest: function() { if ( this._xhr != null ) { return this._xhr; } var xhr = null; var these = [ function() { return new XMLHttpRequest(); } , function() { return new ActiveXObject( "Msxml2.XMLHTTP" ); } , function() { return new ActiveXObject( "Microsoft.XMLHTTP" ); } , function() { return new ActiveXObject( "Msxml2.XMLHTTP.4.0" ); } ]; for ( var i = 0, length = these.length; i < length; i++ ) { var func = these[ i ]; try { xhr = func(); break; } catch( e ) {} } this._xhr = xhr; return this._xhr; }, _load: function( url, data, method ) { var req = this._getXmlHttpRequest(); var mtd = ( method == null ) ? "GET" : "POST"; req.open( mtd, url, false ); if ( mtd == "POST" ) { req.setRequestHeader( "Content-Type", "application/x-www-form-urlencoded" ); } req.send( data ); return req.responseText; }, getResponseText: function( url, data, method ) { return this._load( url, data, method ); }, getResponseJSON: function( url, data, method ) { var text = this._load( url, data, method ); return eval( "("+text+")" ); }, /// Math random: function( limit ) { return Math.floor( Math.random() * limit ); }, /// String decodeHtml: function( str ) { return str.replace( /&(quot|#0*34);/ig, "\"" ) .replace( /&(amp|#0*38);/ig, "&" ) .replace( /&(apos|#0*39);/ig, "'" ) .replace( /&(lt|#0*60);/ig, "<" ) .replace( /&(gt|#0*62);/ig, ">" ) .replace( /&(nbsp|#0*160);/ig, " " ) .replace( /&(frasl|#8260);/ig, "/" ); } } var _NetEaseMs = {}; _NetEaseMs.addArtistName = true; _NetEaseMs.addAlbumName = true; _NetEaseMs.addTrackNum = false; _NetEaseMs.useProxy = true; _NetEaseMs.proxy = "uku";//"uku" or "proxy:port" _NetEaseMs.Prior = [ "h","m","l" ]; _NetEaseMs.directIP = true; _NetEaseMs.arrDomainIP = [ [ "m10.music.126.net", "218.77.92.250" ] //2017/08/18 //,[ "domain" , "ip address" ] //,[ "domain" , "ip address" ] ]; _NetEaseMs.tryDyIP = false; _NetEaseMs.DNS = ""; function isSiteUrl( url ) { var prm; if ( url.match( /http:\/\/music\.163\.com\/#\/(?:m\/)?(album|playlist|dj|song|artist|mv)(\?.+)/ ) && RegExp.$2.match( /[?&]id=\d+/ ) ) return true; if ( url.match( /http:\/\/music\.163\.com\/#\/(?:m\/)?(share)(\?.+)/ ) && (prm=RegExp.$2) && prm.match( /[?&]id=\d+/ ) && prm.match( /[?&]uid=\d+/ ) ) return true; if ( url.match( /http:\/\/music\.163\.com\/(album|playlist|dj|song|artist|mv)(\?.+)/ ) && RegExp.$2.match( /[?&]id=\d+/ ) ) return true; if ( url.match( /http:\/\/music\.163\.com\/(share)(\?.+)/ ) && (prm=RegExp.$2) && RegExp.$2.match( /[?&]id=\d+/ ) && prm.match( /[?&]uid=\d+/ ) ) return true; if ( url.match( /http:\/\/music\.163\.com\/(?:m\/)?(album|song|artist|mv)\/\d+/ ) ) return true; if ( url.match( /http:\/\/music\.163\.com\/(?:m\/)?(playlist|program|share)\/\d+\/\d+/ ) ) return true; if ( url.match( /http:\/\/music\.163\.com\/static\/(album|playlist|song|artist|mv)\/\d+/ ) ) return true; return false; } function getVideoDetail( url ) { if ( typeof _NetEaseMs != "object" ) _NetEaseMs = {}; if ( !_NetEaseMs.Prior instanceof Array ) _NetEaseMs.Prior = [ "h","m","l" ]; var V3toV0 = { "h":"hMusic","m":"mMusic","l":"lMusic","br":"bitrate","fid":"fdsId" }; //var DefaultBr = { "h":320000,"m":160000,"l":96000 }; if ( _NetEaseMs.useProxy && _NetEaseMs.proxy == "uku" ) { _NetEaseMs.proxy = UKUIM().getProxy(); } if ( url.match( /http:\/\/music\.163\.com\/#\/(?:m\/)?(album|playlist|dj|song|artist|mv|share)(\?.+)/ ) || url.match( /http:\/\/music\.163\.com\/(album|playlist|dj|song|artist|mv|share)(\?.+)/ ) ) { var prm = RegExp.$2; var type = RegExp.$1; var id = prm.match( /[?&]id=(\d+)/ )? RegExp.$1: ""; if ( type == "share" ) var uid = prm.match( /[?&]uid=(\d+)/ )? RegExp.$1: ""; } else if ( url.match( /http:\/\/music\.163\.com\/(?:m\/)?(album|song|artist|mv)\/(\d+)/ ) || url.match( /http:\/\/music\.163\.com\/(?:m\/)?(playlist|program|share)\/(\d+)\/(\d+)/ ) || url.match( /http:\/\/music\.163\.com\/static\/(album|playlist|song|artist|mv)\/(\d+)/ ) ) { type = RegExp.$1; if ( type == "program" ) type = "dj"; if ( type == "share" ) { id = RegExp.$3; uid = RegExp.$2; } else { id = RegExp.$2; } } else { return null; } var craving = new CravingSiteScript(); if ( type == "mv" ) { return getVideoDetail_mv( id, craving, _NetEaseMs ); } try { var objHttp = new ActiveXObject( "WinHttp.WinHttpRequest.5.1" ); } catch( e ) { //objHttp = craving._getXmlHttpRequest();//getRealUrlでreferer必須です objHttp = null; } if ( !objHttp ) return null; var arrDat = []; switch ( type ) { case "album": arrDat = getData_album( id, craving, objHttp ); break; case "playlist": arrDat = getData_playlist( id, craving, objHttp ); break; case "dj": case "program": arrDat = getData_dj( id, craving, objHttp ); break; case "song": arrDat = getData_song_v3( id, [id], objHttp ); break; case "artist": arrDat = getData_artist( id, craving, objHttp ); break; case "share": arrDat = getData_share( id, uid, craving, objHttp ); break; default: } if ( !arrDat || !(arrDat instanceof Array) || arrDat.length <= 0 ) return null; var objGru = GetRealUrl( objHttp ); var arrRtn = []; for ( var i = 0; i < arrDat.length; i++ ) { if ( !arrDat[i] || typeof arrDat[i] != "object" ) continue; var obj = {}; obj.name = (typeof arrDat[i].name == "string")? arrDat[i].name: ""; if ( !obj.name ) obj.name = "netease_" + ( arrDat[i].id || (new Date().getTime()) ); if ( !arrDat[i].album && arrDat[i].al ) arrDat[i].album = arrDat[i].al; if ( arrDat[i].album && typeof arrDat[i].album == "object" && arrDat[i].album.name && typeof arrDat[i].album.name == "string" ) { obj.albumname = arrDat[i].album.name; } else { obj.albumname = ""; } if ( !arrDat[i].artists && arrDat[i].ar ) arrDat[i].artists = arrDat[i].ar; var arrAst = []; if ( arrDat[i].artists && (arrDat[i].artists instanceof Array) ) { for ( var j = 0; j < arrDat[i].artists.length; j++ ) { var arrTmp = arrDat[i].artists[j]; if ( !arrTmp || typeof arrTmp != "object" ) continue; if ( arrTmp.name && typeof arrTmp.name == "string" ) arrAst.push( arrTmp.name ); } } obj.artistname = arrAst.join( "," ); var objHd = selectPrior( arrDat[i] ); if ( objHd ) var br = objHd.bitrate || objHd.br; if ( !br ) br = 320000; var songid = arrDat[i].id; obj.realUrl = objGru.getRealUrl( songid, br, (_NetEaseMs.useProxy? _NetEaseMs.proxy: "") ); if ( !obj.realUrl ) continue; obj.index = i+1; arrRtn.push( obj ); } if ( arrRtn.length <= 0 ) return null; var arrDomainIP = []; if ( _NetEaseMs.directIP === true && _NetEaseMs.arrDomainIP && _NetEaseMs.arrDomainIP instanceof Array ) { if ( _NetEaseMs.tryDyIP ) var objNs = new clsNsLookUp(); for ( var i = 0; i < _NetEaseMs.arrDomainIP.length; i++ ) { if ( _NetEaseMs.arrDomainIP[i] instanceof Array && typeof _NetEaseMs.arrDomainIP[i][0] == "string" && typeof _NetEaseMs.arrDomainIP[i][1] == "string" ) { var dyip = ""; if ( _NetEaseMs.tryDyIP && objNs ) { var arrDyIp = objNs.lookup( _NetEaseMs.arrDomainIP[i][0], _NetEaseMs.DNS ); if ( typeof arrDyIp[0] == "string" && arrDyIp[0] !== "127.0.0.1" ) { dyip = arrDyIp[0]; } } if ( dyip ) { arrDomainIP.push( [ _NetEaseMs.arrDomainIP[i][0], dyip ] ); } else { arrDomainIP.push( _NetEaseMs.arrDomainIP[i] ); } } } } var objRtn = {}; for ( var i = 0; i < arrRtn.length; i++ ) { var title = ( _NetEaseMs.addTrackNum? ( (arrRtn[i].index < 10)?("0"+arrRtn[i].index+" "):(""+arrRtn[i].index+" ") ): "" ) + ( (_NetEaseMs.addArtistName && arrRtn[i].artistname)? (arrRtn[i].artistname + " - "): "" ) + arrRtn[i].name + ( (_NetEaseMs.addAlbumName && arrRtn[i].albumname)? (" ~ " + arrRtn[i].albumname): "" ); title = title.replace(/[\\\/:*?"<>|]/g, "_"); var realUrl = arrRtn[i].realUrl; if ( _NetEaseMs.directIP === true && realUrl.match( /(https?:\/\/)([^\/?]+?)(\/.*)/i ) ) { for ( var j = 0; j < arrDomainIP.length; j++ ) { if ( RegExp.$2.toLowerCase() == arrDomainIP[j][0] ) { realUrl = RegExp.$1 + arrDomainIP[j][1] + RegExp.$3; objRtn[ "httpHeader" + i ] = "host: " + arrDomainIP[j][0]; break; } } } objRtn[ "videoTitle" + i ] = title; objRtn[ "videoUrl" + i ] = realUrl; } return objRtn; function selectPrior( objSong ) { //global: _NetEaseMs.Prior //global: var V3toV0 = { "h":"hMusic","m":"mMusic","l":"lMusic" }; var objHd = null; for ( var i = 0; i < _NetEaseMs.Prior.length; i++ ) { if ( objSong[ _NetEaseMs.Prior[i] ] && typeof objSong[ _NetEaseMs.Prior[i] ] == "object" ) { objHd = objSong[ _NetEaseMs.Prior[i] ];//v3 if ( !objHd.bitrate && objHd.br ) objHd.bitrate = objHd.br; if ( !objHd.fdsId && objHd.fid ) objHd.fdsId = objHd.fid; break; } if ( V3toV0[_NetEaseMs.Prior[i]] && objSong[ V3toV0[_NetEaseMs.Prior[i]] ] && typeof objSong[ V3toV0[_NetEaseMs.Prior[i]] ] == "object" ) { objHd = objSong[ V3toV0[_NetEaseMs.Prior[i]] ];//v0 break; } } return objHd; } } function getData_album( albumid, craving, objHttp, preventLoop ) { var objRef = {}; objRef.url = "http://music.163.com/api/album/" + albumid; objRef.method = "GET"; objRef.header = { "Referer":"http://music.163.com/" }; objRef.data = ""; objRef.proxy = ""; objRef.charcode = "utf-8"; objRef.json = true; getResponse( objRef, objHttp ); if ( objRef.objJ && typeof objRef.objJ == "object" && objRef.objJ.album && typeof objRef.objJ.album == "object" && objRef.objJ.album.songs && objRef.objJ.album.songs instanceof Array ) { return objRef.objJ.album.songs; } if ( preventLoop === true ) return null; var pageurl = "http://music.163.com/album?id=" + albumid; return getData_page( pageurl, craving, objHttp ); } function getData_playlist( playlistid, craving, objHttp ) { var playlistapiurl = "http://music.163.com/api/playlist/detail?id=" + playlistid; try { var objJ = craving.getResponseJSON( playlistapiurl ); var arrDat = objJ.result.tracks; } catch( e ) { arrDat = null; } if ( arrDat && arrDat instanceof Array && arrDat.length ) return arrDat; var objRef = {}; objRef.url = playlistapiurl; objRef.method = "GET"; objRef.header = { "Referer":"http://music.163.com/" };//not necessary? objRef.data = ""; objRef.proxy = ""; objRef.charcode = "utf-8"; objRef.json = true; getResponse( objRef, objHttp ); if ( objRef.objJ && typeof objRef.objJ == "object" && objRef.objJ.result && typeof objRef.objJ.result == "object" && objRef.objJ.result.tracks && objRef.objJ.result.tracks instanceof Array ) { return objRef.objJ.result.tracks; } var pageurl = "http://music.163.com/playlist?id=" + playlistid; return getData_page( pageurl, craving, objHttp ); } function getData_dj( djid, craving, objHttp ) { var objRef = {}; objRef.url = "http://music.163.com/api/dj/program/detail?id=" + djid; objRef.method = "GET"; objRef.header = { "Referer":"http://music.163.com/" }; objRef.data = ""; objRef.proxy = ""; objRef.charcode = "utf-8"; objRef.json = true; getResponse( objRef, objHttp ); if ( objRef.objJ && typeof objRef.objJ == "object" && objRef.objJ.program && typeof objRef.objJ.program == "object" && objRef.objJ.program.songs && objRef.objJ.program.songs instanceof Array ) { return objRef.objJ.program.songs; } var pageurl = "http://music.163.com/dj?id=" + djid; return getData_page( pageurl, craving, objHttp ); } function getData_artist( artistid, craving, objHttp ) { var objRef = {}; objRef.url = "http://music.163.com/api/artist/" + artistid; objRef.method = "GET"; objRef.header = { "Referer":"http://music.163.com/" }; objRef.data = ""; objRef.proxy = ""; objRef.charcode = "utf-8"; objRef.json = true; getResponse( objRef, objHttp ); if ( objRef.objJ && typeof objRef.objJ == "object" && objRef.objJ.hotSongs && objRef.objJ.hotSongs instanceof Array ) { return objRef.objJ.hotSongs; } var pageurl = "http://music.163.com/artist?id=" + artistid; return getData_page( pageurl, craving, objHttp ); } function getData_share( shareid, uid, craving, objHttp ) { var pageurl = "http://music.163.com/share?uid=" + uid + "&id=" + shareid; return getData_page( pageurl, craving, objHttp ); } function getData_song( songid, songidz, objHttp, proxy ) { var songapiurl = "http://music.163.com/api/song/detail/" + "?ids=%5B" + songidz.join(",") + "%5D" + (songid? ("&id=" + songid): "" ) + "&csrf_token="; var objRef = {}; objRef.url = songapiurl; objRef.method = "GET"; objRef.header = {"Referer":"http://music.163.com/"}; objRef.data = ""; objRef.proxy = ( (typeof proxy == "string")? proxy: "" ); objRef.charcode = "utf-8"; objRef.json = true; getResponse( objRef, objHttp ); if ( !objRef.objJ || typeof objRef.objJ != "object" ) return null; if ( !objRef.objJ.songs || !(objRef.objJ.songs instanceof Array ) ) return null; return objRef.objJ.songs; } function getData_song_v3( songid, songidz, objHttp, proxy ) { var songapiurl_v3 = "http://music.163.com/weapi/v3/song/detail?csrf_token="; var arrTmp = []; for ( var i = 0; i < songidz.length; i++ ) { arrTmp.push( '{\\"id\\":\\"' + songidz[i] + '\\"}' ); } var data = '{' + ( songid? ('"id":"' + songid + '",'):"" ) + '"c":"[' + arrTmp.join(",") + ']","csrf_token":""}'; var objRef = {}; objRef.url = songapiurl_v3; objRef.method = "POST"; objRef.header = {"Referer":"http://music.163.com/"};//not necessary? objRef.data = ClsEnc().getData( data ); objRef.proxy = ( (typeof proxy == "string")? proxy: "" ); objRef.charcode = "utf-8"; objRef.json = true; getResponse( objRef, objHttp ); if ( objRef.objJ && typeof objRef.objJ == "object" && objRef.objJ.songs && objRef.objJ.songs instanceof Array ) { return objRef.objJ.songs; } //v0 var px = (typeof _NetEaseMs == "object" && _NetEaseMs.useProxy)? _NetEaseMs.proxy: ""; return getData_song( songid, songidz, objHttp, px ); } function getData_page( pageurl, craving, objHttp ) { try { var objHttp2 = craving._getXmlHttpRequest(); objHttp2 = objHttp2 || objHttp; objHttp2.open( "GET", pageurl, false ); objHttp2.send(); var objCnv = new clsCharConvert(); if ( objCnv.isOK && objCnv.convertChar( objHttp2.responseBody, "utf-8" ) ) { var text = objCnv.result; } else { text = objHttp2.responseText; } } catch( e ) { text = ""; } if ( !text ) return null; var arrSid = []; if ( text.match( /