IE 9和10产生意外和不一致的MediaError

时间:2014-05-29 17:11:12

标签: javascript audio internet-explorer-9 internet-explorer-10

我们有一组HTML块 - 比如大约50块 - 经过迭代解析并动态添加Audio个对象:

var SomeAudioWrapper = function(name) {

  this.internal_player = new Audio();

  this.internal_player.src = this.determineSrcFromName(name);
     // ultimately an MP3

  this.play = function() {
    if (someOtherConditionsAreMet()) {
      this.internal_player.play();
    }
  }

}

假设我们在页面加载时生成大约40到80个这些,但对于特定配置始终是相同的集合。在所有测试的浏览器中,这个基本策略似乎都有效。音频加载并成功播放。

在IE的9和10中,出现了一个瞬态错误。有时,在内部.play()对象上调用Audio会失败。检查后,内部Audio对象的.error.code 4MEDIA_ERR_SRC_NOT_SUPPORTED)。文件.duration显示NaN

然而,这只是偶尔发生的,并且是音频文件的一些随机子集。例如,通常 file_abc.mp3播放,但有时会产生错误。在任何一种情况下,网络监视器都显示成功下载。并尝试通过控制台重新加载文件也失败了 - IE的网络监视器中没有出现任何请求:

var a = new Audio();
a.src = "the_broken_file.mp3";
a.play(); // fails
a.error.code; // 4

即使附加查询值也无法重新获取音频或触发任何网络请求:

var a = new Audio();
a.src = "the_broken_file.mp3?v=12345";
a.play(); // fails
a.error.code; // 4

但是,尝试使用相同的代码在新选项卡中加载损坏的音频文件:“不支持的src”可以完美播放。

我们可能会遇到任何资源限制吗? (也许“不支持”的音频会在下载后完成?)是否有任何已知的错误?解决方法?

我认为我们可以很容易地检测文件何时失败。出于其他兼容性原因,我们运行循环来检查音频进度和完成统计数据,以防止通过应用程序(评估)进行直到音频完成。我们可以轻松查找.error值 - 但如果找到一个,我们该如何处理它??

附录:我刚刚发现了一个相关的问题(IE 9/10/11 sound file limit),表明有一个未记录的限制为41 - 不确定这是否是“41个音频文件请求”的限制, “41个内存中的音频对象”,或内容。我还没有找到关于此事的任何M $文件 - 或已知的解决方案。

2 个答案:

答案 0 :(得分:2)

您是否在IE中的音频文件限制上看到了这些页面?这些特定于Sound.js,但这些信息可能适用于您的问题:

https://github.com/CreateJS/SoundJS/issues/40 ...

上一条评论中提到的可能的解决方案:"根据平台控制音频标签的最大数量,并重复使用这些标签,而不是重新创建它们"

其他信息:http://community.createjs.com/kb/faq/soundjs-faq(请参阅标题为“我加载了大量声音,为什么在Internet Explorer中遇到错误?”)

答案 1 :(得分:0)

我没有在Edge或IE11中遇到过这个问题。但是,我编写了一个javascript文件,通过循环播放200个音频文件并查看会发生什么来运行一些测试。我发现IE9和IE10的问题在所有选项卡之间是一致的。因此,如果其他标签打开音频,您甚至无法保证能够加载41个文件。

我正在处理的应用程序有一个自定义声音管理器。我们的解决方案是禁用IE9和IE10的预加载音频(只需按需加载),然后当触发onended或onpause回调时,运行:

this.src = '';

这将释放IE中包含的音频数量。虽然我应该警告它可以向用户所在的当前页面发出请求。当再次调用声音管理器中的播放方法时,设置src并播放它。

我还没有测试过这段代码,但是我写了类似的东西。我认为您可以为实施做的是通过使用这样的解决方案来解决问题:

var isIE = window.navigator.userAgent.match(/MSIE (9|10)/);

var SomeAudioWrapper = function(name) {
  var src = this.determineSrcFromName(name);

  this.internal_player = new Audio();

  // If the browser is IE9 or IE10, remove the src when the
  // audio is paused or done playing. Otherwise, set the src
  // at the start.
  if (isIE) {
    this.internal_player.onended = function() {
      this.src = '';
    };
    this.internal_player.onpause = this.internal_player.onended;
  } else {
    this.internal_player.src = src;
  }

  this.play = function() {
    if (someOtherConditionsAreMet()) {
      // If the browser is IE, set the src before playing.
      if (isIE) {
          this.internal_player.src = src;
      }

      this.internal_player.play();
    }
  }

}