Welcome to WebmasterWorld Guest from 54.226.32.234

Forum Moderators: open

Message Too Old, No Replies

Problems Playing HTML5 Audio

     

l008comm

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

10+ Year Member



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?

Fotiman

1:36 pm on Nov 17, 2011 (gmt 0)

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



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...
}

l008comm

5:10 pm on Nov 17, 2011 (gmt 0)

10+ Year Member



Oh yeah, i tried that too and had problems. I forgot about that one.

l008comm

11:50 pm on Nov 17, 2011 (gmt 0)

10+ Year Member



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.

Fotiman

12:40 am on Nov 18, 2011 (gmt 0)

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



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.
}
}

l008comm

12:49 am on Nov 18, 2011 (gmt 0)

10+ Year Member



Ok I'll try a try-catch again and post back.

l008comm

9:43 pm on Nov 18, 2011 (gmt 0)

10+ Year Member



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();
}
}

l008comm

9:44 pm on Nov 18, 2011 (gmt 0)

10+ Year Member



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.
 

Featured Threads

Hot Threads This Week

Hot Threads This Month