尝试在 iOS 浏览器上通过 JS 播放 .mp3?
Trying to play an .mp3 via JS on iOS browsers?
我尝试使用 HTML 和 JS 制作节拍器。我知道由于限制,音频无法自动播放(无论如何我都不希望它自动播放),所以我放置了一个 <audio ...>
元素,里面有一个 <source ...>
,所有(我想?)适当的属性;我使用通过单击按钮触发的 JS 控制播放。这适用于我的笔记本电脑,甚至适用于 XBox Edge 浏览器,但在 iOS 浏览器(Safari 和 Firefox)上无法播放声音。 HTML 看起来像这样:
<button id="metronome-button">Start</button>
<audio id="metronome-audio" autoplay="0" autostart="0" loop="0">
<source src="tick.mp3" type="audio/mpeg">
</audio>
JS 看起来像这样:
const metronomeAudio = document.getElementById('metronome-audio');
const metronomeButton = document.getElementById('metronome-button');
let metronomeInterval = null;
metronomeButton.addEventListener('click', () => {
metronomeInterval = setInterval(() => {
metronomeAudio.loop = false;
metronomeAudio.pause();
metronomeAudio.play();
}, 500);
});
因为这不起作用,我做了更多的查找并在另一个 Whosebug 线程中找到了这个解决方案,它使用 JS 而根本没有 HTML(除了被按钮的 click
触发)事件):
function startMetronome () {
setInterval(() => {
let audio = new Audio('tick.mp3');
audio.loop = false;
audio.play();
audio.onended = () => {
audio.remove();
}
}, 500);
}
同样,这在 PC 上适用于各种浏览器,为什么 特别是 在 iOS 上失败? (没有在 Android 上测试过,没有设备。)
我不确定这是否在任何地方都有记录(我没有偶然发现),但经过一些额外的测试后我发现 iOS 禁止在 .play()
上使用函数=28=]现有HTML<audio>
元素或JSAudio()
元素,除非直接和同步调用作为a的结果用户 UI 事件。换句话说,这将起作用:
const button = document.getElementById('my-button')
const audio = document.getElementById('my-audio')
button.addEventListener('click', () => {
audio.play()
})
但这行不通:
const button = document.getElementById('my-button')
const audio = document.getElementById('my-audio')
button.addEventListener('click', () => {
setTimeout(() => { audio.play() }, 1000)
})
因此,在异步回调中调用 .play()
会中断 iOS 上的播放。
但是,如此处对此答案的评论中所述:,如果您在同步用户交互事件处理程序中实例化音频元素,则可以重复使用和重新播放(例如 .play()
) Audio()
元素随你喜欢。例如:
const button = document.getElementById('my-button')
let audio = null
button.addEventListener('click', () => {
audio = new Audio('myAudio.mp3')
// Works because `audio` itself was created synchronously during user event handler
setTimeout(() => { audio.play() }, 1000)
})
我尝试使用 HTML 和 JS 制作节拍器。我知道由于限制,音频无法自动播放(无论如何我都不希望它自动播放),所以我放置了一个 <audio ...>
元素,里面有一个 <source ...>
,所有(我想?)适当的属性;我使用通过单击按钮触发的 JS 控制播放。这适用于我的笔记本电脑,甚至适用于 XBox Edge 浏览器,但在 iOS 浏览器(Safari 和 Firefox)上无法播放声音。 HTML 看起来像这样:
<button id="metronome-button">Start</button>
<audio id="metronome-audio" autoplay="0" autostart="0" loop="0">
<source src="tick.mp3" type="audio/mpeg">
</audio>
JS 看起来像这样:
const metronomeAudio = document.getElementById('metronome-audio');
const metronomeButton = document.getElementById('metronome-button');
let metronomeInterval = null;
metronomeButton.addEventListener('click', () => {
metronomeInterval = setInterval(() => {
metronomeAudio.loop = false;
metronomeAudio.pause();
metronomeAudio.play();
}, 500);
});
因为这不起作用,我做了更多的查找并在另一个 Whosebug 线程中找到了这个解决方案,它使用 JS 而根本没有 HTML(除了被按钮的 click
触发)事件):
function startMetronome () {
setInterval(() => {
let audio = new Audio('tick.mp3');
audio.loop = false;
audio.play();
audio.onended = () => {
audio.remove();
}
}, 500);
}
同样,这在 PC 上适用于各种浏览器,为什么 特别是 在 iOS 上失败? (没有在 Android 上测试过,没有设备。)
我不确定这是否在任何地方都有记录(我没有偶然发现),但经过一些额外的测试后我发现 iOS 禁止在 .play()
上使用函数=28=]现有HTML<audio>
元素或JSAudio()
元素,除非直接和同步调用作为a的结果用户 UI 事件。换句话说,这将起作用:
const button = document.getElementById('my-button')
const audio = document.getElementById('my-audio')
button.addEventListener('click', () => {
audio.play()
})
但这行不通:
const button = document.getElementById('my-button')
const audio = document.getElementById('my-audio')
button.addEventListener('click', () => {
setTimeout(() => { audio.play() }, 1000)
})
因此,在异步回调中调用 .play()
会中断 iOS 上的播放。
但是,如此处对此答案的评论中所述:.play()
) Audio()
元素随你喜欢。例如:
const button = document.getElementById('my-button')
let audio = null
button.addEventListener('click', () => {
audio = new Audio('myAudio.mp3')
// Works because `audio` itself was created synchronously during user event handler
setTimeout(() => { audio.play() }, 1000)
})