I'm trying to create, as a starting excercise, a soundboard for our D&D sessions. I'm currently trying to make it so that when a button is clicked, the variable 'audio' is set to that, and that it then runs the function to play or pause audio, depending on whether it's running or not. I have JS and HTML in the same file (I realise this isn't good, however). Below is my code:
<button id="play1st">Heroic Battle Music</button>
<button id="play2nd">Military Battle Music</button>
<button id="play3rd">Stronghold Battle Music</button>
<!--Audio to be played -->
<audio id="heroic" src="heroic.mp3"></audio>
<audio id="combat_rome" src="combat_rome.mp3"></audio>
<audio id="stronghold" src="stronghold.mp3"></audio>
<!--JavaScript audio -->
<script>
function playMusic() {
document.getElementById("play1st").addEventListener ('click', music1());
document.getElementById("play2nd").addEventListener ('click', music2());
document.getElementById("play3rd").addEventListener ('click', music3());
var isPlaying = false;
function music1() {
var audio = new Audio("heroic.mp3");
togglePlay();
};
function music2() {
var audio = new Audio("combat_rome.mp3");
togglePlay();
};
function music3() {
var audio = new Audio("stronghold.mp3");
togglePlay();
};
function togglePlay(){
if (isPlaying){
pause()
} else {
audio.play();
}
};
audio.onplaying = function () {
isPlaying = true;
};
audio.onpause = function () {
isPlaying = false;
}};
</script>
I'm probably missing something very basic, so any explanation would be most welcome. Thank you!
Related
I would like to implement an audio player on all of my WordPress pages and therefore I need to create the HTML element with JS and manipulate it from there. Everything is working, except for when I press the play button, it redirects me to a new page with the audio link and plays it there. I would like to prevent that, so that I can play and stop it on the WP pages themselves and have the audio play in the background.
Any tips are greatly appreciated!
function addAudioPlayer() {
const audioPlayer = document.createElement("a");
audioPlayer.setAttribute("id", "audioPlayer");
audioPlayer.href =
"https://www.hostname.com/wp-content/uploads/2020/09/bird_sound.wav";
audioPlayer.setAttribute("data-id", "[data-song]");
audioPlayer.innerHTML = "▶";
Array.prototype.forEach.call(
document.querySelectorAll("[data-song]"),
function (song) {
song.audio = new Audio(song.href);
song.setAttribute("role", "button");
song.setAttribute("aria-pressed", "false");
}
);
document.addEventListener("click", function (event) {
if (!event.target.hasAttribute("data-song")) return;
event.preventDefault();
if (event.target.getAttribute("aria-pressed") == "true") {
event.target.audio.pause();
event.target.setAttribute("aria-pressed", "false");
return;
}
event.target.audio.play();
event.target.setAttribute("aria-pressed", "true");
},
false
);
document.body.appendChild(audioPlayer);
}
<div>
<audio id="myaudio" src="https://www.hostname.com/wp-content/uploads/2020/09/bird_sound.wav" controls="controls" preload="auto" hidden="true"></audio>
<input type="button" onclick="autoPlay()" value="Play"/>
</div>
<script language="javascript" type="text/javascript">
var myAuto = document.getElementById('myaudio');
function autoPlay(){
myAuto.play();
}
</script>
What exactly is wrong with my selection?
<audio id="cart_add_sound" controls="" preload="auto" hidden="hidden"> <source src="img/cart_add.wav"
type="audio/wav"> </audio>
creating a function
targeting class button-4
attaching an even listener to mouse click
and play the audio with an id of cart_add_sound
// Play Audio on Add to Cart
function playAudio() {
var play = document.querySelector('.button-4')
play.addEventListener('click', function() {
document.getElementById('cart_add_sound').play();
}, true);
}
i know i could use inside html5 onclick="audio.play()" but i want to approach it this way for learning purpose.
You should initialize / execute this function, for example, after the DOM is ready:
// Play Audio on Add to Cart
function playAudio() {
var play = document.querySelector('.button-4')
play.addEventListener('click', function() {
document.getElementById('cart_add_sound').play();
}, true);
}
// DOM ready event
document.addEventListener('DOMContentLoaded', (event) => {
playAudio();
});
Have you run it somewhere?
Demo - https://codepen.io/vyspiansky/pen/BaKKdvW
i fixed it by using getElementsByClassName
and looping through all elements.
// Play Audio on Add to Cart
function playAudio() {
var plays = document.getElementsByClassName('button-4')
for (var i = 0; i < plays.length; i++) {
var play = plays[i]
play.addEventListener('click', function() {
document.getElementById('cart_add_sound').play();
}, true);
}
}
Posted some code earlier, and have tried to revamp it.. to no avail. The code below gives no errors, and I -think- (I am a complete newb) it should work, but I am not sure why it's not playing. I'm trying to make a soundboard for our D&D game. The code is a follows:
<html>
<body>
<audio id="heroic" src="heroic.mp3"></audio>
<button onClick="togglePlay()" id="heroicbutton">Heroic Battle Music</button>
<script>
//<!--Audio as variables-->
var audio1 = new Audio("heroic.mp3")
var isPlaying = false;
function togglePlay(){
if (isPlaying = true){
audio1.pause()
} else {
audio1.play();
}
};
audio1.onplaying = function () {
isPlaying = true;
}
audio1.onpause = function () {
isPlaying = false;
};
</script>
</body>
</html>
The file 'heroic.mp3' is in the same folder, and no errors appear on chrome's developer tools. I am not sure why nothing is playing.
You have actually made a simple mistake here.
Inside the if you should have comparison '==' not assignment '='
if (isPlaying == true){
So, I'm a complete amateur when it comes to coding, but I still like to fiddle around with it.
I'm currently working on a html/jS/PHP based soundboard and I can't figure out how to stop sound from playing when pressing a button to play another one.
<script type="text/javascript" charset="utf-8">
$(function() {
$("audio").removeAttr("controls").each(function(i, audioElement) {
var audio = $(this);
var that = this; //closure to keep reference to current audio tag
$("#doc").append($('<button>'+audio.attr("title")+'</button>').click(function() {
that.play();
}));
});
});
</script>
I hope someone understands that. Thanks in advance.
There is also a PHP code to fetch the audio file automatically from the folder to the front end, probably unnecessary info for this problem.
This is not very difficult to do if you use HTML5 which introduced the HTMLAudioElement.
Here is the minimal code for what you are trying to do:
// Let's create a soundboard module ("sb")
var sb = {
song: null,
init: function () {
sb.song = new Audio();
sb.listeners();
},
listeners: function () {
$("button").click(sb.play);
},
play: function (e) {
sb.song.src = e.target.value;
sb.song.play();
}
};
$(document).ready(sb.init);
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Audio</title>
</head>
<body>
<button value="https://www.gnu.org/music/FreeSWSong.ogg">Song #1</button>
<button value="https://www.gnu.org/music/free-software-song-herzog.ogg">Song #2</button>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
</body>
</html>
You may also consider libraries like howler.js to help you in the development process.
What you could do, is before start playing a new audio pause all available audio on the page. Something like this.
var audioOne = document.querySelector('#audio-1');
var audioTwo = document.querySelector('#audio-2');
var allAudios = document.querySelectorAll('audio');
function stopAllAudio(){
allAudios.forEach(function(audio){
audio.pause();
});
}
document.querySelector('#play-1').addEventListener('click', function(){
stopAllAudio();
audioOne.play();
})
document.querySelector('#play-2').addEventListener('click', function(){
stopAllAudio();
audioTwo.play();
})
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
<audio id="audio-1"
src="http://developer.mozilla.org/#api/deki/files/2926/=AudioTest_(1).ogg">
</audio>
<audio id="audio-2"
src="http://www.w3schools.com/html/horse.mp3">
</audio>
<button id="play-1">
play audio 1
</button>
<button id="play-2">
play audio 2
</button>
</body>
</html>
Instead of adding audio using <audio> tag you could use HTMLAudioElement.
You can stop and reset an audio element by pausing it and setting its current time to 0. You would need to do this whenever a button is clicked. Example:
// Available sounds:
const sounds = {
"Bottle": "http://freewavesamples.com/files/Bottle.wav",
"Bamboo": "http://freewavesamples.com/files/Bamboo.wav"
}
// Load audio elements:
let audios = {};
for (let [title, url] of Object.entries(sounds)) {
audios[title] = new Audio(url);
}
// Create board buttons:
let board = document.getElementById("board");
for (let title of Object.keys(audios)) {
let button = document.createElement("button");
button.textContent = title;
button.dataset["audio"] = title;
board.appendChild(button);
}
// Handle board button clicks:
board.addEventListener("click", function(event) {
let audio = audios[event.target.dataset["audio"]];
if (audio) {
// Pause and reset all audio elements:
for (let audio of Object.values(audios)) {
audio.pause();
audio.currentTime = 0;
}
// Play this audio element:
audio.play();
}
});
<div id="board"></div>
In case you want to leverage the full power of the Web Audio API, you would probably start building your soundboard similar to this:
// Load buffer from 'url' calling 'cb' on complete:
function loadBuffer(url, cb) {
var request = new XMLHttpRequest();
request.open('GET', url);
request.responseType = 'arraybuffer';
request.onload = () => context.decodeAudioData(request.response, cb);
request.send();
}
// Available sounds:
const sounds = {
"Bottle": "url/to/bottle.wav",
"Bamboo": "url/to/bamboo.wav"
};
let audioCtx = new (AudioContext || webkitAudioContext)(),
board = document.getElementById("soundboard"),
buffers = {},
source;
// Load buffers:
for (let [title, url] of Object.entries(sounds)) {
loadBuffer(url, buffer => buffers[title] = buffer);
}
// Create board buttons:
for (let title of Object.keys(sounds)) {
let button = document.createElement("button");
button.textContent = title;
button.dataset["buffer"] = title;
board.appendChild(button);
}
// Handle board button clicks:
board.addEventListener("click", function(event) {
let buffer = buffers[event.target.dataset["buffer"]];
if (buffer) {
if (source) source.stop();
source = audioCtx.createBufferSource();
source.buffer = buffer;
source.connect(audioCtx.destination);
source.start();
}
});
<div id="soundboard"></div>
Please note that the sound URLs given above must either be on the same domain or available under the same origin policy (see CORS headers).
Below code may help others:
var audioMap = new Map();
var rappers = document.querySelectorAll('.rapper');
rappers.forEach(function(rapper){
audioMap.set(rapper, new Audio());
rapper.addEventListener('click', function(){
var audio = new Audio($(this).data('audio'));
audio.play();
audioMap.set(this, audio);
var current = audioMap.get(this);
// console.log('get', current);
audioMap.forEach(function(audio){
if( audio != current ){
audio.pause();
audio.currentTime = 0;
}
});
});
});
For the ones that don't use the audioTag in HTML5 and want to use only vanilla js this may help ya
var songplaying = null; //This is where we will store the current playing song
function playsong(song_name){
//settings
var playing = null;
if(songplaying==null){ //If a song isn't stored that means that it's not playing and vice versa
playing = false;
}else{
playing = true;
}
var dir = "./songs/"+song_name+".mp3"; //Here we get the directory of the song
var song = new Audio(dir); //Making a new audio element
if(!playing){ //This runs when no song is playing
song.play();
songplaying=song; //We save the current playing song
}else{ //This runs when another song is already playing
var song_alredyplaying = songplaying; //We get the audio element (song)
song_alredyplaying.pause(); //Pause the song
song.play(); //Then we play the new song
songplaying=song; //Save the current playing song
}
}
//Example
var playbtn = document.querySelector(".play");
playbtn.addEventListener('click', function(){
playsong("the song name");
};
There is a js-script:
<script>
function start1() {
var audio = new Audio();
audio.src = URL.createObjectURL(document.getElementById('f1').files[0]);
audio.autoplay = true;
}
function start2() {
var audio = new Audio();
audio.src = URL.createObjectURL(document.getElementById('f2').files[0]);
audio.autoplay = true;
}
...
function stop() {
var audio = new Audio();
audio.stop();
}
</script>
and html code:
<body>
<input type="file" id="f1"></input>
<input type="file" id="f2"></input>
...
<button onmousedown="start1()" onmouseup="stop()">1</button>
<button onmousedown="start2()" onmouseup="stop()">2</button>
...
As can be understood through the script, he plays a sound file that loads by using the form files.
But there are two problems:
1) requires that sound is played only during events pressing (onmousedown) and stops when the mouse button is released (onmouseup).
Now the sound is played to the end it does not matter whether you clicked the mouse button and let go of it (because there is no test for this condition).
2) also need to create a simplified version of the script, as the functions for processing should be 16 pieces, but not manually register the same each function. You must create a generated script that will process the N-number of id (start1, start2, etc., f1, f2, etc).
Help to modify the code, you can also fully code jquery. It is not critical.
Thank you.
You can use local variables, you just need an identifier to find the audio element later. You also need to append the audio element to the DOM.
Also, you have to use pause() not stop().
<script>
function start(id, source) {
var aud = document.getElementById(id);
if (aud) {
aud.parentNode.removeChild(aud);
}
var audio = new Audio();
audio.setAttribute("id", id);
audio.src = URL.createObjectURL(document.getElementById(source).files[0]);
document.body.appendChild(audio);
audio.autoplay = true;
}
function stop(id) {
var aud = document.getElementById(id);
aud.pause();
}
</script>
<input type="file" id="f1"></input>
<input type="file" id="f2"></input>
<button onmousedown="start('1', 'f1')" onmouseup="stop('1')">1</button>
<button onmousedown="start('2', 'f2')" onmouseup="stop('2')">2</button>
This should work (Untested):
<script>
var a1 = new Audio();
var a2 = new Audio();
function start1() {
a1.src = URL.createObjectURL(document.getElementById('f1').files[0]);
a1.autoplay = true;
}
function start2() {
a2.src = URL.createObjectURL(document.getElementById('f2').files[0]);
a2.autoplay = true;
}
function stop() {
a1.stop();
a2.stop();
}
</script>