Safari webkitAudioContext.createBuffer API引发NotSupportedError异常

时间:2019-02-10 19:53:01

标签: javascript safari web-audio-api audiocontext webkitaudiocontext

我正在使用JavaScript Web Audio API AudioContext播放音频。它可以与其他主要浏览器正常工作,但是MacOS上的Safari在调用webkitAudioContext.createBuffer API时引发NotSupportedError异常。我发现这个问题Play PCM with javascript也表明在页面末尾Safari存在此类问题。因此,我从此处调试了“工作示例https://o.lgm.cl/example.html(16位LSB)”,并遇到了与Safari相同的问题。

由于我还是StackOverflow的新手,因此无法向该问题添加注释,以询问他们如何解决此问题。那么,有人可以帮忙吗?非常感激!

编辑:

在Safari的JavaScript控制台中运行以下两行代码将重现该问题:

var audioCtx = new (window.AudioContext || window.webkitAudioContext)(); 
var myAudioBuffer = audioCtx.createBuffer(1, 48000, 16000); 

> NotSupportedError: The operation is not supported.

1 个答案:

答案 0 :(得分:0)

您几乎会遇到错误。 Web Audio规范指出,如果sampleRate在支持范围之外,则必须抛出NotSupportedError。但是它也说最低的sampleRate支持应该至少为8000 Hz。

https://webaudio.github.io/web-audio-api/#dom-baseaudiocontext-createbuffer

Safari的Web Audio实现仅支持22050 Hz或更高的AudioBuffers。因此,我建议创建一个32000 Hz的AudioBuffer,因为32是16的倍数,这使得下一步工作容易一些。

在填充缓冲区时,您需要自己插入缺失值以补偿较大的sampleRate。我认为基本的线性插值应该可以正常工作。但是,您也可以使用OfflineAudioContext重新采样AudioBuffer。

在理想的世界(例如Firefox,Chrome或Opera)中,您可以像这样重新采样AudioBuffer:

// Let's assume you have an AudioBuffer called audioBuffer of 1 second at 16 kHz.
const offlineAudioContext = new OfflineAudioContext(
    { length: 32000, sampleRate: 32000 }
);
const audioBufferSourceNode = new AudioBufferSourceNode(
    offlineAudioContext,
    { buffer: audioBuffer }
);

audioBufferSourceNode.start(0);
audioBufferSourceNode.connect(offlineAudioContext.destination);

const resampledAudioBuffer = await offlineAudioContext.startRendering();

变量resampledAudioBuffer现在将以32 kHz引用重新采样的AudioBuffer。

但是Safari中Web Audio API的实现已过时且存在错误。它不仅不支持创建频率低于22050 Hz的AudioBuffers,而且还不能创建频率低于44100 Hz的OfflineAudioContext。

但是,用例所需的只是将数据重新采样两倍。从16 kHz到32 kHz或从44100 Hz到88200 Hz重新采样在理论上是相同的。

因此,您可以创建一个44100 Hz的AudioBuffer,并用实际为16 kHz的数据填充它。然后,您对该缓冲区重新采样到88200 Hz。然后,结果数据将成为32 kHz的原始数据。

这都是非常复杂的,但是不幸的是,我不知道在Safari中还有其他方法可以实现。

为避免需要使用Safari仍然需要的过时语法,我建议使用polyfill。我是standardized-audio-context的作者,这就是为什么我建议这么做的原因,但这不是唯一的一个。