How to get the next element of an array in javascript? - javascript

I am making my own music player in javascript and am working on the next song button. I have it set up to where the songs get added to the playlist and their corresponding ID number gets stored in an array. Then I index the array looking for the current ID of the song and then when the user hits next it goes to the next song in the array.
Here is my code:
$(document).ready(function(){
$("#player").prop("volume",".5");
});
var xmlhttp=new XMLHttpRequest();
xmlhttp.open("GET","playlist.xml",false);
xmlhttp.send();
xmlDoc=xmlhttp.responseXML;
var songlist = new Array();
var currentSong;
function song_play(song_id){
var player = document.getElementById("player");
player.setAttribute("src", "Music/"+song_id+".mp3");
player.play();
songlist.push(song_id);
alert(JSON.stringify(songlist));
currentSong = song_id;
var new_id=song_id-1;
$("#marquee").empty();
$("#marquee").append("<span style='color:red;'>Now Playing: </span>"+xmlDoc.getElementsByTagName("artist")[new_id].childNodes[0].nodeValue+"-");
$("#marquee").append(xmlDoc.getElementsByTagName("track")[new_id].childNodes[0].nodeValue);
};
function add_song(song_id,new_id){
var artist = xmlDoc.getElementsByTagName("artist")[new_id].childNodes[0].nodeValue;
var track = xmlDoc.getElementsByTagName("track")[new_id].childNodes[0].nodeValue;
$("#song_list").append("<a id="+song_id+" href='javascript:void(0)' onclick='song_play(this.id);' class='song'>"+artist+"-"+track+"</a><br/>");
};
function nextSong(currentSong){
var currentSongIndex = songlist.indexOf(currentSong);
var newSong = songlist[currentSongIndex + 1];
song_play(newSong);
};
The problem that I am experiencing is that once I hit the next button, it stops playing music all together.

newSong is representing the song object, not the id of the song and your song_play method is actually using the song id. change nextSong function to:
function nextSong(currentSong){
var currentSongIndex = songlist.indexOf(currentSong);
song_play(currentSongIndex + 1);
};

Related

JS - play different sound after each click

I have a single link and I want the link to play different sounds each time it is clicked. When I click the link it plays both sounds at the same time but I want one sound at a time
var bleep = new Audio('hello.mp3') ;
bleep.src = "hello.mp3" ;
var bleep2 = new Audio('goodbye.mp3') ;
bleep2.src = "goodbye.mp3";
Home
You should make a function out of it that checks which sound was clicked last time. Also, you neither need to set the .src property or pass a string to the play method.
JS:
var bleep = new Audio('hello.mp3');
var bleep2 = new Audio('goodbye.mp3');
var playFirst = true;
function playSound() {
if (playFirst) {
bleep.play();
} else {
bleep2.play();
}
playFirst = !playFirst;
}
HTML:
Home
Instead of attaching the event listener inline as onclick, attach it with JS using addEventListener. This allows you to pick which audio clip to play:
var helloSound = new Audio('hello.mp3');
helloSound.src = "hello.mp3";
var goodbyeSound = new Audio('goodbye.mp3');
goodbyeSound.src = "goodbye.mp3";
var homeLink = document.getElementById('home-link');
homeLink.addEventListener('click', function () {
if (/* condition to play hello */) {
helloSound.play();
} else {
goodbyeSound.play();
}
});
Markup:
Home

audio auto play next song when previous is finished

