// ==UserScript==
// @name 5sing助手
// @namespace heroesm
// @description 5sing功能增强
// @include http://5sing.kugou.com/*
// @include http://fc.5sing.com/*
// @include http://static.5sing.kugou.com/???*
// @version 1.1.2.5
// @grant none
// @run-at document-start
// @downloadURL https://update.greasyfork.icu/scripts/17648/5sing%E5%8A%A9%E6%89%8B.user.js
// @updateURL https://update.greasyfork.icu/scripts/17648/5sing%E5%8A%A9%E6%89%8B.meta.js
// ==/UserScript==
function main(){
//compatible with nonstrict mode
"use strict";
function SongIndex(id){
this.id = id;
}
SongIndex.prototype = {
get song(){return wsingHelper.mSongs[this.id];},
set song(x){wsingHelper.mSongs[this.id] = x;}
};
var wsingHelper = {
aIndex: [],
mSongs: {},
aJSON: [],
aJSON2: [],
nList: 0,
player: {
pos: 1,// 1,2,3,4 correspond to top-left, top-right, bottom-right, bottom-left corner
audio: {},
volume: 1,
repeat: false,
playing: 0,
autoplay: '0',
sequence: false,
shortcut1: 's',
shortcut2: 'd',
shortcut3: 'f',
shortcut4: 'g',
control: '1',
volfix: '0'
},
container: {},
prepare: prepare,
jsonpp: jsonpp,
checkSetting: checkSetting,
jsonp: jsonp,
adjust: adjust,
fix: fix,
search: search,
createOption: createOption,
confirmOption: confirmOption,
resetOption: resetOption,
preventAutoplay: preventAutoplay,
setSongCookies: setSongCookies,
exportList: exportList,
importList: importList,
coin: coin,
searchSong: searchSong,
fetchMore: fetchMore,
fetchToEnd: fetchToEnd,
loadSong: loadSong,
createList: createList,
buildMy: buildMy,
setUpUI: setUpUI,
init: init,
notify: notify
};
var locked = false;
var ended = false;
var sHeadIndex = '';
function prepare(){
Document.prototype.$ = Document.prototype.querySelector;
Element.prototype.$ = Element.prototype.querySelector;
Document.prototype.$$ = Document.prototype.querySelectorAll;
Element.prototype.$$ = Element.prototype.querySelectorAll;
}
function jsonp(sUrl, success){
var Result, sCallback;
sCallback = 'callback_' + (new Date()).getTime();
function callback(Res){
document.head.removeChild(script);
eval('delete window.'+ sCallback);
success(Res);
//Result = Res;
}
window[sCallback] = callback;
sUrl+= (/\?/.test(sUrl) ? '&' : '?');
sUrl+= 'jsoncallback=' + sCallback + '&_=' + (new Date()).getTime();
var script = document.createElement('script');
script.src = sUrl;
/*script.onload = function(){
success(Result);
document.head.removeChild(script);
eval('delete window.'+ sCallback);
}*/
document.head.appendChild(script);
}
// implement jsonp with promise, not in use
function jsonpp(sUrl){
var p = new Promise(function(resolve,reject){
var sCallback;
sCallback = 'callback_' + (new Date()).getTime();
window[sCallback] = callback;
sUrl+= (/\?/.test(sUrl) ? '&' : '?');
sUrl+= 'jsoncallback=' + sCallback + '&_=' + (new Date()).getTime();
var script = document.createElement('script');
script.src = sUrl;
function callback(Res){
resolve(Res);
document.head.removeChild(script);
eval('delete window.'+ sCallback);
}
//script.onload = function(){resolve(Result);}
document.head.appendChild(script);
});
return p;
}
function notify(sText, nTime){
clearTimeout(notify.timeout);
var notifier = wsingHelper.container.notifier;
notifier.textContent = '提示:' + sText;
notifier.style.display = 'unset';
if(typeof nTime == 'number'){
notify.timeout = setTimeout(function(){
notifier.style.display = 'none';
notifier.textContent = '提示:';
}, nTime);
}
}
function keyHandle1(e){
//run before initialization of the main panel
if((!/input|textarea/.test(e.target.tagName.toLowerCase()) || /checkbox|submit/.test(e.target.type)) && e.altKey === false && e.ctrlKey === false){
var key = wsingHelper.player.shortcut1;
if(key && ((e.key && e.key.toLowerCase() == key) || e.code == 'Key' + key.toUpperCase())){
document.$('#helper_toggle').click();
}
}
}
function keyHandle2(e){
//run after initialization of the main panel
if((!/input|textarea/.test(e.target.tagName.toLowerCase()) || /checkbox|submit/.test(e.target.type)) && e.altKey === false && e.ctrlKey === false){
var key;
if((key = wsingHelper.player.shortcut2) && ((e.key && e.key.toLowerCase() == key) || e.code == 'Key' + key.toUpperCase())){
document.$('#helper_set').click();
}
else if((key = wsingHelper.player.shortcut3) && ((e.key && e.key.toLowerCase() == key) || e.code == 'Key' + key.toUpperCase())){
wsingHelper.player.audio.paused? wsingHelper.player.audio.play() : wsingHelper.player.audio.pause();
}
else if((key = wsingHelper.player.shortcut4) && (e.key && e.key.toLowerCase() == key) || e.code == 'Key' + key.toUpperCase()){
try{
document.$('.helper_more').click();
}catch(e){console.log(e);}
}
else if(wsingHelper.player.control == '1'){
//play previous song
if((key = 'h') && (e.key && e.key.toLowerCase() == key) || e.code == 'Key' + key.toUpperCase()){
wsingHelper.loadSong(wsingHelper.player.playing - 1);
}
//increase volume
else if((key = 'j') && (e.key && e.key.toLowerCase() == key) || e.code == 'Key' + key.toUpperCase()){
wsingHelper.player.audio.volume = (wsingHelper.player.audio.volume - 0.1) >= 0 ? wsingHelper.player.audio.volume - 0.1 : 0;
}
//decrease volume
else if((key = 'k') && (e.key && e.key.toLowerCase() == key) || e.code == 'Key' + key.toUpperCase()){
wsingHelper.player.audio.volume = (wsingHelper.player.audio.volume + 0.1) <= 1 ? wsingHelper.player.audio.volume + 0.1 : 1;
}
//play next song
else if((key = 'l') && (e.key && e.key.toLowerCase() == key) || e.code == 'Key' + key.toUpperCase()){
wsingHelper.loadSong(wsingHelper.player.playing + 1);
}
}
}
}
function adjust(sScheme,node,nVer,nHor){
function changePos(node,t,r,b,l){
for(var i = 1; i< arguments.length; i++){
if(typeof arguments[i] != 'number')
arguments[i] = 'unset';
else
arguments[i]+= 'px';
//in strict mode, modification in array variable "arguments" will not be reflected in the named real arguments
node.style.top = arguments[1];
node.style.right = arguments[2];
node.style.bottom = arguments[3];
node.style.left = arguments[4];
}
}
switch(sScheme){
case '1':
changePos(node,nVer,'','',nHor);
break;
case '2':
changePos(node,nVer,nHor,'','');
break;
case '3':
changePos(node,'',nHor,nVer,'');
break;
case '4':
changePos(node,'','',nVer,nHor);
break;
}
}
function getSongSrc(Song){
var url = 'http://service.5sing.kugou.com/song/getsongurl?songid=' + Song.id + '&songtype=' + Song.type + '&from=web&version=6.6.72'
jsonp(url, function(res){
var rawSong = res
try{
Song.src = rawSong['data']['squrl']
notify('成功获取歌曲地址', 3000);
}catch(e){console.log(e);}
});
}
function fix(Song){
notify('地址错误,尝试更新地址……');
getSongSrc(Song)
//var xhr = new XMLHttpRequest();
//xhr.timeout = 10000;
//xhr.ontimeout = xhr.onerror = function(e){
// notify('地址更新失败', 3000);
//};
//xhr.onload = function(e){
// var data = xhr.response;
// data = /ticket["']\s*:\s*(["'])(.+)\1/.exec(data)[2];
// data = JSON.parse(atob(data));
// Song.src = data.file;
// if(wsingHelper.aIndex[wsingHelper.player.playing].song == Song){
// var audio = wsingHelper.player.audio;
// if(audio.src == Song.src){
// notify('歌曲地址无效', 3000);
// }
// else{
// audio.src = Song.src;
// audio.load();
// audio.play();
// notify('地址更新成功', 3000);
// }
// }
//};
//xhr.open('get', 'http://5sing.kugou.com/' + Song.type + '/' + Song.id + '.html');
//xhr.send();
}
function search(sKey, sSite, sType){
var sURI = encodeURIComponent( (sType?sType:'') + sKey +' site:5sing.kugou.com');
if(sSite== 'google')
window.open('https://www.google.com/search?q='+ sURI);
else if(sSite== 'baidu')
window.open('https://www.baidu.com/s?wd='+ sURI);
}
function createOption(divSet){
var sHtml = [
'
',
'
功能区
',
'
',
'
',
'
',
'',
'',
'',
'',
'
',
'
',
'',
'
设置区
',
'
',
' - 自动播放:
',
' - 插件位置:
',
' - 音量设置:
',
' - 面板开关:
',
' - 功能设置:
',
' - 播放暂停:
',
'
',
'
',
' - 播放控制:
',
' - 音量修复:
',
' - 获取更多:
',
'
',
'
',
'
',
'
',
'
',
' ',
' ',
' ',
'
'
].join('\n');
divSet.innerHTML = sHtml;
var t1, t2;
t1 = divSet.$('#helper_fun_goo');
t1.$$('button')[0].onclick = function(e){
var sKey = t1.$('input').value;
search(sKey,'google');
};
t1.$$('button')[1].onclick = function(e){
var sKey = t1.$('input').value;
search(sKey,'google','intitle:');
};
t1.addEventListener('keydown',function(e){
if(e.key == 'Enter' || e.code == 'Enter')
t1.$('button').onclick();
});
t2 = divSet.$('#helper_fun_bai');
t2.$$('button')[0].onclick = function(e){
var sKey = t2.$('input').value;
search(sKey,'baidu');
};
t2.$$('button')[1].onclick = function(e){
var sKey = t2.$('input').value;
search(sKey,'baidu','intitle:');
};
t2.addEventListener('keydown',function(e){
if(e.key== 'Enter' || e.code == 'Enter')
t2.$('button').onclick();
});
divSet.$('#helper_fun_reload').onclick = function(){
try{
window.$wsp.htmlMediaElement.load();
window.$wsp.htmlMediaElement.dispatchEvent(new Event('pause'));
}catch(e){console.log(e);}
};
divSet.$('#helper_fun_load').onclick = function(){
window.wsingHelper.fetchToEnd();
}
divSet.$('#helper_fun_export').onclick = exportList;
divSet.$('#helper_fun_import').onclick = importList;
divSet.$('#helper_opt_con').onclick = function(){
confirmOption(divSet);
wsingHelper.container.$('#helper_set').onclick();
};
divSet.$('#helper_opt_can').onclick = function(){
wsingHelper.container.$('#helper_set').onclick();
};
divSet.$('#helper_opt_cle').onclick = function(){
for(var i = 0,t; i < localStorage.length;i++){
t = localStorage.key(i);
if(t.indexOf('helper_') === 0){
localStorage.removeItem(t);
i--;
}
}
};
return divSet;
}
function checkSetting(){
var t;
t = localStorage.helper_pos;
if(/^[1234]$/.test(t))
wsingHelper.player.pos = t;
t = localStorage.helper_shortcut1;
if(/^[a-z0-9]$/.test(t))
wsingHelper.player.shortcut1 = t;
t = localStorage.helper_shortcut2;
if(/^[a-z0-9]$/.test(t))
wsingHelper.player.shortcut2 = t;
t = localStorage.helper_shortcut3;
if(/^[a-z0-9]$/.test(t))
wsingHelper.player.shortcut3 = t;
t = localStorage.helper_shortcut4;
if(/^[a-z0-9]$/.test(t))
wsingHelper.player.shortcut4 = t;
t = localStorage.helper_play;
if(/^[01][01]$/.test(t)){
wsingHelper.player.repeat = (t.charAt(0) === '1');
wsingHelper.player.sequence = (t.charAt(1) === '1');
}
t = localStorage.helper_autoplay;
if(/^[01]$/.test(t))
wsingHelper.player.autoplay = t;
t = parseFloat(localStorage.helper_volume);
if( t>= 0 && t<= 1){
wsingHelper.player.volume = t;
}
t = localStorage.helper_control;
if(/^[01]$/.test(t))
wsingHelper.player.control = t;
t = localStorage.helper_volfix;
if(/^[01]$/.test(t))
wsingHelper.player.volfix = t;
}
function confirmOption(divSet){
var t;
t = divSet.$('#helper_opt_autoplay').value;
if(/^[01]$/.test(t)) localStorage.helper_autoplay = t;
t = divSet.$('#helper_opt_pos').value;
var a = wsingHelper.container, b = document.$('#helper_toggle');
if(/^[1234]$/.test(t)){
adjust(t,a,60,50);
adjust(t,b,100,10);
localStorage.helper_pos = t;
}
t = divSet.$('#helper_opt_sho').value;
if(/^[a-z0-9]$/.test(t)) localStorage.helper_shortcut1 = wsingHelper.player.shortcut1 = t;
t = divSet.$('#helper_opt_set').value;
if(/^[a-z0-9]$/.test(t)) localStorage.helper_shortcut2 = wsingHelper.player.shortcut2 = t;
t = divSet.$('#helper_opt_pla').value;
if(/^[a-z0-9]$/.test(t)) localStorage.helper_shortcut3 = wsingHelper.player.shortcut3 = t;
t = divSet.$('#helper_opt_get').value;
if(/^[a-z0-9]$/.test(t)) localStorage.helper_shortcut4 = wsingHelper.player.shortcut4 = t;
t = parseFloat(divSet.$('#helper_opt_vol').value);
if( t>= 0 && t<= 1){
wsingHelper.player.audio.volume = t;
localStorage.helper_volume = t.toFixed(2) + '';
}
t = divSet.$('#helper_opt_control').value;
if(/^[01]$/.test(t)) localStorage.helper_control = wsingHelper.player.control = t;
t = divSet.$('#helper_opt_volfix').value;
if(/^[01]$/.test(t)) localStorage.helper_volfix = wsingHelper.player.volfix = t;
}
function resetOption(divSet){
checkSetting();
var t;
t = divSet.$('#helper_opt_autoplay');
t.value = wsingHelper.player.autoplay;
t = divSet.$('#helper_opt_pos');
t.value = wsingHelper.player.pos;
t = divSet.$('#helper_opt_sho');
t.value = wsingHelper.player.shortcut1;
t = divSet.$('#helper_opt_set');
t.value = wsingHelper.player.shortcut2;
t = divSet.$('#helper_opt_pla');
t.value = wsingHelper.player.shortcut3;
t = divSet.$('#helper_opt_get');
t.value = wsingHelper.player.shortcut4;
t = divSet.$('#helper_opt_vol');
t.value = wsingHelper.player.volume;
t = divSet.$('#helper_opt_control');
t.value = wsingHelper.player.control;
t = divSet.$('#helper_opt_volfix');
t.value = wsingHelper.player.volfix;
}
function preventAutoplay(){
if(Object.prototype.watch){
window.watch('$wsp',function(id,oldval,newval){
if(Boolean(newval.htmlMediaElement)){
newval.htmlMediaElement.autoplay = false;
Object.defineProperty(newval.htmlMediaElement,'autoplay',{
get: function(){return false;},
configurable: true
});
newval.htmlMediaElement.addEventListener('canplay',function(e){
e.stopImmediatePropagation();
},true);
}
else{
newval.watch('htmlMediaElement',function(id,oldval2,newval2){
if(newval2 instanceof Audio){
newval2.autoplay = false;
Object.defineProperty(newval2,'autoplay',{
get: function(){return false;},
configurable: true
});
newval2.addEventListener('canplay',function(e){
e.stopImmediatePropagation();
},true);
}
newval.unwatch('htmlMediaElement'); //moving this sentence into end of the upper inner if block means watching constantly ,rather than watching once;
return newval2;
});
}
window.unwatch('$wsp'); //moving this sentence into end of the upper inner if block means watching constantly ,rather than watching once;
return newval;
});
}
else{
var value1 = undefined;
Object.defineProperty(window,'$wsp',{
set: function(newval){
if(Boolean(newval.htmlMediaElement)){
newval.htmlMediaElement.autoplay = false;
Object.defineProperty(newval.htmlMediaElement,'autoplay',{
get: function(){return false;},
configurable: true
});
newval.htmlMediaElement.addEventListener('canplay',function(e){
e.stopImmediatePropagation();
},true);
}
else{
var value2 = undefined;
Object.defineProperty(newval,'htmlMediaElement',{
set: function(newval2){
if(newval2 instanceof Audio){
newval2.autoplay = false;
Object.defineProperty(newval2,'autoplay',{
get: function(){return false;},
configurable: true
});
newval2.addEventListener('canplay',function(e){
e.stopImmediatePropagation();
},true);
}
delete newval.htmlMediaElement; //
newval.htmlMediaElement = newval2; //moving these two sentences into end of the upper inner if block means watching (via the setter way) constantly ,rather than watching once;
value2 = newval2;
},
get: function(){ return value2;},
configurable: true
});
}
delete window.$wsp; //
window.$wsp = newval; //moving these two sentences into end of the upper inner if block means watching (via the setter way) constantly ,rather than watching once;
value1 = newval;
},
get: function(){ return value1;},
configurable :true
});
}
window.addEventListener('load', function(){
if(window.$wsp && window.$wsp.htmlMediaElement) {
window.$wsp.htmlMediaElement.dispatchEvent(new Event('pause'));
var t = document.querySelector('.wsp_c_play');
if(t){
setTimeout(function resend(){
if(t.style.display== 'none' && window.$wsp.htmlMediaElement.paused === true){
window.$wsp.htmlMediaElement.dispatchEvent(new Event('pause'));
setTimeout(resend,100);
}
},100);
}
}
});
//prevent undispatched load event owing to lagging resource loading
setTimeout(function(){
if(!window.$wsp) return;
window.$wsp.htmlMediaElement.dispatchEvent(new Event('pause'));
},5000);
// a new playing mechanism in 5sing will detect the 'h5' capability by testing the presence of global variable Worker; if Worker present, it will create autoplaying audio element which is hard to stop by external script; if not, it shall roll back to elder mechanism.
window.Worker = undefined;
}
function setSongCookies(sSongs){
var iframe = document.createElement('iframe');
iframe.src = 'http://static.5sing.kugou.com/???' + sSongs;
iframe.style.display = 'none';
document.body.appendChild(iframe);
iframe.onload = function(){
//iframe.remove();
//document.body.removeChild(iframe);
};
}
function exportList(){
var sOut = '';
for(var i = 0; i< wsingHelper.aIndex.length; i++){
sOut+= '$'+ wsingHelper.aIndex[i].song.type + '$' + wsingHelper.aIndex[i].song.id;
}
prompt('请复制下面输入框中的字符串以保存歌曲信息:\n\n', sOut.substring(1));
}
function importList(){
var sIn = prompt('请将此前导出的歌曲信息粘贴入下面的输入框:\n\n');
var aIndex = sIn.match(/(yc|fc|bz)\$\d+/ig);
wsingHelper.aIndex = [];
for (var i=0; i
= wsingHelper.aIndex.length){
if(wsingHelper.player.repeat === false)
return false;
else
nIndex = (nIndex < 0 ? wsingHelper.aIndex.length - 1 : 0);
}
try{
var li = wsingHelper.container.olSong.children[wsingHelper.player.playing];
li.className = li.className.replace(/ ?helper_player_playing/g,'');
}catch(e){console.log(e);}
wsingHelper.player.audio.src = wsingHelper.aIndex[nIndex].song.src;
wsingHelper.player.audio.load();
wsingHelper.player.audio.play();
wsingHelper.player.playing = nIndex;
wsingHelper.container.olSong.children[nIndex].className+= ' helper_player_playing';
var info = wsingHelper.container.$('.helper_info'), song = wsingHelper.aIndex[nIndex].song;
info.innerHTML = [
'',
'',
'
',
''+ song.description +'
'
].join('\n');
if(wsingHelper.player.audio.src.slice(-4) == '.wma'){
notify('不支持的wma格式', 3000);
wsingHelper.container.$('.helper_description').innerHTML = '错误:不支持播放wma格式文件';
return false;
}
else{
return true;
}
}
function createList(ol){
var newol = coin('ol','helper_songlist','helper_songlist');
function click(e){
e.preventDefault();
wsingHelper.loadSong(e.currentTarget.index);
}
for(var i = 0, li; i',
' '+ t.songName + '
',
' '+ t.singer + '
',
'\n'
].join('\n');
li.index = i;
li.onclick = click;
newol.appendChild(li);
}
//create checkbox list alongside songs list
var olCheck = coin('ol','helper_checklist','helper_checklist');
wsingHelper.container.aCheck = wsingHelper.container.aCheck || [];
for(var i = 0, li, input, checked; i< newol.childElementCount; i++){
li = wsingHelper.coin('li');
try{
checked = wsingHelper.container.aCheck[i].checked;
}catch(e){checked = false;}
wsingHelper.container.aCheck[i] = input = coin('input');
input.type = 'checkbox';
input.checked = checked;
li.appendChild(input);
olCheck.appendChild(li);
}
wsingHelper.container.aCheck = wsingHelper.container.aCheck.slice(0, i);
if(newol.childElementCount > 0){
var liMore = coin('li','helper_more','','','尝试远程载入更多歌曲');
liMore.onclick = function(){
fetchMore(this);
};
newol.appendChild(liMore);
}
if(wsingHelper.container.olSong) wsingHelper.container.olSong.parentNode.replaceChild(newol, wsingHelper.container.olSong);
if(wsingHelper.container.olCheck) wsingHelper.container.olCheck.parentNode.replaceChild(olCheck, wsingHelper.container.olCheck);
wsingHelper.container.olSong = newol;
wsingHelper.container.olCheck = olCheck;
try{
wsingHelper.aIndex[wsingHelper.player.playing].song.src == wsingHelper.player.audio.src?
(newol.children[wsingHelper.player.playing].className+= ' helper_player_playing') : (wsingHelper.player.playing= -1);
}catch(e){}
return {ol1: olCheck, ol2: newol};
}
function searchSong() {
notify('载入中……');
wsingHelper.aIndex = [];
wsingHelper.mSongs = {};
ended = false;
var t;
if(window.location.href.indexOf('://5sing.kugou.com/my/')!== -1){
//in personal center
wsingHelper.nList = 0;
fetchInCenter({});
}
else if(window.location.href.indexOf('://5sing.kugou.com/fm/m')!== -1){
//in independent playing page, using JSONP to load songs information remotely
var a1 = [], aIndex=[], sIndex, sTip;
a1 = document.$('.playlist').$$('a.btn-view')
for(var i = 0; i< a1.length; i++){
sTip = a1[i].href.match(/(fc|yc|bz)\/\d+/)[0].replace('/','$');
if(sTip != sIndex){
sIndex = sTip
aIndex.push(sIndex);
wsingHelper.aIndex.push(new SongIndex(sIndex));
}
}
jsonp('http://service.5sing.kugou.com/song/find?songinfo=' + aIndex.join('$'), function(res){
wsingHelper.aJSON = res;
for (var i = 0, Song; i < wsingHelper.aJSON.length; i++) {
Song = wsingHelper.aJSON[i];
var song = {
id: Song.id,
src: Song.sign,
type: Song.songtype,
space: 'http://5sing.kugou.com/' + Song.userid,
singer: Song.nickname,
avatar: Song.avatar,
songName: Song.songname,
description: ''
};
var sIndex = song.type + '$' + song.id;
wsingHelper.mSongs[sIndex] = song;
}
wsingHelper.container.olSong && createList(wsingHelper.container.olSong);
notify('载入完成', 3000);
});
}
else if(/:\/\/5sing\.kugou\.com\/\w+\/[a-z]+(?:\/\d+)\.html/.test(window.location.href)){
//in singer space, using JSONP to load songs information remotely
var a1= [], aIndex= [], sHref;
a1 = document.$('.song_list, .per_list').$$('a[href^="http"][href$="html"]');
for(var i = 0; i< a1.length; i++){
if(a1[i].href!= sHref){
sHref = a1[i].href;
var sIndex = sHref.match(/(fc|yc|bz)\/\d+/)[0].replace('/','$');
aIndex.push(sIndex);
wsingHelper.aIndex.push(new SongIndex(sIndex));
}
}
jsonp('http://service.5sing.kugou.com/song/find?songinfo=' + aIndex.join('$'), function(res){
wsingHelper.aJSON = res;
for (var i = 0, Song; i < wsingHelper.aJSON.length; i++) {
Song = wsingHelper.aJSON[i];
var song = {
id: Song.id,
src: Song.sign,
type: Song.songtype,
space: 'http://5sing.kugou.com/' + Song.userid,
singer: Song.nickname,
avatar: Song.avatar,
songName: Song.songname,
description: ''
};
var sIndex = song.type + '$' + song.id;
wsingHelper.mSongs[sIndex] = song;
}
wsingHelper.container.olSong && createList(wsingHelper.container.olSong);
notify('载入完成', 3000);
});
}
else if(/:\/\/5sing\.kugou\.com\/(?:yc|fc|bz)\/\d+\.html/.test(window.location.href)){
//in song page
var Song = JSON.parse(atob(window.globals.ticket || window.pageOptions.ticket));
var song = {
id: Song.songID,
src: Song.file,
type: Song.songType,
space: 'http://5sing.kugou.com/' + Song.singerID,
singer: Song.singer || document.$('.user').$('a').title,
avatar: Song.avatar || document.$('.user').$('img').src,
songName: Song.songName,
description: (t = document.$('.lrc_info_clip'))? t.children[0].innerHTML: (t = document.$('.pl_lianxu'))? t.innerHTML: '未找到描述'
};
getSongSrc(song)
song.description = song.description.replace(//g, '');
var sIndex = song.type + '$' + song.id;
wsingHelper.mSongs[sIndex] = song;
wsingHelper.aIndex.push(new SongIndex(sIndex));
notify('载入完成', 3000);
}
else if(/:\/\/5sing\.kugou\.com\/\w+(\/default\.html|\/)?(#|$)/.test(window.location.href)){
//in the main page of singer space, using 5sing api to search song in order of time
var t = prompt('请用一位数字输入要远程载入的歌曲种类, 1 为原创, 2 为翻唱, 3 为伴奏');
try{
t = parseInt(t.match(/^\s*[123]\s*/));
fetchMore({}, 999999999, t);
}catch(e){
console.log(e);
notify('载入被取消');
}
}
else if(/:\/\/5sing\.kugou\.com\/m\/detail\/(?:yc|fc|bz)-\d+.*\.html/.test(window.location.href) ||
/:\/\/5sing\.kugou\.com\/m\/Song\/detail\/(?:yc|fc|bz)\/\d+(\.html)?/i.test(window.location.href)){
//in mobile page
var song = {
id: window.pageConfig.songId,
src: undefined,
type: window.pageConfig.songType,
space: 'http://5sing.kugou.com/' + window.pageConfig.singerId,
singer: document.$('p.singer').textContent,
avatar: document.$('.cd-box img').src,
songName: document.$('p.song').textContent,
description: ''
};
getSongSrc(song)
var sIndex = song.type + '$' + song.id;
wsingHelper.mSongs[sIndex] = song;
wsingHelper.aIndex.push(new SongIndex(sIndex));
notify('载入完成', 3000);
}
else{
console.log('未支持本页面');
notify('未支持本页面', 3000);
}
}
function fetchInSpaceP(node, songId, songKind){
//use jsonp via promise, not in use
locked = true;
node.innerHTML = '载入中……';
notify('载入中……');
var LastSong = (wsingHelper.aIndex[wsingHelper.aIndex.length-1] || {}).song || {},
id = songId || LastSong.id,
type = songKind || (LastSong.type == 'yc'? 1 : LastSong.type == 'fc'? 2: 3);
if (!id) return;
sHeadIndex = type + '$' + id; // function as jsonp lock
jsonpp('http://service.5sing.kugou.com/song/songListBySongId?songId=' + id +'&songKind='+ type + '&userId=' + window.OwnerUserID + '&isPrev=1&isNext=0')
.then(function(res){
var sIndex = type + '$' + id;
if (sIndex != sHeadIndex)
// prevent duplicate jsonp execution
return;
else
// right jsonp, continue execution and reset the jsonp lock to prevent other jsonp from execution
sHeadIndex = '';
var aJSON2 = wsingHelper.aJSON2 = res;
if(aJSON2.length === 0){
locked = false;
ended = true;
return Promise.reject(1);
}
else {
var aIndex= [], sIndex;
for(var i = 0; i< aJSON2.length; i++){
var sIndex = aJSON2[i].songType + '$' + aJSON2[i].id;
aIndex.push(sIndex);
wsingHelper.aIndex.push(new SongIndex(sIndex));
}
return jsonpp('http://service.5sing.kugou.com/song/find?songinfo=' + aIndex.join('$'));
}
})
.then(function(res){
wsingHelper.aJSON = res;
for (var i = 0, Song; i < wsingHelper.aJSON.length; i++) {
Song = wsingHelper.aJSON[i];
var song = {
id: Song.id,
src: Song.sign,
type: Song.songtype,
space: 'http://5sing.kugou.com/' + Song.userid,
singer: Song.nickname,
avatar: Song.avatar,
songName: Song.songname,
description: ''
};
var sIndex = song.type + '$' + song.id;
wsingHelper.mSong[sIndex] = song;
}
createList(wsingHelper.container.olSong);
locked = false;
notify('载入完成', 3000);
})
.catch(function(err){
node.innerHTML= (err== 1? '已到达结尾': '载入失败,点击重试' + err);
notify(node.innerHTML, 3000);
});
setTimeout(function(){
if(locked) node.innerHTML= '载入中……点击重试';
locked = false;
},3000);
}
function fetchInSpace(node, songId, songKind){
locked = true;
node.innerHTML= '载入中……';
notify('载入中……');
var LastSong = (wsingHelper.aIndex[wsingHelper.aIndex.length-1] || {}).song || {},
id = songId || LastSong.id,
type = songKind || (LastSong.type== 'yc'? 1 : LastSong.type == 'fc'? 2: 3);
if (!id) return;
sHeadIndex = type + '$' + id; // function as jsonp lock
//use jsonp via normal callback approach
jsonp('http://service.5sing.kugou.com/song/songListBySongId?songId=' + id +'&songKind='+ type + '&userId=' + window.OwnerUserID + '&isPrev=1&isNext=0', function(res){
var sIndex = type + '$' + id;
if (sIndex != sHeadIndex)
// prevent duplicate jsonp execution
return;
else
// right jsonp, continue execution and reset the jsonp lock to prevent other jsonp from execution
sHeadIndex = '';
var aJSON2 = wsingHelper.aJSON2 = res;
if(aJSON2.length === 0){
locked = false;
notify('已到达结尾', 3000);
node.innerHTML= '已到达结尾';
ended = true;
}
else{
var aIndex= [];
for(var i = 0; i< aJSON2.length; i++){
var sIndex = aJSON2[i].songType + '$' + aJSON2[i].id;
aIndex.push(sIndex);
wsingHelper.aIndex.push(new SongIndex(sIndex));
}
jsonp('http://service.5sing.kugou.com/song/find?songinfo=' + aIndex.join('$'),function(res){
wsingHelper.aJSON = res;
if(res.length === 0){
locked = false;
notify('出现错误,歌曲不存在', 3000);
node.innerHTML= '出现错误,歌曲不存在';
}
else{
for (var i = 0, Song; i < wsingHelper.aJSON.length; i++) {
Song = wsingHelper.aJSON[i];
var song = {
id: Song.id,
src: Song.sign,
type: Song.songtype,
space: 'http://5sing.kugou.com/' + Song.userid,
singer: Song.nickname,
avatar: Song.avatar,
songName: Song.songname,
description: ''
};
var sIndex = song.type + '$' + song.id;
wsingHelper.mSongs[sIndex] = song;
}
createList(wsingHelper.container.olSong);
locked = false;
notify('载入完成', 3000);
}
});
}
});
setTimeout(function(){
if(locked) node.innerHTML= '载入中……点击重试';
locked = false;
},3000);
}
function fetchInCenter(node){
locked = true;
node.innerHTML= '载入中……';
notify('载入中……');
var nList = wsingHelper.nList + 1,
url= '/my/handler/message?ts=' + (new Date()).getTime(),
xhr = new XMLHttpRequest();
xhr.onload = function(e){
if (nList != wsingHelper.nList + 1){
return;
}
var aData = JSON.parse(xhr.response).Data, i, n;
if(aData.length === 0){
node.innerHTML= '已到达结尾';
notify('已到达结尾', 3000);
ended = true;
locked = false;
}
else{
// search in existed songs list to prevent repeat
//for(i = 0; i< aData.length; i++){
// if(aData[i].Category == 1){
// for(n = 0; n< wsingHelper.aIndex.length; n++){
// if(aData[i].BelongId === wsingHelper.aIndex[n].id) break;
// }
// break;
// }
//}
for(var Song, i=0; i < aData.length; i++) {
if(aData[i].Category == 1){
Song = JSON.parse(aData[i].Content);
var song = {
id: aData[i].BelongId,
src: Song.FileName,
type: Song.SongType == 1? 'yc': Song.SongType == 2? 'fc': Song.SongType == 3? 'bz':'',
space: 'http://5sing.kugou.com/' + aData[i].SrcUser.NewUserID,
singer: aData[i].SrcUser.NickName,
avatar: aData[i].SrcUser.Img,
songName: Song.SongName,
description: Song.Content? Song.Content.replace(/\[(img)\].*?\[\/(\1)\]/,''): ''
};
if (!!song.type){
var sIndex = song.type + '$' + song.id;
wsingHelper.aIndex.push(new SongIndex(sIndex));
wsingHelper.mSongs[sIndex] = song;
}
}
}
wsingHelper.container.olSong && wsingHelper.createList(wsingHelper.container.olSong);
console.log('completed',nList, wsingHelper.nList);
wsingHelper.nList = nList;
notify('载入完成', 3000);
locked = false;
}
};
xhr.onerror = function(){
node.innerHTML= '载入失败,点击重试';
notify('载入失败', 3000);
locked = false;
};
xhr.ontimeout = function(){
node.innerHTML= '载入超时,点击重试';
notify('载入超时', 3000);
locked = false;
};
xhr.open('get', url + '&page=' + nList + '&group=-1');
xhr.timeout = 15000;
xhr.send();
}
function fetchMore(node, songId, songKind){
if (locked) return;
//in personal center
if(window.location.href.indexOf('://5sing.kugou.com/my/')!== -1){
fetchInCenter(node);
}
//in singer space
else if(/:\/\/5sing\.kugou\.com\/\w+\/[a-z]+\/(\d+)\.html/.test(window.location.href)){
fetchInSpace(node, songId, songKind);
//fetchInSpaceP(node, songId, songKind);
}
//try searching all songs of the singer in the main page of singer space
else if(/:\/\/5sing\.kugou\.com\/\w+(\/default\.html|\/)?(#|$)/.test(window.location.href)){
fetchInSpace(node, songId, songKind);
//fetchInSpaceP(node, songId, songKind);
}
else{
node.innerHTML= '当前页面没有可以继续载入的歌曲';
ended = true;
}
}
function fetchToEnd(){
var nInterval;
var node = window.document.$('.helper_more');
function doFetch(){
fetchMore(node);
if (ended) window.clearInterval(nInterval);
}
nInterval = window.setInterval(doFetch, 3000);
notify('将尝试载入全部歌曲信息...')
}
function buildMy(){
var divMain = wsingHelper.container = coin('div', 'helper_container', 'helper_container');
var divBanner = coin('div','helper_banner');
var button1 = coin('button','helper_left','','','上一首'),
button2 = coin('button','helper_right','','','下一首'),
button3 = coin('button','helper_right','','','重载列表'),
button4 = coin('button','helper_left','','','循环播放'),
button5 = coin('button','helper_left','','','列表播放'),
button6 = coin('button','helper_right','helper_set','','功能设置'),
divInfo = coin('div','helper_info helper_clear'),
divSet = coin('div','helper_setting','helper_setting');
divSet.style.display= 'none';
divSet.isInit = false;
button1.onclick = function(e){
wsingHelper.loadSong(wsingHelper.player.playing - 1);
};
button2.onclick = function(e){
wsingHelper.loadSong(wsingHelper.player.playing + 1);
};
button3.onclick = function(e){
wsingHelper.searchSong();
wsingHelper.createList(wsingHelper.container.olSong);
};
button4.onclick = function(e){
wsingHelper.player.repeat= !wsingHelper.player.repeat;
localStorage.helper_play= (wsingHelper.player.repeat?'1':'0') + (wsingHelper.player.sequence? '1' : '0');
this.className= (wsingHelper.player.repeat? this.className + ' helper_selected' : this.className.replace(/ ?helper_selected/g,''));
};
button4.className= (wsingHelper.player.repeat? button4.className + ' helper_selected' : button4.className.replace(/ ?helper_selected/g,''));
button5.onclick = function(e){
wsingHelper.player.sequence= !wsingHelper.player.sequence;
localStorage.helper_play= (wsingHelper.player.repeat? '1' : '0') + (wsingHelper.player.sequence? '1' : '0');
this.className= (wsingHelper.player.sequence? this.className + ' helper_selected' : this.className.replace(/ ?helper_selected/g,''));
};
button5.className= (wsingHelper.player.sequence? button5.className + ' helper_selected' : button5.className.replace(/ ?helper_selected/g,''));
button6.onclick = function(e){
if(divSet.isInit === false){
createOption(divSet);
resetOption(divSet);
divSet.isInit = true;
}
if(divSet.style.display == 'none'){
resetOption(divSet);
divSet.style.display= 'block';
this.className+= ' helper_selected';
}
else{
divSet.style.display= 'none';
this.className = this.className.replace(/ ?helper_selected/g,'');
}
};
var divBottom = coin('div','helper_bottom helper_clear');
var button7 = coin('button','helper_left','','','全选');
var button8 = coin('button','helper_left','','','撤销');
var button9 = coin('button','helper_right helper_send','helper_send','','在独立播放页中播放');
var button10 = coin('button','helper_right','','','查看下载地址');
button7.onclick = function(e){
for( var i = 0; i< wsingHelper.container.aCheck.length; i++){
wsingHelper.container.aCheck[i].checked = true;
}
};
button8.onclick = function(e){
for( var i = 0; i< wsingHelper.container.aCheck.length; i++){
wsingHelper.container.aCheck[i].checked = false;
}
};
button9.onclick = function(e){
var sSongs= '{"data":"',aTemp= [];
for( var i = 0; i< wsingHelper.container.aCheck.length; i++){
if( wsingHelper.container.aCheck[i].checked === true){
aTemp.push( wsingHelper.aIndex[i].song.type + '$' + wsingHelper.aIndex[i].song.id);
}
}
sSongs+= aTemp.join('$') + '","type":0,"playNow":false}';
wsingHelper.setSongCookies(sSongs);
try{
var time = parseInt(window.globals.cookies.get("fmPageTime"));
if(isNaN(time)){
window.open("/fm/m/");
}
}catch(e){
console.log(e)
window.open("/fm/m/");
}
};
button10.onclick = function(e){
var div1 = wsingHelper.container.$('.helper_prompt');
if(!div1){
var aSongs= [];
for( var i = 0; i< wsingHelper.container.aCheck.length; i++){
if( wsingHelper.container.aCheck[i].checked === true){
aSongs.push(wsingHelper.aIndex[i].song);
}
}
div1 = coin('div','helper_prompt','helper_temp');
var ol1 = coin('ol'),
ol2 = coin('ol');
for( var i = 0; i< aSongs.length; i++){
var li1 = coin('li','','','',aSongs[i].songName),
li2 = coin('li','','','',''+ aSongs[i].src +'');
ol1.appendChild(li1);
ol2.appendChild(li2);
}
ol1.appendChild(coin('li','helper_holder','','',' '));
ol2.appendChild(coin('li','helper_holder','','',' '));
div1.appendChild(ol1);
div1.appendChild(ol2);
wsingHelper.container.children[2].appendChild(div1);
}
else
div1.parentNode.removeChild(div1);
};
var notifier = wsingHelper.container.notifier = coin('div', 'helper_notifier', 'helper_notifier', '', '提示');
try{
wsingHelper.searchSong();
}catch(e){console.log(e);}
var divList = coin('div','helper_list'),
divPlayer = coin('div','helper_player helper_clear');
var Ol = createList();
var audio = coin('audio','helper_audio','helper_audio');
wsingHelper.player.audio = audio;
audio.autoplay = false;
audio.controls = true;
wsingHelper.player.audio.volume = wsingHelper.player.volume;
audio.addEventListener('ended',function(e){
if( wsingHelper.player.sequence){
loadSong(wsingHelper.player.playing + 1);
}
else if(wsingHelper.player.repeat){
wsingHelper.player.audio.play();
}
});
audio.addEventListener('volumechange',function(e){
localStorage.helper_volume = wsingHelper.player.audio.volume.toFixed(2) + '';
});
audio.addEventListener('error', function(e){
if(wsingHelper.player.audio.src.slice(-4) != '.wma'){
wsingHelper.fix(wsingHelper.aIndex[wsingHelper.player.playing].song);
}
});
var t = localStorage.helper_pos;
if(/^[1234]$/.test(t))
adjust(t,divMain,60,50);
window.addEventListener('keydown',keyHandle2);
divPlayer.appendChild(audio);
divBanner.appendChild(button1);
divBanner.appendChild(button2);
divBanner.appendChild(button3);
divBanner.appendChild(button4);
divBanner.appendChild(button5);
divBanner.appendChild(button6);
divBanner.appendChild(divInfo);
divBottom.appendChild(button7);
divBottom.appendChild(button8);
divBottom.appendChild(button9);
divBottom.appendChild(button10);
divList.appendChild(Ol.ol1);
divList.appendChild(Ol.ol2);
divMain.appendChild(divSet);
divMain.appendChild(divBanner);
divMain.appendChild(divList);
divMain.appendChild(divBottom);
divMain.appendChild(divPlayer);
divMain.appendChild(notifier);
document.body.appendChild(divMain);
}
function setUpUI() {
try{
document.head.removeChild(document.$('#helper_style'));
document.body.removeChild(document.$('#helper_container'));
document.body.removeChild(document.$('#helper_toggle'));
}
catch(e){}
var style = coin('style',false,'helper_style');
style.innerHTML = [
'.helper_toggle {position: fixed; top: 100px; left: 10px; background: rgba(98, 183, 102, 0.5); width: 28px; height: 28px; border-radius: 14px;z-index: 99999}',
'.helper_toggle *{top: 0px; right: 0px; bottom: 0px; left: 0px; margin: 4px; border-radius: 10px; position: absolute; background: white}',
'.helper_toggle.helper_activate {background: rgba(98, 183, 102, 1); box-shadow: 0px 0px 3px #aaa;}',
'.helper_container {position: fixed; z-index: 99999; top: 60px; left: 50px; background: white; border: 1px solid; overflow: visible; font: 12px/1.5 "Microsoft Yahei",Tahoma,Helvetica,Arial,sans-serif; color: black; text-align: left;}',
'.helper_container * {color: black !important; overflow: visible; visibility: unset}',
'.helper_container body, form, p, ol, ul, p, h1, h2, h3, h4, li, dt, dd, dl, li {padding: 0px; margin: 0px}',
'.helper_container button {background: white; border-radius: 3px; border: #6C0 solid 1px; margin: 2px; cursor: pointer; box-shadow: 1px 1px 0px #aaa;}',
'.helper_container button.helper_selected {background-color: #6c0;}',
'.helper_container ol,ul {white-space: nowrap; list-style: none;}',
'.helper_container img {box-shadow: 0px 0px 2px #888; max-width: 200px; max-height: 200px}',
'.helper_container .helper_banner {overflow: hidden; background: white; position: relative; z-index: 1}',
'.helper_container .helper_banner .helper_info {padding: 0px 5px; width: 440px; min-width: 420px; height: 100px; overflow: auto; resize: both; border-bottom: solid 1px;}',
'.helper_container .helper_banner .helper_info .helper_description {white-space: pre-line; padding: 3px}',
'.helper_container .helper_banner .helper_info a {border: none; margin: 4px; font-weight: normal; font-size: medium;}',
'.helper_container .helper_banner .helper_info a img {width: 60px; height: 60px}',
'.helper_container .helper_setting {position: absolute; z-index: 10; top: 25px; left: 0px; right: 0px; bottom: 35px; background: white; border: none; overflow: auto; text-align: initial;}',
'.helper_container .helper_setting * {margin: 3px;}',
'.helper_container .helper_setting div {padding: 2px; overflow: auto}',
'.helper_container .helper_setting #helper_opt ul {padding-right: 50px}',
'.helper_container .helper_setting #helper_opt ul li {max-width: 40%; height: 28px}',
'.helper_container .helper_setting #helper_opt input {width: 60px; height: 20px}',
'.helper_container .helper_setting .helper_about {overflow: hidden}',
'.helper_container .helper_setting .helper_about>* {visibility: hidden; margin: 0}',
'.helper_container .helper_setting .helper_about:hover>* {visibility: visible}',
'.helper_song {float: left;}',
'.helper_singer {float: right;}',
'.helper_list {height: 300px; min-width: 400px; padding: 5px; overflow: auto; resize: vertical}',
'.helper_list li {padding: 5px; height: 20px;}',
'.helper_list .helper_songlist li:nth-child(odd) {background: #EEEEEE}',
'.helper_list .helper_songlist li:nth-child(even) {background: #FFFFFF}',
'.helper_list .helper_songlist li.helper_player_playing {background: #96E977;}',
'.helper_list .helper_songlist li.helper_more {text-align: center;}',
'.helper_list .helper_songlist li>* {display: block; overflow: hidden; height: 100%;}',
'.helper_checklist {float: left; z-index: 2;}',
'.helper_checklist input {margin: 3px;}',
'.helper_player {position: relative; padding-top:8px;display: block}',
'.helper_player audio {display: block; width: 100%}',
'.helper_prompt {position: absolute; overflow: auto; top: 2px; right: 20px; bottom: 80px; left: 2px; z-index:10; background: white; max-height: 100%; border: solid 1px;}',
'.helper_prompt ol {border: 1px; overflow: auto; min-height: 100%}',
'.helper_prompt ol:nth-child(1) {float: left; width: 35%}',
'.helper_prompt ol:nth-child(2) {overflow: auto; padding-left: 10px; border-left: solid 1px}',
'.helper_notifier {font-size: medium; position: fixed; top: 0px; left: 0px; display: none; background: rgba(0, 0, 0, 0.5); color: white !important; padding: 2px 8px; white-space: pre}',
'.helper_left {float: left} .helper_right {float: right} .helper_clear {clear: both} .helper_clearL {clear: left} .helper_clearR {clear: right}'
].join('\n');
document.head.appendChild(style);
if(window.location.href.indexOf('://5sing.kugou.com/')!== -1){
var divToggle = coin('div','helper_toggle','helper_toggle');
divToggle.onclick = function(e){
e.preventDefault();
var container = document.$('.helper_container');
if(!container)
buildMy();
else{
container.style.display= (container.style.display == 'none' ?'':'none');
if(wsingHelper.player.volfix == '1'){
// a workaround to bypass the mistaken volume indicating in firefox when change the css 'display'
var t = wsingHelper.player.audio.volume;
wsingHelper.player.audio.volume = 1;
wsingHelper.player.audio.volume = t;
}
}
divToggle.className += ' helper_activate';
};
divToggle.innerHTML= '';
checkSetting();
window.addEventListener('keydown',keyHandle1);
var t = localStorage.helper_pos;
if(/^[1234]$/.test(t))
adjust(t,divToggle,100,10);
document.body.appendChild(divToggle);
}
}
function init(){
if(location.href.indexOf('://static.5sing.kugou.com/???') !== -1) {
//modify cookies in static.5sing.kugou.com by operating in a new iframe
var data = decodeURIComponent(location.href.match(/\?\?\?(.+)$/)[1])
console.log('transfered', data)
localStorage.setItem('fmPage_Add',decodeURIComponent(data));
//console.log(localStorage);
return;
}
console.log('helper start');
try{
Object.defineProperty(navigator, 'plugins', {
get: function () {return {length: 0};}
});
}catch(e){console.log(e);}
prepare();
if(localStorage.helper_autoplay !== '1'){
preventAutoplay();
}
document.addEventListener('DOMContentLoaded',setUpUI);
console.log('helper end');
}
init();
window.wsingHelper = wsingHelper;
}
try{
main();
}catch(e){console.log(e);}
// three way to run the script with debug ability.
//var script = document.createElement('script');script.innerHTML = '(' + main.toString() + ')()';document.head.appendChild(script);
//var script = document.createElement('script');script.innerHTML = 'eval(decodeURI("' + encodeURI('debugger;' + main.toString()) + 'main();"))';document.head.appendChild(script);
//var script = document.createElement('script');script.src = 'data:text/javascript;base64,' + btoa('debugger;' + main.toString() + 'main();');document.head.appendChild(script);