我之前已成功使用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要求似乎没有帮助,因为上面的例子应该照顾它。
可以找到简单的示例here,而更复杂的示例是Protracker module player,它表现出相同的行为。
答案 0 :(得分:4)
Safari的Web Audio API实现中存在一些错误,您需要注意这些错误。第一个是在createJavaScriptNode
构造函数中...它似乎有“输入通道”参数设置为0的问题。尝试将其更改为:
createJavaScriptNode(2048, 1, 2)
第二个问题与垃圾收集有关(我认为);一旦你的mixerNode变量超出范围,Safari似乎停止触发onaudioprocess
回调。一种解决方案是在顶级范围引入mixerNode(即在脚本顶部声明var mixerNode;
),然后将JavaScriptNode存储在该顶级变量中。如果您计划动态创建多个mixerNodes,则可以通过在顶级数组变量中存储对它们的引用来实现相同的效果。
如果你做了这两个更改(输入通道参数设置为1,保持对mixerNode的引用),那么你的脚本应该在Safari中按预期工作。