I want to create an audio background player where user can only click on image to play or stop the playback. I have trouble creating or rewirting existing codes to make a playlist for it, that automatically plays next song when previous is finished. I want to do it in vanilla js.
Here is what I have so far:
https://jsfiddle.net/rockarou/ad8Lkkrj/
var imageTracker = 'playImage';
swapImage = function() {
var image = document.getElementById('swapImage');
if (imageTracker == 'playImage') {
image.src = 'http://findicons.com/files/icons/129/soft_scraps/256/button_pause_01.png';
imageTracker = 'stopImage';
} else {
image.src = 'http://findicons.com/files/icons/129/soft_scraps/256/button_play_01.png';
imageTracker = 'playImage';
}
};
var musicTracker = 'noMusic';
audioStatus = function() {
var music = document.getElementById('natureSounds');
if (musicTracker == 'noMusic') {
music.play();
musicTracker = 'playMusic';
} else {
music.pause();
musicTracker = 'noMusic';
}
};
here is the trick to trigger next song:
music.addEventListener('ended',function(){
//play next song
});
How to play another song on same audio tag:
music.pause();
music.src = "new url";
music.load();
music.play();
Now here is a cool example of a playlist in html5, you can load each song at the time, case some clients (mobile) will not be happy when you consume the traffic, in next example all audios are loaded at same time to have a smooth transition from song to song,
loading the songs:
//playing flag
var musicTracker = 'noMusic';
//playlist audios
var audios = [];
$(".song").each(function(){
var load = new Audio($(this).attr("url"));
load.load();
load.addEventListener('ended',function(){
forward();
});
audios.push(load);
});
//active track
var activeTrack = 0;
Highlighting witch song is playing, with a bit of jquery, yeah, case yeah I'm lazy, lazy:
var showPlaying = function()
{
var src = audios[activeTrack].src;
$(".song").removeClass("playing");
$("div[url='" + src + "']").addClass("playing");
};
Fiddle here
Note: If the sound's doesn't play, manually check if audio url's are accessible
[Here a non vanilla solution.] My playlist consists of four songs, they are named 0.mp3, 1.mp3, 2.mp3 and 3.mp3.
<html>
<head><script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script></head>
<body>
<audio id="player" autoplay controls><source src="0.mp3" type="audio/mp3"></audio>
</body>
<script>
var x = 0;
var music = document.getElementById("player");
$("#player").bind("ended", function(){
x=x+1;
music.src = x%4 + ".mp3";
music.load();
music.play();
});
</script>
</html>
The playlist is repeated indefinetely.
Vanilla Javascript variant:
const audioArray = document.getElementsByClassName('songs'); //Get a list of all songs
let i = 0; //Initiate current Index
const player = document.getElementById('player'); //get the player
player.src = audioArray[i].getAttribute('data-url'); //set first Song to play
player.addEventListener('ended',function(){ //when a song finished playing
i++; //increase index
if (i < audioArray.length) { //If current index is smaller than count of songs
player.src = audioArray[i].getAttribute('data-url'); //set next song
return; // stop further processing of this function for now
}
// current index is greater than count of songs
i = 0; // therefore we reset the current index to the first available song
player.src = audioArray[i].getAttribute('data-url'); // and set it to be played
});
In this example you don't set an initial src for the audioplayers source-tag but instead have a list of class 'song'-items with an data-url attribute containing the url/path to the tracks.
I added comments to learn what and why this code is doing what it does.
Of course it could be better but it's a quick throwup of code ;)

Javascript / jQuery check which button is currently playing a song

I'm currently trying to make a song selection list where a user can hit a button to preview a song. I'm struggling with the logic behind setting a buttons innerHTML to read 'Stop preview' when that buttons song is playing and also have the buttons HTML change when a user clicks another button.
Currently my script looks something like:
var playedBy;
var song;
var playing = false;
var audioPlayer = document.getElementById("demo");
function setSong(value, idForPlayed) {
song = value;
audioPlayer.src = song;
audioPlayer.play();
playedBy = idForPlayed;
var currentIdPlayingValue = document.getElementById(idForPlayed).value;
console.log(currentIdPlayingValue);
}
function valueGetter(button) {
song = button.value;
button.className += " playing";
var idForPlayed = button.id;
var value = song;
setSong(value, idForPlayed);
}
function doEnd() {
playing = false;
console.log('we have an end');
document.getElementById('demo').pause();
document.getElementById('demo').currentTime = 0;
}
With the value of the buttons being the URL i'm passing the audio object.
Any help is appreciated here, very unsure on the approach i should take.
Thanks all!
Simple example in code pen : http://codepen.io/anon/pen/XXwXYV
You could toggle the innerHtml and all of the other buttons html on click.
Something like
$('.btn').on('click', function(){
//Add or remove a class for the clicked button to determine if it's playing.
$(this).toggleClass('playing');
if($(this).hasClass('playing')){
//Set all buttons back to play
//And probably call some sort of Stop Playing function
$('.btn').html('Play').removeClass('playing');
$(this).html('Stop Playing').addClass('playing');
}else{
$('.btn').html('Play').removeClass('playing');
}
});

