0

Im trying to build a simple audio player with the HTML5 audio tag. I have 3 <source> elements nested within the main <audio> element, each pointing to an audio track with multiple formats for cross-browser support. I am using a simple button to trigger a "click" event with the following code:

<audio id="myAudio" preload="none">
  <source src="audio/demo.m4a" type="audio/m4a" />
  <source src="audio/demo.mp3" type="audio/mp3" />
  <source src="audio/demo.ogg" type="audio/ogg" />
  <!-- other sources go here -->
</audio>

var audio = document.getElementById("myAudio");

// Change track!
$("#mute").on("click", function(evt) {
    $("#myAudio > source:gt(2)").attr({ src: "audio/demo2.ogg" , type: "audio/ogg"});
    if(!audio.paused) {
        audio.pause();
        audio.play();
    }
});

As you may guess, I'm trying to change the third elements src attribute by applying a :gt(2) filter. Not only am I trying to increment the track, I am also trying to stop the current track from playing so the new track can start playing immediately when the button is pressed. So far this is not having any effect on my webpage.

1
  • make sure you call audio.load() after you switch sources Commented Oct 19, 2013 at 20:41

2 Answers 2

1

If I were you I would not worry about changing the original tag, and instead just use a second audio for demo2. For example:

<audio id="demo1" preload="none">
  <source src="audio/demo.m4a" type="audio/m4a" />
  <source src="audio/demo.mp3" type="audio/mp3" />
  <source src="audio/demo.ogg" type="audio/ogg" />
  <!-- other sources go here -->
</audio>
<audio id="demo2" preload="none">
  <source src="audio/demo2.m4a" type="audio/m4a" />
  <source src="audio/demo2.mp3" type="audio/mp3" />
  <source src="audio/demo2.ogg" type="audio/ogg" />
  <!-- other sources go here -->
</audio>

If you have a lot of these sounds you may want to generate the elements as necessary in javascript.
This code should be adapted for your needs - if you're going to have more than 2 demo sounds you should adapt the code to generate the appropriate ids.

var demo1 = $('#demo1').get();
var demo2 = $('#demo2').get();
//demo2
demo1.play();

// Change track!
$("#mute").on("click", function(evt) {
    demo1.pause();
    demo2.play();
});

If you want to do it the way you were originally going about it then this code should do the trick I think:

// Change track!
$("#mute").on("click", function(evt) {
    audio.pause();
    //not sure if this line will work as intended if you have more than 3 sources...
    $(audio).find("source:gt(2)").attr({ src: "audio/demo2.ogg" , type: "audio/ogg"});
    audio.load();
    audio.play();
});
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks, I didn't actually think of having multiple audio tags. The idea is that i will have more than two sounds to select, then hopefully I can generate some form sliders so the user can rate each sound from 1 - 10 then submit the final results to a server then back to me. Thats the next big part of my challenge! I'll have a play with the code and let you know how I get on.
0

I've had a play with the code and managed to skip to the next piece of audio. At first this didn't work, but as soon as I changed the :gt filter to 1 instead of 2 it successfully incremented the track. I tried two different lines of code for this to work and both seem to work, but my next challenge (as you mentioned) is to be able to increment to a third, fourth, fifth, ..., nth track, then possible skip back to previous tracks. Here is my working code so far:

// Change track!
$("#next").on("click", function(evt) {
    // Change the title of the track
    $("#title > p:last").text("Next Track!");
    // Pause current track
    audio.pause();
    // Load the next track and play it
    $(audio).find("source:gt(1)").attr({ src: "audio/demo2.ogg" , type: "audio/ogg"});
    //$("#myAudio > source:gt(1)").attr({ src: "audio/demo2.ogg" , type: "audio/ogg"});
    audio.load();
    audio.play();
});

I'm slightly confused by the difference of these lines of code below (the second line is commented as it doesn't play any audio at all):

// Get reference to the audio element
var audio = document.getElementById("myAudio");
//var audio = $('#myAudio').get();

Is there a fundamental difference between these lines of code, as I thought they would do the same thing? I know for definite that the second line returns an array.

Also, is there a method that I can call to reset/refresh the current audio track being played?

3 Comments

You're correct it appears - I was under the impression that $ele.get() returns $ele[0] but apparently it constructs a node list! Thanks for pointing that out
And by reset/refresh a track do you mean to switch to a track you already switched off?
Thanks, its okay now I just meant a button or something to reset the playhead of the current track playing if its half way through and somebody wants to reset it back to 0:00. Since all of my sounds are going to be at the most 20 secs long there is no need.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.