var audio;
var playlist;
var tracks;
var current;
var mbuttonstate=0;
var plistshown=true;
var shuffle=0,repeat=0;
var plistRect;
var dpiratio=window.devicePixelRatio?window.devicePixelRatio:1;
var audioCtxt=null;
var CtxtSource=null;
var CtxtAnalyser=null;
var canvas;
var CSpectrum=1024,CSpectrumIF=128;
var SpecWidth=0.7,SpecGap=0.08125;
var caps=[];
var visualselector=null;
var SpecRingRadius=225;
var spectrogrampos=0;
var inkimg=[];
var f1=0,f2=0,penv=0,btrig=0,beatp=0,lastbp=0;
var lpbd=300,lpf=1./(2*Math.PI*lpbd),beatr=0.02;
var frms=0,lastfpsupd=null,fps=0;
var ic1=["#FF3333","#FF8800","#FFFF00","#CCFF00","#33CCFF","#0000FF","#9966FF"];
var ic2=["rgba(204,51,51,0.6)","rgba(187,85,0,0.6)","rgba(255,204,0,0.6)","rgba(153,204,0,0.6)","rgba(51,153,255,0.6)","rgba(0,0,102,0.6)","rgba(153,51,204,0.6)"]
var Ink=function(_vx,_vy,_c)
{
this.x=canvas.width/2;this.y=canvas.height/2;
this.vx=_vx;this.vy=_vy;
this.color=_c>6?6:_c;this.active=true;
};
Ink.prototype.update=function()
{
this.x+=this.vx;this.y+=this.vy;
this.vx*=0.995;this.vy*=0.995;
if(this.x<-10||this.x>canvas.width+10||this.y<-10||this.y>canvas.height+10)
this.active=false;
}
Ink.prototype.draw=function(cctx)
{
cctx.drawImage(inkimg[this.color],this.x+5*window.devicePixelRatio,this.y+5*window.devicePixelRatio);
}
var inks=[];
function inkPrepare()
{
for(var i=0;i<7;++i)
{
inkimg[i]=document.createElement('canvas');
inkimg[i].width=inkimg[i].height=10*window.devicePixelRatio;
var cctx=inkimg[i].getContext('2d');
cctx.fillStyle=ic1[i];
cctx.beginPath();
cctx.arc(5*window.devicePixelRatio,5*window.devicePixelRatio,3*window.devicePixelRatio,0,2*Math.PI);
cctx.fill();
cctx.fillStyle=ic2[i];
cctx.beginPath();
cctx.arc(5*window.devicePixelRatio,5*window.devicePixelRatio,5*window.devicePixelRatio,0,2*Math.PI);
cctx.fill();
}
}
function createInk(_vx,_vy,_c1,_c2)
{
var f=false;
for(var i=0;i<inks.length;++i)
{
if(!inks[i].active)
{inks[i]=new Ink(_vx,_vy,_c1,_c2);f=true;break;}
}
if(!f&&inks.length<512)inks.push(new Ink(_vx,_vy,_c1,_c2));
}
function gup(name,url)
{
if(!url)url=location.href;
name=name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
var regexS="[\\?&]"+name+"=([^&#]*)";
var regex=new RegExp(regexS);
var results=regex.exec(url);
return results==null?null:results[1];
}
function getcookie(key)
{return document.cookie.replace(new RegExp("(?:(?:^|.*;\\s*)"+key+"\\s*\\=\\s*([^;]*).*$)|^.*$"),"$1");}
function initAPI()
{
window.AudioContext=window.AudioContext||window.webkitAudioContext||window.mozAudioContext||window.msAudioContext;
window.requestAnimationFrame=window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.msRequestAnimationFrame;
window.cancelAnimationFrame=window.cancelAnimationFrame||window.webkitCancelAnimationFrame||window.mozCancelAnimationFrame||window.msCancelAnimationFrame;
audioCtxt=new AudioContext;
CtxtSource=audioCtxt.createBufferSource();
CtxtAnalyser=audioCtxt.createAnalyser();
CtxtAnalyser.fftSize=2*CSpectrum;
for(var i=0;i<CSpectrum;++i)caps[i]=0;
}
function init()
{
if( navigator.userAgent.match(/Android/i)
|| navigator.userAgent.match(/webOS/i)
|| navigator.userAgent.match(/iPhone/i)
|| navigator.userAgent.match(/iPad/i)
|| navigator.userAgent.match(/iPod/i)
|| navigator.userAgent.match(/BlackBerry/i)
|| navigator.userAgent.match(/Windows Phone/i)
)
{
visualselector=document.getElementById("playlist").style.width="90%";
document.getElementById("help").style.maxWidth=window.innerWidth+"px";
if(window.innerWidth<window.innerHeight)
document.getElementById("cvs").width=screen.width*0.98,
document.getElementById("cvs").height=(screen.width*0.98/16*9);
else
document.getElementById("cvs").width=(screen.height*0.98/9*16),
document.getElementById("cvs").height=screen.height*0.98;
}
if(!window.devicePixelRatio)window.devicePixelRatio=1;
document.getElementById("cvs").style.width=document.getElementById("cvs").width+"px";
document.getElementById("cvs").style.height=document.getElementById("cvs").height+"px";
document.getElementById("cvs").width=document.getElementById("cvs").width*window.devicePixelRatio;
document.getElementById("cvs").height=document.getElementById("cvs").height*window.devicePixelRatio;
current=0;
visualselector=document.getElementById("visualizationsel");
canvas=document.getElementById("cvs");
audio=document.getElementById("audio");
playlist=$('#playlist');
tracks=playlist.find('li a');
len=tracks.length;SpecRingRadius=canvas.width/2;
audio.volume=.80;SpecWidth=canvas.width/CSpectrum;SpecGap=SpecWidth/10;SpecWidth*=0.9;
initAPI();inkPrepare();document.onmousemove=mm;
CtxtSource=audioCtxt.createMediaElementSource(audio);
CtxtSource.connect(CtxtAnalyser);
CtxtAnalyser.connect(audioCtxt.destination);
plistRect=document.getElementById("playlist").getBoundingClientRect();
for(var i=0;i<playlist.find('a').length;++i)
{
if(playlist.find('a')[i].textContent==decodeURIComponent(gup('title')))
{current=i;run($(playlist.find('a')[i]));break;}
}
playlist.find('a').click(function(e){
e.preventDefault();
link=$(this);
current=link.parent().index()-1;
run(link);
});
visualselector.onchange=function(){
if(this.value!="none"&&this.oldvalue=="none")requestAnimationFrame(updateVisualization);
else canvas.getContext('2d').clearRect(0,0,canvas.width,canvas.height);
document.cookie="playervisualization="+this.value;
this.oldvalue=this.value;
};
window.onresize=windowresize;
audio.ontimeupdate=timeUpdate;
audio.addEventListener('ended',function(e){
if(repeat==0)
{
current++;
if(current==len){
current=0;
if(shuffle)shufflePlist();
link=playlist.find('a')[0];
}else{
link=playlist.find('a')[current];
}
run($(link));
}
});
document.getElementById("shufflesw").onclick=function(){
shuffle=1-shuffle;
if(shuffle==0)
{
document.getElementById("shufflesw").innerHTML="Off";
document.cookie="playershuffle=0";
sortPlist();
}
else
{
document.getElementById("shufflesw").innerHTML="On";
document.cookie="playershuffle=1";
shufflePlist();
}
}
document.getElementById("repeatsw").onclick=function(){
repeat=1-repeat;
if(repeat==0)
{
document.getElementById("repeatsw").innerHTML="Off";
document.cookie="playerrepeat=0";
audio.loop=false;
}
else
{
document.getElementById("repeatsw").innerHTML="On";
document.cookie="playerrepeat=1";
audio.loop=true;
}
}
document.getElementById("plistsw").onclick=togglePlist;
document.body.onmousedown=function(e){if(e.buttons==1)mbuttonstate=1;}
document.body.onmouseup=function(e){if(e.buttons!=1)mbuttonstate=0;}
document.getElementById("tsliderbase").onclick=function(e)
{
var sr=this.getBoundingClientRect();
var p=(e.clientX-sr.left)/sr.width;
audio.currentTime=audio.duration*p;
}
document.getElementById("tsliderbase").onmousemove=function(e)
{
if(!mbuttonstate)return;
var sr=this.getBoundingClientRect();
var p=(e.clientX-sr.left)/sr.width;
audio.currentTime=audio.duration*p;
}
document.getElementById("pbplaypause").onclick=function()
{
if(audio.src==""){run($(playlist.find('a')[0]));return;}
if(audio.paused)
{
audio.play();
document.getElementById("imgplaypause").src="pause.svg";
}
else
{
audio.pause();
document.getElementById("imgplaypause").src="play.svg";
}
}
document.getElementById("pbprev").onclick=function()
{
if(audio.currentTime>10)audio.currentTime=0;
else
{
current--;
if(current<0){
current+=len;
if(shuffle)shufflePlist();
link=playlist.find('a')[len-1];
}else{
link=playlist.find('a')[current];
}
run($(link));
}
}
document.getElementById("pbnext").onclick=function()
{
current++;
if(current==len){
current=0;
if(shuffle)shufflePlist();
link=playlist.find('a')[0];
}else{
link=playlist.find('a')[current];
}
run($(link));
}
switch(getcookie("playershuffle"))
{
case "1":
document.getElementById("shufflesw").innerHTML="On";
document.cookie="playershuffle=1";
shufflePlist();
break;
default:
case "0":
document.getElementById("shufflesw").innerHTML="Off";
document.cookie="playershuffle=0";
sortPlist();
break;
}
switch(getcookie("playerrepeat"))
{
case "1":
document.getElementById("repeatsw").innerHTML="On";
document.cookie="playerrepeat=1";
audio.loop=true;
break;
default:
case "0":
document.getElementById("repeatsw").innerHTML="Off";
document.cookie="playerrepeat=0";
audio.loop=false;
break;
}
if(getcookie("playervisualization").length!==0)
visualselector.value=getcookie("playervisualization");
requestAnimationFrame(updateVisualization);
}
function shufflePlist()
{
for(var i=0;i<playlist.find('a').length;++i)
$(playlist.find('a')[i]).attr("sord",Math.random()*playlist.find('a').length);
var plli=$(playlist).children('li');
plli.sort(
function(a,b)
{
var as=Number($(a).children('a').attr("sord"));
var bs=Number($(b).children('a').attr("sord"));
return as>bs?1:as<bs?-1:0;
}
);
plli.detach().appendTo($(playlist));
var t=$("li.active").children().length?$("li.active").children()[0].textContent:"";
for(var i=0;i<playlist.find('a').length;++i)
{
if(playlist.find('a')[i].textContent==t)
{current=i;break;}
}
}
function sortPlist()
{
var plli=$(playlist).children('li');
plli.sort(
function(a,b)
{
var as=Number($(a).children('a').attr("ord"));
var bs=Number($(b).children('a').attr("ord"));
return as>bs?1:as<bs?-1:0;
}
);
plli.detach().appendTo($(playlist));
var t=$("li.active").children().length?$("li.active").children()[0].textContent:"";
for(var i=0;i<playlist.find('a').length;++i)
{
if(playlist.find('a')[i].textContent==t)
{current=i;break;}
}
}
function formatTime(t)
{
var m=Math.floor(t/60),s=Math.round(t-Math.floor(t/60)*60);
if(s<10)return m+":0"+s;
else if(s==60)return (m+1)+":00";
else return m+":"+s;
}
function bufferedUpdate()
{
var r=0;
for(var i=0;i<audio.buffered.length;++i)
r=r<audio.buffered.end(i)?audio.buffered.end(i):r;
document.getElementById("cbuff").style.width=r/audio.duration*100+"%";
}
function timeUpdate()
{
document.getElementById("timenow").innerHTML=formatTime(audio.currentTime);
document.getElementById("timeleft").innerHTML="-"+formatTime(audio.duration-audio.currentTime);
document.getElementById("ctime").style.width=audio.currentTime/audio.duration*100+"%";
bufferedUpdate();
}
function mm(e)
{
/*if(e.clientX<320&&e.clientY>(window.innerHeight-383))
{
changeImage('../../../koishi_hovr.png');
document.getElementById("aqt").style.opacity="0.5";
}
else
{
changeImage('../../../koishi_norm.png');
document.getElementById("aqt").style.opacity="1.0";
}*/
}
function windowresize()
{
if(plistshown)
{
document.getElementById("playlist").style.left=(window.innerWidth-plistRect.width)/2+"px";
plistRect=document.getElementById("playlist").getBoundingClientRect();
}
else
{
}
}
function run(link)
{
var trurl="";
if(window.location.href.indexOf("&title=")==-1)
trurl=window.location.href;
else
trurl=window.location.href.substr(0,window.location.href.indexOf("&title="));
trurl=trurl.concat("&title=");
trurl=trurl.concat(link.attr('tr'));
window.history.replaceState("","The Stupid Online Player",trurl);
document.getElementById("imgplaypause").src="pause.svg";
audio.src=link.attr('href');
document.getElementById("nowplaying").innerHTML="Now Playing: "+link.attr('tr');
par=link.parent();
par.addClass('active').siblings().removeClass('active');
audio.load();
audio.play();
}
function togglePlist()
{
document.getElementById("plistsw").onclick=function(){};
plistshown=!plistshown;
if(plistshown)
{
for(var i=0;i<playlist.find('a').length;++i)
$(playlist.find('a')[i]).css("transition","0.8s");
document.getElementById("plistsw").innerHTML="[↓Hide Playlist]";
setTimeout(
function(){
document.getElementById("playlist").style.left=(window.innerWidth-plistRect.width)/2+"px";
document.getElementById("playlist").style.top=document.getElementById("plistref").getBoundingClientRect().top+"px";
document.getElementById("playlist").style.background="rgba(153,187,238,0.6)";
for(var i=0;i<playlist.find('a').length;++i)
$(playlist.find('a')[i]).css("color","");
}
,40);
setTimeout(
function(){
document.getElementById("playlist").style.position="static";
document.getElementById("plistsw").onclick=togglePlist;
plistRect=document.getElementById("playlist").getBoundingClientRect();
for(var i=0;i<playlist.find('a').length;++i)
$(playlist.find('a')[i]).css("transition","none");
}
,840);
}
else
{
var d=$(document).scrollTop();
$('html,body').stop().animate({scrollTop:0},d);
setTimeout(
function(){
plistRect=document.getElementById("playlist").getBoundingClientRect();
document.getElementById("playlist").style.position="fixed";
document.getElementById("playlist").style.top=plistRect.top+"px";
document.getElementById("playlist").style.left=plistRect.left+"px";
for(var i=0;i<playlist.find('a').length;++i)
$(playlist.find('a')[i]).css("transition","0.8s");
},
d+1);
setTimeout(
function(){
document.getElementById("playlist").style.top="100%";
document.getElementById("playlist").style.background="rgba(153,187,238,0)";
document.getElementById("plistsw").onclick=togglePlist;
for(var i=0;i<playlist.find('a').length;++i)
$(playlist.find('a')[i]).css("color",$(playlist.find('a')[i]).hasClass("active")?"rgba(255,204,0,0);":"rgba(32,172,255,0)");
},
d+5);
document.getElementById("plistsw").innerHTML="[↑Show Playlist]";
}
}
function updateVisualization()
{
if(visualselector.value=="spectrum")
{
var cctx=canvas.getContext('2d');
cctx.clearRect(0,0,canvas.width,canvas.height);
try{
var freqarr=new Uint8Array(CtxtAnalyser.frequencyBinCount);
CtxtAnalyser.getByteFrequencyData(freqarr);
for(var i=0;i<CSpectrum;++i)
{
var color='hsl('+i*360.0/CSpectrum+',100%,50%)';
cctx.fillStyle=color;
cctx.fillRect(i*(SpecWidth+SpecGap),canvas.height-(canvas.height*freqarr[i]/255.),SpecWidth,canvas.height*freqarr[i]/255.);
if(caps[i]<freqarr[i])caps[i]=freqarr[i];else if(caps[i]>0)--caps[i];
color='hsl('+i*360.0/CSpectrum+',100%,25%)';
cctx.fillStyle=color;
cctx.fillRect(i*(SpecWidth+SpecGap),canvas.height-(canvas.height*caps[i]/255.)-1,SpecWidth,1);
}
}catch(e){
if(caps[i]>0)--caps[i];
color='hsl('+i*360.0/CSpectrum+',100%,25%)';
cctx.fillStyle=color;
cctx.fillRect(i*(SpecWidth+SpecGap),canvas.height-caps[i]-1,SpecWidth,1);
};
}
if(visualselector.value=="spectrumring")
{
var cctx=canvas.getContext('2d');
cctx.clearRect(0,0,canvas.width,canvas.height);
try{
var freqarr=new Uint8Array(CtxtAnalyser.frequencyBinCount);
CtxtAnalyser.getByteFrequencyData(freqarr);
for(var i=0;i<CSpectrum;++i)
{
var color='hsl('+i*360.0/CSpectrum+',100%,50%)';
cctx.strokeStyle=color;
cctx.beginPath();cctx.moveTo(canvas.width/2.,canvas.height/2.);
cctx.lineTo(canvas.width/2.-Math.cos(2*Math.PI*(i/CSpectrum))*SpecRingRadius*freqarr[i]/255.,
canvas.height/2.-Math.sin(2*Math.PI*(i/CSpectrum))*SpecRingRadius*freqarr[i]/255.);
cctx.stroke();
if(caps[i]<freqarr[i])caps[i]=freqarr[i];else if(caps[i]>0)--caps[i];
color='hsl('+i*360.0/CSpectrum+',100%,25%)';
cctx.strokeStyle=color;
cctx.beginPath();
cctx.moveTo(canvas.width/2.-Math.cos(2*Math.PI*(i/CSpectrum))*SpecRingRadius*(caps[i]+1)/255.,
canvas.height/2.-Math.sin(2*Math.PI*(i/CSpectrum))*SpecRingRadius*(caps[i]+1)/255.);
cctx.lineTo(canvas.width/2.-Math.cos(2*Math.PI*(i/CSpectrum))*SpecRingRadius*caps[i]/255.,
canvas.height/2.-Math.sin(2*Math.PI*(i/CSpectrum))*SpecRingRadius*caps[i]/255.);
cctx.stroke();
}
}catch(e){
if(caps[i]>0)--caps[i];
color='hsl('+i*360.0/CSpectrum+',100%,25%)';
cctx.strokeStyle=color;
cctx.moveTo(canvas.width/2.-Math.cos(2*Math.PI*(i/CSpectrum))*SpecRingRadius*(caps[i]+1)/255.,
canvas.height/2.-Math.sin(2*Math.PI*(i/CSpectrum))*SpecRingRadius*(caps[i]+1)/255.);
cctx.lineTo(canvas.width/2.-Math.cos(2*Math.PI*(i/CSpectrum))*SpecRingRadius*caps[i]/255.,
canvas.height/2.-Math.sin(2*Math.PI*(i/CSpectrum))*SpecRingRadius*caps[i]/255.);
cctx.stroke();
};
}
if(visualselector.value=="scope")
{
var cctx=canvas.getContext('2d');
cctx.clearRect(0,0,canvas.width,canvas.height);
try{
var tdomainarr=new Uint8Array(CtxtAnalyser.frequencyBinCount);
CtxtAnalyser.getByteTimeDomainData(tdomainarr);
cctx.lineWidth=dpiratio;
cctx.strokeStyle="#000";
cctx.beginPath();
var x=0;
for(var i=0;i<CSpectrum;++i)
{
if(i==0)cctx.moveTo(x,tdomainarr[i]/128.*canvas.height/2);
else cctx.lineTo(x,tdomainarr[i]/128.*canvas.height/2);
x+=canvas.width*1./CSpectrum;
}
cctx.stroke();
}catch(e){
console.log(e.message);
};
}
if(visualselector.value=="spectrogram")
{
var cctx=canvas.getContext('2d');
try{
var freqarr=new Uint8Array(CtxtAnalyser.frequencyBinCount);
CtxtAnalyser.getByteFrequencyData(freqarr);
cctx.clearRect(spectrogrampos/1800*canvas.width,0,canvas.width/1800,canvas.height);
for(var i=0;i<CSpectrum;++i)
{
var color='rgba(0,0,0,'+freqarr[i]/256.+')';
cctx.fillStyle=color;
cctx.fillRect(spectrogrampos/1800*canvas.width,(CSpectrum-i)/CSpectrum*canvas.height,canvas.width/1800.,canvas.height/CSpectrum);
}
++spectrogrampos;if(spectrogrampos>=1800)spectrogrampos=0;
}catch(e){
};
}
if(visualselector.value=="inkfountain")
{
var cctx=canvas.getContext('2d'),ts=Date.now(),tu;
cctx.clearRect(0,0,canvas.width,canvas.height);
++frms;if(Date.now()-lastfpsupd>500){if(lastfpsupd)fps=1000*frms/(Date.now()-lastfpsupd),frms=0;lastfpsupd=Date.now();}
try{
var freqarr=new Uint8Array(CtxtAnalyser.frequencyBinCount);
CtxtAnalyser.getByteFrequencyData(freqarr);
for(var i=0;i<CSpectrumIF;++i)
{
var r=0;
for(var j=0;j<8;++j)r+=freqarr[i*8+j];
r/=8.;
if(r-caps[i]>7)
{
var color=Math.floor(i*8.0/CSpectrumIF),rad=Math.random()*Math.PI*2;
var ndrops=(128-i)/128.*3+1;ndrops*=(r/128.);ndrops=Math.floor(ndrops);if(ndrops<1)ndrops=1;
for(var k=0;k<ndrops;++k)
{
createInk(((r-caps[i]-7)/32*24+12)*Math.cos(rad),((r-caps[i]-7)/32*24+12)*Math.sin(rad),color);
rad=Math.random()*Math.PI*2;
}
}
if(r>caps[i])caps[i]=r;else caps[i]-=2;
}
}catch(e){
console.log(e.message);
};
tu=Date.now();
var aa=0;
for(var i=0;i<inks.length;++i){
if(inks[i].active){inks[i].update();inks[i].draw(cctx);++aa}
}
cctx.fillStyle="#000";
cctx.font="1em Courier, monospace";
cctx.fillText("Active droplets "+aa+", "+fps.toFixed(2)+" FPS",0,10);
cctx.fillText("Update time "+(tu-ts)+"ms, render time "+(Date.now()-tu)+"ms",0,24);
}
if(visualselector.value=="shakeurbody")
{
var cctx=canvas.getContext('2d');
cctx.clearRect(0,0,canvas.width,canvas.height);
try{
var tdomainarr=new Float32Array(CtxtAnalyser.frequencyBinCount);
CtxtAnalyser.getFloatTimeDomainData(tdomainarr);
for(var i=0;i<CSpectrum;++i)
{
var kbf=1/(audioCtxt.sampleRate*lpf),br=Math.exp(-1/(audioCtxt.sampleRate*beatr));
f1+=(kbf*(tdomainarr[i]-f1));
f2+=(kbf*(f1-f2));
var env=Math.abs(f2);
if(env>penv)penv=env;else{penv*=br;penv+=(1-br)*env;}
if(!btrig){if(penv>0.20)btrig=1;}else{if(penv<0.125)btrig=0;}
beatp=0;if(btrig&&!lastbp)beatp=1;lastbp=beatp;
if(beatp)document.body.style.transform='translateY(100px)';else document.body.style.transform='translateY(0px)';
}
}catch(e){
document.body.style.transform='translateY(0px)';
};
}else document.body.style.transform='none';
if(visualselector.value!="none")
af=requestAnimationFrame(updateVisualization);
}