5

I have a WAV file in Blob and in order to convert it to MP3 I need to convert it to Int16Array first (to follow the example from here: https://github.com/zhuker/lamejs).

E.g.

var mp3encoder = new lamejs.Mp3Encoder(2, 44100, 128);
// instead of `var samples = new Int16Array(44100);` I want something like `var samples = new Int16Array(blob);`
var mp3Tmp = mp3encoder.encodeBuffer(samples);

Is this possible?

Alex Netkachov
  • 13,172
  • 6
  • 53
  • 85

1 Answers1

3

Provided you know the data is actually a blob of 16-bit ints, then yes, it's possible:

  1. Read the Blob into an ArrayBuffer via its arrayBuffer method (the original answer had to use FileReader, but now Blob has an arrayBuffer method; see the edit history if for some reason you have to support old environments without it):

    samples.arrayBuffer()
    .then(buffer => {
        // ...
    })
    .catch(error => {
        // ...handle/report error...
    });
    
  2. View the ArrayBuffer as an Int16Array via the Int16Array constructor:

    const data = new Int16Array(buffer);
    

Now data is the array buffer from the blob viewed as an Int16Array.

Something along these lines:

samples.arrayBuffer()
.then(buffer => {
    const data = new Int16Array(buffer);
    // ...use `data` here...
})
.catch(error => {
    // ...handle/report error...
});
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • 1
    Now I can upvote :) Note you can also use the onload event argument `.target.result` – Piou Aug 30 '19 at 08:18
  • Didn't work for me: Sometimes getting this error, sometimes it saves just "pssh" as mp3 Uncaught RangeError: byte length of Int16Array should be a multiple of 2 – MAZ Sep 28 '21 at 13:13
  • @DmitryMind - That error means that you don't have a blob containing 16-bit int values. If you did, its length would be a multiple of 2. From the first sentence of the answer: *"Provided you know the data is actually a blob of 16-bit ints..."* – T.J. Crowder Sep 28 '21 at 13:15
  • I'm getting blob from microphone via mediaRecorder, how can I control these values? – MAZ Sep 28 '21 at 13:18
  • @DmitryMind - I don't know, I haven't used it. But I wouldn't expect it to return 16-bit int values, looking at [the MDN docs](https://developer.mozilla.org/en-US/docs/Web/API/MediaStream_Recording_API) it seems more likely to be bytes. So you'd want a `Uint8Array` or an `Int8Array` instead of an `Int16Array` (if I'm correct about that). – T.J. Crowder Sep 28 '21 at 13:26