AudioContext 无法在 Safari 上运行,但可以在 Google Chrome 上运行

问题描述 投票:0回答:2

我知道我需要在 Safari 中进行用户交互后创建音频上下文。然而下面的代码还是不行。

HTML

<button onclick="play">Play</button>

Javascript

function play() {  
  var AudioContext = window.AudioContext || window.webkitAudioContext
  var ctx = new AudioContext()

  fetch('MP3_URL')
    .then((response) => response.arrayBuffer())
    .then((arrayBuffer) => ctx.decodeAudioData(arrayBuffer))
    .then((audioBuffer) => {
      var source = ctx.createBufferSource()
      source.buffer = audioBuffer
      source.connect(ctx.destination)
      source.start(ctx.currentTime)
    })
}

相同的代码在 Google Chrome 上工作,但在 safari 上工作。

javascript html safari audiocontext
2个回答
0
投票

我对我来说确实没有意义,但在这种情况下,Safari 需要另一次推动才能启动

AudioContext
。创建
resume()
后立即调用
AudioContext
应该可以工作。

// ...
var ctx = new AudioContext();

ctx.resume();

fetch('MP3_URL')
// ...

0
投票

调用

resume()
,但它无法使用 AudioContext 和 MediaElementSource 在我的 iPhone 上播放声音。

const createAudio = () => {
    const audio = new Audio(SRC)
    audio.autoplay = true
    audio.crossOrigin = "anonymous"
    audio.controls = true
    audio.addEventListener('error', (e) => console.log(e) )

    document.body.appendChild(audio)
    return audio
}

document.querySelector("#element-source").onclick = () => {
    audioContext = new AudioContext()
    audioElement = createAudio()
    const source = audioContext.createMediaElementSource(audioElement)
    source.connect(audioContext.destination)
    audioContext.resume()
    audioElement.play()
}

上面的代码在 Mac Safari 上运行良好。但 iPhone 不播放声音。

没有AudioContext的普通音频元素可以播放相同的音频文件和相同的音频元素, 带有 AudioContext 的振荡器也可以在 iOS Safari 上播放。

// plain audio element without AudioContext.
document.querySelector("#no-context").onclick = () => {
    audioElement = createAudio()
    audioElement.play()
}

// OscillatorNode and GainNode with AudioContext
document.querySelector("#oscillator").onclick = () => {
    audioContext = new AudioContext()
    const oscillator = new OscillatorNode(audioContext, {
        type: "square",
        frequency: 100, // Value in Herz
    })
    const gainNode = new GainNode(audioContext, { gain: 0.1 })

    oscillator.connect(gainNode)
    gainNode.connect(audioContext.destination)
    oscillator.start(0)
}

CodePen 上的示例页面。 https://codepen.io/moicci/pen/NWoROmd

© www.soinside.com 2019 - 2024. All rights reserved.