safari - 使用 Web Audio API webkitAudioContext() 在 Safari 中没有声音
问题描述
我正在尝试使用Web Audio API
在我的应用程序中播放声音React
。
它目前正在除 Safari 之外的所有浏览器中播放声音v12.1
。
我知道 Safari 对自动播放有限制,并且需要用户交互才能播放声音,所以我有一个调用该_play()
函数的播放按钮:
_play = (url, index) => {
this._getData(url);
this.source.start(index)
}
它正在调用如下_getData()
所示的函数:
_getData(url) {
this.source = this.audioContext.createBufferSource();
var request = new XMLHttpRequest();
request.open('GET', url, true);
request.responseType = 'arraybuffer';
request.onload = () => {
var audioData = request.response;
console.log(this.audioContext)
this.audioContext.decodeAudioData(audioData, buffer => {
this.source.buffer = buffer;
this.source.connect(this.audioContext.destination);
},
function(e){ console.log("Error with decoding audio data" + e.err); });
}
request.send();
}
this.audioContext
使用以下组件在组件中创建constructor
:
this.audioContext = new (window.AudioContext || window.webkitAudioContext)();
在按下播放之前,里面会输出这个console.log(this.audioContext)
:request.onload
...按下播放后:
但没有声音播放(在 Safari 中)。
我究竟做错了什么?
解决方案
我认为您遇到的问题是,一旦您调用 start(),Safari 就不允许您再修改缓冲区。
例如,当您按下播放按钮时,以下页面会在 Safari 中播放一秒钟的噪音。
<!DOCTYPE html>
<html>
<body>
<button id="play-button">play</button>
<script>
document
.getElementById('play-button')
.addEventListener('click', () => {
const audioContext = new AudioContext();
const audioBufferSourceNode = audioContext.createBufferSource();
const sampleRate = audioContext.sampleRate;
const audioBuffer = audioContext.createBuffer(1, sampleRate, sampleRate);
const channelData = audioBuffer.getChannelData(0);
for (let i = 0; i < sampleRate; i += 1) {
channelData[i] = (Math.random() * 2) - 1;
}
audioBufferSourceNode.buffer = audioBuffer;
audioBufferSourceNode.connect(audioContext.destination);
audioBufferSourceNode.start(audioContext.currentTime);
});
</script>
</body>
</html>
但是稍微修改一下就不行了。在分配缓冲区之前启动 audioBufferSourceNode 时,将不再有输出。
audioBufferSourceNode.connect(audioContext.destination);
audioBufferSourceNode.start(audioContext.currentTime);
audioBufferSourceNode.buffer = audioBuffer;
我想您可以通过在启动源代码之前等待 HTTP 响应和音频解码来使您的代码正常工作。确保在执行this.source.buffer = buffer
之前执行this.source.start(index)
。
我希望这有帮助。
推荐阅读
- ssl - 创建 cUrl 请求时 SSL 证书已过期。域-> subdomain.domain (Magento)
- c++ - 在 Windows 上使用 Qt+ICC
- oracle-apex - Oracle APEX 预渲染点 - APEX 21.1
- java - 根据 kotlin 中的时间戳过滤 json 响应
- javascript - 使用 .map() 反应的未定义变量
- ios - 我的应用程序图标未正确加载?
- python - 由于 EnvironmentError 无法安装软件包:[WinError 5] 访问被拒绝
- json - 如何设置从 Power BI 到 Google Firebase 的连接?
- react-native - React Native:如何从循环中获取值到钩子 useState
- webassembly - DataWriter.StoreAsync() 在 WASM 上不可用