前端 javascript 苹果IOS系统Safari手机浏览器自动播放问题

前端虐我千万遍,我仍待它如初恋。前端开发中,各种坑多如牛毛,刚好今天又踩一个。

本次项目中需要开发一个音乐播放器,关于音频播放在众多安卓手机上测试均无问题,上IOS测试就完蛋了。

网上常见自动播放方法基本都是在页面载入时候监听 touch 事件,触发事件在自动播放,此方法不适用本次项目需求。

先梳理一下项目流程

H5页面,有一个音乐列表,该列表仅显示音乐名字等基本信息。

点击某首歌曲时候,将音乐加入播放器的播放列表,同时会查询服务器接口,判断该音乐是否支持免费播放,如果支持免费播放,直接拿播放地址播放即可,否则跳转支付。

伪代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
// 页面载入新建 audio 标签
const audio = new Audio()
item.on('click', async () => {
const res = await getPlayUrl({xxx})
if (res.code === 1) {
// 接口请求完成赋值
audio.src = res.src
audio.load()
audio.play()
} else {
// 支付流程
}
})

以上代码在安卓手机运行毫无问题,但是IOS上无法运行,原因是因为有异步 ajax 查询,在查询之后再操作音频播放,IOS会认为该操作不是用户触发,不会给播放。

如何处理

如果将以上代码稍作处理,IOS播放也无问题:

1
2
3
4
5
6
7
8
9
10
11
12
13
item.on('click', async () => {
// 触发事件新建 audio 标签
const audio = new Audio()
const res = await getPlayUrl({xxx})
if (res.code === 1) {
// 接口请求完成赋值
audio.src = res.src
audio.load()
audio.play()
} else {
// 支付流程
}
})

代码没怎么修改,只是将创建 audio 标签放在了 click 事件中,如此操作IOS也认为无问题,可以播放。

但是这样做有个问题:点击多次会生成很多 audio 标签,每次新建 audio 时候需要销毁上一次创建的 audio ,而 audio 无销毁方法,需要手动暂停播放,这样做对程序不太友好,还是希望使用一个 audio 标签最好。

解决办法

结合上面每次新建 audio 能播放的思路,尝试在click事件时候先播放一段音频,等接口完了再切换即可。

代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 页面载入新建 audio 标签
const audio = new Audio()
item.on('click', async () => {
audio.src = '空白音频'
audio.load()
audio.play()
const res = await getPlayUrl({xxx})
if (res.code === 1) {
// 接口请求完成赋值
audio.src = res.src
audio.load()
audio.play()
} else {
// 支付流程
}
})

以上代码也能解决异步事件后面的播放问题,当然还需要处理进入支付流程需要停止播放,本文不再赘述。

—-5.31新增—-

更好一点处理方式,在播放后立即暂停空白音频,等待接口请求完成再播放新的音频:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 页面载入新建 audio 标签
const audio = new Audio()
item.on('click', async () => {
audio.src = '空白音频'
audio.load()
audio.play().then(() => {
audio.pause() //播放后立即暂停空白音频
}).catch(() => {})
const res = await getPlayUrl({xxx})
if (res.code === 1) {
// 接口请求完成赋值
audio.src = res.src
audio.load()
audio.play()
} else {
// 支付流程
}
})

附件

空白音频附件:audio-blank.mp3

本文由 linx(544819896@qq.com) 创作,采用 CC BY 4.0 CN协议 进行许可。 可自由转载、引用,但需署名作者且注明文章出处。本文链接为: https://blog.jijian.link/2021-04-28/js-ios-auto-play/

如果您觉得文章不错,可以点击文章中的广告支持一下!