Audio API to calculate the duration of several songs

3

I'm working on an player and I need to know how to calculate the length of multiple MP3s that are selected on the user's machine by a input of type file ?

EDIT:

Follow my current code and it does not return the correct value ...

var audioElement2 = document.createElement('audio');
var fill;
var tamanho = 0;
$("#file666").change(function() {
    fill = this.files.length;


    for (var i = 0; i < fill; i++) {
    file3[i] = this.files[i];

    fileB = URL.createObjectURL(file3[i]);
    audioElement2.setAttribute('src', fileB);

    $(audioElement2).on("loadedmetadata", function () {
    tamanho = tamanho + parseInt(audioElement2.duration);
    });

    }


    $("#musicas").html("Músicas Carregadas: " + fill + " (Tempo Total: " + tamanho + ")");
});

I'm trying to use a for loop with a variable by adding all mp3's but it does not work, it returns "0" as a result ...

JSFiddle

    
asked by anonymous 10.09.2014 / 22:05

3 answers

2

loademetadata is an event, so you almost did it: it is called and you need to increment a variable to store Total Time and update the user interface every time the event occurs.

Perhaps the best way is to link this variable to HTML , using AngularJS .

JSfiddle with code in link

HTML:

<input type="file" id="fileInputSelector" size="60" name="fileInputSelector" multiple>
<div id="musicas">Músicas Carregadas: 0 (Tempo Total: 0 segundos)</div>

Code

var tempoTotal = 0;

$("#fileInputSelector").change(function () {
    var quantidadeDeArquivos = this.files.length;
    for (var i = 0; i < quantidadeDeArquivos; i++) {
        var esteArquivo = this.files[i];
        fileB = URL.createObjectURL(esteArquivo);

        var audioElement2 = new Audio(fileB);
        audioElement2.setAttribute('src', fileB);
        audioElement2.onloadedmetadata = function (e) {
            tempoTotal = tempoTotal + parseInt(this.duration);
            $("#musicas").html("Músicas Carregadas: " + quantidadeDeArquivos + " (Tempo Total: " + tempoTotal + " segundos)");
            //alert("loadedmetadata" + tempoTotal);
        }
    }
    tempoTotal = 0;
});
    
13.09.2014 / 19:24
1

In html5 there is the property duration

In your case it would look something like:

duracao = audioElement.duration

Remembering that the return will be in seconds!

To convert from seconds to minutes / hours I use the moment .

follow code:

var seconds = audioElement.duration;
var duration = moment.duration(seconds, "seconds");

var time = "";
var hours = duration.hours();
if (hours > 0) { time = hours + ":" ; }

time = time + duration.minutes() + ":" + duration.seconds();
    
11.09.2014 / 00:42
1

To analyze the length of the MP3 file, the easiest (and perhaps even efficient) way is to iterate through all the selected files, read their contents and interpret the file header.

Data Read

Be file of type File , you can read data as follows:

var reader = new FileReader();
reader.onloadend = function(evt) {
    if (evt.target.readyState == FileReader.DONE) { // DONE == 2
        // evt.target.result; <-- contém os bytes lidos.
  }
};

var blob = file.slice(start, stop + 1); // start = 0, stop deve ser grande o suficiente.
reader.readAsBinaryString(blob);

Interpreting the Header

Now either you build a parser or use one that already exists. I recommend the mp3-parser . After making the reference to the downloaded JS, use:

var tags = mp3Parser.readTags(new DataView(/* bytes do mp3 */));

Now, just look at the tags variable to get all the information you want.

Putting together ...

The code for interpreting a single file will then look similar to:

var reader = new FileReader();
reader.onloadend = function(evt) {
    if (evt.target.readyState == FileReader.DONE) {
        var tags = mp3Parser.readTags(new DataView(evt.target.result));
        // basta analisar a variável tags.
  }
};

var blob = file.slice(start, stop + 1);
reader.readAsBinaryString(blob);

The analysis of the variable tags and the integration of the proposed code with the code of the question remain as an exercise; D

    
13.09.2014 / 19:14