【问题标题】:Trying to play an .mp3 via JS on iOS browsers?尝试在 iOS 浏览器上通过 JS 播放 .mp3?
【发布时间】:2021-05-23 19:38:12
【问题描述】:

我尝试使用 HTML 和 JS 制作节拍器。我知道由于限制,音频无法自动播放(无论如何我都不想要它),所以我在里面放置了一个带有 <source ...><audio ...> 元素,其中包含所有(我认为?)适当的属性;我使用由按钮单击触发的 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);
});

由于这不起作用,我做了更多的查找,并在另一个 StackOverflow 线程中找到了这个解决方案,该线程使用 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上测试,没有设备。)

【问题讨论】:

标签: javascript html5-audio mobile-website


【解决方案1】:

我不确定这是否记录在任何地方(我没有偶然发现),但经过一些额外测试后,我发现 iOS 禁止在 现有 HTML 上使用 .play() 函数&lt;audio&gt; 元素或 JS Audio() 元素,除非作为用户 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 上的播放。

但是,正如在此答案的评论中提到的:https://stackoverflow.com/a/54432573/983173,如果您在同步用户交互事件处理程序中实例化您的音频元素,您可以重复使用和重新播放(例如.play())@ 987654329@ 元素随你喜欢。例如:

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)
})

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-04-09
    • 1970-01-01
    • 2013-01-10
    • 2020-04-15
    • 2014-02-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多