HTML5 Audio - stop current play when another sound is started - javascript

I am using this method to play audio files when you click on an image:
http://jsfiddle.net/v97Kq/3/
function imageSwitch(_imgID, _imgStart, _imgStop, _soundFileMp3, _soundFileOgg) {
this.imgID = _imgID;
this.imgStart = _imgStart;
this.imgStop = _imgStop;
this.song = new Audio();
if (this.song.canPlayType("audio/mpeg"))
this.song.src = _soundFileMp3;
else
this.song.src = _soundFileOgg;
this.song.loop = true;
this.pos = 0;
this.e;
this.change = function () {
if (this.pos == 0) {
this.pos = 1;
document.getElementById(this.imgID).src = this.imgStop;
this.song.play();
} else {
this.pos = 0;
document.getElementById(this.imgID).src = this.imgStart;
this.song.pause();
}
}
}
It works good! - but how can I get it to stop playing the currently playing sound when another link is clicked and another sound begins?

I found this solution to my issue above, works perfectly.
which I eventually found here:
<script>
var currentPlayer;
function EvalSound(soundobj) {
var thissound=document.getElementById(soundobj);
if(currentPlayer && currentPlayer != thissound) {
currentPlayer.pause();
}
if (thissound.paused)
thissound.play();
else
thissound.pause();
thissound.currentTime = 0;
currentPlayer = thissound;
}
</script>

Related

Browser video flickers when switching clip [HTML, JS]

I want to have video clips that seamlessly transition from one to another(with idle animations). For starters, I wanted to use the normal browser player and just switch sources when one clip ends like this:
var videos = [
"video/1.webm",
"video/2.webm",
"video/3.webm",
"video/4.webm",
];
let i = 0;
const videoCount = videos.length;
const element = document.getElementById("video");
element.addEventListener('ended', myHandler, false);
function myHandler() {
i++;
if (i == videoCount) {
i = 0;
}
element.setAttribute("src", videos[i]);
element.autoplay = true;
// element.preload = true;
// element.muted = true;
element.load();
}
The problem is that there is a stutter/flicker or delay before a new clip starts playing(in chrome and firefox). The clips I have don't contain any black or empty frames(clips I have loop fine).
As far as I can tell it shows a blank screen for a frame or two.
Is there any way to preload the clips so they switch instantaneously?
The comments from Will and VC.One were leading me onto the right path. I created 2 video elements and instead of pushing and pulling the z-index I pushed it off screen with:
.hidden {
position: absolute;
left: -100vw;
}
I ended up using this:
var videos = [
"video/v1.webm",
"video/v2.webm",
"video/v3.webm",
// ...
];
var i = 0;
const videoCount = videos.length;
const v1 = document.getElementById("video");
const v2 = document.getElementById("video2");
v1.muted = true;
v2.muted = true;
v1.setAttribute("src", videos[i]);
v1.load();
v1.play();
i++;
v2.setAttribute("src", videos[i]);
v2.load();
v1.addEventListener('ended', vHandler, false);
v2.addEventListener('ended', vHandler, false);
function vHandler() {
if((i+1) == videoCount)
i = 0;
if(i % 2 == 0) {
i++;
v2.setAttribute("src", videos[i]);
v2.load();
v1.classList.remove("hidden");
v2.classList.add('hidden');
v1.play();
} else {
i++;
v1.setAttribute("src", videos[i]);
v1.load();
v2.classList.remove("hidden");
v1.classList.add('hidden');
v2.play();
}
}

How do I restart my timer and refresh my vital stats without refreshing the window?

I'm trying this in vanilla javascript. I have a little virtual pet who randomly loses life stats every second. When these get to zero, the screen changes. My restart button takes me back to the screen I want but my timer isn't running after hitting restart so the stats don't go down.
I feel my problem is with my timePassed() and restart() functions (to the bottom of the code) but I'm getting myself in a tangle now. Also don't want to just have the restart button refresh the window as its hosted in codepen and its not allowed.
I'm really stuck. Can you help?
//set up levels to a start at a maximum of 4
var hunger=4;
var happiness=4;
var health=4;
//create a random number 1-3
function answer(){
return Math.floor(Math.random() * 3)+1;
}
//time count starts at 0
var i=0;
//every minute take away 1 randomly from x, y or z
function decrease(){
if (answer() === 1){
hunger--;
}else if (answer()===2){
health--;
}else if(answer()===3){
happiness--;
}};
//show gameplay board
function showX(){
var x = document.getElementById("game");
x.style.display = "block";
}
function hideScreen() {
var y = document.getElementById("game");
y.style.display = "none";
}
function hideX() {
var z = document.getElementById("dead");
z.style.display = "none";
}
function changeStar() {
var star = document.getElementById('star');
if (happiness===4) {
star.src = "https://res.cloudinary.com/dytmcam8b/image/upload/v1561725934/virtual%20pet/s1.png";
}
else if (happiness===3){
star.src = "https://res.cloudinary.com/dytmcam8b/image/upload/v1561725934/virtual%20pet/s2.png";
}else if (happiness===2){
star.src = "https://res.cloudinary.com/dytmcam8b/image/upload/v1561725934/virtual%20pet/s3.png";
}else if (happiness===1){
star.src = "https://res.cloudinary.com/dytmcam8b/image/upload/v1561725934/virtual%20pet/s4.png";
}
}
function changeDonut() {
var donut = document.getElementById('donut');
if (hunger===4) {
donut.src = "https://res.cloudinary.com/dytmcam8b/image/upload/v1561725898/virtual%20pet/h1.png";
}
else if (hunger===3){
donut.src = "https://res.cloudinary.com/dytmcam8b/image/upload/v1561725898/virtual%20pet/h2.png";
}else if (hunger===2){
donut.src = "https://res.cloudinary.com/dytmcam8b/image/upload/v1561725898/virtual%20pet/h3.png";
}else if (hunger===1){
donut.src = "https://res.cloudinary.com/dytmcam8b/image/upload/v1561725898/virtual%20pet/h4.png";
}
}
function changeHeart() {
var heart = document.getElementById('heart');
if (health===4) {
heart.src = "https://res.cloudinary.com/dytmcam8b/image/upload/v1561725918/virtual%20pet/l1.png";
} else if (health===3){
heart.src = "https://res.cloudinary.com/dytmcam8b/image/upload/v1561725919/virtual%20pet/l2.png";
}else if (health===2){
heart.src = "https://res.cloudinary.com/dytmcam8b/image/upload/v1561725919/virtual%20pet/l3.png";
}else if (health===1){
heart.src = "https://res.cloudinary.com/dytmcam8b/image/upload/v1561725919/virtual%20pet/l4.png";
}
}
function x(){
document.getElementById('dead').innerHTML = '<span class="deadline">Oh, no! You killed Benny! You survived for ' + i + ' seconds. Can you do better next time?</span>';
}
//when clicking on pill, food , game or drink, make a sou
//on dying, make a sound.
//have a restart button on the death screen
document.getElementById("food").onclick= function feed(){
if (hunger<4){
hunger++;
}
}
document.getElementById("drink").onclick= function drink(){
if (hunger<4){
hunger++;
}
}
document.getElementById("pill1").onclick= function heal(){
if (health<4){
health++;
}
}
document.getElementById("games").onclick= function play(){
if (happiness<4){
happiness++;
}
}
var munchAudio = new Audio('https://res.cloudinary.com/dytmcam8b/video/upload/v1562342736/sounds/zapsplat_human_eat_biscuit_mouth_closed_28532.mp3');
var slurpAudio = new Audio('https://res.cloudinary.com/dytmcam8b/video/upload/v1562342736/sounds/zapsplat_human_drink_from_glass_slurp_single_21665.mp3');
var laughAudio = new Audio('https://res.cloudinary.com/dytmcam8b/video/upload/v1562343433/sounds/zapsplat_human_male_middle_aged_laugh_slightly_sinister_003_32379.mp3');
var pillAudio = new Audio('https://res.cloudinary.com/dytmcam8b/video/upload/v1562343433/sounds/noisecreations_SFX-NCFREE02_Synth-Swell.mp3');
function myAudioFunction(verb) {
if(verb === 'munch') {
munchAudio.play();
} else if(verb === 'slurp') {
slurpAudio.play();
} else if(verb === 'laugh'){
laughAudio.play();
}else if(verb === 'pill'){
pillAudio.play();
}
}
//function that uses random number to decrease vital stats and change images as the stats go down
function timePassed(){
i++;
answer();
decrease();
changeStar();
changeDonut();
changeHeart();
// once stats hit 0, stop timer and hide Benny to show death message
if (hunger==0|| happiness==0|| health==0){
clearInterval(timer);
x();
hideScreen();
}
}
var timer= setInterval('timePassed()', 1000);
//restart function
function restart(){
health=4;
happiness=4;
hunger=4;
showX();
hideX();
timePassed();
}
var button = document.getElementById("restart");
button.onclick = function() {
restart();
};
Could you please try ending your reset function by calling the timer variable again?
I suspect that the setInterval is interrupted when the restart function is called and the time passes function thereby called again.

