javascript - 在 javascript 中将 Float32Array 转换为 base64
问题描述
Uint8Array
有很多关于将 blob 转换为 base64的问答。但我一直无法找到如何从 32 位数组转换为 base64。这是一个尝试。
function p(msg) { console.log(msg) }
let wav1 = [0.1,0.2,0.3]
let wav = new Float32Array(wav1)
p(`Len array to encrypt=${wav.length}`)
let omsg = JSON.stringify({onset: { id: 'abc', cntr: 1234}, wav: atob(wav) })
p(omsg)
atob
给出:
Uncaught InvalidCharacterError: Failed to execute 'atob' on 'Window':
The string to be decoded is not correctly encoded."
需要什么中间步骤才能将浮点数正确编码为 base64 ?请注意,我也尝试过TweetNacl-util
这种atob
方式:
nacl.util.encodeBase64(wav)
这会导致相同的错误。
Update UsingJSON.stringify
直接将每个 float 元素转换为其 ascii 等效项 - 这会使 datasize 膨胀。对于以上内容:
“0.10000000149011612”,“1”:0.20000000298023224,“2”:0.30000001192092896
我们正在传输大型阵列,因此这是一个次优的解决方案。
更新已接受答案中解决方案的关键要素是使用Float32Array(floats).buffer
. 我不知道这个buffer
属性。
解决方案
您当前代码的问题在于它nacl.util.encodeBase64()
接受了字符串、数组或 Uint8Array。由于您的输入不是 Array 或 Uint8Array,因此它假定您希望将其作为字符串传递。
解决方案当然是先将其编码为 Uint8Array,然后将 Uint8Array 编码为 base64。解码时,首先将 base64 解码为 Uint8Array,然后将 Uint8Array 转换回 Float32Array。这可以使用 JavaScript ArrayBuffers 来完成。
const floatSize = 4;
function floatArrayToBytes(floats) {
var output = floats.buffer; // Get the ArrayBuffer from the float array
return new Uint8Array(output); // Convert the ArrayBuffer to Uint8s.
}
function bytesToFloatArray(bytes) {
var output = bytes.buffer; // Get the ArrayBuffer from the Uint8Array.
return new Float32Array(output); // Convert the ArrayBuffer to floats.
}
var encoded = nacl.util.encodeBase64(floatArrayToBytes(wav)) // Encode
var decoded = bytesToFloatArray(nacl.util.decodeBase64(encoded)) // Decode
如果你不喜欢函数,这里有一些单行代码!
var encoded = nacl.util.encodeBase64(new Uint8Array(wav.buffer)) // Encode
var decoded = new Float32Array(nacl.util.decodeBase64(encoded).buffer) // Decode