make javascript keypress sounds exclusive to one another? - javascript

I have a simple site that triggers sounds on javascript keypress events. I need it to work so that when another sound is triggered the previous sound stops. For example when I press the next chord, the previous chord stops playing. I also need to create exclusivity groups, so that the next chord stops the previous chord, but doesn't stop the drums.
<div class="keys">
<div data-key="90" class="key">
<kbd>Z</kbd>
<span class="sound">Intro Drums</span>
</div>
<div data-key="88" class="key">
<kbd>X</kbd>
<span class="sound">Verse Drums</span>
</div>
<div data-key="67" class="key">
<kbd>C</kbd>
<span class="sound">Build Drums</span>
</div>
<div data-key="86" class="key">
<kbd>V</kbd>
<span class="sound">Drop Drums</span>
</div>
<div data-key="66" class="key">
<kbd>B</kbd>
<span class="sound">Bmajor(VI)</span>
</div>
<div data-key="78" class="key">
<kbd>N</kbd>
<span class="sound">C#major(VII)</span>
</div>
<div data-key="77" class="key">
<kbd>M</kbd>
<span class="sound">D#m(i)</span>
</div>
<div data-key="188" class="key">
<kbd><</kbd>
<span class="sound">Bbm(v)</span>
</div>
</div>
<audio data-key="90" src="sounds/drums/Drums1_Tambo.mp3"></audio>
<audio data-key="88" src="sounds/drums/Drums2_Verse.mp3"></audio>
<audio data-key="67" src="sounds/drums/Drums3_BuildUp.mp3"></audio>
<audio data-key="86" src="sounds/drums/Drums4_Drop.mp3"></audio>
<audio data-key="66" src="sounds/dropChords/ChordsBass1_Bmaj(VI).mp3"></audio>
<audio data-key="78" src="sounds/dropChords/ChordsBass2_CSharpmaj(VII).mp3"></audio>
<audio data-key="77" src="sounds/dropChords/ChordsBass3_DSharpm(i).mp3"></audio>
<audio data-key="188" src="sounds/dropChords/ChordsBass4_Bbm(iv).mp3"></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; // stops the function from running
audio.currentTime = 0; //rewind to the start
audio.play();
key.classList.add('playing');
};
function removeTransition(e) {
if(e.propertyName !== 'transform') return;
this.classList.remove('playing');
}
const keys = document.querySelectorAll('.key');
keys.forEach(key => key.addEventListener('transitionend', removeTransition));
window.addEventListener('keydown', playSound);
</script>
</body>
</html>

Related

pause the other playing video when play a new video jquery

