0

After searching a while for how to make audio tag to play a song from local machine, I found this solution (Play audio local file with html):

var $audio = $('#myAudio');
$('input').on('change', function(e) {
  var target = e.currentTarget;
  var file = target.files[0];
  var reader = new FileReader();

  console.log($audio[0]);
   if (target.files && file) {
        var reader = new FileReader();
        reader.onload = function (e) {
            $audio.attr('src', e.target.result);
            $audio.play();
        }
        reader.readAsDataURL(file);
    }
});

And html:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="file">
<audio controls id="myAudio" autoplay></audio>

The above code looks good for one file. The question is that is there a good way to load multiple files from input to make the audio play them like a playlist, without creating multiple instances of FileReader simultaneously? Something like storing the files in array first, and then feeding src or audio from that array.

Lamar
  • 1,761
  • 4
  • 24
  • 50
  • input elements can allow selection of multiple files. Why do you want to do this though? If the files are held on the local machine the user can just play them with any media player they like, and have full control – ADyson May 24 '17 at 19:38
  • It's a fun project for creating a player in browser. I know I can select multiple files from file input, but how to add those file to the playlist? – Lamar May 24 '17 at 19:39
  • i guess you would get the list of selected files in an array, and alter the source of the audio control to the next one whenever it finishes the last one? there are events to tell you when that happens https://developer.mozilla.org/en/docs/Web/Guide/Events/Media_events – ADyson May 24 '17 at 19:46
  • I think you can't just use the path of the files to load audio from local machine. That's why we need FileReader. – Lamar May 24 '17 at 19:52
  • 1
    i didn't say you didn't need it. but if you have an input with the "multiple" attribute specified, then `target.files` is an array potentially containing >1 entries. keep count of where you're up to in the array, and then when the previous audio completes, use Filereader to get the next item out of the array and play it (just like you do now with a single file). sorry, i thought that would become obvious – ADyson May 24 '17 at 20:11
  • Can you please provide an example. I have a vague idea but not sure how to implement it. – Lamar May 24 '17 at 20:21

1 Answers1

5

createObjectURL instead of new FileReader()

var songs = document.getElementById("songs"),
    myAudio = document.getElementById("myAudio");
function next(n){
  var url = URL.createObjectURL(files[n]);
  myAudio.setAttribute('src', url);
  myAudio.play();
}
var _next = 0,
    files,
    len;
songs.addEventListener('change', function() {
  files = songs.files;
  len = files.length;
  if(len){
    next(_next);
  }
});
myAudio.addEventListener("ended", function(){
   _next += 1;
   next(_next);
   console.log(len, _next);
   if((len-1)==_next){
     _next=-1;
   }
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="file" id="songs" multiple>
<audio controls id="myAudio" autoplay></audio>
alessandrio
  • 4,282
  • 2
  • 29
  • 40
  • Wow man! That's much easier than FileReader. Just for my information, can we still do it with FileReader, because every time I bind the target result it gives me: src(unknown) in audio tag? – Lamar May 24 '17 at 20:53
  • @Lamar It also can. But maybe it gives you unknown because it does not recognize the audio name – alessandrio May 24 '17 at 20:57
  • 1
    Thanks anyway, I'm marking this as solution since it looks much lighter than FileReader. – Lamar May 24 '17 at 21:02