JavaScript DOM audio not playing - javascript

Okay, I'm losing my mind here.
I'm trying to code a very simple player just for myself -- something crude but functional.
<button onclick="javascript:PlayAudio();">Play</button>
<script>
var audio = new Audio();
audio.src = "file.mp3"; // this file is in the same directory as the html page
var PlayAudio = function()
{
audio.play();
};
</script>
Should work, right? I know it's not the BEST way to do it, but here's the thing: I've rewritten this code a couple hundred times and nothing seems to be working. There aren't even any error codes/exceptions/whatever that I can find. The browser says it's loaded the file just fine. What's even weirder is when I check the paused member in the audio object, no matter how many times I call the play() method, it still returns true.
When I load the page just as a file in my browser, lo and behold, it plays! Just fine! But if I were to change the onclick event to audio.play();, it doesn't work anymore. I want to run this on a server though.
I promise you there is no additional code. No JQuery, no weird server plugins (not even PHP!). Just Apache, Windows, nothing else.
And I know the browser can play the audio because when I copy audio.src and go to the address, it'll play just fine. Even the protocol is fine; the HTTP:/// address is not trying to load the File:/// address and vice versa. (I need the audio to play as a DOM so I can randomize the audio file later on; I'm just trying to get my browser to play one stinkin' file in the first place.)
I know I can do this in HTML with some JavaScript, but I know this can work in pure javascript too (ignoring the <button>) because I've done this before a LONG time ago. So what changed?
I've also tried to load the definitions using window.onload, but that doesn't work neither.
So... what the heck? I'm am stupid or something? I can accept that; I just need to know.

I think it's because of the path to the mp3 file. Also, separate your HTML from JavaScript code like so:
HTML
<button id="btn">Play</button>
JavaScript
const btnSound = document.querySelector('#btn');
btnSound.addEventListener('click', () => {
const sound = new Audio('./file.mp3') // assuming it's in the directory
sound.play();
});

If you're trying to create a dynamic audio element in pure Javascript...
Create a div on your document to act as container for the dynamic tag
in JS, create the audio element then add to page (via adding it to Div container)
Then you can try a code setup like this...
<div id="container">
<button onclick="PlayAudio('file.mp3')">Play</button>
<div>
<script>
//#create new audio tag
var myAudioElement = document.createElement( "audio");
myAudioElement.setAttribute("controls", "true" );
//myAudioElement.setAttribute("id", "myAudioTag"); //# if you'll need access "by ID"
//# add element to page DOM
document.getElementById('container').appendChild( myAudioElement );
function PlayAudio ( inputURL) //# input is a String like "file.mp3"
{
myAudioElement.setAttribute("src", inputURL);
myAudioElement.play();
}
</script>
Note: To run the playAudio() function without clicking a button just call:
PlayAudio ( "someOtherFile.mp3" );
PS: Below is an example of a "better" approach. Better here means less headaches (more intuitive) but it uses the HTML that you want to avoid. Notice no .src is specified because you can still use JS to update such property by code.
<!DOCTYPE html>
<html>
<body>
<h1>Test Audio Playback </h1>
<audio id="myAudioTag" controls> <source src=" " type="audio/mpeg"> </audio>
<br>
<button onclick="PlayAudio();"> Play </button>
</body>
<script>
var audio = document.getElementById("myAudioTag");
audio.src = "file.mp3"; // this file is in the same directory as the html page
function PlayAudio() { audio.play(); }
//# call this function whenever track must be changed
//# example use: changeAudio( "https://example.com/files/song2.mp3" );
function changeAudio( inputURL) //is a String of some other mp3 file
{
audio.src = inputURL;
audio.play();
}
</script>
</html>

Write your code like this
<button onclick="PlayAudio();">Play</button>
<script>
var PlayAudio = function()
{
var audio = new Audio("file.mp3")
audio.play();
};
</script>
If it still does not work then also try to write onClick

Related

Creating play/pause functions with current audio javascript