I have many videos on one page.
I am using jquery to play and pause the videos
when I click on the play button it should play.
I did this using jquery. now I need to pause the other videos when I press play on the next or previous video. could you help me, please?
a screenshot is here
$('video').each(function(i, el) {
var p = $(el).parent();
$('.play-toggle', p).click(function(e) {
var button = $(this);
if (button.hasClass('playvideo')) {
button.removeClass('playvideo');
$('.play', button).hide();
$('.pause', button).show();
el.play();
} else {
button.addClass('playvideo');
$('.play', button).show();
$('.pause', button).hide();
el.pause();
}
});
});
$('video').each(function(i, el) {
var p = $(el).parent();
$('.sound-toggle', p).click(function(e) {
var button = $(this);
if (button.hasClass('playsound')) {
button.removeClass('playsound');
$('.play-sound', button).hide();
$('.pause-sound', button).show();
el.muted = true;
} else {
button.addClass('playsound');
$('.play-sound', button).show();
$('.pause-sound', button).hide();
el.muted = false;
}
});
});
<div class="video-player">
<video id="video1" width="420">
<source src="<?php echo base_url(); ?>assets/video/video.mp4" type="video/mp4">
Your browser does not support HTML video.
</video>
<div class="controls">
<button class="play-toggle playvideo">
<span class="play"><i class="fa-solid fa-play"></i></span>
<span class="pause" style="display: none;"><i class="fa-solid fa-pause"></i></span>
</button>
<button class="sound-toggle playsound">
<span class="play-sound"><i class="fa-solid fa-volume-high"></i></span>
<span class="pause-sound" style="display: none;"><i class="fa-solid fa-volume-xmark"></i></span>
</button>
</div>
</div>
To do what you require you can create a function which loops through all video elements and calls pause() on then. You can then call this function when a video is played.
In addition, note that instead of looping through the video elements on document.ready, you can instead attach event handlers to the media control buttons which use DOM traversal to find the related content when they are clicked. This has the benefit of simplfying the code, and maknig it easier to maintain. Try this:
let pauseAllVideos = excludeVideo => $('video').not(excludeVideo).each((i, v) => {
v.pause();
$(v).closest('.video-player').find('.play-toggle')
.removeClass('pause').addClass('play')
.find('i').removeClass('fa-pause').addClass('fa-play');
});
$('.play-toggle').on('click', e => {
let $button = $(e.currentTarget);
let video = $button.closest('.video-player').find('video')[0];
pauseAllVideos(video);
$button.toggleClass('play pause').find('i').toggleClass('fa-play fa-pause');
video[video.paused ? 'play' : 'pause']();
});
$('.sound-toggle').on('click', e => {
let $button = $(e.currentTarget);
let video = $button.closest('.video-player').find('video')[0];
$button.toggleClass('play-sound pause-sound').find('i').toggleClass('fa-volume-high fa-volume-xmark');
video.muted = !video.muted;
});
// This is just for this demo, so it doesn't deafen people :)
// it can be removed in your production version
$('video').each((i, v) => v.volume = 0.1);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.1/css/all.min.css" integrity="sha512-KfkfwYDsLkIlwQp6LFnl8zNdLGxu9YAA1QvwINks4PhcElQSvqcyVLLD9aMhXd13uQjoXtEKNosOWaZqXgel0g==" crossorigin="anonymous" referrerpolicy="no-referrer"
/>
<p>Video #1:</p>
<div class="video-player">
<video id="video1" width="420">
<source src="http://grochtdreis.de/fuer-jsfiddle/video/sintel_trailer-480.mp4" type="video/mp4">
Your browser does not support HTML video.
</video>
<div class="controls">
<button class="play-toggle playvideo">
<span class="play"><i class="fa-solid fa-play"></i></span>
<span class="pause" style="display: none;"><i class="fa-solid fa-pause"></i></span>
</button>
<button class="sound-toggle playsound">
<span class="play-sound"><i class="fa-solid fa-volume-high"></i></span>
<span class="pause-sound" style="display: none;"><i class="fa-solid fa-volume-xmark"></i></span>
</button>
</div>
</div>
<p>Video #2:</p>
<div class="video-player">
<video id="video2" width="420">
<source src="http://grochtdreis.de/fuer-jsfiddle/video/sintel_trailer-480.mp4" type="video/mp4">
Your browser does not support HTML video.
</video>
<div class="controls">
<button class="play-toggle playvideo">
<span class="play"><i class="fa-solid fa-play"></i></span>
<span class="pause" style="display: none;"><i class="fa-solid fa-pause"></i></span>
</button>
<button class="sound-toggle playsound">
<span class="play-sound"><i class="fa-solid fa-volume-high"></i></span>
<span class="pause-sound" style="display: none;"><i class="fa-solid fa-volume-xmark"></i></span>
</button>
</div>
</div>

HTML and Javascript audio playlist able to jump tracks via smartphone controls

