I am messing with this exercise where a sound is played depending on which key you press (N, S, B or F).
I would also like to play each sound when the button is clicked, so it also works for mobile and the user has another option to play the sounds. What is the best way to approach this?
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Key sounds</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="keys">
<div data-key="78" class="key">
<kbd>N</kbd>
<span class="sound">nani</span>
</div>
<div data-key="83" class="key">
<kbd>S</kbd>
<span class="sound">scrambling</span>
</div>
<div data-key="66" class="key">
<kbd>B</kbd>
<span class="sound">barber</span>
</div>
<div data-key="70" class="key">
<kbd>F</kbd>
<span class="sound">face</span>
</div>
</div>
<audio data-key="78" src="sounds/nani.m4a"></audio>
<audio data-key="83" src="sounds/scrambling.m4a"></audio>
<audio data-key="66" src="sounds/barber.m4a"></audio>
<audio data-key="70" src="sounds/chap.m4a"></audio>
<script>
function playSound(e) {
const audio = document.querySelector(`audio[data-key="${e.keyCode}"]`);
const key = document.querySelector(`.key[data-key="${e.keyCode}"]`);
if(!audio) return; // stop the function from running all together
audio.currentTime = 0; // rewind to the start
audio.play();
key.classList.add('playing');
}
function removeTransition(e) {
if(e.propertyName !== 'transform') return; // skip it if it's not a transform
this.classList.remove('playing');
}
const keys = document.querySelectorAll('.key');
keys.forEach(key => key.addEventListener('transitionend', removeTransition));
window.addEventListener('keydown', playSound);
</script>
</body>
</html>
You could extend your code with the following:
keys.forEach(element => {
// Add a click event listener to each ".key" element, so that
// clicking plays the corresponding audio
element.addEventListener('click', () => {
// Fetch the key for the audio object that matches the key of
// this element
const audioKey = element.getAttribute('data-key');
// Query the document for the audio object corresponding to
// this element's key.
// The document.querySelector will get the first element from
// the document that matches the selector you pass.
// The audio[data-key="${ audioKey } part means "get an audio
// element that has a data-key attrbitute whose value matches
// that of the current element's "data-key" (ie 78, 83, etc)
const audio = document.querySelector(`audio[data-key="${ audioKey }"]`);
// Play the audio in the same way as you currently are
audio.currentTime = 0;
audio.play();
element.classList.add('playing');
})
})
Related
I am trying to add audio to text to be played on click (in the background) and pause on click again (To read the text on the click)
The website is made with WordPress.
I have entered this script using wp code snippet plugin, and sat the functionality to be played over site header
and in posts, I am trying to enter something like this
var yourAudio = document.getElementById('yourAudio'),
ctrl = document.getElementById('audioControl');
ctrl.onclick = function () {
// Update the Button
var pause = ctrl.innerHTML === 'pause!';
ctrl.innerHTML = pause ? 'play!' : 'pause!';
// Update the Audio
var method = pause ? 'pause' : 'play';
yourAudio[method]();
// Prevent Default Action
return false;
};
<audio id="yourAudio" preload="none">
<source src="https://cgejordan.com/wp-content/uploads/2023/01/0007.mp3" type="audio/wav" />
</audio>
<a id="audioControl" href="##">Arabic Word 1</a>
<audio id="yourAudio" preload="none">
<source src="https://cgejordan.com/wp-content/uploads/2023/01/0008.mp3" type="audio/wav" />
</audio>
<a id="audioControl" href="##">Arabic Word 2</a>
<audio id="yourAudio" preload="none">
<source src="https://cgejordan.com/wp-content/uploads/2023/01/0009.mp3" type="audio/wav" />
</audio>
<a id="audioControl" href="##">Arabic Word 3</a>
code reference: https://stackoverflow.com/a/7639343
But texts are not playing the audios when clicked
Could you please assist on how to make it work? and to keep the same text without changing it to Play! Pause! when clicked? just play and pause audio on word click
And do you suggest a better way to add audios into texts without making the page too large \slow?
I have tried many plugins but nothing worked as needed
I recommend using a generator function for each audio element, this generator function should store a reference for the audio element and then use this reference to play the correspondent audio once a word or button is clicked.
Here there's an example of such generator function.
A key point is that you should structure your data in a way you can easily reference both audio source and text. This can be achieved with an arrayand you can use the following object shape:
{ key: '...', text: 'Some text' }
After that the generation function uses a target container for inserting the audio/button containers and each container leverages an event listener that triggers its own audio file and play/pauses according to its current play state.
Note: Preview the following snippet in full page mode to properly see the example
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="https://cdn.tailwindcss.com"></script>
</head>
<style>
.btn--active {
background: #db3535 !important;
}
</style>
<body>
<div
id="audio-root"
class="flex flex-col items-center justify-center h-screen bg-gray-100"
></div>
</body>
<script>
const data = [
{
audioSrc: "https://cgejordan.com/wp-content/uploads/2023/01/0007.mp3",
text: "Arabic Word 1"
},
{
audioSrc: "https://cgejordan.com/wp-content/uploads/2023/01/0007.mp3",
text: "Arabic Word 2"
},
{
audioSrc: "https://cgejordan.com/wp-content/uploads/2023/01/0007.mp3",
text: "Arabic Word 3"
},
];
/**
* #param {HTMLElement} root
* #param {Array} data
*/
function generateAudioElements(root, data) {
data.map((item) => {
const id = crypto.randomUUID();
const container = document.createElement("div");
const audioElement = document.createElement("audio");
const textElement = document.createElement("button");
const textElementClasses = "mt-2 text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:ring-blue-300 font-medium rounded-lg text-sm px-5 py-2.5 mr-2 mb-2 dark:bg-blue-600 dark:hover:bg-blue-700 focus:outline-none dark:focus:ring-blue-800"
textElement.classList.add(
...textElementClasses.split(" ")
)
audioElement.src = item.audioSrc;
audioElement.controls = true;
audioElement.textContent = item.text;
audioElement.id = id;
textElement.textContent = item.text;
textElement.addEventListener("click", (event) => {
const audio = document.getElementById(id);
// toggle play state
if (audio.paused) {
audio.play();
// Styles
event.target.classList.add('btn--active');
} else {
audio.pause();
// Styles
event.target.classList.remove('btn--active');
}
});
container.appendChild(audioElement);
container.appendChild(textElement);
root.appendChild(container);
});
}
generateAudioElements(document.getElementById("audio-root"), data);
</script>
</html>
Im new here, my problem is that Im trying to play music or another sound with an onclick event, the problem begin when I try to stop that sound, I expect that the sound stop, but the sound begin ring again, here is the javascript code:
const playToPause = document.getElementById("play-song");
// main audio functions
function playSound() {
const audio = new Audio("track_path");
addEventListener("click", _ => {
switch (playToPause.value) {
case "pause":
audio.play();
playToPause.value = "play";
break;
case "play":
audio.pause();
playToPause.value = "pause"
}
console.log(playToPause.value);
});
};
And here is the button element
<button id="play-song" value="pause" onclick="playSound()" class="fa-solid fa-play fa-3x action-buttons"></button>
i had try before with if...else if, sentence and i changed it by a switch sentence thinking that the problem was on if...else if.
Later I use a console.log to see the value of the button and I get this the first time that I click it:browser console as code tag with "```")
the console show that:
play jquery.client.js:16
But if I click again on the button, to stop the sound, it detect as a double click
The console show that:
play jquery.client.js:16 (The first click)
pause jquery.client.js:16
play jquery.client.js:16
Sorry, for my bad english, I hope that anyone can help thanks in advance :)
Your problem is that you're redefining the audio variable each time the function is executing - with the result that the audio.play() or audio.pause() is playing or pausing that just-created sound. It does nothing with any that were previously playing.
To fix, just move the definition of audio outside the function.
Also, as #Ivar says in his comment, your addEventListener should not be inside the function, or you add new listeners each time. Your function will already run each time the button is clicked because of the inline onclick attribute on the button.
So change your code to this:
const playToPause = document.getElementById("play-song");
const audio = new Audio("track_path");
// main audio functions
function playSound() {
switch (playToPause.value) {
case "pause":
audio.play();
playToPause.value = "play";
break;
case "play":
audio.pause();
playToPause.value = "pause"
}
console.log(playToPause.value);
};
<!-- User Audio Tag -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<audio id="audio-tag">
<source src="./partham-ganesh-besado-re.mp3" type="audio/ogg">
<source src="./partham-ganesh-besado-re.mp3" type="audio/mpeg">
</audio>
<button onclick="play()" type="button">Play</button>
<button onclick="pause()" type="button">Pause</button>
<script>
var audio = document.getElementById("audio-tag");
function play() {
audio.play();
}
function pause() {
audio.pause();
}
</script>
</body>
</html>
I am making a mental health website in which there is a meditation area. there are two div cards and inside of each, there is one button that plays and stops music when clicked.
I am using script tags inside the html file for extra information.
Purpose:
when the buttons inside each of the two card div is clicked, a guided meditation audio should play.
there is a long audio and a short audio that comes in two formats of mp3 and ogg.
Problem:
one of the audios play perfectly but the second one doesn't work. meaning it wont play and stop when the button is clicked.
can you please check and tell me what's wrong.
<div class="main-box">
<div class="slot1">
<p class="line line1">this is the long music</p>
<audio id=rollSound loop>
<source src="sounds/long-medi.mp3" type="audio/mpeg">
<source src="sounds/long-medi.ogg" type="audio/ogg">
Your browser does not support the sound files. Please proceed by using other solutions.
<!--the obove text will only show if the users' browser does not play the two files. -->
</audio>
<button id=play>play/stop</button>
<script>
const rollSound = document.getElementById('rollSound');
const btn = document.getElementById('play');
btn.addEventListener("click", e => rollSound.paused ? rollSound.play() : rollSound.pause());
</script>
</div>
<div class="slot2">
<p class="line line2">this is for short music</p>
<audio id=shortsound loop>
<source src="sounds/short-medi.mp3" type="audio/mpeg">
<source src="sounds/short-medi.ogg" type="audio/ogg">
Your browser does not support the sound files. Please proceed by using other solutions.
</audio>
<button id=roll>play/stop</button>
<script>
const shortsound = document.getElementById('shortsound');
const btn = document.getElementById('roll');
btn.addEventListener("click", e => shortsound.paused ? shortsound.play() : shortsound.pause());
</script>
</div>
There is an error when executing your script because you can not declare var btn = a second time.
Instead change the following
const shortsound = document.getElementById('shortsound');
const btn = document.getElementById('roll');
btn.addEventListener("click", e => shortsound.paused ? shortsound.play() : shortsound.pause());
to something like this:
const shortsound = document.getElementById('shortsound');
const btn2 = document.getElementById('roll');
btn2.addEventListener("click", e => shortsound.paused ? shortsound.play() : shortsound.pause());
and it will work, see this jsfiddle:
https://jsfiddle.net/snw3950L/1/
I have these couple of radio sources:
Radio 1 - http://ice3.securenetsystems.net/CKDX?playSessionID=2F01BCBA-BE9D-2A65-5B280ECE3E397AFE
Radio 2 - http://ice5.securenetsystems.net/CIRV?playSessionID=2EFE4082-EC1E-6FA0-10941E29181F671A
They both are working fine originally but when I put these sources in HTML in front of the src, they stop working and it's unable to play the audio.
Here's my code:
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" integrity="sha384-wvfXpqpZZVQGK6TAh5PVlGOfQNHSoD2xbE+QkPxCAFlNEevoEH3Sl0sibVcOQVnN" crossorigin="anonymous">
<div class="container">
<span class="trigger-audio fa fa-play">
<audio src="http://ice3.securenetsystems.net/CKDX?playSessionID=2F01BCBA-BE9D-2A65-5B280ECE3E397AFE"
volume="1.0">
</audio>
</span>
<br>
<br>
<br>
<span class="trigger-audio fa fa-play">
<audio src="http://ice5.securenetsystems.net/CIRV?playSessionID=2EFE4082-EC1E-6FA0-10941E29181F671A"
volume="1.0">
</audio>
</span>
<script>
const audioButtons = document.querySelectorAll('.trigger-audio')
const buttonToStopAllAudios = document.querySelector('.fa-stop')
const getAudioElementFromButton = buttonElement =>
buttonElement.querySelector('audio')
const stopAudioFromButton = buttonElement => {
// Pause the audio
getAudioElementFromButton(buttonElement).pause()
// Update element classes
buttonElement.classList.add('fa-play')
buttonElement.classList.remove('fa-pause')
}
const playAudioFromButton = buttonElement => {
// Pause the audio
getAudioElementFromButton(buttonElement).play()
// Update element classes
buttonElement.classList.remove('fa-play')
buttonElement.classList.add('fa-pause')
}
audioButtons.forEach(audioButton => {
audioButton.addEventListener('click', () => {
// I get this first because I have to pause all the audios before doing anything, so I have to know it this audio was paused or not
const audioElement = getAudioElementFromButton(audioButton)
const audioIsPaused = audioElement.paused
// Stop all audios before starting this one
audioButtons.forEach(stopAudioFromButton)
audioIsPaused
? playAudioFromButton(audioButton) // Play if it's paused
: stopAudioFromButton(audioButton) // Pause if it's playing
})
})
buttonToStopAllAudios.addEventListener('click', () => {
audioButtons.forEach(stopAudioFromButton)
})
</script>
What would be the easiest way to fix this?
I'm a beginner so any help would be appreciated. :)
I'm working on a simple project that includes a media (mp3) player in the sidebar. I can get the play/pause button to visually switch and I can turn off the audio by assigning a href to another image however when trying to get the swapped image to pause audio I just can't seem to figure it out, here's my code..
EDIT: deleted shotty code
EDIT: Figured out three ways to do this, the two kind people below posted great ways but I also figured out how to crudely do this via jquery.
$('#left-05-pause_').click(function(){
$('#left-05-pause_').hide();
$('#left-05-play_').show();
});
$('#left-06-audio_').click(function(){
audio.volume = 1;
$('#left-06-audio_').hide();
$('#left-06-mute_').show();
});
Mitch, I have three points for you:
there's no need to wrap <a> around <img>
for performance avoid overuse of selecting elements (like getElementById), because once you've selected a link to the element put it into a variable and use again to access the same element
use native info about element's state (for <audio> in this example) - explore its properties
All in all just try next sample (file names have been changed for clarity):
<body>
<audio id="audioId">
<source src="song.mp3" type="audio/mp3" />
</audio>
<img id="imageId" src="play.png" onclick="toggle()" />
<script>
var audio = document.getElementById( 'audioId' )
, image = document.getElementById( 'imageId' )
function toggle()
{
if ( audio.paused )
{
image.src = 'pause.png'
audio.play()
}
else
{
image.src = 'play.png'
audio.pause()
}
}
</script>
</body>
You can try this
<a href="#">
<img src="http://royaltrax.com/aadev/images/left/images/left_05.png" id="imgPauseChange" onclick="changeImage()">
</a>
<script language="javascript">
function changeImage() {
if (document.getElementById("imgPauseChange").src == "http://royaltrax.com/aadev/images/left/images/left_05.png")
{
document.getElementById("aud").play();
document.getElementById("imgPauseChange").src = "http://royaltrax.com/aadev/images/left/images/left_05-pause.png";
}
else
{
document.getElementById("aud").pause();
document.getElementById("imgPauseChange").src = "http://royaltrax.com/aadev/images/left/images/left_05.png";
}
}
</script>