web-dev-qa-db-ja.com

javascriptreadAsArrayBufferは空の配列バッファを返します

FileReaderreadAsArrayBufferプロパティを使用してローカルファイルを読み取ろうとしています。読み取りは成功し、「onload」コールバックで、reader.resultにArrayBufferオブジェクトが表示されます。しかし、配列バッファは空です。長さは設定されていますが、データは設定されていません。このデータを取得するにはどうすればよいですか?

これが私のコードです

<!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

誰かがこのデータを取得する方法を教えてもらえますか?セキュリティ上の問題はありますか?エラーはなく、onerrorは実行されません。

コメントから:バッファの内容にアクセスする方法を教えてください。私は実際にAudioContext...を使用してオーディオファイルを再生しようとしています...そのためには、バッファデータが必要になります...

9
Anand N

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

これを jsfiddle でライブでご覧ください。これは、FirefoxとChromeで機能します。

ブラウザは通常コンテンツを直接ログに記録するので(バッファが大きくない場合)、私はconsole.log(new Uint8Array())を適切に投入しました。 ArrayBuffersで実行できるその他の作業については、たとえば、 対応するMDNドキュメント

5
nmaier

配列バッファを読み取り、それをバイナリ文字列に変換する方法は次のとおりです。

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を出力しようとすると、常に空のオブジェクト{}が表示されます。

8