浏览器音视频自动播放

前言

在开发中可能有遇到这样的需求,当用户打开页面后,需要自动播放视频或音频,按理说那就打开页面时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;
	  }
相关推荐
王哈哈^_^42 分钟前
【数据集】【YOLO】【目标检测】交通事故识别数据集 8939 张,YOLO道路事故目标检测实战训练教程!
前端·人工智能·深度学习·yolo·目标检测·计算机视觉·pyqt
cs_dn_Jie1 小时前
钉钉 H5 微应用 手机端调试
前端·javascript·vue.js·vue·钉钉
开心工作室_kaic2 小时前
ssm068海鲜自助餐厅系统+vue(论文+源码)_kaic
前端·javascript·vue.js
有梦想的刺儿2 小时前
webWorker基本用法
前端·javascript·vue.js
cy玩具2 小时前
点击评论详情,跳到评论页面,携带对象参数写法:
前端
qq_390161773 小时前
防抖函数--应用场景及示例
前端·javascript
John.liu_Test4 小时前
js下载excel示例demo
前端·javascript·excel
Yaml44 小时前
智能化健身房管理:Spring Boot与Vue的创新解决方案
前端·spring boot·后端·mysql·vue·健身房管理
PleaSure乐事4 小时前
【React.js】AntDesignPro左侧菜单栏栏目名称不显示的解决方案
前端·javascript·react.js·前端框架·webstorm·antdesignpro
哟哟耶耶4 小时前
js-将JavaScript对象或值转换为JSON字符串 JSON.stringify(this.SelectDataListCourse)
前端·javascript·json