Stop html sound with Javascript/Jquery - javascript

I am trying to start and stop a sound, when a button, which class changes with .toggleClass() is clicked. The sound should start when i click the button and stop when i click it again or when another button, which plays another sound is clicked. But instead of stopping, the sound just starts playing from the beginning when i click the button again. I tried several methods but nothing seems to work with the current code i have. It is important for me, that the sound is also stopped, when another sound is being played. That works already.
I hope you are able to understand what i mean, I don't know how to explain it better. (Sorry for my bad english and just hit me up if you have any questions). I would be glad if someone could help me.
That is my attempt at stopping the sound:
$(document).ready(function () {
$(".fa-volume-up").click(function () {
$('audio').each(function () {
this.pause();
this.currentTime = 0;
});
});
});
And here is my whole code:
//Icon color change
$(document).ready(function() {
$(".fa-volume-off,.fa-volume-up").click(function() {
$(".fa-volume-off").toggleClass("fa-volume-up");
});
});
//Sound
var currentsound;
function EvalSound(soundobj) {
if (currentsound) {
currentsound.pause();
}
var thissound = document.getElementById(soundobj);
thissound.currentTime = 0;
thissound.play();
currentsound = thissound;
}
//Stop sound on click
$(document).ready(function() {
$(".fa-volume-up").click(function() {
$('audio').each(function() {
this.pause();
this.currentTime = 0;
});
});
});
/*basic document style*/
body,
html {
font-family: 'Open Sans', sans-serif;
font-size: 18px;
}
p {
width: 400px;
margin: auto;
margin-top: 50px;
}
audio {
display: none;
}
/*Icon style*/
.fa-volume-off {
width: 14px;
}
.fa-volume-up {
color: #3ad27a;
}
.fa-volume-off,
.fa-volume-up:hover {
cursor: pointer
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link href='http://fonts.googleapis.com/css?family=Open+Sans:300' rel='stylesheet' type='text/css'>
<link rel="stylesheet" href="http://fortawesome.github.io/Font-Awesome/assets/font-awesome/css/font-awesome.css">
<p>
A wonderful serenity has taken possession of my entire soul, whole heart. Israel (Sparring) - Chance The Rapper
<i class="fa fa-volume-off" onClick="EvalSound('sound1');StopSound(soundobj)"></i>
I am alone, and feel the charm of existence in this spot, which was created for the bliss of souls like mine.
</p>
<audio class="audio" id="sound1" src="http://soundbible.com//mp3/Coin_Drop-Willem_Hunt-569197907.mp3" controls preload="auto" autobuffer></audio>

I just figured out how to do this without adding new classes and ids for every sound element.
Here is the working js code:
$(document).ready(function () {
//change icon and icon color
$(".fa-volume-off,.fa-volume-up").click(function () {
$(this).toggleClass("fa-volume-up");
$('.fa-volume-up').not($(this)).removeClass('fa-volume-up');
//stop audio on second button click
$(".speaker").click(function () {
if (!$(this).hasClass("fa-volume-up")) {
$(".audio").trigger("pause");
}
});
});});
//stop sound and start different sound
var currentsound;
function EvalSound(soundobj) {
if (currentsound) {
currentsound.pause();
}
var thissound = document.getElementById(soundobj);
thissound.currentTime = 0;
thissound.play();
currentsound = thissound;
};
And the demo:
$(document).ready(function() {
//change icon and icon color
$(".fa-volume-off,.fa-volume-up").click(function() {
$(this).toggleClass("fa-volume-up");
$('.fa-volume-up').not($(this)).removeClass('fa-volume-up');
//stop audio on second button click
$(".speaker").click(function() {
if (!$(this).hasClass("fa-volume-up")) {
$(".audio").trigger("pause");
}
});
});
});
//stop sound and start second sound
var currentsound;
function EvalSound(soundobj) {
if (currentsound) {
currentsound.pause();
}
var thissound = document.getElementById(soundobj);
thissound.currentTime = 0;
thissound.play();
currentsound = thissound;
};
/*basic document style*/
body,
html {
font-family: 'Open Sans', sans-serif;
font-size: 18px;
font-weight: 400;
}
p {
width: 400px;
margin: auto;
margin-top: 50px;
}
audio {
display: none;
}
/*Icon style*/
.fa-volume-off {
width: 14px;
}
.fa-volume-up {
color: #3ad27a;
}
.fa-volume-off,
.fa-volume-up:hover {
cursor: pointer
}
<link href="https://fontawesome.io/assets/font-awesome/css/font-awesome.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<link href='http://fonts.googleapis.com/css?family=Open+Sans:300' rel='stylesheet' type='text/css'>
<p>
A wonderful serenity has taken possession of my entire soul, whole heart. Israel (Sparring) - Chance The Rapper
<i class="fa fa-volume-off speaker" onClick="EvalSound('sound1');StopSound(soundobj)"></i> I am alone, and feel the charm of existence in this spot, which was created for the bliss of souls like mine.
<i class="fa fa-volume-off speaker" onClick="EvalSound('sound2');StopSound(soundobj);SoundEnded();"></i> A wonderful serenity has taken possession of my entire soul, whole heart.<i class="fa fa-volume-off speaker" onClick="EvalSound('sound3');StopSound(soundobj)"></i>
</p>
<audio class="audio" id="sound1" src="http://soundbible.com//mp3/Coin_Drop-Willem_Hunt-569197907.mp3" controls preload="auto" autobuffer></audio>
<audio class="audio" id="sound2" src="wiz.mp3" controls preload="auto" autobuffer></audio>
<audio class="audio" id="sound3" src="drake.m4a" controls preload="auto" autobuffer></audio>

Here is the code
$(document).ready(function () {
$(".audio-control").click(function () {
var audio = $('.audio').get(0);
if (audio.paused == false) {
$('.audio-control').removeClass('fa-volume-up').addClass('fa-volume-off');
audio.pause();
} else {
$('.audio-control').removeClass('fa-volume-off').addClass('fa-volume-up');
audio.play();
}
});
});
and here is the example
https://jsfiddle.net/5f2cbs0m/2/

Related

How to perform jquery script only once?

I use the isInViewport script to play the video on scroll, but it doesn't look very good because it happens multiple times. Please tell how to limit the triggering of animation or video playback to literally once. Tried to add with one() and true/false but the code didn't work (I still green in jquery).
<div class="block"><span>Video below</span></div>
<div class="block video-block">
<video class="video" loop="loop" width="640" controls="controls" muted>
<source src="http://denis-creative.com/wp-content/uploads/2018/01/video.mp4" type="video/mp4" />
<source src="http://denis-creative.com/wp-content/uploads/2018/01/video.ogv" type="video/ogv" />
<source src="http://denis-creative.com/wp-content/uploads/2018/01/video.webm" type="video/webm" />
</video>
</div>
<div class="block"><span>Video above</span></div>
.block{
height: 100vh;
font-size: 60px;
text-align: center;
display: flex;
}
.block > *{
margin: auto;
display: inline-block;
max-width: 100%;
}
// Plugin isInViewport
!function(e,n){"object"==typeof exports&&"undefined"!=typeof module?n(require("jquery"),require("window")):"function"==typeof define&&define.amd?define("isInViewport",["jquery","window"],n):n(e.$,e.window)}(this,function(e,n){"use strict";function t(n){var t=this;if(1===arguments.length&&"function"==typeof n&&(n=[n]),!(n instanceof Array))throw new SyntaxError("isInViewport: Argument(s) passed to .do/.run should be a function or an array of functions");return n.forEach(function(n){"function"!=typeof n?(console.warn("isInViewport: Argument(s) passed to .do/.run should be a function or an array of functions"),console.warn("isInViewport: Ignoring non-function values in array and moving on")):[].slice.call(t).forEach(function(t){return n.call(e(t))})}),this}function o(n){var t=e("<div></div>").css({width:"100%"});n.append(t);var o=n.width()-t.width();return t.remove(),o}function r(t,i){var a=t.getBoundingClientRect(),u=a.top,c=a.bottom,f=a.left,l=a.right,d=e.extend({tolerance:0,viewport:n},i),s=!1,p=d.viewport.jquery?d.viewport:e(d.viewport);p.length||(console.warn("isInViewport: The viewport selector you have provided matches no element on page."),console.warn("isInViewport: Defaulting to viewport as window"),p=e(n));var w=p.height(),h=p.width(),v=p[0].toString();if(p[0]!==n&&"[object Window]"!==v&&"[object DOMWindow]"!==v){var g=p[0].getBoundingClientRect();u-=g.top,c-=g.top,f-=g.left,l-=g.left,r.scrollBarWidth=r.scrollBarWidth||o(p),h-=r.scrollBarWidth}return d.tolerance=~~Math.round(parseFloat(d.tolerance)),d.tolerance<0&&(d.tolerance=w+d.tolerance),l<=0||f>=h?s:s=d.tolerance?u<=d.tolerance&&c>=d.tolerance:c>0&&u<=w}function i(n){if(n){var t=n.split(",");return 1===t.length&&isNaN(t[0])&&(t[1]=t[0],t[0]=void 0),{tolerance:t[0]?t[0].trim():void 0,viewport:t[1]?e(t[1].trim()):void 0}}return{}}e="default"in e?e.default:e,n="default"in n?n.default:n,/**
* #author Mudit Ameta
* #license https://github.com/zeusdeux/isInViewport/blob/master/license.md MIT
*/
e.extend(e.expr[":"],{"in-viewport":e.expr.createPseudo?e.expr.createPseudo(function(e){return function(n){return r(n,i(e))}}):function(e,n,t){return r(e,i(t[3]))}}),e.fn.isInViewport=function(e){return this.filter(function(n,t){return r(t,e)})},e.fn.run=t});
//# isInViewport
// Play Video
$(function() {
var $video = $('.video');
var $window = $(window);
$window.scroll(function() {
if ($video.is(":in-viewport")) {
$video[0].play();
} else {
$video[0].pause();
}
});
});
You could add a var to check if the video is still playing (for example is_playing) and check it with an inner if:
$(function() {
var $video = $('.video');
var $window = $(window);
var is_playing = false;
$window.scroll(function() {
if ($video.is(":in-viewport")) {
if (!is_playing) {
is_playing = true;
$video[0].play();
}
} else {
$video[0].pause();
}
});
});

Audio is not playing without pressing mouse or any key in Javascript

I am trying to play an audio which is a smoke detecting sound whenever I sense smoke. But the problem is audio is not playing correctly. If I click the mouse on the page, then sound comes. Even if I press any key from the keyboard, then also sound comes. So, I need a way to play the music without clicking the mouse on the page or pressing any key from the keyboard. Help me out. Thanks.
<tr>
<table align="center" style=" border: 5px solid grey; width:100%;">
<td valign="center"><t style="font-size: 70px; padding-left:0px; color: white; font-family: serif;">SMOKE:</t></td>
<td valign="center">
<i id="smoke" style="font-family: 'verdana'; font-weight: 'bold'; font-size: 75px;">{{ smokestatus }}</i>
</td>
</tr>
<audio id="myAudio">
<source src={{ url_for('static', filename='smoke_detector_beeps.mp3') }} type="audio/mpeg">
Your browser does not support the audio element.
</audio>
<script>
var x = document.getElementById("myAudio");
function playAudio() {
x.play();
}
function pauseAudio() {
x.pause();
}
</script>
<script>
if (document.getElementById('smoke').innerText == "NO SMOKE" ) {
document.getElementById('smoke').style.color = 'green';
}
else if (document.getElementById('smoke').innerText == "SMOKE DETECTED" ) {
document.getElementById('smoke').style.color = 'red';
document.getElementById('smoke').style.fontSize = '65px';
document.getElementById("smoke").className = "blink";
playAudio();
}
else if (document.getElementById('smoke').innerText == "SENSOR DISCONNECTED" ) {
document.getElementById('smoke').style.color = 'yellow';
document.getElementById('smoke').style.fontSize = '60px';
pauseAudio();
}
else if (document.getElementById('smoke').innerText == "SENSOR CONNECTED" ) {
document.getElementById('smoke').style.color = 'green';
}
else {
document.getElementById('smoke').style.color = 'white';
}
</script>
</table>
</tr>
The answer depends on when you want the sound to be played:
If you only want to check for the smoke status on page load, you can wrap your logic that's currently within the second script tag into a function.
This function can then be called when the window loads by using:
window.onload = checkSmoke()
If you want the function to be called multiple times whenever the smoke status changes, you will have to call the function again.
Here's a small JSFiddle to show what I mean.
If this wasn't the answer you were looking for, let me know!

Slow video down to a stop gradually

I'm working on a project where a video plays in the background and events need to be fired at certain points in the video. At these points, the video needs to gradually slow down and stop before the event displays.
So far I have made this happen by getting the frame rate and the more it goes up the slower the video playback is, however, it is quite stuttery and jumps into slowing down very fast I would like something smoother. Also currently when you then want to replay the video it falls within the slow down to a stop area of the frames and starts to slow down before starting to play again. I've put in a different video to my actual video as for demo purposes so there is only one event which actually fires in this due to the video being small but there's need to be multiple events at different points in the video.
var currentFrame = $('#currentFrame');
var video = VideoFrame({
id: 'video',
frameRate: 29.97,
callback: function(frame) {
currentFrame.html(frame);
if ((frame > 60) && (frame < 135) || (frame > 875) && (frame < 952) || (frame > 1700) && (frame < 1798)) {
decrease_rate(frame);
} else {
reset_frames_rate();
}
}
});
$('#play-pause').click(function() {
ChangeButtonText();
});
window.decrease_rate = decrease_rate;
var frame_on_start = 0,
frame_rate_dif,
new_speed;
function decrease_rate(frame) {
if (frame_on_start == 0) {
console.log("frame rate reset");
frame_on_start = frame;
} else {
frame_rate_dif = frame - frame_on_start;
new_speed = 1 - (frame_rate_dif / 100);
document.querySelector('video').playbackRate = new_speed;
if (frame_rate_dif > 65) {
reset_frames_rate();
video.video.pause();
video.stopListen();
$("#play-pause").html('Play');
show_event();
}
}
}
window.show_event = show_event;
function show_event() {
$('.event1').removeClass('hide_event');
}
window.reset_frames_rate = reset_frames_rate;
function reset_frames_rate() {
frame_on_start = 0;
frame_rate_dif = 0;
document.querySelector('video').playbackRate = 1;
}
function ChangeButtonText() {
if (video.video.paused) {
video.video.play();
video.listen('frame');
$("#play-pause").html('Pause');
$('.event1').addClass('hide_event');
} else {
video.video.pause();
video.stopListen();
$("#play-pause").html('Play');
}
}
#container {
position: relative;
}
.hide_event {
display: none;
}
.event1 {
position: absolute;
top: 40%;
left: 0px;
background-color: white;
width: 100%;
text-align: center;
}
<script src="https://rawgit.com/allensarkisyan/VideoFrame/master/VideoFrame.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="container">
<video height="180" width="100%" id="video">
<source src="http://www.w3schools.com/html/mov_bbb.mp4"></source>
</video>
<div id="event1" class="event1 hide_event">
<p>Display event</p>
</div>
</div>
<div class="frame">
<span id="currentFrame">0</span>
</div>
<div id="controls">
<button id="play-pause">Play</button>
</div>