Loop is not working properly

I have create a javascript to change the audio after the audio ended.
var songlist = new Array("a.mp3", "b.mp3", "c.mp3", "d.mp3", "e.mp3", "f.mp3");
var dir = "music/";
var curr_track = 0;
var isfirstrun;
function start()
{
if(curr_track == songlist.length)
curr_track = 0;
var track = document.getElementById('track');
track.innerHTML = curr_track;
var audio = document.getElementById('audio');
isfirstrun = true;
audio.src = dir+songlist[curr_track];
audio.load();
audio.play();
if(isfirstrun == true)
{
audio.addEventListener('ended', function(){ curr_track++; start();}, false);
isfirstrun = false;
}
}
And inside the HTML,
<body onload="start();">
The track used in the code is to show what is the current track number, and I found out that the output is
0 then 1 then 3 then 7
Hence, it is missing c.mp3, e.mp3 and f.mp3 from the songlist.
How can I solve the problem of the looping?
Every time the song ends, you are adding another event handler. This is why you see +1, +2, +4 etc. because the number of event handlers doubles each time around.
This is the main reason why I prefer to use audio.onended = function() {curr_track++; start();};
But anyway, to fix this all you have to do is have an "isfirstrun" variable, starting at true, then only add the event listener if it is true and set it to false.

How to choose each element from an array in their respective order? (jquery, JS)

My code:
I understand that my for loop assigns all array elements to the variable pickSound and that is why I am left with it only playing the last element. So how can I get it to play each element in order and start over once done.
function show() {
var sounds = new Array(
"audio/basement.mp3",
"audio/roll.mp3",
"audio/gatorade.mp3",
"audio/half.mp3",
"audio/hotdogs.mp3",
"audio/keys.mp3",
"audio/heil.mp3",
"audio/money.mp3",
"audio/ours.mp3",
"audio/pass.mp3"
);
for (var i = 0; i < sounds.length; i++){
var pickSound = sounds[i];
}
$('#divOne').html("<embed src=\""+ pickSound +"\" hidden=\"true\" autostart=\"true\" />");
return false;
};
You could try using the audio element and the ended event.
HTML:
<audio id="audio" controls preload></audio>
JS:
(function() {
var audioEl = document.getElementById('audio'),
counter = -1,
songs = [
'http://forestmist.org/wp-content/uploads/2010/04/html5-audio-loop.mp3',
'http://www.quackit.com/music/good_enough.mp3',
'http://forestmist.org/wp-content/uploads/2010/04/html5-audio-loop.mp3',
'http://www.quackit.com/music/good_enough.mp3'];
function nextSong() {
audioEl.removeEventListener('ended', nextSong);
if (songs[++counter]) {
audioEl.src = songs[counter];
audioEl.addEventListener('ended', nextSong);
audioEl.play();
} else {
alert('All done!');
}
}
nextSong();
}());​
DEMO
" I should have added that each click of the button plays a new sound. So a new sound can be played at any time."
I take it that means the sounds aren't to be played continuously on an automatic loop. You intend for a click of a button to play whichever sound is next and then stop?
In the following code the nextSound variable holds the index of whatever sound should be played next. When a button is clicked (insert your button's ID or other selector as appropriate) the file name associated with that index is used and then nextSound is incremented using the modulus operator to loop back to zero when it gets to the end of the array.
$(document).ready(function() {
var sounds = ["audio/basement.mp3",
"audio/roll.mp3",
"audio/gatorade.mp3",
"audio/half.mp3",
"audio/hotdogs.mp3",
"audio/keys.mp3",
"audio/heil.mp3",
"audio/money.mp3",
"audio/ours.mp3",
"audio/pass.mp3"],
nextSound = 0;
$("#yourButtonIDHere").click(function() {
$('#divOne').html("<embed src=\""+ sounds[nextSound] +"\" hidden=\"true\" autostart=\"true\" />");
nextSound = (nextSound + 1) % sounds.length;
});
});
Note also that it is generally recommend to declare arrays with the square bracket [] array literal syntax rather than new Array().

Categories