2

我正在开发一个使用 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 的信息。必要的类型信息是否存在于某处而我只是没有找到它?如果它不存在,创建它会很困难吗?或者,有没有办法完全绕过这组类的类型检查(不是我的首选选项,但如果这是我们现在能做的最好的选择,我会接受它)?还是有一些我不知道的完全不同的方法来解决这个问题?

4

1 回答 1

2

解决,至少到第一个近似值。这一行:

    PlayerService._audioContext = new ((<any>window).AudioContext || (<any>window).webkitAudioContext)();

创建一个适用于 ios 和非 ios 平台的音频上下文,并且“any's”可以防止打字稿抱怨。这将满足我的目的,直到浏览器都远离 webkit 前缀,或者它被适当的类型定义支持。

我遇到的 decodeAudioData() 问题是由于 ios 上的 Chrome 无法理解我试图播放的 .ogg 文件。当我切换到 mp3 时,它起作用了。

于 2017-02-27T22:58:44.637 回答