56

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.

Derek 朕會功夫
  • 84,678
  • 41
  • 166
  • 228
Jmh2013
  • 2,321
  • 2
  • 22
  • 36

6 Answers6

102

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/

Vitim.us
  • 16,145
  • 12
  • 81
  • 96
  • Now it complains that `source` is null. So it doesn't even get to the `audio.load()` – Jmh2013 May 29 '12 at 03:04
  • 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 May 29 '12 at 03:12
  • 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 May 29 '12 at 03:31
  • 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 – Vitim.us May 29 '12 at 03:51
  • 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. – Jmh2013 May 29 '12 at 14:18
  • Angular example: var video = angular.element('#audio'); if (audio){ audio.load(); } – Daniel C Jul 21 '17 at 14:46
4

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

Try this:

Replace:

audio.load();

with:

audio.play();
Derek 朕會功夫
  • 84,678
  • 41
  • 166
  • 228
2

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.

Vadorequest
  • 12,672
  • 17
  • 87
  • 183
1

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();
Musa
  • 89,286
  • 16
  • 105
  • 123
-1

change this

audio.src='audio/ogg/' + document.getElementById(song1.ogg);

to

audio.src='audio/ogg/' + document.getElementById('song1');
Satya
  • 8,182
  • 5
  • 30
  • 49
  • 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 May 29 '12 at 01:45