6

I have a couple of audio elements that appear in the body of my page. They look like this.

      <audio id="sound1" preload="auto">
      <source id="sound1source" src="../../Content/Audio/gau.mp3">
      //add .ogg here later
      </audio>
      <audio id="sound2" preload="auto">
      <source id="sound2source" src="../../Content/Audio/mah.mp3">
      //add .ogg here later
      </audio>

The audio plays when a user mouses over certain divs. Here's the code that triggers it.

var audio = $("#sound1")[0];
$("#ChoiceA").mouseenter(function () {
    audio.play();
});
var audio2 = $("#sound2")[0];
$("#ChoiceB").mouseenter(function () {
    audio2.play();
});

Everything above works fine. My problem occurs when I attempt to dynamically change the source element after making an ajax call. Here's my javascript that accomplishes that.

var src1 = "../../Content/Audio/" + data.nouns[0].Audio1 + ".mp3";
var src2 = "../../Content/Audio/" + data.nouns[1].Audio1 + ".mp3";

$("#sound1source").attr("src", src1);
$("#sound2source").attr("src", src2);

When I inspect the page after triggering the ajax call to change the source path for the audio elements, I see that the source is updated. No problem there. The problem is that the audio that the new paths point to does not play.

After hunting around I found this note on w3.org "Dynamically modifying a source element and its attribute when the element is already inserted in a video or audio element will have no effect. To change what is playing, either just use the src attribute on the media element directly, or call the load() method on the media element after manipulating the source elements."

The comment on w3.org seems to be related so I tried calling $('#sound1').load() and also $('#sound1source').load(). Neither solved my problem.

Can someone tell me what I've done wrong? If I need to cause the audio element to load again after dynamically changing the src, how do I do that?

-------------UPDATE-------------

Based on Swatkins suggestion I created the following function to create the audio tag when the user mouses over the target div. Unfortunately this has not solved the problem either.

    function attachAudio1(src) {

        $('#audio1').remove();
        var audio = $('<audio>');
        audio.attr("src", src);
        audio.attr("id", "audio1");
        audio.appendTo('body');
        attachPlayAction();
    };

    function attachPlayAction() {
        var audio = $("#audio1")[0];
        $('#ChoiceA').live('mouseenter', function () {
            audio.play();
        });


    };
hughesdan
  • 3,019
  • 12
  • 57
  • 80

3 Answers3

13

You should call load like this:

var audio = $("#sound1")[0];
$("#ChoiceA").mouseenter(function () {
   audio.load();
   audio.play();
});
var audio2 = $("#sound2")[0];
$("#ChoiceB").mouseenter(function () {
   audio.load();
   audio2.play();
});

Have not tested doing it like above, but have testet this previously with a seperate function looking something like this:

<audio id="sound1" preload="auto" src="../../Content/Audio/gau.mp3">

function changeAudio(){
    audio = document.getElementById("sound1");
    audio.src = "../../Content/Audio/" + data.nouns[0].Audio1 + ".mp3";
    audio.load();
    audio.play();
}

$("#ChoiceA").mouseenter(function () {
    changeAudio();
});

and that worked fine for me?


EDIT: Adding a fiddle, maybe that will help you figure this out?

http://jsfiddle.net/Z3VrV/

adeneo
  • 312,895
  • 29
  • 395
  • 388
  • I tried it like your first example and it's still not working. Your second example will take some time to implement the way my code is currently organized. – hughesdan Oct 07 '11 at 23:00
  • You could do something temporary to test this by just adding it to the html with the onmouseover event, like this maybe: onmouseover="document.getElementById('sound1').src='../../Content/Audio/someother.mp3';" and see if changes the sound and starts playing it. – adeneo Oct 07 '11 at 23:28
0

load() followed by play() right away leads to trouble. Trying listening for the canplay event before attempting to play the audio as suggested in https://stackoverflow.com/a/8705478/1374208

Community
  • 1
  • 1
titicaca
  • 61
  • 1
  • 3
0

This is tricky. I would try replacing the whole <audio> element instead of just changing its source. This way, the new audio element hasn't been added to the page, so it will be forced to load the file.

swatkins
  • 13,530
  • 4
  • 46
  • 78
  • Thanks for the suggestion. Unfortunately it doesn't solve the problem either. See above for the example function I used to test this. – hughesdan Oct 08 '11 at 01:26
  • Correction...it doesn't work in Firefox. In Chrome this approach works somewhat. The first audio plays fine. Then when the first audio is replaced with the second the result is that they play on top of each other. Maybe the browser is doing some weird caching? – hughesdan Oct 08 '11 at 02:15
  • Firefox does not support MP3 in the audio tag, have you tried another file format. – adeneo Oct 09 '11 at 11:58
  • My issue in the above comment had to do with the fact that I did not call .die to remove the old mouseover event. The firefox issue I think is also related to how I'm attaching the mouseover event. – hughesdan Oct 10 '11 at 21:42