Autoplay not working on my Javascript Slider

My goal is to coding a slider in Javascript, with a Class inside. But I meet 2 issues :
the Autoplay does not work
if I click on the Pause Button, and then click again on the play button, the autoplay does not work either
The HTML page is located there :
http://p4547.phpnet.org/bikes/slider.html
Here is my Javascript code :
class Diaporama {
constructor() {
this.controls = document.querySelectorAll('.controls');
this.slides = document.querySelectorAll('#diaporama .slide');
this.currentSlide = 0;
this.n = null;
this.playing = true;
this.pauseButton = document.getElementById('pause');
this.next = document.getElementById('next');
this.previous = document.getElementById('previous');
}
// Afficher les boutons previous, play, pause, next :
controlling() {
for(let i=0; i < this.controls.length; i++){
this.controls[i].style.display = 'inline-block';
}
}
// Slider Automatique :
goToSlide(n) {
this.slides[this.currentSlide].className = 'slide';
this.currentSlide = (n + this.slides.length)%this.slides.length;
this.slides[this.currentSlide].className = 'slide showing';
console.log(this.currentSlide);
}
nextSlide() {
this.goToSlide(this.currentSlide + 1);
}
previousSlide() {
this.goToSlide(this.currentSlide - 1);
}
slideInterval() {
setInterval(this.nextSlide,5000);
}
pauseSlideshow() {
this.pauseButton.innerHTML = '<i class="fas fa-play"></i>';
this.playing = false;
clearInterval(this.slideInterval);
}
playSlideshow() {
this.pauseButton.innerHTML = '<i class="fas fa-pause"></i>';
this.playing = true;
this.slideInterval = setInterval(this.nextSlide,5000);
}
nextItem() {
next.onclick = () => {
this.pauseSlideshow();
this.nextSlide();
}
}
previousItem() {
previous.onclick = () => {
this.pauseSlideshow();
this.previousSlide();
}
}
// Changement de slide par les touches du clavier :
clickKeyboard() {
document.addEventListener("keydown", ({keyCode}) => {
if(keyCode === 37){
this.nextSlide();
}
else if(keyCode === 39){
this.previousSlide();
}
})
}
};
let slider = new Diaporama();
slider.controlling();
slider.goToSlide(0);
slider.nextSlide();
slider.previousSlide();
slider.pauseSlideshow();
slider.playSlideshow();
slider.nextItem();
slider.previousItem();
slider.clickKeyboard();
This issue is inside playslideShow. When it calls this.nextSlide inside setInterval, the scope of this has changed. this refers to the window.
You can use bind() in this case, to make sure it refers to the slider object:
playSlideshow() {
this.pauseButton.innerHTML = '<i class="fas fa-pause"></i>';
this.playing = true;
this.slideInterval = setInterval(this.nextSlide.bind(this),5000);
}
Oh no, sorry, I found out why my Pause button was bugging.
I just added a new function :
restart() {
this.pauseButton.onclick = () => {
if(this.playing){ this.pauseSlideshow(); }
else{ this.playSlideshow(); }
}
}
It works fine now !

