浏览器音视频自动播放

前言

在开发中可能有遇到这样的需求,当用户打开页面后,需要自动播放视频或音频,按理说那就打开页面时play()一下不就搞定了吗,但实际情况很明显不是,不然也没得这篇文章喽,要实现这个需求,我们得先了解一下浏览器自动播放策略。再给出相应解决方案。

浏览器自动播放策略 Chrome浏览器的自动播放策略自Chrome66起生效,动机是改善用户体验

策略详情: Chrome 的自动播放政策很简单:

始终允许静音自动播放。 在以下情况下,带声音的自动播放会被允许: 用户已经与当前域进行了交互(click、tap) 在桌面设备上,用户的==媒体参与度==指数阈值已超过,这意味着用户之前播放过有声视频。 用户已将网站添加到移动设备上的主屏幕或在桌面上安装了 PWA。 顶部帧可以将自动播放权限委派给其 iframe,以允许自动播放声音。 ==媒体参与度(MEI, Media Engagement Index)==

媒体参与度 (MEI) 是衡量个人在网站上使用多媒体的倾向。

它是一个数字,可通过 chrome://media-engagement/ 查看。

数值越高,用户对该站点的媒体参与度越高,就越有机会自动播放。

但对于开发者而言:

媒体参与度的计算规则无法通过技术手段更改

媒体参与度的计算规则不同版本的浏览器可能会有变动

实现方案

首先呢,我们直接在用户进入页面的时候play(),可以发现视频并没有播放,并且报错Uncaught (in promise) DOMException: play() failed because the user didn't interact with the document first

html 复制代码
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <link rel="stylesheet" href="./index.css" />
  </head>
  <body>
    <div class="vdo-container">
      <video src="https://www.runoob.com/try/demo_source/movie.mp4"></video>
    </div>
    <script>
      const vdo = document.querySelector('video');
      vdo.play();
    </script>
  </body>
</html>

这个错误的意思是浏览器已经尝试在没有用户交互的情况下播放媒体文件,但是因为这是不允许的,所以浏览器拒绝了该操作。如果没有这个保护机制,那么网站可以在用户不知情的情况下播放音频和视频,这是不安全和不负责任的行为。

方案1: 互动后播放

先尝试自动播放,若发生异常,则引导用户进行互动操作,然后再进行播放

进入页面后发现不能自动播放,这时显示开始播放按钮,用户点击后开始播放。

方案2: 互动后出声

先静音播放,然后根据是否能自动播放决定是否取消静音,如果:

  1. 能自动播放,取消静音
  2. 不能自动播放,引导用户进行互动操作后取消静音
html 复制代码
<!DOCTYPE html>
  <html lang="en">
    <head>
      <meta charset="UTF-8" />
      <meta http-equiv="X-UA-Compatible" content="IE=edge" />
      <meta name="viewport" content="width=device-width, initial-scale=1.0" />
      <title>互动后取消静音</title>
      <link rel="stylesheet" href="./index.css" />
    </head>
    <body>
      <div class="vdo-container">
        <video src="https://www.runoob.com/try/demo_source/movie.mp4"></video>
        <div class="modal">
          <button class="btn">打开声音</button>
        </div>
      </div>
   
      <script>
        const vdo = document.querySelector('video');
        const modal = document.querySelector('.modal');
        const btn = document.querySelector('.btn');
        function play() {
          vdo.muted = true; // 静音
          vdo.play();
          const ctx = new AudioContext();
          const canAutoPlay = ctx.state === 'running';
          ctx.close();
          if (canAutoPlay) {
            vdo.muted = false;
            modal.style.display = 'none';
            btn.removeEventListener('click', play);
          } else {
            modal.style.display = 'flex';
            btn.addEventListener('click', play);
          }
        }
        play();
      </script>
    </body>
  </html>
  
  <!-- https://www.runoob.com/try/demo_source/movie.mp4 -->
</html>

进入页面后静音播放视频,然后判断是否允许自动播放,如果允许,则取消静音,但我们这里不允许,所以显示打开声音按钮。

引用的index.css文件内容如下:

css 复制代码
 * {
	    margin: 0;
	    padding: 0;
	    box-sizing: border-box;
	  }
	   
	  .vdo-container {
	    width: 50%;
	    margin: 1em auto;
	    position: relative;
	  }
	  video {
	    display: block;
	    width: 100%;
	  }
	  .modal {
	    position: absolute;
	    inset: 0;
	    background: rgba(0, 0, 0, 0.5);
	    display: flex;
	    justify-content: center;
	    align-items: center;
	    display: none;
	  }
	  .btn {
	    border: none;
	    outline: none;
	    background: #409eff;
	    color: #fff;
	    display: inline-block;
	    line-height: 1;
	    white-space: nowrap;
	    cursor: pointer;
	    text-align: center;
	    transition: 0.1s;
	    font-weight: 500;
	    user-select: none;
	    padding: 12px 20px;
	    font-size: 14px;
	    border-radius: 4px;
	  }
	  .btn:hover {
	    background: #66b1ff;
	  }
	  .btn:active {
	    background: #3a8ee6;
	  }
	  .btn:disabled {
	    background: #66b1ff80;
	    cursor: not-allowed;
	  }
相关推荐
福兮说8 小时前
设计稿是 #4A7C6F,页面量出来是 #4B7C6F:HEX、HSL、透明度、canvas 来回转的七个坑
前端·javascript·css·canvas
郑州光合科技余经理9 小时前
海外版外卖加盟:总站与分站配送规则怎么分开管
java·开发语言·前端·后端·uni-app·php·ai编程
小呆呆6669 小时前
副业搞起来,小说,漫画,漫剧的成本优化思路
前端·后端·面试
Dovis(誓平步青云)10 小时前
浇水提醒刚弹出又消失,植物状态别只存一个百分比
开发语言·前端·javascript·pdf·ecmascript·电脑
码艺-Alimjan10 小时前
Vben Admin 新增维吾尔语 Vben-Modal的关键坑之一
前端·javascript·vue.js
可乐鸡翅yeah_11 小时前
hls.js 手动自定义 http 请求 loader,修改请求头实战
开发语言·前端·javascript·网络协议·http·ecmascript·m3u8在线
IT_陈寒11 小时前
Vite静态资源导入这个坑我帮你们踩过了
前端·人工智能·后端
广州华水科技11 小时前
大坝安全监测解决方案:单北斗GNSS形变监测系统应用与维护
前端
yivifu12 小时前
中文古籍电子书注释集成
前端·javascript·python·beautifulsoup·epub
默_笙12 小时前
🛴 从散件到整机:DeepAgents 与 Agent 身上预留的那些"插槽"(前置介绍)
前端·javascript