Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

haxe.io.Bytes.getData(): BytesData != ArrayBuffer #173

Open
derRaab opened this issue Sep 4, 2020 · 2 comments
Open

haxe.io.Bytes.getData(): BytesData != ArrayBuffer #173

derRaab opened this issue Sep 4, 2020 · 2 comments

Comments

@derRaab
Copy link

derRaab commented Sep 4, 2020

Hi! I'm not sure if that is even an issue, but it took me a while to understand the difference between the Browser based implementation and the one used by node (electron). So I figured others might run into this very specific case as well:

In a nutshell this is the actual runtime difference: Bytes.getData() returns ArrayBuffer in the browser but Buffer in node (electron):

// Browser:
haxe.io.Bytes.getData() : js.lib.ArrayBuffer
// Node (electron):
haxe.io.Bytes.getData() : js.node.Buffer

If you're interested - first the JavaScript runtime error I ran into:

Uncaught (in promise) TypeError: Failed to execute 'decodeAudioData' on 'BaseAudioContext': parameter 1 is not of type 'ArrayBuffer'.
    at AudioContextWaveformVc._onArrayBuffer (AudioContextWaveformVc.hx:126)

This is my little handler causing problems where _audioContext is an AudioContext instance:

function _onArrayBuffer( arrayBuffer : ArrayBuffer ) {
    _audioContext.decodeAudioData( arrayBuffer, _onDecodeAudioSuccess, _onDecodeAudioError );
}

This is my bytes receiving handler, which extracts the needed ArrayBuffer and forwards it:

function _onBytes( data : Bytes ): Void {
    var arrayBuffer : ArrayBuffer = data.getData();
    _onArrayBuffer( arrayBuffer );
}

So if I use Google Chrome and Http to load the bytes it works fine:

var http : Http = new Http( url );
    http.onBytes = _onBytes;
    http.request( true );

BUT if I use the File API to read the bytes, decoding audio throws the TypeError:

var bytes : Bytes = File.getBytes( path );
_onBytes( bytes );

After some research I figured out, that running node (electron), Bytes.getData() actually returns a js.node.Buffer instance:
Bildschirmfoto 2020-09-04 um 12 44 23

So in my case I had to convert the node buffer into an array buffer, which led me to this quite old stack overflow answer:
https://stackoverflow.com/questions/8609289/convert-a-binary-nodejs-buffer-to-javascript-arraybuffer/31394257#31394257

Just in case you need that:

class BufferUtil {
    public static function toArrayBuffer(buf:Buffer): ArrayBuffer {
        var ab = new ArrayBuffer(buf.length);
        var view = new Uint8Array(ab);
        for (i in 0...buf.length) {
            view[i] = buf[i];
        }
        return ab;
    }
}

So is Bytes.getData() not consistent on all platforms?
Is this expected behaviour?
Or is this just a very rare edge case?

@kevinresol
Copy link
Contributor

I guess that's because the Bytes instance is created with js.node.Buffer.hxToBytes()?

@derRaab
Copy link
Author

derRaab commented Jan 13, 2021

I wonder if my conversion method will double the memory usage. And especially if loading a big media file that processing does take a while. Hm.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants