我知道我需要在 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 上工作。
我对我来说确实没有意义,但在这种情况下,Safari 需要另一次推动才能启动
AudioContext
。创建 resume()
后立即调用 AudioContext
应该可以工作。
// ...
var ctx = new AudioContext();
ctx.resume();
fetch('MP3_URL')
// ...
调用
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