javascript readAsArrayBuffer返回空数组缓冲区

Ana*_*d N 9 javascript arraybuffer audiocontext

我试图使用FileReader readAsArrayBuffer属性读取本地文件.读取成功,在"onload"回调中,我在reader.result中看到了Array Buffer对象.但是Array Buffer只是空的.设置长度,但不设置数据.我如何获得这些数据?

这是我的代码

<!DOCTYPE html>
<html>

<body>
    <input type="file" id="file" />
</body>

<script>
    function handleFileSelect(evt) {

        var files = evt.target.files; // FileList object

        var selFile = files[0];
        var reader = new FileReader();
        reader.onload = function(e) {
            console.log(e.target.result);
        };

        reader.onerror = function(e) {
            console.log(e);
        };
        reader.readAsArrayBuffer(selFile);
    }


    document.getElementById('file').addEventListener('change', handleFileSelect, false);
</script>

</html>
Run Code Online (Sandbox Code Playgroud)

reader.result的控制台输出

e.target.result
ArrayBuffer {}
e.target.result.byteLength
25312
Run Code Online (Sandbox Code Playgroud)

谁能告诉我如何获取这些数据?有一些安全问题吗?没有错误,不执行onerror.

来自评论:你能告诉我如何访问缓冲区内容吗?我实际上正在尝试播放音频文件AudioContext...为此我需要缓冲数据...

Roh*_*gar 8

这是如何读取数组缓冲区并将其转换为二进制字符串,

function onfilechange(evt) {
var reader = new FileReader(); 
reader.onload = function(evt) {
  var chars  = new Uint8Array(evt.target.result);
  var CHUNK_SIZE = 0x8000; 
  var index = 0;
  var length = chars.length;
  var result = '';
  var slice;
  while (index < length) {
    slice = chars.subarray(index, Math.min(index + CHUNK_SIZE, length)); 
    result += String.fromCharCode.apply(null, slice);
    index += CHUNK_SIZE;
  }
  // Here you have file content as Binary String in result var
};
reader.readAsArrayBuffer(evt.target.files[0]);
}
Run Code Online (Sandbox Code Playgroud)

如果您尝试通过console.log打印ArrayBuffer,则始终会获得空对象{}


nma*_*ier 5

好吧,使用这些AudioContext东西播放声音实际上并不难。

  1. 设置上下文。
  2. 将任何数据加载到缓冲区中(例如,FileReader用于本地文件,XHR用于远程内容)。
  3. 设置一个新的源,然后启动它。

总而言之,是这样的:

var context = new(window.AudioContext || window.webkitAudioContext)();

function playsound(raw) {
    console.log("now playing a sound, that starts with", new Uint8Array(raw.slice(0, 10)));
    context.decodeAudioData(raw, function (buffer) {
        if (!buffer) {
            console.error("failed to decode:", "buffer null");
            return;
        }
        var source = context.createBufferSource();
        source.buffer = buffer;
        source.connect(context.destination);
        source.start(0);
        console.log("started...");
    }, function (error) {
        console.error("failed to decode:", error);
    });
}

function onfilechange(then, evt) {
    var reader = new FileReader();
    reader.onload = function (e) {
        console.log(e);
        then(e.target.result);
    };
    reader.onerror = function (e) {
        console.error(e);
    };
    reader.readAsArrayBuffer(evt.target.files[0]);
}


document.getElementById('file')
  .addEventListener('change', onfilechange.bind(null, playsound), false);
Run Code Online (Sandbox Code Playgroud)

可以在jsfiddle中实时查看此内容,该版本可在Firefox和Chrome中使用。

我采取了一个console.log(new Uint8Array())很好的措施,因为浏览器通常会直接记录内容(如果缓冲区不大)。有关您可以使用ArrayBuffer的其他内容,请参见相应的MDN文档