5

I've looked at all the similar questions having to do with FileReader and readAsArrayBuffer() but haven't had any luck.

I'm trying to use the Web Audio API to read in a local mp3 file and process it with FileReader in order to use it for some music visualization.

This is what I have currently:

    var file = "../../audio/magic_coldplay.mp3";
    var fileReader = new FileReader();

    fileReader.onload = function (e) {
            var fileResult = e.target.result;
            visualizer.start(fileResult);
    };

    fileReader.onerror = function (e) {
        debugger
    };

    fileReader.readAsArrayBuffer(file);

I'm getting the error: "Failed to execute 'readAsArrayBuffer' on 'FileReader': parameter 1 is not of type 'Blob'."

So I guess file isn't a Blob. The examples I've seen online have the user uploading their own mp3 file. How can I make this work with a local mp3?

thanks for any pointers you may have!

4
  • 2
    What do you call local? On your server? So yes file here is a string, far from a File or Blob... If this string represents a valid URI pointing to the file, then you can do fetch(file).then(r=>r.blob()).then(blob=>fileReader.readAsArrayBuffer(blob)) Commented Sep 21, 2017 at 23:19
  • Yup on my server, running it locally right now. Commented Sep 21, 2017 at 23:22
  • So yes, fetch the data first, but actually, fetch it as arrayBuffer directly, don't even go through the fileReader. (I may write an answer when I'll get my hands back to a real keyboard) Commented Sep 21, 2017 at 23:24
  • That worked! So, just so I understand what's going on -- you're getting the file string, converting it to a blob, and then reading it as an array buffer? What do you mean by "don't even go through the fileReader" Thank you!! Commented Sep 21, 2017 at 23:27

1 Answer 1

5

In your code, file is a String, which would be better renamed url; FileReader doesn't know what to do with a String and thus will throw the error you've got.

Since this string is an URI pointing to a file, what you have to do is to fetch the data at the other hand of the URI.

For this, you've got at least two similar APIs: traditional XHR and more recent Fetch.

Both these APIs allow you to request the file as a Blob, so that you can use it with the FileReader API once fetched:

// traditional XHR
var xhr = new XMLHttpRequest();
xhr.open('get', url);
xhr.responseType = 'blob'; // we request the response to be a Blob
xhr.onload = function(e){
  fileReader.readAsArrayBuffer(this.response);
}
xhr.send();

// or newer Fetch
fetch(url)
  .then(resp => resp.blob())
  .then(blob => fileReader.readAsArrayBuffer(blob));

But in your case, what you need is the ArrayBuffer representation of this file. Both these APIs also provide an option to directly request the file as an ArrayBuffer, making the FileReader useless:

// traditional XHR
var xhr = new XMLHttpRequest();
xhr.open('get', url);
xhr.responseType = 'arraybuffer'; // directly as an ArrayBuffer
xhr.onload = function(e){
  visualizer.start(this.response); // no need to use a FileReader anymore
}
xhr.send();

// or newer Fetch
fetch(url)
  .then(resp => resp.arrayBuffer()
  .then(buf => visualizer.start(buf));
Sign up to request clarification or add additional context in comments.

2 Comments

Should this go underneath fileReader.onload = function (e)? I'm trying to figure out what fileResult is equal to
Actually - got it. visualizer.start(buf) works - does that sound right?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.