我无法在任何地方找到这个问题的明确答案。我正在寻找一种最简单的方法,可以在chrome中的文档加载时自动无缝地循环.wav文件。似乎webaudio api是最好的做法,但我找不到简单的文档。对safari和其他人的支持也会很棒但不那么重要。
我查看过w3.org示例,但它没有帮助
我认为除了按钮的on.click之外,这是我最想要的:https://forestmist.org/blog/web-audio-api-loops/
这里我为我自己的音频实现了forestmist,它在safari中完美运行但在chrome中停止:http://infinitelimitations.us/mess-motion/web-audio-api-loops-demo/index.html
这是该页面的源代码:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Web Audio API Loops Demo</title>
</head>
<body>
<form>
<button id="button-loop-1" type="button" value="1">Loop 1</button>
</form>
<script>
//--------------
// Audio Object
//--------------
var audio = {
buffer: {},
compatibility: {},
files: [
'hoodie_robot_clipped.wav',
'beat.wav'
],
proceed: true,
source_loop: {},
};
//-----------------
// Audio Functions
//-----------------
audio.findSync = function(n) {
var first = 0,
current = 0,
offset = 0;
// Find the audio source with the earliest startTime to sync all others to
for (var i in audio.source_loop) {
current = audio.source_loop[i]._startTime;
if (current > 0) {
if (current < first || first === 0) {
first = current;
}
}
}
if (audio.context.currentTime > first) {
offset = (audio.context.currentTime - first) % audio.buffer[n].duration;
}
return offset;
};
audio.play = function(n) {
if (audio.source_loop[n]._playing) {
audio.stop(n);
} else {
audio.source_loop[n] = audio.context.createBufferSource();
audio.source_loop[n].buffer = audio.buffer[n];
audio.source_loop[n].loop = true;
audio.source_loop[n].connect(audio.context.destination);
var offset = audio.findSync(n);
audio.source_loop[n]._startTime = audio.context.currentTime;
if (audio.compatibility.start === 'noteOn') {
/*
The depreciated noteOn() function does not support offsets.
Compensate by using noteGrainOn() with an offset to play once and then schedule a noteOn() call to loop after that.
*/
audio.source_once[n] = audio.context.createBufferSource();
audio.source_once[n].buffer = audio.buffer[n];
audio.source_once[n].connect(audio.context.destination);
audio.source_once[n].noteGrainOn(0, offset, audio.buffer[n].duration - offset); // currentTime, offset, duration
/*
Note about the third parameter of noteGrainOn().
If your sound is 10 seconds long, your offset 5 and duration 5 then you'll get what you expect.
If your sound is 10 seconds long, your offset 5 and duration 10 then the sound will play from the start instead of the offset.
*/
// Now queue up our looping sound to start immediatly after the source_once audio plays.
audio.source_loop[n][audio.compatibility.start](audio.context.currentTime + (audio.buffer[n].duration - offset));
} else {
audio.source_loop[n][audio.compatibility.start](0, offset);
}
audio.source_loop[n]._playing = true;
}
};
audio.stop = function(n) {
if (audio.source_loop[n]._playing) {
audio.source_loop[n][audio.compatibility.stop](0);
audio.source_loop[n]._playing = false;
audio.source_loop[n]._startTime = 0;
if (audio.compatibility.start === 'noteOn') {
audio.source_once[n][audio.compatibility.stop](0);
}
}
};
//-----------------------------
// Check Web Audio API Support
//-----------------------------
try {
// More info at http://caniuse.com/#feat=audio-api
window.AudioContext = window.AudioContext || window.webkitAudioContext;
audio.context = new window.AudioContext();
} catch(e) {
audio.proceed = false;
alert('Web Audio API not supported in this browser.');
}
if (audio.proceed) {
//---------------
// Compatibility
//---------------
(function() {
var start = 'start',
stop = 'stop',
buffer = audio.context.createBufferSource();
if (typeof buffer.start !== 'function') {
start = 'noteOn';
}
audio.compatibility.start = start;
if (typeof buffer.stop !== 'function') {
stop = 'noteOff';
}
audio.compatibility.stop = stop;
})();
//-------------------------------
// Setup Audio Files and Buttons
//-------------------------------
for (var a in audio.files) {
(function() {
var i = parseInt(a) + 1;
var req = new XMLHttpRequest();
req.open('GET', audio.files[i - 1], true); // array starts with 0 hence the -1
req.responseType = 'arraybuffer';
req.onload = function() {
audio.context.decodeAudioData(
req.response,
function(buffer) {
audio.buffer[i] = buffer;
audio.source_loop[i] = {};
var button = document.getElementById('button-loop-' + i);
button.addEventListener('click', function(e) {
e.preventDefault();
audio.play(this.value);
});
},
function() {
console.log('Error decoding audio "' + audio.files[i - 1] + '".');
}
);
};
req.send();
})();
}
}
</script>
</body>
</html>
答案 0 :(得分:16)
花了一夜的研究,但我终于找到了最简单的解决方案:
<script type="text/javascript">
//this is the webaudio loooooppppppp
//enter url in the next line
var url = 'hoodie_robot_clipped.wav';
/* --- set up web audio --- */
//create the context
var context = new AudioContext();
//...and the source
var source = context.createBufferSource();
//connect it to the destination so you can hear it.
source.connect(context.destination);
/* --- load buffer --- */
var request = new XMLHttpRequest();
//open the request
request.open('GET', url, true);
//webaudio paramaters
request.responseType = 'arraybuffer';
//Once the request has completed... do this
request.onload = function() {
context.decodeAudioData(request.response, function(response) {
/* --- play the sound AFTER the buffer loaded --- */
//set the buffer to the response we just received.
source.buffer = response;
//start(0) should play asap.
source.start(0);
source.loop = true;
}, function () { console.error('The request failed.'); } );
}
//Now that the request has been defined, actually make the request. (send it)
request.send();
</script>
答案 1 :(得分:0)
对于那些可能不会使用wav且不关心完美无缝的人……使用HTMLMediaElement.loop使其非常简单
var myAudio = document.getElementById('my-audio');
var play = document.getElementById('play');
var pause = document.getElementById('pause');
// set loop
myAudio.loop = true;
// associate functions with the 'onclick' events
play.onclick = playAudio;
pause.onclick = pauseAudio;
function playAudio() {
myAudio.play();
}
function pauseAudio() {
myAudio.pause();
}
<audio id="my-audio" src="http://static1.grsites.com/archive/sounds/medical/medical006.mp3"></audio>
<button id="play">PLAY</button>
<button id="pause">PAUSE</button>