javascript readAsArrayBuffer返回空数组缓冲区

时间:2014-06-05 10:00:14

标签: 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>

reader.result的控制台输出

e.target.result
ArrayBuffer {}
e.target.result.byteLength
25312

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

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

2 个答案:

答案 0 :(得分: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]);
}

如果您尝试通过console.log打印ArrayBuffer,则总是会得到空对象{}

答案 1 :(得分:4)

好吧,使用AudioContext内容播放声音实际上并不那么难。

  1. 设置上下文。
  2. 将任何数据加载到缓冲区(例如FileReader表示本地文件,XHR表示远程资料。
  3. 设置新来源,然后启动它。
  4. 总而言之,这样的事情:

    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);
    

    jsfiddle中查看此内容,该版本适用于Firefox和Chrome。

    我投入了console.log(new Uint8Array())以获得良好的衡量标准,因为浏览器通常会直接记录内容(如果缓冲区不是很大)。 对于您可以使用ArrayBuffer执行的其他操作,请参阅例如corresponding MDN documentation