我之前已经成功使用 Web Audio API 中的JavaScriptAudioNode在 Chrome 和 Safari 6.0 中合成和混合音频。但是,最新版本的 Safari 似乎不再工作,因为它不调用onaudioprocess来填充源缓冲区。
这是一个简化的示例,它只播放静音并在每次调用onaudioprocess时将文本附加到文档正文:
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
$("a").click(function() {
var context = new webkitAudioContext();
var mixerNode=context.createJavaScriptNode(2048, 0, 2);
mixerNode.onaudioprocess=function(ape) {
var buffer=ape.outputBuffer;
for(var s=0;s<buffer.length;s++)
{
buffer.getChannelData(0)[s]=0;
buffer.getChannelData(1)[s]=0;
}
$("body").append("buffering<br/>");
};
$("body").html("");
mixerNode.connect(context.destination);
return false;
});
});
</script>
</head>
<body>
<a href="#">start</a>
</body>
</html>
上面的示例在 Chrome 中按预期工作,但在桌面 Safari 中不起作用。iOS 版本的 Safari 也不起作用,但它一开始就对我不起作用。
调用context.createJavaScriptNode确实会返回类型为JavaScriptAudioNode的正确对象,并且将其连接到目标节点不会引发任何异常。context.activeSourceCount保持为零,但在 Chrome 中也是如此,因为它显然只计算AudioBufferSourceNode类型的活动节点。context.currentTime也按预期递增。
我在这里做错了什么还是这是一个实际的错误或 Safari 中缺少的功能?Apple 文档没有提到JavaScriptAudioNode(也没有提到新名称ScriptProcessorNode),但它在 Safari 6 的第一个版本之前确实有效。iOS Safari 对用户输入的要求似乎没有帮助,因为上面的示例应该注意那个。
简单的例子可以在这里找到,一个更复杂的例子是我的Protracker 模块播放器,它表现出相同的行为。