iOS 15: 锁屏几分钟后网络音频播放在 Safari 中停止工作
iOS 15: Web Audio playback stops working in Safari after locking screen for a few minutes
这似乎是我将 iPod Touch 升级到 iOS 15 (15.0.1) 后的一个问题。
当 运行 下面的例子时,它在第一次加载时工作正常,播放声音的次数不限。但是,如果我锁定 iPod Touch 的屏幕,然后 return 几分钟后,声音将不再播放。为了排除故障,我在 AudioContext 实例上设置了一个状态更改侦听器,并验证了 Safari 在屏幕锁定时将状态设置为 interrupted
后将状态设置回 running
。然而,声音没有播放。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>audio-test</title>
</head>
<body>
<script>
const AudioContext = window.AudioContext || window.webkitAudioContext;
const audioContext = new AudioContext();
// Create AudioBuffer and fill with two seconds of white noise.
const channels = 2;
const frameCount = audioContext.sampleRate * 2.0;
const audioBuffer = audioContext.createBuffer(channels, frameCount, audioContext.sampleRate);
for (var channel = 0; channel < channels; channel++) {
var nowBuffering = audioBuffer.getChannelData(channel);
for (var i = 0; i < frameCount; i++) {
nowBuffering[i] = Math.random() * 2 - 1;
}
}
const button = document.createElement('button');
button.textContent = 'Play Audio';
document.body.append(button);
button.addEventListener('click', () => {
const currentSourceNode = new AudioBufferSourceNode(audioContext, {
buffer: audioBuffer,
});
currentSourceNode.connect(audioContext.destination);
currentSourceNode.start();
});
</script>
</body>
</html>
奇怪的是,如果我向 HTML 添加一个指向某个 mp3 文件的音频元素,代码中甚至根本没有引用该文件,然后锁定屏幕一段时间然后返回到页面不再影响音频播放。
更新代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>audio-test</title>
</head>
<body>
<script>
const AudioContext = window.AudioContext || window.webkitAudioContext;
const audioContext = new AudioContext();
// Create AudioBuffer and fill with two seconds of white noise.
const channels = 2;
const frameCount = audioContext.sampleRate * 2.0;
const audioBuffer = audioContext.createBuffer(channels, frameCount, audioContext.sampleRate);
for (var channel = 0; channel < channels; channel++) {
var nowBuffering = audioBuffer.getChannelData(channel);
for (var i = 0; i < frameCount; i++) {
nowBuffering[i] = Math.random() * 2 - 1;
}
}
const button = document.createElement('button');
button.textContent = 'Play Audio';
document.body.append(button);
button.addEventListener('click', () => {
const currentSourceNode = new AudioBufferSourceNode(audioContext, {
buffer: audioBuffer,
});
currentSourceNode.connect(audioContext.destination);
currentSourceNode.start();
});
</script>
<audio src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/858/outfoxing.mp3" crossorigin="anonymous"></audio>
</body>
</html>
屏幕锁定不允许脚本在 IOS 上 运行。
我的解决方法是 运行 2 个音频播放器元素。
一个 audioElementWithSound,另一个带有空的 10s.mp3 文件。
点击播放开始两个元素。
然后我有一个事件监听器在 empty.mp3 上监听 'ended',如果 withSound 还没有播放完,re-starting empty.mp3。
看起来像这样:
let audioElement();
let stayAwakeAudio();
function playSound(){
audioElement.src = "/assets/audioClip.mp3"
audioElement.play;
stayAwake()
}
function stayAwake() {
console.log("I'm awake");
stayAwakeAudio.src = "/assets/empty10sSoundFile.mp3";
stayAwakeAudio.play();
}
stayAwakeAudio.addEventListener('ended', function () {
if (audioElement.play) {
console.log('Audio still playing')
stayAwake();
}
else {
console.log('No audio playing, letting screen time out');
}
}, false);
这似乎是我将 iPod Touch 升级到 iOS 15 (15.0.1) 后的一个问题。
当 运行 下面的例子时,它在第一次加载时工作正常,播放声音的次数不限。但是,如果我锁定 iPod Touch 的屏幕,然后 return 几分钟后,声音将不再播放。为了排除故障,我在 AudioContext 实例上设置了一个状态更改侦听器,并验证了 Safari 在屏幕锁定时将状态设置为 interrupted
后将状态设置回 running
。然而,声音没有播放。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>audio-test</title>
</head>
<body>
<script>
const AudioContext = window.AudioContext || window.webkitAudioContext;
const audioContext = new AudioContext();
// Create AudioBuffer and fill with two seconds of white noise.
const channels = 2;
const frameCount = audioContext.sampleRate * 2.0;
const audioBuffer = audioContext.createBuffer(channels, frameCount, audioContext.sampleRate);
for (var channel = 0; channel < channels; channel++) {
var nowBuffering = audioBuffer.getChannelData(channel);
for (var i = 0; i < frameCount; i++) {
nowBuffering[i] = Math.random() * 2 - 1;
}
}
const button = document.createElement('button');
button.textContent = 'Play Audio';
document.body.append(button);
button.addEventListener('click', () => {
const currentSourceNode = new AudioBufferSourceNode(audioContext, {
buffer: audioBuffer,
});
currentSourceNode.connect(audioContext.destination);
currentSourceNode.start();
});
</script>
</body>
</html>
奇怪的是,如果我向 HTML 添加一个指向某个 mp3 文件的音频元素,代码中甚至根本没有引用该文件,然后锁定屏幕一段时间然后返回到页面不再影响音频播放。
更新代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>audio-test</title>
</head>
<body>
<script>
const AudioContext = window.AudioContext || window.webkitAudioContext;
const audioContext = new AudioContext();
// Create AudioBuffer and fill with two seconds of white noise.
const channels = 2;
const frameCount = audioContext.sampleRate * 2.0;
const audioBuffer = audioContext.createBuffer(channels, frameCount, audioContext.sampleRate);
for (var channel = 0; channel < channels; channel++) {
var nowBuffering = audioBuffer.getChannelData(channel);
for (var i = 0; i < frameCount; i++) {
nowBuffering[i] = Math.random() * 2 - 1;
}
}
const button = document.createElement('button');
button.textContent = 'Play Audio';
document.body.append(button);
button.addEventListener('click', () => {
const currentSourceNode = new AudioBufferSourceNode(audioContext, {
buffer: audioBuffer,
});
currentSourceNode.connect(audioContext.destination);
currentSourceNode.start();
});
</script>
<audio src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/858/outfoxing.mp3" crossorigin="anonymous"></audio>
</body>
</html>
屏幕锁定不允许脚本在 IOS 上 运行。
我的解决方法是 运行 2 个音频播放器元素。 一个 audioElementWithSound,另一个带有空的 10s.mp3 文件。
点击播放开始两个元素。 然后我有一个事件监听器在 empty.mp3 上监听 'ended',如果 withSound 还没有播放完,re-starting empty.mp3。
看起来像这样:
let audioElement();
let stayAwakeAudio();
function playSound(){
audioElement.src = "/assets/audioClip.mp3"
audioElement.play;
stayAwake()
}
function stayAwake() {
console.log("I'm awake");
stayAwakeAudio.src = "/assets/empty10sSoundFile.mp3";
stayAwakeAudio.play();
}
stayAwakeAudio.addEventListener('ended', function () {
if (audioElement.play) {
console.log('Audio still playing')
stayAwake();
}
else {
console.log('No audio playing, letting screen time out');
}
}, false);