Web Audio API source.start() 仅在第二次调用时播放(在 safari 中)

Web Audio API source.start() only plays the second time it is called (in safari)

我正在学习如何使用 Web 音频 API,但我遇到了一个我不确定如何解决的问题。不知道是不是因为我是新手,还是有什么不懂的地方。

基本上我正在创建一个播放短 mp3 的函数。它应该在第一次播放音频时通过 http GET 将 MP3 加载到音频缓冲区。 (后续请求相同的音频不需要重新获取mp3)

下面的代码在 Chrome 中完全正确。但是在 Safari 中 playAudio('filename') 不会在第一次调用时播放音频。之后的每一次它都工作正常。非常感谢任何比我更有经验的人的专家建议。

<script>
var context;

function init() {
    try {
        window.AudioContext = window.AudioContext || window.webkitAudioContext;
        context = new AudioContext();
    }
    catch(e) {
        alert("Your browser doesn't support Web Audio API");
    }
}
window.addEventListener('load', init);    

function loadAudio(w) {
    var audioURL='https://biblicaltext.com/audio/' + w + '.mp3';
    var request = new XMLHttpRequest();
    request.open("GET", audioURL, true);
    request.responseType = 'arraybuffer';
    request.onload = function() {
        //console.log("update", request.readyState, request.status)
        if (request.readyState === 4) {
            if (request.status === 200) {
                //take the audio from http request and decode it in an audio buffer
                context.decodeAudioData(request.response, function(buffer) {
                    if(buffer) {
                        console.log(w, buffer);
                        playAudioBuffer(w, buffer);
                    } else {
                        console.log("audio buffer decoding failed")
                    }
                }, function(ec) {
                    console.log("http request buffer decoding failed")
                });
            } else {
                console.log("get", audioURL, "failed", request.status)
            }
        }
    }
    request.send();
}

var audioBuffer;
var currentWord;

function playAudio(w) {
    if (typeof audioBuffer === 'undefined' || audioBuffer == null || currentWord != w) {
        audioBuffer = null
        currentWord = ""
        console.log("reqest load of different word", w)
        loadAudio(w)
    } else {
        playAudioBuffer(w, audioBuffer)
    }
}

function playAudioBuffer(w, buffer) {
    audioBuffer = buffer
    currentWord = w
    var source = context.createBufferSource();
    source.buffer = audioBuffer;
    source.connect(context.destination);
    source.start();
    console.log('playing', currentWord);
}

</script>


<a href="javascript:playAudio('ἦν')">Play ἦν</a>
<br>
<a href="javascript:playAudio('ὥστε')">Play ὥστε</a>
<br>
<a href="javascript:playAudio('οὐρανός')">Play οὐρανός</a>
<br>
<a href="javascript:playAudio('υἱός')">Play υἱός</a>
<br>
<a href="javascript:playAudio('εἷς')">Play εἷς</a>
<br>

我是否遇到了某种奇怪的情况,即 Safari 正在阻止声音,因为 link 的点击与音频的 loading/playing 断开了几分之一秒?

事实证明,'unlock' 音频的方法是在用户首次与页面交互时播放 silent/hidden 声音,以确保未来的音频请求能够正常运行。

https://paulbakaus.com/tutorials/html5/web-audio-on-ios/

这是我使用的:

window.addEventListener('touchstart', function() {

    // create empty buffer
    var buffer = myContext.createBuffer(1, 1, 22050);
    var source = myContext.createBufferSource();
    source.buffer = buffer;

    // connect to output (your speakers)
    source.connect(myContext.destination);

    // play the file
    source.noteOn(0);

}, false);

我意识到我可能不是第一个在 SO 上问这个问题的人,但是搜索关键字(safari play first time vs second time)在 SO 上没有出现任何东西,所以我我倾向于回答并留下这个。如果社区删除我的菜鸟问题会更好,那么我很乐意这样做。