我有以下HTML:
<script type="text/javascript">
window.onload = function() {
var volumeBars = {
mono: document.getElementById("monoFill")
};
document.getElementById("open-file").onchange = function(evt) {
var file = evt.target.files[0];
var reader = new FileReader();
reader.onload = function(e) {
playSound(e.target.result);
console.log(e.target.result);
}
reader.readAsArrayBuffer(file);
}
var context = new AudioContext();
function playSound(arraybuffer) {
context.close();
context = new AudioContext();
var source = context.createBufferSource();
context.decodeAudioData(arraybuffer, function(buffer) {
source.buffer = buffer;
});
//=
console.log(arraybuffer)
var analyser = context.createAnalyser();
analyser.smoothingTimeConstant = .9;
analyser.fftSize = 1024;
jsNode = context.createScriptProcessor(2048, 1, 1);
jsNode.onaudioprocess = function() {
var array = new Uint8Array(analyser.frequencyBinCount);
analyser.getByteFrequencyData(array);
volumeBars.mono.style.height = Math.average(array) * 2 + "px";
volumeBars.mono.innerHTML = Math.floor(Math.average(array));
console.log(volumeBars.mono.innerHTML);
}
source.connect(analyser);
source.connect(context.destination);
jsNode.connect(context.destination);
analyser.connect(jsNode);
source.start();
}
Math.average = function(arguments) {
var numbers;
if (arguments[0] instanceof Array) {
numbers = arguments[0];
} else if (typeof arguments[0] == "number") {
numbers = arguments;
}
var sum = 0;
var average = 0;
for (var i = 0; i < numbers.length; i++) {
sum += numbers[i];
}
average = sum / numbers.length;
return average;
}
}
</script>
<div id="container">
<div class="bar" id="mono">
<div class="fill" id="monoFill"></div>
</div>
</div>
<input type="file" id="open-file" accept="audio/*">
我面临的问题是,我想要替换块
var file = evt.target.files[0];
使用本地文件,不需要每次都加载。我一直无法找到将文件编码为ArrayBuffer
的方法。我确信这是一个非常业余的问题,有一个明显的答案,但欢迎任何帮助。
答案 0 :(得分:1)
由于你想要的是访问服务器上的文件,你只需要发出一个Ajax请求,将响应设置为ArrayBuffer,这里不需要FileReader。
使用fetch API看起来像
const a_ctx = new(window.AudioContext || window.webkitAudioContext)();
fetch('https://dl.dropboxusercontent.com/s/1cdwpm3gca9mlo0/kick.mp3')
.then(resp => resp.arrayBuffer()) // request as ArrayBuffer
.then(buf => a_ctx.decodeAudioData(buf))
.then(a_buf => {
btn.onclick = e => {
let node = a_ctx.createBufferSource();
node.buffer = a_buf;
node.connect(a_ctx.destination);
node.start(0);
};
btn.disabled = false;
});
<button id="btn" disabled>play</button>
<!-- Promising decodeAudioData for Safari https://github.com/mohayonao/promise-decode-audio-data/ [MIT] -->
<script src="https://cdn.rawgit.com/mohayonao/promise-decode-audio-data/eb4b1322/build/promise-decode-audio-data.min.js"></script>
var a_ctx = new(window.AudioContext || window.webkitAudioContext)();
var xhr = new XMLHttpRequest();
xhr.open('get', 'https://dl.dropboxusercontent.com/s/1cdwpm3gca9mlo0/kick.mp3');
xhr.responseType = 'arraybuffer'; // request as ArrayBuffer
xhr.onload = function() {
var buf = xhr.response;
a_ctx.decodeAudioData(buf, function(a_buf) {
btn.onclick = function(e) {
let node = a_ctx.createBufferSource();
node.buffer = a_buf;
node.connect(a_ctx.destination);
node.start(0);
};
btn.disabled = false;
});
};
xhr.send();
<button id="btn" disabled>play</button>