I have an extension for chrome I am working on, I have an HTML popup that has buttons that play audio. I don't think my approach is the most elegant and I am having trouble exploring ways to shrink this down. I know this is very inefficient. I want to be able to tell which button was clicked on the HTML page, then using that ID play the audio file with that same ID. The way I have it now is using the EventListener in javascript to use multiple functions to stop or play. Is there a way to put all of this in one function through javascript or jquery to fix this chaos? Since I am doing this on a chrome extension I cannot use Javascript in the HTML document.
Currently I have my HTML like this;
<script type="text/javascript" src="js/audio.js"></script>
Stop Audio
Audio 1
Audio 2
Audio 3
My JS file like this to create the variables for my audio files.
var aud1 = new Audio();
var aud2 = new Audio();
var aud3 = new Audio();
Along with this function to start playback when a button is selected with the coresponding name.
function aud1play() {
aud1.src = "mp3/aud1.mp3";
aud1.play();
}
document.getElementById('aud1').addEventListener('click', aud1play);
//you get the trend
To stop my audio I have the following function:
function audstop() {
aud1.pause;
aud2.pause;
aud3.pause;
document.getElementById('stopbutton').addEventListener('click', audstop);
var audios= Array.prototype.map.call(document.getElementsByClassName("myButton"),function(el){
var audio=new Audio();
audio.preload="none";//=> not preloaded
audio.src="mp3/"+el.id+".mp3";
el.onclick=audio.play.bind(audio);
return audio;
});
Simply iterate over your buttons, create an audio element with the right src for it, and bind the onclick listener to its play function. Then map the audio elements.
document.getElementById('stopbutton').addEventListener('click', function(){
audios.forEach(audio=>audio.pause());
});
To stop, simply iterate over the audio elements and call the stop function on each...

Preload Javascript audio to play in script

I have a simple program where I run this script:
function PlayAudio(Location){
var audio = new Audio(Location);
audio.Play()
}
in an onclick HTML attribute. I have a fancy loading picture that I know how to make appear and have successfully made it work. I would like to show this picture while the audio is loading, and then make it go away after the audio file is done loading and ready to play. Right now, there is a considerable delay between clicking the element and hearing the sound.
My trouble is knowing when the audio is done loading and ready to play. I figure the best way to know when it's complete loading is to preload the file in-script. I don't know how to do that.
And that's my question:
How do you preload files inside a script?
Or, is there a way to know when an audio file is finally playing?
Note: I cannot use an <audio> element, unless there is some way to nest a <div> inside the <audio> so that the sound in the <audio> is triggered by clicking anywhere in the content of the <div>
Sorry for my slightly confusing descriptions!
Thanks,
Lucas N
You can use canplaythrough event
Sent when the ready state changes to CAN_PLAY_THROUGH, indicating that
the entire media can be played without interruption, assuming the
download rate remains at least at the current level.
function PlayAudio (Location){
var audio = new Audio;
audio.oncanplaythrough = function(event) {
// do stuff, e.g.; set loading `img` `style` `display` to `none`
this.play();
}
audio.src = Location;
}
You change its preload attr by
. audio.preload = "auto";
It will load the whole audio file on start

How to make MPEG-DASH video loop

If playing an MPEG Dash video using dash.js, is it possible to make it loop, i.e. when the video has downloaded fully, replay the downloaded content, without having to download any more data or possibly just raising the resolution if possible, but this is not essential.
The standard code for displaying this is:
<div>
<video id="videoPlayer"></video>
</div>
<script src="https://cdn.dashjs.org/v2.0.0/dash.all.min.js"></script>
<script>
(function(){
var url = "./Videos/146252.mpd";
var player = dashjs.MediaPlayer().create();
player.initialize(document.querySelector("#videoPlayer"), url, true);
})();
</script>
The video element has a loop attribute. Have you tried setting it?

Generate sound using JavaScript

I am trying to generate sound using JavaScript. I have used the following code
<html>
<script type="text/javascript" src="jquery-1.4.2.js"></script>
<script>
function PlaySound(soundObj) {
var sound = document.getElementById(soundObj);
sound.Play();
}
function init() {
//alert("");
PlaySound('sound1')
}
window.onload = init;
</script>
<body>
<form name="myform">
<input type=button id="b1" name="b1name" value="Play Sound" onClick="PlaySound('sound1')">
</form>
Move mouse here
<embed src="beep-5.wav" autostart="false" width="0" height="0" id="sound1" enablejavascript="true">
</body>
</html>
Sound is being generated on button click and on mouseover. It is not being generated in the init function. If I call the below function in another JavaScript function, it does not work. Another point is that if I keep alerting before calling, then sound comes.
PlaySound('sound1')
I have tried using $("#b1").click(); (button click in JavaScript) but it's not working.
I know this is duplicate of this question, but the answer there did not work for me. I am really confused. Please help out.
Can I play this sound twice at a time?
The sound file may not have finished loading when init is called, but if you include an alert or when you manually click a button, there is enough time in between for the browser to have loaded the file.
That being said, embed is a non-standard and deprecated tag, and you really shouldn't be using it for playing sounds. Have a look at the HTML5 audio tag instead.
If you want a web page to play a sound via JavaScript, and you want the page to:
validate
work in all modern browsers
work across multiple platforms
work without plugins
The answer is simple: you can't do it. End of story.
Sure, you can come up with an example that works in one version of one browser on one platform, but I'll guarantee you: it won't work everywhere.
a fast and dirty way (it also compatible with old browsers, even IE5) is to use can embedded a small wave file inside your javascript which then could be played as a resources (without saving to actual file), use binary encoding (same as embedding PNG into JS).
a better way is building a JS Audio object, playing a bit (with buffer) that can be generated any frame-sound you'll like...
use JS Audio Object
var output = new Audio();
output.mozSetup(1, 44100);
var samples = new Float32Array(22050);
for (var i = 0, l = samples.length; i < l; i++) {
samples[i] = Math.sin(i / 20);
}
(also here)
If we generate sound using jquery sound plug in, http://plugins.jquery.com/project/sound_plugin playing sound on start up/java script without much delay. Working fine in IE and firefox.
By Introducing delay according to comment by casablanca, sound is playing in java script.Here is the code i have added:
This referring link Introduce delay
function callback(){
return function(){
PlaySound('sound1');
}
}
function init() {
// alert("");
setTimeout(callback(), 500);
}

Playing dynamically embedded sound object via Javascript

I need to background load some WAV files for an HTML page using AJAX. I use AJAX to get the details of the WAV files, then use the embed tag, and I can confirm that the files have loaded successfully because when I set autostart to true, the files play. However, I need the files to play only when the user clicks on a button (or an event is fired). The following is my code to preload these files:
function preloadMedia() {
for(var i = 0; i < testQuestions.length; i++) {
var soundEmbed = document.createElement("embed");
soundEmbed.setAttribute("src", "/media/sounds/" + testQuestions[i].mediaFile);
soundEmbed.setAttribute("hidden", true);
soundEmbed.setAttribute("id", testQuestions[i].id);
soundEmbed.setAttribute("autostart", false);
soundEmbed.setAttribute("width", 0);
soundEmbed.setAttribute("height", 0);
soundEmbed.setAttribute("enablejavascript", true);
document.body.appendChild((soundEmbed));
}
}
I use the following code to play the file (based on what sound file that user wants to play)
function soundPlay(which) {
var sounder = document.getElementById(which);
sounder.Play();
}
Something is wrong here, as none of the browsers I have tested on play the files using the code above. There are no errors, and the code just returns.
I would have left it at that (that is - I would have convinced the client to convert all WAV's to MP3 and use MooTools). But I realized that I could play the sound files, which were not dynamically embeded.
Thus, the same soundPlay function would work for a file embeded in the following manner:
<embed src="/media/sounds/hug_sw1.wav" id="sound2" width="0" heigh="0" autostart="false" enablejavascript="true"/>
anywhere within the HTML.
And it plays well in all the browsers.
Anyone have a clue on this? Is this some sort of undocumented security restriction in all the browsers? (Please remember that the files do get preloaded dynamically, as I can confirm by setting the autostart property to true - They all play).
Any help appreciated.
Hmm.. perhaps, you need to wait for the embed object to load its "src" after calling preloadMedia() ?
Are you sure that the media file is loaded when you call soundPlay() ?
i know your question got a bit old by now, but in case you still wonder...
soundEmbed.setAttribute("id", testQuestions[i].id);
you used the same id twice, yet getElementById returns only one element, or false if it doesn't find exactly one matching element.
you could try something like this:
soundEmbed.setAttribute("id", "soundEmbed_"+testQuestions[i].id);
always keep in mind that an id must be unique
Just a tip for more compatibility:
I read here that width and height need to be > 0 for Firefox on MacOS.

Categories

Resources