HTML 踩坑笔记: video 标签 autoplay 属性失效(Error: Uncaught (in promise) DOMException: play() failed)

0. 项目背景

  • 浏览器:Chrome

在前端项目中使用 <video /> 标签

1. 问题描述

使用如下 html 元素

<video autopaly />
  • 核心问题:自动播放无效

尝试: 主动调用 play 方法(失败)

加入如下代码

<video autopaly />

<script>
  document.querySelector('video').play()
<script/>

产生如下报错

Uncaught (in promise) DOMException: play() failed because the user didn't interact with the document first.

2. 解决方案

问题在于 Chrome 的视频政策:传送门 - Autoplay policy in Chrome

重点就是:

避免自动播放视屏,最小化用户安装 Ads Block 的想法hh

因此我们可以提出以下三种解决方案

2.1 解决方案 1: 静音

根据 Chrome 的规则,加上 muted 静音属性就允许自动播放了

<video src="sample.mp4" autoplay muted></video>

然而这或许就失去播放的意义了hh,还要找个机会把静音取消掉

2.2 解决方案 2: 监听初次点击后播放

第二种办法就是等待用户进行第一次操作之后就能够播放了,代码如下

  • index.html
<video src="sample.mp4" controls autoplay></video>

<script>
  const video = document.querySelector('video');

  // auto play when script loaded
  video
    .play()
    .then(() => {
      console.log(`autoplay well`);
    })
    .catch((e) => {
      console.log(`autoplay fail, wait for first click`);
      if (e instanceof DOMException) {
        // play before user intersact
        const autoPlayAfterAnyClick = () => {
          video.play();
          document.removeEventListener('click', autoPlayAfterAnyClick);
        };

        document.addEventListener('click', autoPlayAfterAnyClick);
        throw e;
      } else {
        // or rethrow
        throw e;
      }
    });
</script>

我们先调用 play 方法检测是否调用成功,如果因为 autoplay policy 失败则监听 document 的点击事件

2.3 解决方案 3: 将视频放入用户操作链路后段(推荐)

最后一种应该也是最好的,那就是不要自动播放,或是说根据用户的操作/路由/导航,再进行视频的加载、播放,如此一来 autoplay 属性也不会受 policy 的影响

  • index2.html
<video controls autoplay></video>

<button id="load">Load video</button>

<script>
  const video = document.querySelector('video');

  document.querySelector('#load').addEventListener('click', () => {
    video.src = './sample.mp4';
  });
</script>

参考连接

TitleLink
Autoplay policy in Chrome - Chrome Developershttps://developer.chrome.com/blog/autoplay/#developer-switches
what constitues user gesture - stackoverflowhttps://stackoverflow.com/questions/56388258/what-constitues-user-gesture

完整代码示例

https://github.com/superfreeeee/Blog-code/tree/main/front_end/html/html_video_autoplay

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