4

I am trying to use an html audio player where the src attribute swaps when a different song on the track list is selected to play.

I wrote the code below and it swaps the src in the player fine, but the actual song that the player plays doesn't update even though this new src url has been swapped.

Any ideas would be greatly appreciated.

<!-- PLAYER -->
<div id="player_container">
  <div id="player_wrapper">
    <audio id="player" controls>
      <source src="default_song_url" type="audio/ogg">              
      <source src="default_song_url" type="audio/mpeg">
      Your browser does not support the audio element.
    </audio>        
  </div>     
</div>


<!-- TRACK LIST (fed through a for loop for other songs) -->
 <tr>
  <td>Song title</td>
  <td><a class="play_song1">Play</a> </td>
         <script>
      $(document).ready(function(){
        $(".play_song1").click(function(){
          $("#player_wrapper source").attr("src", "song_1_url");
                                           });
      });
    </script> 
</tr>
user3903296
  • 189
  • 1
  • 2
  • 10

1 Answers1

2

UPDATE

Just added more details, a bigger playlist, and the use of an array for easier expansion. The next improvement would be JSON.

Using plain JavaScript is sometimes simpler than jQuery, like with audio and video.

  • Use getElementById to get reference to #player
  • then the .src attribute change by dot notation.
  • Then .load method is needed when you swap src
  • And .play of course.
  • Normally, I would use addEventListener for the click event but jQuery is easier.

Note: Although the src attribute is located on the <source>, notice I referred to the <audio> instead.

Also Note: I removed the ogg because mp3 is universal right now, and I don't see that changing for years to come.

Yet Another Note: Do not use <table> or any of it's interface (i.e. tr, th, td, etc...) for layout, they are used for data.

$(document).ready(function() {

  // Playlist is an array of 5 songs.²
  var playlist = ['balls.mp3', 'pf-righteous.mp3', 'fightclub.mp3', '111.mp3', '00.mp3'];

  // A delegated click event is on each li.song 
  // when triggered the following happens:
  $(".song").on('click', function(e) {

    // This prevents the anchors from jumping like they normally do.
    e.preventDefault();

    // $(this) is the li.song that was picked by user. Use .data()
    // to determine the li.song's index number.
    var song = $(this).data('idx');

    // Reference the audio element
    var ply = document.getElementById('player');

    // This url is the location where the mp3s reside.¹
    var base = 'http://glpjt.s3.amazonaws.com/so/av/';

    // Here the src is concatenated  
    // 1. The base¹ URL +
    // 2. The playlist array² index is machted with #playlist li.play.³ 
    // 3. After the new src is made, load() the player and play()
    ply.src = base + playlist[song];
    ply.load();
    ply.play();
  });
});
<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
</head>

<body>

  <div id="playerBox">
    <div id="playerLayer">

      <audio id="player" controls>
        <source src="http://glpjt.s3.amazonaws.com/so/av/pf-righteous.mp3" type="audio/mpeg">
      </audio>
    </div>

    <dl id="playlist">

      <dt>Playlist</dt>
      <!--Each list item has a unique data-idx='x' and an identical .song class.³-->
      <a href="#" data-idx="0" class="song">
        <dd>Play 0</dd>
      </a>
      <a href="#" data-idx="1" class="song">
        <dd>Play 1</dd>
      </a>
      <a href="#" data-idx="2" class="song">
        <dd>Play 2</dd>
      </a>
      <a href="#" data-idx="3" class="song">
        <dd>Play 3</dd>
      </a>
      <a href="#" data-idx="4" class="song">
        <dd>Play 4</dd>
      </a>
    </dl>

  </div>

  <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.2/jquery.min.js"></script>
zer00ne
  • 41,936
  • 6
  • 41
  • 68