问题
I've been trying to follow the steps in some tutorials for playback of a simple, encoded local wav or mp3 file with the web Audio API using a button. My code is the following (testAudioAPI.js):
window.AudioContext = window.AudioContext || window.webkitAudioContext;
var context = new AudioContext();
var myBuffer;
clickme = document.getElementById('clickme');
clickme.addEventListener('click',clickHandler);
var request = new XMLHttpRequest();
request.open('GET', 'WoodeBlock_SMan_B.wav', true);
request.responseType = 'arraybuffer';
// Decode asynchronously
request.onload = function() {
context.decodeAudioData(request.response, function(theBuffer) {
myBuffer = theBuffer;
}, onError);
}
request.send();
function playSound(buffer) {
var source = context.createBufferSource(), g = context.createGain();
source.buffer = buffer;
source.start(0);
g.gain.value = 0.5;
source.connect(g);
g.connect(context.destination);
}
function clickHandler(e) {
playSound(myBuffer);
}
And the HTML file would look like this:
<!doctype html>
<html>
<body>
<button id="clickme">Play</button>
<script src='testAudioAPI.js'></script>
</body>
</html>
However, no sound is achieved whatsoever. I've tried several snippets but I still can't figure it out. When I try to generate a sound by synthesizing it by creating an oscillator node, I do get sound, but not with buffers from local files. What would be the problem here? Thank you all.
回答1:
Local files, huh? Are you just grabbing them from the filesystem (e.g. "file://"), or do you have a local web server running?
From what I recall, serving directly from the filesystem violates CORS in most (all?) browsers – which will prevent your AJAX request from succeeding.
Maybe try serving the page with python -m SimpleHTTPServer
or similar, and then access it at http://localhost:8000.
From what I can tell, all of your code looks fine.
回答2:
You have a call to onError
which isn't defined.
Apart from that it should be working, but not with Chrome because Chrome blocks all XMLHttpRequest to local files. But with Firefox for example it should work once you define (or get rid of) your call to onError
.
回答3:
minimalistic approach to modern ES6.
- new AudioContext();
- context.createBufferSource();
- source.buffer = audioBuffer; audioBuffer requests ArrayBuffer data by fetch, and then decodeAudioData decodes to AudioBuffer.
- source.start()
<button id="start">playSound</button>
const audioPlay = async url => {
const context = new AudioContext();
const source = context.createBufferSource();
const audioBuffer = await fetch(url)
.then(res => res.arrayBuffer())
.then(ArrayBuffer => context.decodeAudioData(ArrayBuffer));
source.buffer = audioBuffer;
source.connect(context.destination);
source.start();
};
document.querySelector('#start').onclick = () => audioPlay('music/music.mp3');
stop play: source.stop();
The Web Audio API cannot be played automatically, you need to be triggered by an event.
来源:https://stackoverflow.com/questions/30482887/playing-a-simple-sound-with-web-audio-api