浏览器音视频自动播放

前言

在开发中可能有遇到这样的需求,当用户打开页面后,需要自动播放视频或音频,按理说那就打开页面时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;
	  }
相关推荐
qiyi.sky5 分钟前
JavaWeb——Vue组件库Element(3/6):常见组件:Dialog对话框、Form表单(介绍、使用、实际效果)
前端·javascript·vue.js
煸橙干儿~~8 分钟前
分析JS Crash(进程崩溃)
java·前端·javascript
安冬的码畜日常17 分钟前
【D3.js in Action 3 精译_027】3.4 让 D3 数据适应屏幕(下)—— D3 分段比例尺的用法
前端·javascript·信息可视化·数据可视化·d3.js·d3比例尺·分段比例尺
l1x1n01 小时前
No.3 笔记 | Web安全基础:Web1.0 - 3.0 发展史
前端·http·html
昨天;明天。今天。1 小时前
案例-任务清单
前端·javascript·css
zqx_72 小时前
随记 前端框架React的初步认识
前端·react.js·前端框架
惜.己2 小时前
javaScript基础(8个案例+代码+效果图)
开发语言·前端·javascript·vscode·css3·html5
什么鬼昵称3 小时前
Pikachu-csrf-CSRF(get)
前端·csrf
长天一色3 小时前
【ECMAScript 从入门到进阶教程】第三部分:高级主题(高级函数与范式,元编程,正则表达式,性能优化)
服务器·开发语言·前端·javascript·性能优化·ecmascript
NiNg_1_2343 小时前
npm、yarn、pnpm之间的区别
前端·npm·node.js