Stopping an audio element by ID - javascript

Thanks for checking out my question. I'm running into a stumbling block stopping an audio element and I'm hoping to get some help. I'm creating audio elements dynamically with arguments, like this.
var audio = document.createElement("audio");
audio.setAttribute('id', params[0]);
This works fine, params[0] is a user argument. I can alert audio.id and I get 'backgroundmusic' for example. And audio.play works. The problem comes when I try to stop it.
var audio = document.getElementById(params[0]);
audio.pause();
I thought this would work, but it returns null every time. I'm a total javascript rookie and Im sure this is a rookie mistake, but what am I doing wrong?
Thank you very much in advance.

After creating the audio element, append it to some element in the dom.
var audioElement = document.createElement('audio');
audioElement.setAttribute('src', 'http://home.tiscali.nl/~jvanderw/malaysia02/sounds/greatargus.mp3');
audioElement.setAttribute('id', "user_id");
audioElement.load()
$("#audio_div").append(audioElement);
I created a fiddle, check this http://jsfiddle.net/QG68M/

I had observed that you did not attached the audio object to the DOM/Document. This causes document.getElementByID to fail in finding the element. the easiest way to stop the audio file from playing is to keep a reference to the audio object that you created.
var audioControl;
function CreateAudioElement(params)
{
audioControl = document.createElement("audio");
audioControl.setAttribute('id', params[0]);
}
function StopAudioElement()
{
audioControl.pause();
}

Related

I'm having trouble playing audio in javascript at the same time

So far, I have tried using this function to create a new audio element every time it is called:
function createAudio(src, type){
var sound = new Audio();
var source = document.createElement('source');
source.type = type;
source.src = src;
sound.appendChild('source');
sound.play();
};
That way, if you want to play a single audio file called, for example, "gunshot.mp3", but multiple times you can use this line of code:
createSound('gunshot.mp3','audio/mpeg');
This works ok, but what will happen is that when the sound is loaded a bunch of times, it will just stop running entirely. Every time that you reload the game its like rolling dice to see which sounds will or won't run, and even when it does run its patchy and inconsistent.
I'm guessing that it has something do with the html page being overloaded with new elements, so is there maybe a way to clear the elements every once and a while, like clearing a particle array so it doesn't get too long? Or is it just that my function is not correct in the first place?
Thanks!

How to check whether a sound file is playing in JavaScript