I'm creating an HTML audio playlist, everything runs fine, except that I would like the user to be able to jump tracks using smartphones controls (as if he were listening to Spotify), but with this html playlist the use cant jump from tracks via the smartphone controls, instead he can only foward or backward 10secs (as showed in the picture below).
Phone control
Is there anyway to make a html + js playlist that a user can jump tracks from the smartphone control?
Here is the code I am using if its important:
Code
<div class="container">
<div class="large-toggle-btn">
<i class="large-play-btn"><span class="screen-reader-text">Large toggle button</span></i>
</div>
<!-- /.play-box -->
<div class="info-box">
<div class="track-info-box">
<div class="track-title-text"></div>
<div class="audio-time">
<span class="current-time">00:00</span> /
<span class="duration">00:00</span>
</div>
</div>
<!-- /.info-box -->
<div class="progress-box">
<div class="progress-cell">
<div class="progress">
<div class="progress-buffer"></div>
<div class="progress-indicator"></div>
</div>
</div>
</div>
</div>
<!-- /.progress-box -->
<div class="controls-box">
<i class="previous-track-btn disabled"><span class="screen-reader-text">Previous track button</span></i>
<i class="next-track-btn"><span class="screen-reader-text">Next track button</span></i>
</div>
<!-- /.controls-box -->
<div class="play-list-row" data-track-row="1">
<div class="small-toggle-btn">
<i class="small-play-btn"><span class="screen-reader-text">Small toggle button</span></i>
</div>
<div class="track-number">
1.
</div>
<div class="track-title">
<a class="playlist-track" href="#" data-play-track="1">Calexico - Across The Wire</a>
</div>
</div>
<div class="play-list-row" data-track-row="2">
<div class="small-toggle-btn">
<i class="small-play-btn"><span class="screen-reader-text">Small toggle button</span></i>
</div>
This can be achieved with the Media Session API.
Open this demo from a smartphone: https://batman.dev/static/70677190/
<title>Testing</title>
<meta name="viewport" content="width=device-width">
<audio controls />
<script>
const audio = document.querySelector('audio')
const tracks = [
'https://opus-bitrates.anthum.com/audio/hyper/music-96.opus',
'https://opus-bitrates.anthum.com/audio/music-96.opus',
]
let trackIdx = 0
audio.src = tracks[trackIdx]
navigator.mediaSession.setActionHandler('previoustrack', prev)
navigator.mediaSession.setActionHandler('nexttrack', next)
function prev() {
trackIdx--
playAudio()
}
function next() {
trackIdx++
playAudio()
}
function playAudio() {
audio.src = tracks[Math.abs(trackIdx % tracks.length)]
audio.play()
navigator.mediaSession.playbackState = 'playing'
}
</script>

playPause is not defined (Not Play the Video)

