解决Chrome浏览器控制台Uncaught (in promise) DOMException问题的方法

发布于 2019-07-21  394 次阅读


起因

今天和往常一样,习惯性进入了自己的小破站看一眼

唯一不同的就是之前用的浏览器不是Chrome,问题来了,我的音乐呢???

经过

打开控制台一看,提示 Uncaught (in promise) DOMException 

???什么鬼东西,赶快Google了一下(为什么不百度?因为百度没搜到...)

然后找到了某位大佬的教程,地址:http://www.nooong.com/docs/chrome_video_autoplay.htm

在最新版的Chrome浏览器(以及所有以Chromium为内核的浏览器)中,已不再允许自动播放音频和视频。(Google的某些做法还真是令开发者不爽)。就算你为video或audio标签设置了autoplay属性也一样不能自动播放。如果你用 javascript 代码显式调用play方法,你将会在控制台看到如下异常:

Uncaught (in promise) DOMException

这是因为,Chrome只允许用户对网页进行主动触发后才可自动播放音频和视频。其实,严格地来说,是Chrome不允许在用户对网页进行触发之前播放音频,而视频其实是不受限制的。但因为视频文件同样包含了音频,所以也一同被禁止了。Chrome这样做的目的是为了防止开发者滥用自动播放功能而对用户产生骚扰。

常规解决方法

比较常规的做法是,为video标签设置muted属性,使它静音,这样视频就能自动播放了,但是没有声音。然后待用户在网页上有了任意触发后,再将muted去掉。或者让用户手动去打开音频(腾讯视频就是这样做的)。

<video autoplay muted></video>
document.body.addEventListener('mousedown', function(){
vdo.muted = false;
}, false);

但是这样给用户的体验终归不太好。那么接下来介绍一种非常规的做法。

非常规( Hack )解决方法

Chrome浏览器虽然对video标签和audio标签做了非常严格的限制,但它对另一个同样能播放音频和视频的标签iframe的限制却没那么严格。那么我们是否可使用iframe来触发权限呢?

<video></video>
<iframe allow="autoplay" style="display:none" src="一个空的音频文件"></iframe>
ifm.onload = function() {
    vdo.src = 'YOUR_VIDEO_URL';
    vdo.oncanplay = function() {
        vdo.play();
    };
};

将iframe的src属性指向一个音频文件,使它播放音频。为了给用户比较好的体验,这个音频文件最好是一个空的音频文件,即没有音频内容的文件,时长也尽可能短一点,比如500ms。

当iframe播放了这个音频文件后,就能触发网页播放音频的权限,这样再来播放视频或音频,就没有问题了。

PS:上面的代码只是随手写的,你可根据自己的逻辑加以优化,只要清楚这个原理就可以了。

综上所述,咱使用了方法二,在页面添加了

<iframe style="display:none" src="<?php echo TEMPLATE_URL; ?>audio/null.mp3">
</iframe>

再打开Chrome一看,唔姆~问题解决。

由此Chrome浏览器的自动播放问题解决了,但是又引出了第二个问题...

控制台报错

Resource interpreted as Document but transferred with MIME type audio/mpeg: "<?php echo TEMPLATE_URL; ?>audio/null.mp3".
你知道的太多了