I’m making a simple music player in HTML, Javascript and CSS that plays the song/music files locally, in my html I have an audio element and 3 buttons (select files, previous song, next song) and a
element that should display the name of each song that is being played, this is my html code :
<button id="select-audio">Select Files</button>
<button id="prv">Previous</button>
<button id="nxt">Next</button>
<audio id="aud" controls></audio>
<p id="title"></p>
now in my Javascript code I try to get the name of the song and display it using this line (inside a for loop) where audName is the index
document.getElementById("title").innerHTML=input.files[audName].name
however the
element only displays the last song in the list without changing it when the song ends or when I click on the next or previous button (note in the following code I didn’t place the previous line in the next and previous and end functions but I tired it and it didn’t work), this is my JS code
const aud = document.getElementById("aud");
const prv = document.getElementById("prv");
const nxt = document.getElementById("nxt");
let audios = [];
let selectAudio = document.getElementById("select-audio");
//Listen when the select-audio button is clicked to perform the action of selecting the audio files
selectAudio.addEventListener('click', function(){
//CREATE AN INPUT ELEMENT AND THEN CHECK FOR CHANGE
const input = document.createElement('input');
input.type = "file";
input.accept = "audio/*";
input.multiple = true;
input.onchange = function (e){
audios = Array.from(e.target.files);
playAudios(audios,0); //it's 0 here so that it plays the first audio
for (let audName = 0; audName < audios.length; audName++){
document.getElementById("demo").innerHTML = input.files[audName].name;
}
};//END OF ONCHANGE FUNCTION OF THE INPUT
input.click();
}//END OF THE ADD EVENT LISTENER FUNCTION
);//END OF selectAudio EVENT LISTENER
//Play the Audios, NOTE that the following function was called previousely under the onchange function
// so that it changes once the audio player's value is changed
function playAudios (audios, index){
//First let's define a function to play the next audio file
function nxtAudio(){
if (index < audios.length -1){ index++ }
else { index=0; }
const url = URL.createObjectURL(audios[index]);
aud.src = url;
aud.play();
}//END OF nxtAudio FUNCTION
//Next let's define a function to play the previous audio file
function prvAudio(){
if (index > 0){ index-- }
else { index = audios.length - 1 ; }
const url = URL.createObjectURL(audios[index]);
aud.src = url;
aud.play();
}//END OF prvAudio FUNCTION
//Listen when the Audio has ENDED
aud.addEventListener('ended', function(){
nxtAudio();
}//END OF THE 'ENDED' FUNCTION
);//END OF THE addEventListener
//LISTEN WHEN THE NEXT BUTTON IS CLICKED
nxt.addEventListener('click', function(){
nxtAudio();
});//END OF NXT
//LISTEN WHEN THE PREVIOUS BUTTON IS CLICKED
prv.addEventListener('click', function(){
prvAudio();
});//END OF PRV
//START PLAYING THE FIRST AUDIO
const url = URL.createObjectURL(audios[index]);
aud.src = url;
aud.play();
}// THE END OF THE playAudios FUNCTION
I mostly tried the following line
document.getElementById("title").innerHTML=input.files[audName].name
I expected the name to be update once the input value changes but nothing happened
2
Answers
That’s because you need to change the title in several places inside your
playAudios()
funcion.You are currently placing the title change on file upload, but that’s not what plays the song.
Inside the playAudios add following function:
Then add following line at end (last line before the
}
) ofnxtAudio
,prvAudio
andplayAudios
functions:And remove your for loop after the
playAudios(audios,0)
calle
. Use ratherevt
orevent
play()
function insteadaudios
as argument to functions if you already use a scoped variable. Functions will have access to it regardlessURL.createObjectURL
don’t forget to also use revokeObjectURL to free up memorymod()
that will do the job for you like:index = mod(++index, tot)
for next and respectively--
for the prev action. (Notice theprev
instead ofprv
;))