jQuery: Multiple audio player buttons

I would like to make 4 play buttons which plays mp3 audio. The play function is working every 4 buttons, but unfortunately the pause is not working for either of them. Maybe the pause condition is wrong?
<div class="audio-button">
<audio src="media/test.mp3"></audio>
</div>
<div class="audio-button">
<audio src="media/test2.mp3"></audio>
</div>
<div class="audio-button">
<audio src="media/test3.mp3"></audio>
</div>
<div class="audio-button">
<audio src="media/test4.mp3"></audio>
</div>
$(document).ready(function() {
var playing = false;
$('.audio-button').click(function() {
$(this).toggleClass("playing");
var song = $(this).find('audio').attr('src');
var audio = new Audio(song);
if (playing == false) {
audio.play();
playing = true;
} else {
audio.pause();
playing = false;
}
});
});
You need to grab the audio element directly from the button as a child and interact with that. You do not need to clone the Audio object using a constructor.
$(document).ready(function() {
var playing = false;
// Add file names.
$('.audio-button').each(function() {
var $button = $(this);
var $audio = $button.find('audio');
$($('<span>').text($audio.attr('src'))).insertBefore($audio);
});
// Add click listener.
$('.audio-button').click(function() {
var $button = $(this);
var audio = $button.find('audio')[0]; // <-- Interact with this!
// Toggle play/pause
if (playing !== true) {
audio.play();
} else {
audio.pause();
}
// Flip state
$button.toggleClass('playing');
playing = !playing
});
});
.fa.audio-button {
position: relative;
display: block;
width: 12em;
height: 2.25em;
margin-bottom: 0.125em;
text-align: left;
}
.fa.audio-button:after {
position: absolute;
right: 0.8em;
content: "\f04b";
}
.fa.audio-button.playing:after {
content: "\f04c";
}
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.6.3/css/font-awesome.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button class="fa audio-button">
<audio src="media/test.mp3"></audio>
</button>
<button class="fa audio-button">
<audio src="media/test2.mp3"></audio>
</button>
<button class="fa audio-button">
<audio src="media/test3.mp3"></audio>
</button>
<button class="fa audio-button">
<audio src="media/test4.mp3"></audio>
</button>
do you want to stop the other three when one is clicked?
If so you can try:
$(document).ready(function () {
$('.audio-button').click(function (e) {
var button = $(e.target).closest('.audio-button');
var audio = button.find('audio');
var audioDom = audio.get(0);
$('audio[data-is-playing]').not(audio).each(function (i, currentAudioDom) {
var currentButton = $(currentAudioDom).closest('.audio-button');
currentButton.removeClass('playing');
currentButton.removeAttr('data-is-playing');
currentAudioDom.$audio.pause();
});
button.addClass('playing');
audio.attr('data-is-playing', '');
audioDom.$audio = audioDom.$audio || new Audio(audio.attr('src'));
audioDom.$audio.play();
});
});
Fix:
Actually I'm not sure if the audio element is an Audio Object in itself, if so, you can call the play/pause directly on the audioDom/currentAudioDom elements and forget about the $audio thing...

