change <audio> src with javascript

127,255

Solution 1

Try this snippet

list.onclick = function(e) {
  e.preventDefault();

  var elm = e.target;
  var audio = document.getElementById('audio');

  var source = document.getElementById('audioSource');
  source.src = elm.getAttribute('data-value');

  audio.load(); //call this to just preload the audio without playing
  audio.play(); //call this to play the song right away
};
<ul style="list-style: none">
  <li>Audio Files
    <ul id="list">
      <li><a href="#" data-value="http://media.w3.org/2010/07/bunny/04-Death_Becomes_Fur.oga">Death_Becomes_Fur.oga</a></li>
      <li><a href="#" data-value="http://media.w3.org/2010/07/bunny/04-Death_Becomes_Fur.mp4">Death_Becomes_Fur.mp4</a></li>
      <li><a href="#" data-value="http://media.w3.org/2010/11/rrs006.oga">rrs006.oga</a></li>
      <li><a href="#" data-value="http://media.w3.org/2010/05/sound/sound_90.mp3">sound_90.mp3</a></li>
    </ul>
  </li>
</ul>

<audio id="audio" controls="controls">
  <source id="audioSource" src=""></source>
  Your browser does not support the audio format.
</audio>

JSFiddle http://jsfiddle.net/jm6ky/2/

Solution 2

with jQuery:

 $("#playerSource").attr("src", "new_src");

    var audio = $("#player");      

    audio[0].pause();
    audio[0].load();//suspends and restores all audio element

    if (isAutoplay) 
        audio[0].play();

Solution 3

Try this:

Replace:

audio.load();

with:

audio.play();

Solution 4

Here is how I did it using React and CJSX (Coffee JSX) based on Vitim.us solution. Using componentWillReceiveProps I was able to detect every property changes. Then I just check whether the url has changed between the future props and the current one. And voilà.

@propTypes =
    element: React.PropTypes.shape({
         version: React.PropTypes.number
         params:
             React.PropTypes.shape(
                 url: React.PropTypes.string.isRequired
                 filename: React.PropTypes.string.isRequired
                 title: React.PropTypes.string.isRequired
                 ext: React.PropTypes.string.isRequired
             ).isRequired
     }).isRequired

componentWillReceiveProps: (nextProps) ->
    element = ReactDOM.findDOMNode(this)
    audio = element.querySelector('audio')
    source = audio.querySelector('source')

    # When the url changes, we refresh the component manually so it reloads the loaded file
    if nextProps.element.params?.filename? and
    nextProps.element.params.url isnt @props.element.params.url
        source.src = nextProps.element.params.url
        audio.load()

I had to do it this way, because even a change of state or a force redraw didn't work.

Solution 5

If you are storing metadata in a tag use data attributes eg.

<li id="song1" data-value="song1.ogg"><button onclick="updateSource()">Item1</button></li>

Now use the attribute to get the name of the song

var audio = document.getElementById('audio');
audio.src='audio/ogg/' + document.getElementById('song1').getAttribute('data-value');
audio.load();
Share:
127,255
Jmh2013
Author by

Jmh2013

I am a Software Engineer primarily doing front end development.

Updated on August 16, 2021

Comments

  • Jmh2013
    Jmh2013 almost 3 years

    I have multiple audio files that I want to stream based on the user selects. How do I do that? This is what I have so far and it doesn't seem to work.

    *UPDATE: Made a few changes and now its claiming that audio.load(); is not a function. Can anyone tell me why that is? The Code is updated to reflect the changes.

    JavaScript:

    function updateSource(){ 
        var audio = document.getElementById('oggSource');
        audio.src = 
            'audio/ogg/' + 
            document.getElementById('song1').getAttribute('data-value');
        audio.load();
    }
    

    HTML:

    <audio id="audio" controls="controls">
        <source id="oggSource" src="" type="audio/ogg"></source>
        <source id="mp3Source" type="audio/mp3"></source>
            Your browser does not support the audio format.
    </audio>
    
    <ul style="list-style: none">
        <li>Sunday May 27, 2012
            <ul style="display: none">
                <li id="song1" data-value="song1.ogg">
                    <button onclick="updateSource();">Item1</button>
                </li>
                <li>Item2</li>
                <li>Item3</li>
            </ul>
        </li>
    </ul>
    

    Item2 and Item3 I will want to play a different audio file when they are clicked on.

  • Jmh2013
    Jmh2013 about 12 years
    It still doesn't seem to work. Firebug is saying its getting a 500 because it looks like its passing %5Bobject%20HTMLLIElement%5D that in when it runs the document.getElementById('song1'); I'm not sure what that means.
  • Jmh2013
    Jmh2013 about 12 years
    FF and Chrome are now saying that audio.load() is not a function. Do you know why that is?
  • Musa
    Musa about 12 years
    @Fourthmeal70 Post your updated code so we can see what the problem is.
  • Jmh2013
    Jmh2013 about 12 years
    Now it complains that source is null. So it doesn't even get to the audio.load()
  • Jmh2013
    Jmh2013 about 12 years
    Nevermind, source was null because I mispelled the id in one place. But now it doesn't do anything. Firebug doesn't show any errors but it still isn't working. Not sure why.
  • Jmh2013
    Jmh2013 about 12 years
    I had to do both. Its working now but how to I make it so the media player show up?
  • Derek 朕會功夫
    Derek 朕會功夫 about 12 years
  • Jmh2013
    Jmh2013 about 12 years
    Adding src="" there makes it stop working. Firebug says its getting an invalid URI. But when src="" is not there it plays the song fine.
  • Derek 朕會功夫
    Derek 朕會功夫 about 12 years
    No no no, that src is just an example! You don't need to follow it. All I mean is that controls.
  • Jmh2013
    Jmh2013 about 12 years
    Yeah I am using your example. I just had to add audio.play() after I loaded the file. Now it plays the music, but I'd like the media player to show up, for some reason it stays hidden.
  • Jmh2013
    Jmh2013 about 12 years
    Oh! That was the only difference between what I already had and your example. I have controls there and it still does not show up.
  • Jmh2013
    Jmh2013 about 12 years
    Actually it shows up fine in Chrome. In FF it shows up once the song ends but not when it first starts.. Any Ideas?
  • Derek 朕會功夫
    Derek 朕會功夫 about 12 years
    Hmm... It works on my Firefox though. (maybe it is some where in your page you didn't notice)
  • Vitim.us
    Vitim.us about 12 years
    The player UI is different for each browser, in safari I can see a little black player. I'm not sure if firefox add a UI to the audio tag, but You can do the player UI yourself, and add buttons to player.play() player.pause() etc... including sliders and time stamp
  • Jmh2013
    Jmh2013 about 12 years
    Not that I see.. I guess I'll have to play around with it. My main issue has been resolved though. Thank you.
  • Jmh2013
    Jmh2013 about 12 years
    I realize it's different for each browser. It just seems odd that it only shows up in FF once the song ends, but shows up fine from the beginning in other browsers. I've never made a player UI myself, but it might be something I try to do.
  • loonix
    loonix almost 7 years
    Angular example: var video = angular.element('#audio'); if (audio){ audio.load(); }
  • Spankied
    Spankied almost 3 years
    Audio.load() triggers a render loop when adapted to libs like React.