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);
}
Related
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
I am trying to figure out how to continuously play random audio sound bites, one after another without having them overlap on an HTML page using jquery. I have code that plays random sound bites on a timer, but sometimes they overlap and sometimes there is a pause in between the sounds. I had looked into ended and other EventListeners but I really have no idea what I am doing. Here is a portion my code:
<html>
<audio id="audio1">
<source src="cnn.mp3"></source>
</audio>
<audio id="audio2">
<source src="sonycrackle.mp3"></source>
</audio>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){
$('audio').each(function(){
this.volume = 0.6;
});
var tid = setInterval(playIt, 2000);
});
function playIt() {
var n = Math.ceil(Math.random() * 2);
$("#audio"+n).trigger('play');
};
Is there a way to just continuously play these sounds bites one after another right after the previous sound plays? FWIW I have many sound bites but I am just showing two above for reference.
So I dabbled a bit, here's a full pure JavaScript solution.
Should be cross-browser, haven't tested (/lazy). Do tell me if you find bugs though
var collection=[];// final collection of sounds to play
var loadedIndex=0;// horrible way of forcing a load of audio sounds
// remap audios to a buffered collection
function init(audios) {
for(var i=0;i<audios.length;i++) {
var audio = new Audio(audios[i]);
collection.push(audio);
buffer(audio);
}
}
// did I mention it's a horrible way to buffer?
function buffer(audio) {
if(audio.readyState==4)return loaded();
setTimeout(function(){buffer(audio)},100);
}
// check if we're leady to dj this
function loaded() {
loadedIndex++;
if(collection.length==loadedIndex)playLooped();
}
// play and loop after finished
function playLooped() {
var audio=Math.floor(Math.random() * (collection.length));
audio=collection[audio];
audio.play();
setTimeout(playLooped,audio.duration*1000);
}
// the songs to be played!
init([
'http://static1.grsites.com/archive/sounds/background/background005.mp3',
'http://static1.grsites.com/archive/sounds/background/background006.mp3',
'http://static1.grsites.com/archive/sounds/background/background007.mp3'
]);
Some quick suggestions is add the attribute preload="auto" to the audio element and change the script to be $(window).onload instead of document ready. Document ready fires when html is in place but not necessarily when audio and other assets (like images) have loaded.
You could also look into using the AudioBuffer Interface in the new Web Audio API, it's described as "this interface represents a memory-resident audio asset (for one-shot sounds and other short audio clips)." which sounds like what you need. I believe part of the issues you're having (random pauses/delays/sound glitches with the audio element) are one of the reasons why it's being developed.
Read more here:
https://dvcs.w3.org/hg/audio/raw-file/tip/webaudio/specification.html#AudioBuffer
Unfortunately it's only Chrome and lastest Safari supported with Firefox support supposedly in the next 6(ish) months and no word yet on IE support.
hiii all,
this is my very first post on stackoverflow, I always used to be a guy sitting back and see what happens here, never contributed, but now i finally got a chance..
MY question is I have a swf file, and I am playing it on my html page using SWFObject,now I want to implement a javascript method which triggers when videos gets completely played or get stopped..
here's my code
<html><head>
<title>PENSIONS BOOST</title>
<script type="text/javascript" src="https://aimhighermarketing.s3.amazonaws.com/videocontrollers/swfobject.js"></script>
</head><body>
<div id="player" align="center">
<script type="text/javascript">
var so = new SWFObject('https://aimhighermarketing.s3.amazonaws.com/videocontrollers/player.swf','mp1','640','480','10');
so.addParam('allowscriptaccess','always');
so.addParam('allowfullscreen','true');
so.addVariable('frontcolor','FFFFFF');
so.addVariable('lightcolor','FFFFFF');
so.addVariable('screencolor','FFFFFF');
so.addParam('flashvars','&file=HTTP://soci7361#socialnetworkbizbuilder.com/videos/pbsalesvideov2.mp4&&controlbar=none&autostart=true');
so.write('player');</script>
</div>
</body>
</html>
,any kind of help is very much appreciated..
Kindly help..
Thanks
Would love to help you out, but unfortunately you are missing very important information. SWFObject is just a tool to place the object tag safely on the user's browser. Remember those days you had to click on the OBJECT tag in order to activate it? Well, SWFObject fixes that... and much more.
What we need to know is which video player are you using? Flash is actually what fires the events to a javascript, which is what you'd be listening for.
The most popular of them is usually JWPlayer or Flowplayer.
If you can let us know which one it is, or what kind of flash player you are using, I'd be happy to do some quick research for you.
Never mind, I just visited your SWF File and found it is JW Player 4.
Here is the JS Code to listen for event changes:
var player;
function playerReady(object) {
player = document.getElementById(object.id);
player.addModelListener("state","playerStateChanged");
}
function playerStateChanged(obj) {
if (obj.newstate == 'COMPLETED') {
// Your video has finished playing
} else if (obj.oldstate == 'IDLE' AND obj.newstate == 'PLAYING') {
// Your video started to play. Now, this is not fully accurate. IDLE can also mean they pressed STOP and sat there.
}
}
In all reality, you should have a "startedVideo = false;" and on the first play change it to true. Then you'll be able to tell when it was first started playing..
Even though JWPlayer is up to version 5, they do still have a full JS API Doc online:
JWPlayer 4 JavaScript API
I am wondering if there's a way to play audio when user exit my website?
for example. "thanks for visiting etc."
No, you can't reliably play audio when the user leaves the website. Although you can start it (using onbeforeunload), it won't finish playing.
And seriously, if you did, it would only irritate people. :-)
I did a little test(still novice to the whole HTML5) and came up with this solution:
<script>
function myLoadHandler(evt)
{
var audio_file1 = document.getElementById('audioID');
audio_file1.volume = 0
audio_file1.play();
}
if ("onpagehide" in window) {
window.addEventListener("pageshow", myLoadHandler, false);
} else {
window.addEventListener("load", myLoadHandler, false);
}
</script>
<script>
function playAudio() {
var audio_file1 = document.getElementById('audioID');
audio_file1.volume = 1
audio_file1.play();
}
</script>
<body onunload="playAudio()">
<div>
<div>
<audio id="audioID" src="your_audio.wav" preload="auto"></audio>
</div>
</div>
</body>
I tested it on latest Chrome and Firefox. Works only in Firefox-I guess that Chrome deletes all resources from memory quicker, than the javascript can execute.
Another weird thing is that even with preload="auto", the audio seems to actually buffer after it is played(either from script or from UI), so that's why I play it on load with volume 0.
And one more thing- like someone mentioned in the previous answer-it would probably be annoying. Use with caution.
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.