Javascript audio does not stop and play multiple tracks simultaniously.
I'm trying to shuffle randomly number of MP3/WAV tracks and it working nicely up until the point it suppose to stop the last track so there is a live merge between the previous tracks and it obviously sounds like a mess.
I bet it's a tiny tweak to solve that issue but... :)
anyways Here is my code :
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8>
<title> </title>
</head>
<body>
Thanks in advance for your kind help :D
var t=setInterval(function(){myTimer()},3000);
var files=
[
'Hezi-Gangina#1.mp3',
'Hezi-Gangina#2.mp3',
'Hezi-Gangina#3.mp3',
'Hezi-Gangina#4.mp3'
];
function myTimer()
{
if(audio)
{
audio.pause();
audio.currentTime=0;
delete audio;
}
var i=Math.floor(Math.random()*files.length);
var url=files[i];
var audio=new Audio(url);
audio.play();
document.title=url.replace(/\.[^/.]+$/,'');
}
</script>
</body>
</html>
The problem is the interval's callback function myTimer().
Let's have a look:
if(audio)
{
audio.pause();
audio.currentTime=0;
delete audio;
}
Above, you're checking for the existence of the variable audio but this condition won't ever be true. Why? It's defined after this check and it's defined in the local scope of the callback function:
var audio=new Audio(url);
audio.play();
So the local variable will be re-defined on each call to myTimer and just 'lives' inside this function.
To fix this, you need to make audio a global variable and modify the if check to like this:
if(audio != null)
this will make sure it won't try to stop the audio the first time.
Here's your modified code:
var audio=null;
var t=setInterval(function(){myTimer()},3000);
var files=
[
'Hezi-Gangina#1.mp3',
'Hezi-Gangina#2.mp3',
'Hezi-Gangina#3.mp3',
'Hezi-Gangina#4.mp3'
];
function myTimer()
{
if(audio != null)
{
audio.pause();
audio.currentTime=0;
delete audio;
}
var i=Math.floor(Math.random()*files.length);
var url=files[i];
audio=new Audio(url);
audio.play();
}
Related
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){
I have been asked to update my question so here goes:
I have records in a database, some of which have wave file names attached. I am looping through the database and wanting to write out the word "Play" in a column under a header named Audio File. When "Play" is clicked on, the audio player plays the file and turns the href word to "Pause". When my code loops through these records, it is assigning a separate ID to each href. For me to call the function that starts the audio player, I need to send an audioControl ID (aControl) variable as well as the src source file (thissource) variable for the audio player - hence the & and " in the function call. When I use the onclick event in a button, it triggers the function. However, when I click the href link (which is what I want instead of a button) nothing happens. I am not sure which part of the code is messy, as I found the function code on the internet. Thank-you in advance for any and all help.
No matter what I do, my href onclick will not trigger a javascript function. I have taken the return false out of the function and put it in the href but that doesn't work either. I have put the same onclick code in a button and it triggers great.
HTML:
<a href='#' onclick='passvariables(" & aControl & "," & thissource & ");'>Play</a>
Javascript:
function passvariables(aControl, thissource)
{
var yourAudio= new Audio();
yourAudio.src = thissource;
yourAudio.type = 'audio/wav';
ctrl = document.getElementById(aControl);
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;
}
}
Just have onclick call passvariables without the return and have passvariables return false.
You can try:
window.passvariables = function(aControl, thissource) {
// Your code
};
My guess if that your function is defined within another function (executed onload for instance). Hence "passvariables" is not defined in the "window" scope.
I saw you updated your questions that's good :)
First I recommend you to use the javascript library jquery which is easier to manipulate the DOM and you can easily find ressources and help on this site.
Here's what your code should look. I haven't tested it but it's a good overview of what this should be.
Put this in the <head> section of your HTML code
<script src="http://code.jquery.com/jquery-1.12.0.min.js"></script>
<script>
$(document).ready(function() {
//Assigning onClick function for every HTML tags having the css class "Play"
$('.Play').click(function(){
if($(this).html() == "Play"){
//retrieving information about the audio
var waveFile = $(this).attr("data-waveFile");
var audioId = $(this).attr("data-audioId");
//calling the startAudio function and assign the Audio object to myAudioObject
var myAudioObject = startAudio(waveFile, audioId);
if(myAudioObject){
//Audio started playing
$(this).html("Pause");
}else{
alert("error while starting to play file");
}
}else{
var isPaused = pauseAudio(myAudioObject);
if(isPaused){
//The pauseAudio function returned true so the audio is paused
$(this).html("Play");
}else{
alert("error while pausing");
}
}
});
//Functions to manage audio Player
function startAudio(waveFile, audioId){
audioObject = document.getElementById("audio");
audioObject.src = waveFile;
audioObject.play();
return true;
}
function pauseAudio(){
//do whatever to pause
audioObject = document.getElementById("audio");
audioObject.pause();
return true;
}
});
</script>
in the <body> section of your HTML code where you construct the table using database datas :
<table>
<tr>
<td>Song name</td>
<td>Action</td>
</tr>
<tr>
<td><%=WaveFile%></td>
<td>Play</td>
</tr>
</table>
<audio id="audio"></audio>
Note the <%=WaveFile%> and <%=AudioId%> should be the values you get from the database in your loop
Thank-you everyone for your help! I finally got it working! Here is the code:
yAudio = "'yourAudio" & thisline & "'"
aControl = "'audioControl" & thisline & "'"
thissource = "'/WaveFiles/" & RS.Fields("AudioIssues") &"'"
R"<td width=12 class=allprint>Play</td>"
// Call and play audio via JavaScript
$(document).ready(function()
{
var aElement = document.createElement('audio');
$('.Play').click(function()
{
if($(this).html() == "Play")
{
var waveFile = $(this).attr("data-waveFile");
var audioID = $(this).attr("data-audioId");
aElement.setAttribute('src', waveFile);
aElement.load()
aElement.addEventListener("load", function()
{
aElement.play();
$(this).html("Stop");
$(".duration span").html(aElement.duration);
$(".filename span").html(aElement.src);
}, true);
aElement.play();
$(this).html("Stop");
}
else
{
var waveFile = $(this).attr("data-waveFile");
var audioID = $(this).attr("data-audioId");
aElement.setAttribute('src', waveFile);
aElement.pause();
$(this).html("Play");
}
});
});
So i have a web app with basic authentication.
When im logged in, an Interval is set:
$("#login").click(function(e) {
var interval = setInterval(function(){myFunction();}, 2000); });
Then when im logged out i need to stop the interval:
$("#logout").click(function(e) {
if(typeof interval !== 'undefined') clearInterval(interval); });
But it doesnt work, i think the way to check if an interval exist is wrong...i can set the interval so it is running when im logged in, but i need to stop/clear it when i click on my Logout button and it doesnt...
PS. im using the interval to check "myFunction" automatically every 2 seconds, but maybe there is another way to accomplish this without an interval? thx
Your interval variable needs to be declared at a higher scope where it is available to both functions. As you have it now, it is a local variable that ONLY exists within the particular invocation of your event handler function. So, when the next event handler is called, that previous variable no longer exists. You may also want to protect against successive clicks on login:
var interval;
$("#login").click(function(e) {
if (!interval) {
interval = setInterval(function(){myFunction();}, 2000);
}
});
$("#logout").click(function(e) {
clearInterval(interval);
interval = null;
});
And, you don't need to check to see if interval is undefined. You can just call clearInterval() on it and clearInterval() will protect against any invalid argument you pass it.
Here is a simple example where your interval variable should be in global scope for both click events.
<!DOCTYPE html>
<html>
<head>
<title></title>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){
function myFunction(){
var d = new Date();
var t = d.toLocaleTimeString();
document.getElementById("demo").innerHTML = t;
}
var interval;
$("#start").click(function(){
interval = setInterval(function(){
myFunction();
},2000);
});
$("#stop").click(function(){
clearInterval(interval);
});
});
</script>
</head>
<body>
<p id="demo"></p>
<button id="start">Start</button>
<button id="stop">Stop</button>
</body>
</html>
I have created a site with image thumbnails of people I have photographed. When a visitor clicks on one of the thumbnails the full image is revealed using jQuery, and an audio introduction plays. I have a different audio introduction for each thumbnail/image combination - 15 at present with more being added daily.
I would like to ensure that if a visitor clicks on another thumbnail before the previous audio file has completed, that the previous audio file is stopped/paused to allow the new audio file to be played - thereby ensuring two or more tracks do not play simultaneously.
I am currently using the following snippet of code, wrapped in an anonymous function, to play each audio file individually when the appropriate thumbnail is clicked - so this snippet is duplicated for each audio file, but don't know how to ensure they do not play over one another.
$(".bridget-strevens").click(function(){
var audio = $('#bridget-strevens-intro')[0];
if (audio.paused){
audio.play();
} else {
audio.pause();
}
});
Any help you could give me would be very grateful, as I am just starting to learn jQuery, and don't have the knowledge to come up with a workable solution.
Thanks in advance for your help!
Add a .audio class to all your audio elements and loop through all of them when an audio is clicked.
$(".bridget-strevens").click(function () {
$('.audio').each(function (index, value) {
if (!value.paused) {
value.pause();
}
});
var audio = $('#bridget-strevens-intro')[0];
if (audio.paused) {
audio.play();
} else {
audio.pause();
}
});
If that seems too heavy for you then simply add the audio element in a global variable such as:
var currentAudio;
Then when a new audio is clicked, simply pause that one, play the new one and update the currentAudio variable with the new element currently being played.
var currentAudio = null;
$(".bridget-strevens").click(function () {
if(currentAudio != null && !currentAudio.paused){
currentAudio.pause();
}
var audio = $('#bridget-strevens-intro')[0];
if (audio.paused) {
audio.play();
currentAudio = audio;
} else {
audio.pause();
}
});
Update:
Thanks for the prompt responses! Grimbode, I've tried what you
suggest, and that seems to work. However is there the ability to stop
and reset rather than just pause - so if they clicked on 1 then [2]
before 1 finished, then clicked 1 again, that 1 would start from
the beginning again rather than the point at which it was paused? And
is there any way of check the state 'globally', and then add code for
each individual audio file - just to keep the amount of code and
duplication down? Thanks again!! –
Yes. Play audio and restart it onclick explains in detail how to do this. The final result would look something like this:
var currentAudio = null;
$(".bridget-strevens").click(function () {
if(currentAudio != null && !currentAudio.paused && currentAudio != this){
currentAudio.pause();
//Here we reset the audio and put it back to 0.
currentAudio.currentTime = 0;
}
var audio = $('#bridget-strevens-intro')[0];
if (audio.paused) {
audio.play();
currentAudio = audio;
} else {
audio.pause();
}
});
You can't really optimize the code much more. You're going to have apply the click event on every audio element. You're going to have to keep the current playing audio element memorized so you don't have to loop through all the audio files.
If you really want to take this further you could create a library to handle everything. Here is an example:
(function(){
var _ = function(o){
if(!(this instanceof _)){
return new _(o);
}
if(typeof o === 'undefined'){
o = {};
}
//here you set attributes
this.targets = o.targets || {};
this.current = o.current || null;
};
//create fn shortcut
_.fn = _.prototype = {
init: function(){}
}
//Here you create your methods
_.fn.load = function(){
//here you load all the files in your this.targets.. meaning you load the source
//OR you add the click events on them.
//returning this for chainability
return this
};
//exporting
window._ = _;
})();
//here is how you use it
_({
targets: $('.audio')
}).load();
I am new to HTML5 and I am exploring HTML5 features. There I came across audio tag.
I written code with it to play sound files.
I am having one problem with this tag. On button click, I want to change the sound file stopping the previous one.
I searched a lot but didn't find anything.
Please help me to stop the sound played by audio tag.
Here is my code;
try
{
if(MyAudio != undefined)
{
MyAudio = null;
}
MyAudio = new Audio("filename");
MyAudio.play();
}
catch(v)
{
//alert(v.message);
}
Try this:
try
{
if(MyAudio != undefined)
{
MyAudio.pause();
}
MyAudio = new Audio("filename");
MyAudio.play();
}
catch(v)
{
//alert(v.message);
}
As commented in this cuestión: HTML5 Audio stop function, a better solution could be:
var sound = document.getElementById("audio");
sound.pause();
sound.currentTime = 0;