How do I play the same sound on multiple clicks, using jQuery and Javascript

Currently, I have an explosion sound firing when my bubble's pop, using the explode effect from jQuery. I'm wanting to be able to click on one bubble after another, without having to pause waiting for the other sound to finish. I've tried using a variable to change to a different audio object with no luck. Any help would be appreciated!
The same problem is happening in jsfiddle: jsfiddle.net/xbrjp/1/
My HTML
<body style="background:black;">
<style>
.circleBase {
-webkit-border-radius: 999px;
-moz-border-radius: 999px;
border-radius: 999px;
behavior: url(PIE.htc);
}
.type1 {
padding:20px;
background: white;
border:1px solid black;
color:black;
}
</style>
<div class="circleBase type1" style="display:table-cell; vertical-align:middle;">
<div align="center">Bubble 1</div></div>
<div class="circleBase type1" style="display:table-cell; vertical-align:middle;">
<div align="center">Bubble 2</div></div>
<div class="circleBase type1" style="display:table-cell; vertical-align:middle;">
<div align="center">Bubble 3</div></div>
</body>
<script>
$( ".type1" ).click(function() {
$( this ).toggle( "explode", {pieces: 50 }, 2000);
});
$(document).ready(function() {
var audioElement = document.createElement('audio');
audioElement.setAttribute('src', 'http://www.soundjay.com/mechanical/sounds/explosion-01.mp3');
//audioElement.load()
$.get();
audioElement.addEventListener("load", function() {
audioElement.play();
}, true);
var audioElement2 = document.createElement('audio');
audioElement2.setAttribute('src', 'http://www.soundjay.com/mechanical/sounds/explosion-01.mp3');
//audioElement.load()
$.get();
audioElement2.addEventListener("load", function() {
audioElement2.play();
}, true);
var x = 0;
if(x == 0) {
$('.type1').click(function() {
audioElement.play();
});
x = 1;
}
if(x == 1) {
$('.type1').click(function() {
audioElement2.play();
});
x = 0;
}
$('.pause').click(function() {
audioElement.pause();
});
});
</script>
I would actually take the route of creating an <audio> element for each bubble:
http://jsfiddle.net/8qc9V/
$(document).ready(function () {
$(".type1").click(function () {
$(this).toggle("explode", {
pieces: 50
}, 2000);
$(this).find('audio').get(0).play();
});
$('.type1').each(function() {
$('<audio/>')
.attr('src','http://www.soundjay.com/mechanical/sounds/explosion-01.mp3')
.appendTo(this);
});
});

Categories

Resources