Welcome to WebmasterWorld Guest from 184.72.148.222

Forum Moderators: open

Message Too Old, No Replies

Problems Playing HTML5 Audio

     
9:33 am on Nov 17, 2011 (gmt 0)

Junior Member

10+ Year Member

joined:Nov 22, 2004
posts: 113
votes: 0


I've been updating my site and making it HTML5 compliant, plus upgrading the jQ/js, giving it a much smoother experience. One of the additions I've done is adding small subtle audio feedback cues. Like a computer that beeps when you do something wrong, so do my network tests beep when you submit invalid data. This is what I'm using for the HTML:

<audio id="audio_error" preload="auto">
<source src="http://<? echo $_SERVER['HTTP_HOST']; ?>/audio/error.ogg" type="audio/ogg">
<source src="http://<? echo $_SERVER['HTTP_HOST']; ?>/audio/error.mp3" type="audio/mp3">
</audio>


Then I play the audio with this:
document.getElementById('audio_error').play();

It works very well, with the obvious exception: IE.
Specifically, older versions of IE don't know how to support this, and so when you get to the play() command, all js stops. It's very annoying. I've eeked around this so far by always making the audio play command the last thing that is run. But as my scripts get more and more complicated, it's time that I need a real solution.

So I made a wrapper function, with the idea that I'd somehow check to see if .play() was supported, before trying to play the audio. If it's not supported, no worries, just do nothing. I already do some class-changing to give visual feedback. The audio is just a bonus.

So I tried two different things with my wrapper function, and neither worked. Neither would work reliably that is. They'd work, then not work, without me having made any more changes in code. And this odd behavior was not just in IE, these wrapper functions tanked even in modern browsers.


function play_a_sound($sound)
{
if (typeof play == "function")
{ document.getElementById($sound).play(); }
else
{ alert('audio fail'); }
}

and

function play_a_sound($sound)
{
if (window.HTMLAudioElement)
{ document.getElementById($sound).play(); }
else
{ alert('audio fail'); }
}


The $sound I passed to the function was simply a string of the ID of the sound I wanted to play.
The "alert()"s above are just for debugging, both functions would simply do nothing audio was not supported. But like I said, these two wrapper functions would not work reliably, not just in IE, but in modern browsers too. Sometimes they'd work, sometimes they wouldn't. Sometimes I'd get audio once, and not again.

Clearly I'm barking up the wrong tree here. What am I doing wrong?
1:36 pm on Nov 17, 2011 (gmt 0)

Senior Member from US 

WebmasterWorld Senior Member fotiman is a WebmasterWorld Top Contributor of All Time 10+ Year Member Top Contributors Of The Month

joined:Oct 17, 2005
posts: 4986
votes: 12


Have you tried just wrapping your play() call in a try/catch block?


try {
document.getElementById('audio_error').play();
}
catch(e) {
// Nothing to see here... move along...
}
5:10 pm on Nov 17, 2011 (gmt 0)

Junior Member

10+ Year Member

joined:Nov 22, 2004
posts: 113
votes: 0


Oh yeah, i tried that too and had problems. I forgot about that one.
11:50 pm on Nov 17, 2011 (gmt 0)

Junior Member

10+ Year Member

joined:Nov 22, 2004
posts: 113
votes: 0


Is there possibly something wrong with the way I'm passing the ID of the audio element to my function?

function play_a_sound($sound)
{
document.getElementById($sound).play();
}


And calling that simply like so:
play_a_sound("audio_done");

It seems like play can't find the ID I'm looking for *sometimes*, but only when it's in my wrapper function. When I call play directly, it always works in browsers that support it.
12:40 am on Nov 18, 2011 (gmt 0)

Senior Member from US 

WebmasterWorld Senior Member fotiman is a WebmasterWorld Top Contributor of All Time 10+ Year Member Top Contributors Of The Month

joined:Oct 17, 2005
posts:4986
votes: 12


Well, the audio element in your first example has an ID of "audio_error" vs. "audio_done" as in your last example (but I'm assuming you just have another audio element with that ID as well).

I would change it to this, though:


function play_a_sound($sound)
{
try {
document.getElementById($sound).play();
}
catch (e) {
// If IE thinks that the element can't be found or
// doesn't have a play method, an null exception
// may stop the code, so catch it and do nothing.
// This will prevent the JavaScript from stopping
// all execution entirely.
}
}
12:49 am on Nov 18, 2011 (gmt 0)

Junior Member

10+ Year Member

joined:Nov 22, 2004
posts: 113
votes: 0


Ok I'll try a try-catch again and post back.
9:43 pm on Nov 18, 2011 (gmt 0)

Junior Member

10+ Year Member

joined:Nov 22, 2004
posts: 113
votes: 0


I friend clued me in to this code which works perfectly for me:


function play_a_sound($name)
{
if (document.createElement('audio').canPlayType)
{
document.getElementById($name).play();
}
}
9:44 pm on Nov 18, 2011 (gmt 0)

Junior Member

10+ Year Member

joined:Nov 22, 2004
posts: 113
votes: 0


So I just want to comment that this forum's code-tag really ought to do a LITTLE more to differentiate between code and regular text. You can barely see the difference. At least give code a very light grey background color. Also it would be much more useful of tabs were preserved.
 

Join The Conversation

Moderators and Top Contributors

Hot Threads This Week

Featured Threads

Free SEO Tools

Hire Expert Members