Javascript / jQuery check which button is currently playing a song - javascript

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');
}
});

Related

button click prevents second sound playing

I have a simple Javascript program that plays a sound when correct button is clicked in response to a question.
If the user answers a second question too quickly and clicks a second correct answer the sound doesnt play a second time as first play has not completed.
Do I need to disable the answer buttons for the duration of the sound?
Any other ways roound?
Suggestions please
Scruffy code added 27.9.2022
function setQuestion(){
// string question
var questionText =" x 3 = ";
questionText=aTimes[index]+ questionText;
document.getElementById("Question").innerHTML= questionText;
aAnswers[0]=(aTimes[index]*3);
aAnswers[1]=Math.floor((Math.random() *10) *(aTimes[index] + 1));
aAnswers[2]=Math.floor((Math.random() *10) * (aTimes[index] + 2));
shuffleArray(aAnswers)
document.getElementById("Answer1").innerHTML= aAnswers[0];
document.getElementById("Answer2").innerHTML= aAnswers[1];
document.getElementById("Answer3").innerHTML= aAnswers[2];
}
function answerCheck(poss){
//*****************************************************************
//*** does the button clicked match the correct multiple of 3
//*****************************************************************
if (poss.innerHTML==(aTimes[index]*3) ) {
changePicture();
index=(index+1);
**playAudio();**
resetButtons();
setQuestion() ;
if (index==10){
alert("done");
}
}
else{
alert("not a match");
poss.style.backgroundColor = "grey";
}
}
function resetButtons(){
document.getElementById("Answer1").style.backgroundColor = "#008CBA" ;
document.getElementById("Answer2").style.backgroundColor = "#008CBA";
document.getElementById("Answer3").style.backgroundColor = "#008CBA";
}
**function playAudio()** {
//************** Play a reward sound
var x = document.getElementById("myAudio");
x.play();
}
</script>
The HTML audio element probably isn't a great fit for what you want to do here. I'd recommend using a library like Howler.

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 ;)

Reset link background color on previously selected

Hi I have a song playlist & use javascript in the player to set the back ground color to light green on the playing song. I am aware I could use a:focus however if the user selects the lyrics while the song is playing the song will continue to play however it looses focus so the background color reverts to original. I need a way to use javascript to change the color of the song back to its original when the song is no longer playing or another song is selected. code below.
<!-- Video Player Script -->
var video_playlist = document.getElementById("video_player");
var links = video_playlist.getElementsByTagName('a');
for (var i=0; i<links.length; i++) {
links[i].onclick = handler;
};
function handler(e) {
e.preventDefault();
videotarget = this.getAttribute("href");
filename = videotarget.substr(0, videotarget.lastIndexOf('.')) || videotarget;
video = document.querySelector("#video_player video");
source = document.querySelectorAll("#video_player video source");
source[0].src = filename + ".mp3";
video.load();
video.play();
this.style.background = "#AAFF8D";
};
If this is an html5 video then use the onended proptery to detect when the video finishes playing:
video.onended = function(e) {
// change background color here
};
It appears that you are using a <video> for the music. With that in mind by "song is no longer playing." I'm going to assume that means the video has ended. In that case you can have an event onended that will change the background color to the original:
var player = document.getElementById("video_player");
player.onended = function(){
// Change background color here
};
After scouring google & some playing came up with the answer.
Thank you goes out to Spencer Wieczorek & Walker Boh for answers I thought should work.
Code Below:
<!-- Video Player Script -->
<!-- Get Selected Link -->
var video_playlist = document.getElementById("video_player");
var links = video_playlist.getElementsByTagName('a');
**var ele = video_playlist.getElementsByTagName("a");
var activeEle = null;**
for (var i=0; i<links.length; i++)
{
links[i].onclick = handler;
};
<!-- Find Previously Selected Link -->
**for( var i=0; i<ele.length; i++ )
{
if( ele.item(i).style.background == "##AAFF8D" )
{
document.write(ele.item(i).id);
break;
}
}**
<!-- Highlight Selected Link & Remove Highlght On Previous Link -->
**function highlight( )
{
if (activeEle){
activeEle.style.background = "#F9F9F9";
}
var oObj = event.currentTarget;
oObj.style.background = "#AAFF8D";
activeEle = oObj;
}**
function handler(e)
{
e.preventDefault();
videotarget = this.getAttribute("href");
filename = videotarget.substr(0, videotarget.lastIndexOf('.')) ||
videotarget;
video = document.querySelector("#video_player video");
source = document.querySelectorAll("#video_player video source");
source[0].src = filename + ".mp3";
video.load();
video.play();
**highlight();**
};

Dynamic sounds not playing after two plays

I have a little html5 application where you can play a sound by clicking a button.
I have a function that adds an <audio> tag to a <div> with an id "playing." The sound removes itself when it is done.
function sound(track){
$("#playing").append("<audio src=\"" + track + "\" autoplay onended=\"$(this).remove()\"></audio>");
}
For the button I have:
<button onclick="sound('sounds/tada.mp3')">Tada</button>
When I click the button, an <audio> briefly appears in the element inspector and disappears when it is finished, just the way I want it, but after triggering it two times, it just stops working in Chrome, at least. There are no errors in the console either.
What is going on?
Get rid of the onclick/onend in your HTML and reference the button in your js:
HTML
<button id='tada' sound_url='sounds/tada.mp3'>Tada</button>
And the JS
var sound = function(track){
$("#playing").append("<audio id='played_audio' src='\" + track + \"' autoplay='true'></audio>");
}
$('#tada').on('click', function () {
var sound_url = $(this).attr('sound_url');
sound(sound_url);
});
$('#playing').on('end', 'played_audio', function() {
$(this).remove();
});
Okay, lets see..
var audioURL = "http://soundbible.com/mp3/Canadian Geese-SoundBible.com-56609871.mp3";
var audioEl = null;
function removeAudio() {
if (audioEl && audioEl.parentNode)
audioEl.parentNode.removeChild(audioEl);
}
function sound() {
removeAudio();
audioEl = document.createElement("audio");
audioEl.src = audioURL;
audioEl.controls = true;
audioEl.addEventListener("ended", removeAudio); // <-- Note it's ended, not end!
document.getElementById("playing").appendChild(audioEl);
audioEl.play();
}
document.getElementById("tada").addEventListener("click", sound);
<div id="playing">
</div>
<button id="tada">Tada</button>
I'm not seeing any problems with this script.
Decide audioURL, set audioEl to null as it will be used later
When the element with ID "tada" is clicked, run our sound function.
Remove the audio.
Create the audio element.
When the audio is finished, remove the audio.
Append the audio to the element with ID "playing".
Play the audio.
One thing to note is that I use the ended event, not the end event.
(This answer is here because Andrew really wants us to answer it.)

Categories