290 lines
9.5 KiB
HTML
290 lines
9.5 KiB
HTML
|
<style>
|
||
|
|
||
|
#seekbar {
|
||
|
width: 60%;
|
||
|
}
|
||
|
@media (max-width: 1153px) {
|
||
|
#seekbar {
|
||
|
width: 50%;
|
||
|
}
|
||
|
}
|
||
|
@media (max-width: 899px) {
|
||
|
#seekbar {
|
||
|
width: 40%;
|
||
|
}
|
||
|
}
|
||
|
@media (max-width: 737px) {
|
||
|
#seekbar {
|
||
|
width: 30%;
|
||
|
}
|
||
|
}
|
||
|
@media (max-width: 624px) {
|
||
|
#seekbar {
|
||
|
width: 20%;
|
||
|
}
|
||
|
}
|
||
|
@media (max-width: 542px)
|
||
|
{
|
||
|
#seekbar {
|
||
|
width: 10%;
|
||
|
}
|
||
|
}
|
||
|
@media (max-width: 479px)
|
||
|
{
|
||
|
#prev {
|
||
|
display: none;
|
||
|
}
|
||
|
}
|
||
|
#volume
|
||
|
{
|
||
|
width: 5%;
|
||
|
}
|
||
|
#myfooter
|
||
|
{
|
||
|
|
||
|
position: absolute;
|
||
|
display: block;
|
||
|
bottom: 0px;
|
||
|
width: 100%;
|
||
|
padding: 4px;
|
||
|
}
|
||
|
</style>
|
||
|
<div class="row">
|
||
|
<div class="col">
|
||
|
<ul class="list-group" id="tracks">
|
||
|
<!--<li class="list-group-item"><a href="#">Substance</a></li>-->
|
||
|
</ul>
|
||
|
</div>
|
||
|
<div class="col">
|
||
|
|
||
|
<div class="container text-center player-box">
|
||
|
<h1 id="artist"></h1>
|
||
|
<h3 id="album"></h3>
|
||
|
|
||
|
<img height="250" width="250" src="" id="art" alt="">
|
||
|
<h4 id="track"></h4>
|
||
|
<audio id="player"></audio>
|
||
|
</div>
|
||
|
|
||
|
</div>
|
||
|
</div>
|
||
|
<footer id="myfooter" class="bg-dark">
|
||
|
<button onclick="prev_track()" id="prev" class="btn btn-primary"><img src="{{rooturl}}skip-prev.svg" alt="Prev"></button>
|
||
|
<button id="play" onclick="playpause()" class="btn btn-primary"><img id="play_img" src="{{rooturl}}play.svg" alt="Play"></button>
|
||
|
<button onclick="next_track()" id="next" class="btn btn-primary"><img src="{{rooturl}}skip-next.svg" alt="Next"></button>
|
||
|
<span id="curlbl" class="text-light">0:00</span>
|
||
|
<input type="range" onmousedown="seekdown()" onmouseup="seekup()" onmousemove="seekmove()" onclick="seekclick()" ontouchstart="seekdown()" ontouchmove="seekmove()" ontouchend="seekup()" min="0" max="1000" value="0" class="form-range" id="seekbar">
|
||
|
<span id="totallbl" class="text-light">0:00</span>
|
||
|
<input type="range" class="form-range" id="volume" onchange="volume()">
|
||
|
<a class="btn btn-primary" id="download"><img src="{{rooturl}}download.svg" alt="Download"></a>
|
||
|
<button class="btn btn-primary" onclick="repeat_button()"><img id="repeat_icon" src="{{rooturl}}repeat_off.svg" alt="Repeat Off"></button>
|
||
|
<button class="btn btn-primary" onclick="shuffle_button()"><img id="shuffle_icon" src="{{rooturl}}shuffle_off.svg" alt="Shuffle Off"></button>
|
||
|
</footer>
|
||
|
<script>
|
||
|
const list = {{list}};
|
||
|
const track = document.getElementById('track');
|
||
|
const artist = document.getElementById('artist');
|
||
|
const album = document.getElementById('album');
|
||
|
const art = document.getElementById('art');
|
||
|
const player = document.getElementById('player');
|
||
|
const play_img = document.getElementById('play_img');
|
||
|
const curlbl = document.getElementById('curlbl');
|
||
|
const seekbar = document.getElementById('seekbar');
|
||
|
const totallbl = document.getElementById('totallbl');
|
||
|
const repeat_icon = document.getElementById('repeat_icon');
|
||
|
const shuffle_icon = document.getElementById('shuffle_icon');
|
||
|
const tracks = document.getElementById('tracks');
|
||
|
const download = document.getElementById('download');
|
||
|
const prev = document.getElementById('prev');
|
||
|
const _volume = document.getElementById('volume');
|
||
|
var track_index = 0;
|
||
|
_volume.value = player.volume * 100;
|
||
|
function volume()
|
||
|
{
|
||
|
player.volume = _volume.value / 100;
|
||
|
}
|
||
|
function set_track(i)
|
||
|
{
|
||
|
|
||
|
track_index = i;
|
||
|
console.log(track_index);
|
||
|
if(track_index < list.length)
|
||
|
{
|
||
|
player.src = list[track_index].url;
|
||
|
art.src = list[track_index].art;
|
||
|
track.innerText = list[track_index].name;
|
||
|
artist.innerText = list[track_index].artist;
|
||
|
album.innerText = list[track_index].album;
|
||
|
download.href = list[track_index].download;
|
||
|
}
|
||
|
player.play();
|
||
|
}
|
||
|
|
||
|
for(i=0;i<list.length;i++)
|
||
|
{
|
||
|
var li=document.createElement('li');
|
||
|
li.classList.add('list-group-item');
|
||
|
var link = document.createElement('button');
|
||
|
|
||
|
var j= (o)=>{
|
||
|
set_track(o.i);
|
||
|
};
|
||
|
|
||
|
link.onclick = j.bind(this,{i});
|
||
|
link.innerText = list[i].name;
|
||
|
link.classList.add('btn');
|
||
|
link.classList.add('btn-link');
|
||
|
li.appendChild(link);
|
||
|
tracks.appendChild(li);
|
||
|
}
|
||
|
|
||
|
|
||
|
set_track(0);
|
||
|
|
||
|
function next_track()
|
||
|
{
|
||
|
var rpt=parseInt(localStorage.getItem("audio_repeat") ?? "0");
|
||
|
if(rpt === 1) return;
|
||
|
|
||
|
var shuffle=(localStorage.getItem("audio_shuffle") ?? "false") === 'true';
|
||
|
|
||
|
if(shuffle)
|
||
|
{
|
||
|
set_track(Math.floor(Math.random() * list.length));
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
|
||
|
if(track_index + 1 >= list.length)
|
||
|
{
|
||
|
if(rpt === 2) set_track(0);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
set_track(track_index+1);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
function shuffle_button()
|
||
|
{
|
||
|
var shuffle=(localStorage.getItem("audio_shuffle") ?? "false") === 'false';
|
||
|
localStorage.setItem('audio_shuffle',shuffle.toString());
|
||
|
set_repeat_button();
|
||
|
}
|
||
|
function prev_track()
|
||
|
{
|
||
|
if(track_index > 0)
|
||
|
{
|
||
|
set_track(track_index-1);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
var rpt=parseInt(localStorage.getItem("audio_repeat") ?? "0");
|
||
|
|
||
|
if(rpt === 2)
|
||
|
set_track(list.length-1);
|
||
|
else
|
||
|
set_track(0);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function set_repeat_button()
|
||
|
{
|
||
|
var shuffle=(localStorage.getItem("audio_shuffle") ?? "false") === 'true';
|
||
|
var rpt=parseInt(localStorage.getItem("audio_repeat") ?? "0");
|
||
|
player.loop = rpt === 1;
|
||
|
shuffle_icon.src = shuffle ? "{{rooturl}}shuffle_on.svg" : "{{rooturl}}shuffle_off.svg";
|
||
|
prev.disabled = shuffle;
|
||
|
switch(rpt)
|
||
|
{
|
||
|
case 0:
|
||
|
repeat_icon.src = "{{rooturl}}repeat_off.svg";
|
||
|
repeat_icon.alt = "Repeat Off";
|
||
|
break;
|
||
|
case 1:
|
||
|
repeat_icon.src = "{{rooturl}}repeat_one.svg";
|
||
|
repeat_icon.alt = "Repeat One";
|
||
|
break;
|
||
|
default:
|
||
|
repeat_icon.src = "{{rooturl}}repeat_all.svg";
|
||
|
repeat_icon.alt = "Repeat All";
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
set_repeat_button();
|
||
|
|
||
|
function repeat_button()
|
||
|
{
|
||
|
var rpt=parseInt(localStorage.getItem("audio_repeat") ?? "0");
|
||
|
rpt = (rpt+1) % 3;
|
||
|
localStorage.setItem("audio_repeat",rpt.toString());
|
||
|
set_repeat_button();
|
||
|
}
|
||
|
|
||
|
var down=false;
|
||
|
|
||
|
function seekdown()
|
||
|
{
|
||
|
down=true;
|
||
|
player.currentTime = (seekbar.value / 1000) * player.duration;
|
||
|
|
||
|
}
|
||
|
function seekup()
|
||
|
{
|
||
|
down=false;
|
||
|
}
|
||
|
function seekmove()
|
||
|
{
|
||
|
|
||
|
if(down)
|
||
|
player.currentTime = (seekbar.value / 1000) * player.duration;
|
||
|
}
|
||
|
function seekclick()
|
||
|
{
|
||
|
player.currentTime = (seekbar.value / 1000) * player.duration;
|
||
|
}
|
||
|
player.ondurationchange = () => {
|
||
|
var sec= new Number();
|
||
|
var min= new Number();
|
||
|
sec = Math.floor( player.duration );
|
||
|
min = Math.floor( sec / 60 );
|
||
|
sec = Math.floor( sec % 60 );
|
||
|
sec = sec >= 10 ? sec : '0' + sec;
|
||
|
totallbl.innerText = `${min}:${sec}`;
|
||
|
}
|
||
|
player.onplay = () => {
|
||
|
play_img.src = "{{rooturl}}pause.svg";
|
||
|
play_img.alt = "Pause";
|
||
|
}
|
||
|
|
||
|
player.onpause = () => {
|
||
|
play_img.src = "{{rooturl}}play.svg";
|
||
|
play_img.alt = "Play";
|
||
|
}
|
||
|
player.onended = ()=>{
|
||
|
next_track();
|
||
|
}
|
||
|
player.ontimeupdate = () => {
|
||
|
var curTime=player.currentTime;
|
||
|
var totalTime = player.duration;
|
||
|
var myOffset = (curTime / totalTime) * 1000;
|
||
|
if(!down)
|
||
|
seekbar.value = myOffset;
|
||
|
|
||
|
/*https://stackoverflow.com/a/21930876*/
|
||
|
|
||
|
var sec= new Number();
|
||
|
var min= new Number();
|
||
|
sec = Math.floor( curTime );
|
||
|
min = Math.floor( sec / 60 );
|
||
|
sec = Math.floor( sec % 60 );
|
||
|
sec = sec >= 10 ? sec : '0' + sec;
|
||
|
curlbl.innerText = `${min}:${sec}`;
|
||
|
};
|
||
|
|
||
|
function playpause()
|
||
|
{
|
||
|
if(player.paused) player.play(); else player.pause();
|
||
|
}
|
||
|
</script>
|