var soundObject = null;
function PlaySound() {
var textvalue = document.getElementById('<%= TextBox7.ClientID %>').value;
if (soundObject != null) {
document.body.removeChild(soundObject);
soundObject.removed = true;
soundObject = null;
}
soundObject = document.createElement("embed");
soundObject.setAttribute("src", textvalue);
soundObject.setAttribute("hidden", false);
soundObject.setAttribute("autostart", true);
document.getElementById("div1").appendChild(soundObject);
Above is my javascript code, TextBox7.text="c:\temp\abc.wav" in c#. I have two questions:
1. Is there anyway to tell whether the file c:\temp\abc.wax exists before playing the audio file?
2. How to check if the file start playing or not (since I put autostart)?
My intention is to alert user if the file does not exist or not playing?
PS: Actually, the program is working, it will play the audio when file exists and show a blackscreen if the audio file not found. I just want to make it better so that the user know what is going on.
The <embed> element does not give you that level of control over the audio file being played. If you are able to, I would strongly encourage using the HTML5 <audio> element instead. It inherits from the HTMLMediaElement Dom interface which gives you access to a lot more media specific data. The <embed> element only inherits from the HTMLElement which does not give the same level of control.
You can change your above code to be:
soundObject = new Audio();
soundObject.src = textValue;
soundObject.hidden = true;
soundObject.autoplay = true;
document.getElementById("div1").appendChild(soundObject);
soundObject.play();
Once you do that if you get an error on playback you can use soundObject.error to access the error message. This will give you an error if the file doesn't exist or any other error during playback.
To tell if the file is actively playing you can monitor the soundObject.played to see what part of the file has already been played.
I hope this solves your problem for you!
Edit:
I am attaching a JSFiddle that will hopefully give you a better idea of how to use this feature here.

using the video.js api duration call returns 0 while video is much longer

okay So I'm trying to leverage the video.js project as it's seems pretty amazing!
anyways, im writing my first script that interacts with the api which can be found below. it's basically just supposed to output the current play time to the div current_time , the id of video tag is my_stream anyways here's all my javascript ... the problem im having is playLength=0 and current time never updates when video is playing and remains at 0 (ie. is never more then 0 ) im not sure what im doing wrong here ... the api rules i followed can also be found here video.js api docs
function current_time(){
_V_("my_stream").ready(function(){
var myPlayer = this;
// EXAMPLE:
var playLength = myPlayer.duration();
do
{
var position = myPlayer.currentTime();
var myTextArea = document.getElementById('time_count');
myTextArea.innerHTML = position;
}
while(position < playLength);
});
}
window.onload = current_time
anyhelp from any one who's implemented anything with the api or just see something dumb i've done would be greatly appreciated, thanks!
You're assigning the duration to playLength before playback begins. If that's zero when you assign it, it will remain zero. Check the note in the API doc "NOTE: The video must have started loading before the duration can be known, and in the case of Flash, may not be known until the video starts playing."
It looks like you're only concerned about the duration to work out when the video is playing. It would be far better just to use the timeupdate event instead.
var myPlayer;
var myTextArea = document.getElementById('time_count');
videojs('my_stream').ready(function(){
myPlayer = this;
myPlayer.addEvent('timeupdate', onProgress);
});
function onProgress() {
myTextArea.innerHTML = myPlayer.currentTime();
}
This should execute after the DOM has loaded (with window.onload, or jQuery's $(document).ready()), or go in a script tag in the body after the video and #time_count elements.
I Have sort-of solved this problem bymyself by modifying the code I Had written so it now works like so
function current_time(){
_V_("my_stream").ready(function(){
var myPlayer = this;
var playLength = myPlayer.duration();
var position = myPlayer.currentTime();
var myTextArea = document.getElementById('time_count');
myTextArea.innerHTML = position + "/" + playLength;
t=setTimeout(function() {current_time()},2000);
});
}
... although it seems stupid to poll duration continuosly, I actually don't need this value going forward in development, however both populate properly now once the video is playing so it's kinda a solution. I'm not going to except my own answer right away to see if anyone can solve this a better way, or if you can explain why video.js changes the id tag and how to properly deal with it i'll give you an up vote and accept your answer if it all makes sense to me.

Why isn't my audio rewinding?

I'm having a bit of trouble rewinding audio in Javascript. I basically have a countdown that beeps each second as it gets towards the end of the countdown.
I tried using;
var bip = new Audio("http://www.soundjay.com/button/beep-7.wav");
bip.play();
but it didn't beep every second which I'm guessing has something to do withit having to load a new sound every second. I then tried loading the sound externally and triggering it with the following code.
bip.pause();
bip.currentTime = 0;
console.log(bip.currentTime);
bip.play();
but this only plays the sound once then completely fails to rewind it (this is shown by the console logging a time of 0.19 seconds after the first playthrough).
Is there something I'm missing here?
In google chrome I noticed that it only works if you have the audio file in same domain. I have no problems if the audio file is in same domain. Event setting .currentTime works.
Cross-domain:
var bip = new Audio("http://www.soundjay.com/button/beep-7.wav");
bip.play();
bip.currentTime; //0.10950099676847458
bip.currentTime = 0;
bip.currentTime; //0.10950099676847458
Same-domain:
var bip = new Audio("beep-7.wav");
bip.play();
bip.currentTime; //0.10950099676847458
bip.currentTime = 0;
bip.currentTime; //0
I tried googling for a while and could find nothing in specs about this or even any discussion.
when I want rewind I simply load the audio again:
my_audio.load()
*btw, I also use a eventlistener for 'canplay' to trigger the my_audio.play(). It seems that this is necessary in android, and maybe other devices also*
To further dsdsdsdsd's answer with a bit of paint-by-numbers for the "whole shebang"
NOTE: In my app, loc1 is a dummy that refers to the song's stored location
// ... code before ...
tune = new Audio(loc1); // First, create audio event using js
// set up "song's over' event listener & action
tune.addEventListener('ended', function(){
tune.load(); //reload audio event (and reset currentTime!)
tune.play(); //play audio event for subsequent 'ended' events
},false);
tune.play(); // plays it the first time thru
// ... code after ...
I spent days and days trying to figure out what I was doing wrong, but it all works fine now... at least on the desktop browsers...
As of Chrome version 37.0.2062.120 m, the behaviour described by #Esailija has not changed.
I workaround this issue by encoding the audio data in base64 encoding and feed the data to Audio() using data: URL.
Test code:
snd = new Audio('data:audio/ogg;base64,[...base64 encoded data...]');
snd.onloadeddata = function() {
snd.currentTime = 0;
snd.play();
setTimeout(function() {
snd.currentTime = 0;
snd.play();
}, 200);
};
(I am surprised that there are no bug reports or references on this matter... or maybe my Google-fu is not strong enough.)

JS .play() on iPad plays wrong file...suggestions?

So, I am building a web app that has a div with text that changes on various user actions (it's stepping through an array of pieces of text). I'm trying to add audio to it, so I made another array with the sound files in the appropriate positions:
var phrases=['Please hand me the awl.','etc1','etc2','etc3'];
var phrasesAudio=['awl.mp3','etc1.mp3','etc2.mp3','etc3.mp3'];
And on each action completion, a 'counter' variable in incremented, and each array looks for the object at that counter
var audio = document.createElement("audio"),
canPlayMP3 = (typeof audio.canPlayType === "function" &&
audio.canPlayType("audio/mpeg") !== "");
function onAction(){
correct++;
document.getElementById('speech').innerHTML=phrases[correct];
if(canPlayMP3){
snd = new Audio(phrasesAudio[correct]);
}
else{
snd = new Audio(phrasesAudioOgg[correct]);
}
snd.play();
}
(the text replaces a div's HTML and I use .play() for the audio object)...usually works okay (and ALWAYS does in a 'real' browser), but on the iPad (the actual target device) after a few successful iterations, the TEXT continues to progress accurately, but the AUDIO will hiccup and repeat a sound file one or more times. I added some logging and looking there it reports that it's playing screw.mp3 (just an example, no particular file is more or less error prone), but in actuality it plays screwdriver.mp3 (the prior file, if there is an error, the audio always LAGS, never LEADS)...because of this I am thinking that the problem is with my use of .play()...so I tried setting snd=null; between each sound, but nothing changed...Any suggestions for how to proceed? This is my first use of audio elements so any advice is appreciated. Thanks.
edit: I've also tried setting the files with snd.src (based on https://wiki.mozilla.org/Audio_Data_API) and this caused no audio to play
for iPad you need to call snd.load() before snd.play() - otherwise you get "odd" behaviour...
see for some insight:
http://jnjnjn.com/187/playing-audio-on-the-ipad-with-html5-and-javascript/
Autoplay audio files on an iPad with HTML5
EDIT - as per comment from the OP:
Here https://developer.mozilla.org/En/Using_audio_and_video_in_Firefox you can find a tip on halting a currently playing piece of media with
var mediaElement = document.getElementById("myMediaElementID");
mediaElement.pause();
mediaElement.src = "";
and, following that with setting the correct src, load(), play() works great

Categories

Resources