我正在开发一个使用 Web Audio API 播放音频文件的网站。我在 Visual Studio Code 中使用 typescript 和 Angular 2。我可以让所有东西在 ios 以外的平台上运行良好;但是在例如 iPad 上,我遇到了一些莫名其妙的错误。
第一个问题是如何获得适用于 ios 和非 ios 平台的 AudioContext。我知道它可以用普通的 javascript 来完成,例如http://gopherwoodstudios.com/wa/mp3/test.htm。需要按下按钮很烦人,但我可以忍受。所以我认为我遇到的问题与打字稿有关。(我是打字稿新手,所以我可能在这里误解了一些基础知识。)
在 ios 上,你在运行时得到的仍然是 webkitAudioContext,而不是 AudioContext。我使用的打字稿定义似乎不明白如何处理。要么,要么我不知道如何告诉它它需要知道什么。最初我有一个 AudioContext 类型的成员变量,在非 ios 平台上一切正常。为了适应 ios,我尝试将变量的类型更改为 any,这样我就可以放入 webkitAudioContext(如果存在而 AudioContext 不存在);该代码看起来像这样(这都是原型代码,因此错误处理非常临时):
export class PlayerService {
private static _audioContext: any = null;
//......
public static getAudioContext(): any {
if (!PlayerService._audioContext) {
try {
if (typeof AudioContext !== "undefined") {
// We have an AudioContext type, so use it.
PlayerService._audioContext = new AudioContext();
} else if (window['webkitAudioContext'] !== "undefined") {
// We don't have AudioContext, but we do have webkitAudioContext,
// so attempt to use that.
PlayerService._audioContext = Object.create(window['webkitAudioContext'].prototype);
} else {
throw new Error('AudioContext not supported. :(');
}
} catch (err) {
console.log(err.message);
alert('Cannot create audio context.');
throw err;
}
}
return PlayerService._audioContext;
}
这仍然适用于非 ios 平台;在 ios 上,它设法返回一个 webkitAudioContext,并带有预期的方法和属性。(Object.create(...) 是我能找到的让这么多工作的唯一方法。)后来,当我在这个对象上调用 decodeAudioData 时,我得到一个错误,上面写着
TypeError: Can only call AudioContext.decodeAudioData on instance of AudioContext.
由于它试图调用 decodeAudioData 方法的变量被键入为“any”而不是“AudioContext”,我不知道它从哪里得到它必须是 AudioContext 的想法。但无论如何,这都不是解决问题的正确方法。我在任何地方都没有关于 webkitAudioContext 的类型信息,只有关于 AudioContext 的信息。必要的类型信息是否存在于某处而我只是没有找到它?如果它不存在,创建它会很困难吗?或者,有没有办法完全绕过这组类的类型检查(不是我的首选选项,但如果这是我们现在能做的最好的选择,我会接受它)?还是有一些我不知道的完全不同的方法来解决这个问题?