如何使用Web音频API播放声音文件Safari?

时间:2018-02-03 13:12:44

标签: javascript ios audio safari web-audio-api

我正在修改脚本以播放我在Codepen上发现的mp3,以使其在Safari上运行。在Firefox和Chrome中它工作正常,但Safari抱怨:"未处理的Promise Rejection:TypeError:参数不够 的index.html:25"

我已经阅读https://developer.apple.com/library/archive/documentation/AudioVideo/Conceptual/Using_HTML5_Audio_Video/PlayingandSynthesizingSounds/PlayingandSynthesizingSounds.html这比我需要的东西要高得多。我只是想在我的mp3中播放声音。我需要网络音频,因为这是让它在iOS Safari上运行的唯一方法。

有谁知道如何让Safari开心?

https://codepen.io/kslstn/full/pagLqL



(function () {
    
  if('AudioContext' in window || 'webkitAudioContext' in window) {  
    // Check for the web audio API. Safari requires the webkit prefix.


  const URL = 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/123941/Yodel_Sound_Effect.mp3';
    
  var AudioContext = window.AudioContext || window.webkitAudioContext;
  var context = new AudioContext(); // Make it crossbrowser    
      
  const playButton = document.querySelector('#play');
    
  let yodelBuffer;

  window.fetch(URL)
    .then(response => response.arrayBuffer())
    .then(arrayBuffer => context.decodeAudioData(arrayBuffer))
    .then(audioBuffer => {
      yodelBuffer = audioBuffer;
    });
    
    playButton.onclick = () => play(yodelBuffer);

  function play(audioBuffer) {
    const source = context.createBufferSource();
    source.buffer = audioBuffer;
    source.connect(context.destination);
    source.start();
  }

}

}());

<button id="play">Yodel!</button>
&#13;
&#13;
&#13;

1 个答案:

答案 0 :(得分:1)

Safari(Webkit)不支持BaseAudioContext.decodeAudioData()的基于Promise的语法。请参阅以下链接中的详细浏览器兼容性

https://developer.mozilla.org/en-US/docs/Web/API/BaseAudioContext/decodeAudioData

所以你需要使用旧的回调语法,如下所示。它适用于高于6.0的Safari和高于10的Chrome

window.fetch(URL)
  .then(response => response.arrayBuffer())
  .then(arrayBuffer => context.decodeAudioData(arrayBuffer, 
                                               audioBuffer => {
                                                 yodelBuffer = audioBuffer;
                                                }, 
                                               error => 
                                               console.error(error)
                                              ))