In order to make video play when someone clicks on the play button, the button must become the pause icon to show that you can play and pause. Right now, the video does not play when I click on the play button. There is an error message that says playPause is not defined.
ERROR
1(index):131 Uncaught ReferenceError: playPause is not defined at HTMLButtonElement.onclick
HTML JS
jQuery(document).ready(function($){
var ppbutton = document.getElementById("vidbutton");
ppbutton.addEventListener("click", playPause);
myVideo = document.getElementById("video1");
function playPause() {
if (myVideo.paused) {
myVideo.play();
ppbutton.innerHTML = "Pause";
}
else {
myVideo.pause();
ppbutton.innerHTML = "Play";
}
}
});
<div class="hero">
<div class="container">
<div class="wrapper">
<div class="row">
<div class="video">
<video height="369px" width="610px" muted id="video1" poster="assets/img/photo.jpg">
<source src="/assets/video/bjp__video.mp4" type="video/mp4">
<source src="/assets/video/bjp__video.webm" type="video/webm">
</video>
<div class="name">
<img alt="name" src="assets/img/bjp_title.png">
</div>
</div>
<div class="info__hero__content">
<p>I help  <span><b>people with disabilities</b></span> and <span><b>entrepreneurs</b></span> to find their hide abilities and resources for their businesses.</p>
</div>
</div>
</div>
</div>
</div>
<div>
<div class="play__btn">
<button id="vidbutton" onclick="playPause()">
<img alt="play button" src="/assets/img/play__button.svg">
</button>
</div>
<div class="line"></div>
</div>
Try removing the onclick event from the button itself. That is what is causing the error.
jQuery(document).ready(function($){
var ppbutton = document.getElementById("vidbutton");
ppbutton.addEventListener("click", playPause);
myVideo = document.getElementById("video1");
function playPause() {
if (myVideo.paused) {
myVideo.play();
ppbutton.innerHTML = "Pause";
}
else {
myVideo.pause();
ppbutton.innerHTML = "Play";
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="hero">
<div class="container">
<div class="wrapper">
<div class="row">
<div class="video">
<video height="169px" width="410px" id="video1" poster="https://ourtube.co.uk/upload/photos/2021/11/928b8656defe100bf7c75815db0edf992b1e33d2wK9QTHR7ny9ahCHqPYKf.video_thumb_5245_11.jpeg">
<source src="https://ourtube.co.uk/watch/TMaamxje77GKe9q" type="video/mp4">
</video>
<div class="name">
<img alt="name" src="assets/img/bjp_title.png">
</div>
</div>
<div class="info__hero__content">
<p>I help  <span><b>people with disabilities</b></span> and <span><b>entrepreneurs</b></span> to find their hide abilities and resources for their businesses.</p>
</div>
</div>
</div>
</div>
</div>
<div>
<div class="play__btn">
<button id="vidbutton">
<img alt="play button" src="https://brandnewtube.com/themes/youplay/img/icon.png"> Play
</button>
</div>
<div class="line"></div>
</div>

Playing a specific video file when there are multiple buttons, videos

Problem
I have four divs each with their own video file and button.
Right now, it is coded in a way that it only works with one file, but unfortunately not all of them.
I've tried using .each and using the index of the element, but I kept running into an issue where .pause() was not a function
Codepen
https://codepen.io/onlyandrewn/pen/NBvPjx
Objective
Clicking on a group's button should play that group's specific video file
scripts.js
$(function(){
function playVideo() {
var video = $(".video--inline")[0];
if (video.paused) {
video.play();
video.muted = false;
} else {
video.pause();
video.muted = true;
}
// Loads the clip again, so that it reverts back to the poster image
video.addEventListener("ended", function(){
video.load();
$("button").find("i").removeClass("fa-pause");
$("button").find("i").addClass("fa-play");
});
}
$("button").click(function(){
playVideo();
});
});
index.html
<div class="group">
<video src="https://gia.guim.co.uk/2013/10/nsa-decoded/html/asset/video/p1/p1-1.webm" class="video--inline"></video>
<div class="button__wrapper">
<button>Listen</button>
</div>
</div>
<div class="group">
<video src="https://gia.guim.co.uk/2013/10/nsa-decoded/html/asset/video/p1/p1-2.webm" class="video--inline"></video>
<div class="button__wrapper">
<button>Listen</button>
</div>
</div>
<div class="group">
<video src="https://gia.guim.co.uk/2013/10/nsa-decoded/html/asset/video/p1/p1-3.webm" class="video--inline"></video>
<div class="button__wrapper">
<button>Listen</button>
</div>
</div>
<div class="group">
<video src="https://gia.guim.co.uk/2013/10/nsa-decoded/html/asset/video/p1/p1-5.webm" class="video--inline"></video>
<div class="button__wrapper">
<button>Listen</button>
</div>
</div>
Pass click event to your playVideo function then target video like this:
var video = $(e.target).closest('.group').find('video')[0];
$(function(){
function playVideo(e) {
var video = $(e.target).closest('.group').find('video')[0];
if (video.paused) {
video.play();
video.muted = false;
} else {
video.pause();
video.muted = true;
}
// Loads the clip again, so that it reverts back to the poster image
video.addEventListener("ended", function(){
video.load();
$("button").find("i").removeClass("fa-pause");
$("button").find("i").addClass("fa-play");
});
}
$("button").click(playVideo);
});
.group {display:inline-block; width:20vw}
video {width:20vw}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="group">
<video src="https://gia.guim.co.uk/2013/10/nsa-decoded/html/asset/video/p1/p1-1.webm" class="video--inline"></video>
<div class="button__wrapper">
<button>Listen</button>
</div>
</div>
<div class="group">
<video src="https://gia.guim.co.uk/2013/10/nsa-decoded/html/asset/video/p1/p1-2.webm" class="video--inline"></video>
<div class="button__wrapper">
<button>Listen</button>
</div>
</div>
<div class="group">
<video src="https://gia.guim.co.uk/2013/10/nsa-decoded/html/asset/video/p1/p1-3.webm" class="video--inline"></video>
<div class="button__wrapper">
<button>Listen</button>
</div>
</div>
<div class="group">
<video src="https://gia.guim.co.uk/2013/10/nsa-decoded/html/asset/video/p1/p1-5.webm" class="video--inline"></video>
<div class="button__wrapper">
<button>Listen</button>
</div>
</div>
Update
We're passing a function name as a parameter to the click handler:
$("button").click(playVideo)
So playVideo will be called on click and the click Event object will be passed to playVideo as a parameter (we called it e): function playVideo(e).
e.target is the clicked element (button).
Then we're traversing from the button to the corresponding video.

Why won't my button play my sound and go to the link?

This looks like a basic problem but failed to find the answer.. Is there anything I need to add for the button to bring a user to the home page and play the sound? At the moment it only plays the sound. I want it to play the sound immediately then go to the homepage.
function playBeep() {
var sound = document.getElementById("Sound")
sound.play()
}
<div class="animatedButton">
<audio id="Sound" src="https://www.soundjay.com/button/sounds/beep-07.mp3"></audio>
<button id="aButton" onclick="playBeep()">
<img src="img/Home.png">
</button>
</div>
You should wait until the <audio> element is done playing, then tell the browser to navigate to a new page:
function playBeep() {
var sound = document.getElementById("Sound");
sound.play();
sound.addEventListener('ended', function () {
location.href = 'Home.html';
});
}
<div class="animatedButton">
<audio id="Sound" src="https://www.soundjay.com/button/sounds/beep-07.mp3"></audio>
<button id="aButton" onclick="playBeep()">
<img src="img/Home.png">
</button>
</div>
just need to add your link window.location = "http://stackoverflow.com";
function playBeep() {
var sound = document.getElementById("Sound")
sound.play();
window.location = "http://stackoverflow.com";
}
<div class="animatedButton">
<audio id="Sound" src="https://www.soundjay.com/button/sounds/beep-07.mp3"></audio>
<button id="aButton" onclick="playBeep()">
<img src="img/Home.png">
</button>
</div>
function playBeep() {
var sound = document.getElementById("Sound")
sound.play();
window.location.href = '/'; //Go to HomePage
}
<div class="animatedButton">
<audio id="Sound" src="https://www.soundjay.com/button/sounds/beep-07.mp3"></audio>
<button id="aButton" onclick="playBeep()">
<img src="img/Home.png">
</button>
</div>
Your button is not in the <a>tag
Maybe this will work :
<a href="Home.html">
<button id="aButton" onclick="playBeep()">
<img src="img/Home.png">
</button>
</a>
Your problem is the closing tag of a.
the tag "a" has to wrap the whole button.
<a href="Home.html">
<button id="aButton" onclick="playBeep()">
<img src="img/Home.png">
</button>
</a>
You could always use jQuery to listen for the sound to end and redirect the user.
/* Bind Ended Event to Sound */
$('#Sound').on('ended', function(){
console.log('User Redirected');
});
/* Bind Click Event to Button */
$('#aButton').on('click', function() {
$('#Sound')[0].play();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="animatedButton">
<audio id="Sound" src="https://www.soundjay.com/button/sounds/beep-07.mp3"></audio>
<button id="aButton">
<img src="http://findicons.com/files/icons/1580/devine_icons_part_2/128/home.png">
</button>
</div>
Or you could use just JavaScript to listen for the sound to end and redirect the user.
/* Variable Defaults */
var sound = document.getElementById('Sound');
var button = document.getElementById('aButton');
/* Bind Ended Event to Sound */
sound.addEventListener('ended', function(){
console.log('User Redirected');
});
/* Bind Click Event to Button */
button.addEventListener('click', function() {
sound.play();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="animatedButton">
<audio id="Sound" src="https://www.soundjay.com/button/sounds/beep-07.mp3"></audio>
<button id="aButton">
<img src="http://findicons.com/files/icons/1580/devine_icons_part_2/128/home.png">
</button>
</div>

Categories

Resources