thumbnail
前端的音视频自动播放,一直以来都是一个很玄学的东西。像B站、抖音这类视频网站,你会发现它都能够实现自动播放,但是一旦到了我们自己的网站上它就不行了。今天我们来讲讲浏览器的自动播放策略。
SCOTT STIDIO

介绍

以Chrome浏览器为例,从Chrome66开始之后,增加了浏览器自动播放的策略。这么做的原因也很简单,就是为了改善用户体验。不然的话,所有的网站都能自动播放,用户一进这个网站啥也没看到,就看到一个全屏的广告,然后声音很大被吓一跳,用户体验就会很差。

Chrome的自动播放策略

1. 始终允许静音自动播放。

2. 在以下情况下,带声音的自动播放会被允许。

允许的情况

  • 用户已经与当前域进行了交互(click、tap)。
  • 在桌面设备上,用户的媒体参与度指数阈值已经超过,它就能够实现自动播放。
  • 用户已将网站添加到移动设备的主屏幕或在桌面上安装了PWA。

3. 顶部域可以将自动播放权限委派给其iframe,以允许自动播放声音。

什么是媒体参与度

它的全称叫做media engagement index,它是用来衡量个人在网站上使用多媒体的倾向,换人话来说就是这个用户对你这个网站上的多媒体,也就是视频、音频,对这些东西到底有多感兴趣,它算出来呢是一个数字,这个数字呢可以通过一个地址来查看,chrome://media-engagement/

可以看到每个网站对应的Score,如果分数太低的话,浏览器就不会允许自动播放。

那么具体来说,我是一个网站的开发者,我如何来提高用户对我这个网站上的评分呢?评分越高,我就越能够拥有自动播放的能力,那我是不是要详细的去了解这个媒体参与度它到底是怎么算的,它的数字是怎么算出来的?

其实不需要,有几个原因,一是它的分数算法是比较复杂的,要考虑很多情况。比方说你这个用户在这个网站上之前有没有播放过视频?播放了多久?当时这个视频在这个视口版面有多大?他可能要考虑很多因素来综合判断,甚至还包括用户有多长时间没有访问这个网站的。那么这个评分是不是要得重新计算,这些都是考量的因素,而且关键是什么呢?关键是对于开发者而言,这个媒体参与度的计算规则,我们是无法通过技术手段来更改的,无论你写什么样的代码,你都无法更改这个计算规则。第二呢,这个计算规则在不同版本的浏览器可能会有变动。

所以综合下来的话,你要去改这个计算规则就不可能,那不能改怎么办?只能适应,也就是说你在自动播放音视频的时候,你就要做个假设,有可能它是播放不成功的,那么你就要针对成功和不成功分别去写这个逻辑。

解决方案

那么像在那些大的视频网站上,他们是怎么做的呢?

方案一:互动之后再播放

互动之后再播放是啥意思?就是我先尝试着把视频的自动播放,如果说发生了异常,就像下面的代码那样报错了是吧?那么这个时候呢,我就出现一个按钮在页面上,然后让用户去点一下这个按钮,点了过后,是不是有交互了,有了交互之后就可以自动播放了。Uncaught (in promise) DOMException: play() failed because the user didn't interact with the document first.

来看下这个例子,页面内有一个视频和一个蒙层和默认是隐藏的一个按钮。然后我们写的一个play方法播放视频,然后去调用它。首先呢,我找到这个视频元素,尝试的去播放它,因为它是一个promise,所以需要等它的返回结果。如果说返回的这个promise是拒绝的,那么就进入catch启表示播放失败,那么在这里就认为它是自动播放失败。

当然这个音视频的播放失败会有很多原因,其他的原因这个例子先暂时不考虑,就认为它是自动播放失败。这时候就分开走逻辑了,如果是播放失败的情况下,我就要把那个蒙层给显示出来,然后给这个按钮注册一个点击事件,点击了过后再重新的去调用这个play方法。因为你点了之后不就有不操作了吗?有了不操作不就能播放了吗?所以点击之后视频就会播放了。

方案二:互动后打开声音

第二种方案是我们目前企业里边经常使用的方案,像抖音使用的就是第二种方案。你的播放策略不是写着可以静音播放吗?对吧?那我就先静音播放,然后再判断一下到底能不能自动播放,如果说能的话,那就把声音打开,取消静音,如果说不能的话,那么就引导用户进行互动操作之后再取消静音。

代码呢并不复杂,你看还是一个play方法。首先静音,静音完了过后就直接播放了,我就不用去等待它了,因为它一定能播放成功的。然接下来我就要判断了,到底是不是能够带声音的播放,这里呢我顺便写了第二种判断是否能够自动播放的方式,就是使用音频上下文,因为这个自动播放策略啊,它不仅仅会影响到video元素和audio元素,还会影响到那些音频上下文里边的声音啊,这个玩意呢,一般是做声音合成和处理的。我们创建一个音频上下文,它里边一个属性叫state,如果说它是能够自动播放的话,那么这个状态呢,就是running,这个上下文里边有个音轨就开始走了,但是呢,如果说它状态不是running,而是suspense表示挂起,那么就得到的是false,我们就可以通过判断它是不是等于running来得到是不是能够自动播放,然后不要忘记把这个上下文给关闭掉。如果说能自动播放的话那就把静音取消,然后蒙层隐藏对吧,把按钮的事件取消掉。如果说不能自动播放的话,那么我就把蒙层显示出来,给按钮注册一个点击事件,然后点击之后呢,还是调用一个方法,那么点击之后是不是就有交互操作了,那就一定能够自动播放。

总结

不同的网站会有不同的做法,有的是直接静音实现自动播放,有的是显示一个蒙层让你点击播放,而打开声音的操作也就是在引导你去点击页面实现交互,都是一样的道理。

最后~如果本文对你有所帮助,可以点个赞或者请我喝杯奶茶~万分感谢🎉🎉🎉