How to know that the file has reached the end with Filereader()?

Asked

Viewed 449 times

2

I’m making a system that when the file has just been read opens the next file, the files are MP3 and wanted to play a sequence of songs whenever one finishes. How to do this with Filereader()?

I tried to reader.onloadend = (function() {}); but it didn’t work, as soon as the file is loaded it already performs the function, I need it to run only when it finishes being read...

Code to date:

<input type="file" id="file" multiple="multiple">
<button id="openNewSessionButton" disabled>Open New Room</button><br />
<script>
var connection = new RTCMultiConnection('stream');
connection.session = {
    audio: true,
    oneway: true
};

// connect to signaling gateway
connection.connect();

// open new session
$("#openNewSessionButton").click(function() {
    connection.open();
});

$("#file").change(function() {
var fileA = this.files[0];
var fileB = this.files[1];
readFile3(fileA);
});

function readFile3(file){
    var file1 = URL.createObjectURL(file);
    var context = new AudioContext(),
        buffer;

    var playAudioFile = function (buffer) {
        var source = context.createBufferSource();
        source.buffer = buffer;
        source.connect(context.destination);
        source.start(0); // Play sound immediatel
        var destination = context.createMediaStreamDestination();
        source.connect(destination);

                        connection.attachStreams.push(destination.stream);
                        connection.dontAttachStream = true;
                        $("#openNewSessionButton").removeAttr('disabled');



            var current2 = source.buffer.duration;
            var n = Math.floor(current2);
            var b = n * 1000;

            var timer = setTimeout(function(e) {

            readFile3(fileB); //THIS LINE ? IS CORRECT ?

            }, b);
    };

    var loadAudioFile = (function (url) {
        var request = new XMLHttpRequest();

        request.open('get', file1, true);
        request.responseType = 'arraybuffer';


        request.onload = function () {
                context.decodeAudioData(request.response, function(incomingBuffer) {

                        playAudioFile(incomingBuffer);

                     }
                );
        };

        request.send();

    }());
</script>
  • 1

    How strange... I have one example on my website, and use readAsArrayBuffer with the event onload and everything works well. The file is already in memory when onload is executed. Take a look at the function loadIntoMemoryAndPlay, line 294 of the page (tested OK on Chrome, Firefox and Opera).

  • 1

    You really need to use one FileReader()? Can you play the audio via another method? If so, take a look at the function prepareStreamingAndPlay of my example, line 314 of the file.

  • 1

    Just one detail... I’ve been editing the example, and now the line numbers are 302 (loadIntoMemoryAndPlay) and 339 (prepareStreamingAndPlay) :)

  • Hi @carlosrafaelgn, I saw your examples and found it really cool and I even changed the system I was using, but I can’t move to the next track when the first one ends, I edited the question and added the code I’m using now......

  • @carlosrafaelgn got some result...I will post the answer...

  • Funny, really! Looks like an unsolved bug... : P

Show 1 more comment

2 answers

1

There’s a difference between carry and execute.

I believe you’ve already succeeded carry correctly all files, in sequence, to memory. Filereader functionality ends there; Javascript has access to bits of files chosen by the user.

The next step, which is effectively execute these files, is where you are struggling. And the news is not good. Even if you used the correct event (which by the way is the onended(), in your Audiobuffer buffer, as in the code that follows), it seems that it is not very well implemented in the browsers yet. Too bad! Follow the change for you to try:

// Import callback function that provides PCM audio data decoded as an audio buffer
context.decodeAudioData(e.target.result, function (buffer) {
    // ...
    // Aqui vai a modificação:
    buffer.onended = function(){
        console.log("Uma música acabou... Iniciar a próxima?");
    }
    // ...
});

If by some miracle this works, it would be good to report back to the rest of the staff knowing that it is already implemented, and in WHICH browser :)

  • Hi @Rui Pimentel, I did some tests and it doesn’t really work...!

0


I got results and I’m working on the system, the error was very simple, I was trying to run the function readFile3(); with the variable not set, I only had to put the function inside the $("#file"). change(); where the variable was set, thus:

<input type="file" id="file" multiple="multiple">
<script>

var connection = new RTCMultiConnection('stream');
connection.session = {
    audio: true,
    oneway: true
};


// connect to signaling gateway
connection.connect();


$("#file").change(function() {

$(this).attr('disabled','disabled');

var fileA = this.files[0];
var fileB = this.files[1];
readFile3(fileA);


function readFile3(file){
    file1 = URL.createObjectURL(file);
    var context = new AudioContext(),
        buffer;

    var playAudioFile = function (buffer) {
        var source = context.createBufferSource();
        source.buffer = buffer;
        source.connect(context.destination);
        source.start(0); // Play sound immediatel
        var destination = context.createMediaStreamDestination();
        source.connect(destination);

                        connection.attachStreams.push(destination.stream);
                        connection.dontAttachStream = true;
                        connection.open();


            var current2 = source.buffer.duration;
            var n = Math.floor(current2);
            var b = n * 1000;

            var timer = setTimeout(function(e) {

            connection.close();
            readFile3(fileB);
            $("#result").html("TRANSMITINDO 2");

            }, b);
    };

    var loadAudioFile = (function (url) {
        var request = new XMLHttpRequest();

        request.open('get', file1, true);
        request.responseType = 'arraybuffer';


        request.onload = function () {
                context.decodeAudioData(request.response, function(incomingBuffer) {

                        playAudioFile(incomingBuffer);

                     }
                );
        };

        request.send();

    }());
};
});
</script>

Chava is a Timeout with the time of mp3, as explained here : http://updates.html5rocks.com/2012/01/Web-Audio-FAQ

Browser other questions tagged

You are not signed in. Login or sign up in order to post.