How to pause previous audio function?

When I press the button, I want to play a song, when I press the second song a second time, and when the third one, the cycle repeats again, but the first song is shorter than the second one, and if you click many times, the long song plays simultaneously with its other copy. Is it possible to stop the previous music and move on to another?
Html:
< a id="Play">test< / a>
Script:
window.onload=function(){
let number = 0;
var t;
document.getElementById('Play').addEventListener('click',function(){
let audio = new Audio();
if ( number == 0 ) {
audio.src = '/assets/sound/test.mp3';
number = 1;
}
else
if ( number == 1 ) {
audio.src = '/assets/sound/curious&loony.mp3';
number = 0;
}
audio.autoplay = true;
});
}
sound.pause();
sound.currentTime = 0;
Use this for pause audio
Found a way.
How to:
<script>
var i = 1, player = new Audio();
player.src = "/assets/sound/sound1.mp3";
document.querySelector('#play-button').addEventListener('click', function(e) {
e.preventDefault();
if (i === 1) {
player.src = "/assets/sound/sound1.mp3";
i = 0;
} else if (i === 0) {
player.src = "/assets/sound/sound2.mp3";
i = 1;
}
player.play();
});
</script>
Play me harder

Stop sound in a react component

My app is playing some audios depending on various triggers. I want the user to be able to stop the sound when he decides it.
this is what I did, based on this post:
audioPlayer(sound){
const audioGetReady = new Audio("...mp3")
const audioTenSec = new Audio("...mp3");
const audioNext = new AudioAudio("...mp3");
const audioRest = new AudioAudio("...mp3")
const audioCongrats = new AudioAudio("...mp3")
if(sound == 'getReady'){
audioGetReady.play()
}
if(sound == 'tenSeconds'){
audioTenSec.play()
}
if(sound == 'next'){
audioNext.play()
}
if(sound == 'rest'){
audioRest.play()
}
if(sound == 'congrats'){
audioCongrats.play()
}
if(sound == 'stop'){
audioGetReady.pause();
audioGetReady.currentTime = 0;
audioTenSec.pause();
audioTenSec.currentTime = 0;
audioNext.pause();
audioNext.currentTime = 0;
audioRest.pause();
audioRest.currentTime = 0;
audioCongrats.pause();
audioCongrats.currentTime = 0;
}
}
It doesn't work, I also tried to use ".muted = true;" as shown here
I think your code should be like below. In your code, every time you call audioPlayer function, new Audio object is created, which means the audio you start and pause are different.
audioGetReady = new Audio("...mp3");
audioTenSec = new Audio("...mp3");
audioNext = new AudioAudio("...mp3");
audioRest = new AudioAudio("...mp3");
audioCongrats = new AudioAudio("...mp3");
audioPlayer(sound){
if(sound == 'getReady'){
this.audioGetReady.play()
}
if(sound == 'tenSeconds'){
this.audioTenSec.play()
}
if(sound == 'next'){
this.audioNext.play()
}
if(sound == 'rest'){
this.audioRest.play()
}
if(sound == 'congrats'){
this.audioCongrats.play()
}
if(sound == 'stop'){
this.audioGetReady.pause();
this.audioGetReady.currentTime = 0;
this.audioTenSec.pause();
this.audioTenSec.currentTime = 0;
this.audioNext.pause();
this.audioNext.currentTime = 0;
this.audioRest.pause();
this.audioRest.currentTime = 0;
this.audioCongrats.pause();
this.audioCongrats.currentTime = 0;
}
}

Categories