声音没法自动播放这个在IOS/Android上面一直是个惯例,桌面版的Safari在2017年的11版本也宣布禁掉带有声音的多媒体自动播放功能,紧接着在2018年4月份发布的Chrome 66也正式关掉了声音自动播放,也就是说浏览器
<audio autopaly></audio> <video autoplay></video>
在桌面版浏览器也将失效。ide
最开始移动端浏览器是彻底禁止音视频自动播放的,考虑到了手机的带宽以及对电池的消耗。可是后来又改了,由于浏览器厂商发现网页开发人员可能会使用GIF动态图代替视频实现自动播放,正如IOS文档所说,使用GIF的带宽流量是Video(h264)格式的12倍,而播放性能消耗是2倍,因此这样对用户反而是不利的。又或者是使用Canvas进行hack,如Android Chrome文档提到。所以浏览器厂商放开了对多媒体自动播放的限制,只要具有如下条件就能自动播放:post
(1)没音频轨道,或者设置了muted属性性能
(2)在视图里面是可见的,要插入到DOM里面而且不是display: none或者visibility: hidden的,没有滑出可视区域。url
换句话说,只要你不开声音扰民,且对用户可见,就让你自动播放,不须要你去使用GIF的方法进行hack.桌面版的浏览器在近期也使用了这个策略spa
对于网页开发人员来讲,应当如何有效地规避这个风险呢?.net
Chrome的文档给了一个最佳实践:先把音视频加一个muted的属性就能够自动播放,而后再显示一个声音被关掉的按钮,提示用户点一下打开声音。对于视频来讲,确实能够这样处理,而对于音频来讲,不少人是监听页面点击事件,只要点一次了就开始播放声音,通常就是播放个背景音乐。可是若是对于有多个声音资源的页面来讲如何自动播放多个声音呢?code
首先,若是用户还没进行交互就调用播放声音的API,Chrome会这么提示:orm
DOMException: play() failed because the user didn't interact with the document first.视频
Safari会这么提示:
NotAllowedError: The request is not allowed by the user agent or the platform in the current context, possibly because the user denied permission.
Chrome报错提示最为友善,意思是说,用户尚未交互,不能调play。用户的交互包括哪些呢?包括用户触发的touchend, click, doubleclick或者是 keydown事件,在这些事件里面就能调play.
因此上面提到不少人是监听整个页面的点击事件进行播放,无论点的哪里,只要点了就行,包括触摸下滑。这种方法只适用于一个声音资源,不适用多个声音,多个声音应该怎么破呢?这里并非说要和浏览器对着干,“逆天而行”,咱们的目的仍是为了提高用户体验,由于有些场景若是能自动播放确实比较好,如一些答题的场景,须要听声音进行答题,若是用户在答题的过程当中能依次自动播放相应题目的声音,确实比较方便。同时也是讨论声音播放的技术实现。
原生播放视频应该就只能使用video标签,而原生播放音频除了使用audio标签以外,还有另一个API叫AudioContext,它是可以用来控制声音播放并带了不少丰富的操控接口。调audio.play必须在点击事件里面响应,而使用AudioContext的区别在于只要用户点过页面任何一个地方以后就都能播放了。因此能够用AudioContext取代audio标签播放声音。
对于移动端开发可考虑用原生AudioContext,使用参考:https://juejin.im/post/5af7129bf265da0b8262df4c
对于浏览器pc网页能够不用这么麻烦,设置了muted属性就能够绕过去,解决方案就是默认先加上muted标签,要播放的时候先关掉静音,再调用play方法播放就能够。