【问题标题】:js / html5 audio: Why is canplaythrough not fired on iOS safari?js / html5 音频:为什么不能在 iOS Safari 上触发 canplaythrough?
【发布时间】:2019-03-29 00:21:31
【问题描述】:

我使用下面的代码来预加载一组音频文件(在用户与启动进程的按钮交互之后)。在所有音频文件“canplaythrough”触发后,代码继续:

var loaded = 0;
function loadedAudio() {
    // this will be called every time an audio file is loaded
    // we keep track of the loaded files vs the requested files
    loaded++;
    console.log(loaded + " audio files loaded!");
    if (loaded == audioFiles.length){
      // all have loaded
      main();
    }
}

function preloadsounds()
{
  $("#loader").show();
  console.log(level.config);
  audioFiles = level.config.soundfiles;

  // we start preloading all the audio files with html audio
  for (var i in audioFiles) {
      preloadAudio(audioFiles[i]);
  }

}

function preloadAudio(url)
{
  console.log("trying to preload "+ url);
  var audio = new Audio();
  // once this file loads, it will call loadedAudio()
  // the file will be kept by the browser as cache
  audio.addEventListener('canplaythrough', loadedAudio, false);

  audio.addEventListener('error', function failed(e)
  {
    console.log("COULD NOT LOAD AUDIO");
    $("#NETWORKERROR").show();
  });
  audio.src = url;
}

在 Android(Chrome 和 Firefox)上运行良好,但在 iOs Safari 上没有触发单个 canplaythrough 事件(在 5s 上实时测试并在 11.x 上模拟 X)。所有文件均来自同一来源。我的日志中也没有收到任何错误消息。

我错过了什么?

(我上面代码的基础来自:https://stackoverflow.com/a/31351186/2602592

【问题讨论】:

    标签: javascript html html5-audio


    【解决方案1】:

    在设置src后尝试调用load()方法。

    function preloadAudio(url)
    {
      console.log("trying to preload "+ url);
      var audio = new Audio();
      // once this file loads, it will call loadedAudio()
      // the file will be kept by the browser as cache
      audio.addEventListener('canplaythrough', loadedAudio, false);
    
      audio.addEventListener('error', function failed(e)
      {
        console.log("COULD NOT LOAD AUDIO");
        $("#NETWORKERROR").show();
      });
      audio.src = url;
    
      audio.load();  // add this line
    }
    

    【讨论】:

    • 太棒了!那成功了!供将来参考:w3schools.com/tags/av_met_load.asp“load() 方法用于在更改源或其他设置后更新音频/视频元素。”谢谢!
    • 在 iOS 中不适合我。没有错误或警告,即使在添加 load() 之后也不会触发事件。在 iphone 8 11.4 模拟器和 IRL iphone X iOS 12 中进行测试。但是,我确实在移动 safari 的检查器网络选项卡中看到由于某种原因取消了请求,代码 206。该死,safari 就是个垃圾浏览器。
    • @StephenTetreault 206 status 表示浏览器成功接收到文件的部分内容。这是流媒体音频吗?上面的代码等待整个文件被加载,所以这可能是流内容的问题。尝试使用canplayloadedmetadata 事件而不是canplaythrough
    • 在我的场景@GabrielePetrioli 中很容易解决。仅适用于 iOS 浏览器,使用几百毫秒的超时解决了它。不是最漂亮的解决方案,但它没有任何明显的问题。
    • MacOS 上的 Safari 也有类似的问题。这也为我解决了。
    【解决方案2】:

    您是否检查过网络/服务器并确认 Safari 正在下载音频文件?

    如果 Safari 没有下载音频(或者只加载元数据而不是完整文件),您可以尝试在设置 audio.src 之前设置 audio.preload = 'auto'

    【讨论】:

      【解决方案3】:

      我看到很多声称要让音频对象工作,尤其是在 Safari 上!

      要快速进行,我可以告诉您,您不需要太多,只需知道在 Safari 5 及更高版本以及所有浏览器上运行所有内容即可。

      1. 如果您只使用一个,则通过重新加载列表或文件中的第一个文件来强制调用低谷。 Trough 事件是允许用户读取文件的事件,因为它允许知道文件是否已加载并准备好被读取。如果你构建一个播放器,你必须计划并让用户只有在通过时才点击播放。

                  ObjectAudio.src = file;

      2. 使用槽更新您的播放器

        ObjectAudio.addEventListener ('canplaythrough', Function, false);

      3. 使用进度更新百分比缓冲条。

        ObjectAudio.addEventListener ('progress', Function, false);

      4. 使用 timeupdate 事件更新阅读栏。

        ObjectAudio.addEventListener ('timeupdate', Function, false);

      你不需要复杂的东西,我知道你在做什么。


      ** 只需担心 Safari 5 Widows。要使对象工作,必须在用户上安装 QuickTime,否则 Safari 5 将无法识别 HTML 5 音频对象。

      【讨论】:

        猜你喜欢
        • 2018-10-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-05-01
        • 1970-01-01
        • 2012-06-14
        • 2015-10-24
        • 1970-01-01
        相关资源
        最近更新 更多