前端视频无法自动播放的问题,基于Chrome浏览器的自动播放策略原理,详细解释加了autoplay属性之后视频仍然不能自动播放的问题,并提供了二种主流的解决方法

news2025/1/16 15:48:21

目录

一,什么是Chrome浏览器的自动播放策略?(原理讲解,懂了原理解决问题就会非常简单)

1.生活场景中的案例

2.Chrome自动播放策略

3.什么是媒体参与度 

二: 案例演示(无法播放的情况)

1.使用autoplay属性

2.我们使用js来控制视频自动播放

3.这究竟是为什么

三.解决方案

1.引导用户进行交互

2.先静音播放,让用户自己控制声音


一,什么是Chrome浏览器的自动播放策略?(原理讲解,懂了原理解决问题就会非常简单)

1.生活场景中的案例

试问一下,如果你正在上班摸鱼准备刷抖音或者B站时,但是忘记了调小声音或是忘记了带耳机,突然的视频声音放出来会不会让你特别尴尬,旁边可都是人看着呢,而且你要是放了个正常的视频还好,不然的话,纯纯大社死有咩有。

所以呢,在2018年Chrome就提出了这种自动播放的策略,主要是为了照顾用户的体验感。

2.Chrome自动播放策略

  • 始终允许静音模式下自动播放

  • 在以下的情况中,带声音播放会被允许:

    ①用户已经与当前的域进行了交互(也就是click,tap事件)。

    ②在桌面设备上,用户的媒体参与度指数阈值已经超过,这意味着用户之前播放过有声视频。

    ③用户已经将网站添加到移动设备上的主屏幕或允在桌面上安装了PWA。

  • 顶部帧可以将自动播放权限委派给其iframe,来允许自动播放声音

3.什么是媒体参与度 

媒体参与度(Media Engagement)是指用户与媒体内容进行互动的程度,可以通过多个指标来衡量。这些指标主要包括观看时间、观看率、转化率、交互行为等。Chrome基于这个媒体参与度有一套自己算法,我们可以通过:chrome://media-engagement/ 查看

二: 案例演示(无法播放的情况)

1.使用autoplay属性

就使用一个盒子里面放一个video标签并且加上autoplay属性

<div class="box">
    <video src="./img/_12084f25eab2e6978b505b0520b978b-1-64.MP4" autoplay></video>
  </div>

可以看到虽然我们设置了autoplay属性但是视频还是不能播放(如果你能播放,你可以试着刷新几次看看,他就不能自动播放了,具体原因暂且未知,总之我们必须要保证它每次都能按照我们的需求来才行)

这时我们可以看一下控制台有没有报错

 可以看到控制台是已经报错了,这个报错信息大概的意思就是用户没有与此视频进行第一次的交互,导致无法自动播放

 可以看到,有道翻译过来也是类似的意思

2.我们使用js来控制视频自动播放

js的代码也是非常简单的

  const video = document.querySelector('video')
  video.play()

但是play()方法并没有起到任何作用(如果自动播放可以多刷新几次,就可以发现这是不可控的)

3.这究竟是为什么

我们可以查看媒体参与度来看看:chrome://media-engagement/

 可以看到我当前的网页的得分(Score)是最低的,也就是这个原因,我们的Chrome浏览器不允许我们自动播放,可能有些人会想到静音播放,没错这是现代非常主流的一种解决方法,下面会讲解。

三.解决方案

1.引导用户进行交互

我们在理解了这个原理之后呢,就自然而然的能想到解决方法了,既然要用户与其交互,那我们就让他交互呗,我们可以设置一个按钮来控制他的播放。

  <div class="box">
    <video src="./img/_12084f25eab2e6978b505b0520b978b-1-64.MP4" autoplay></video>
    <div class="model">
      <button>开始播放</button>
    </div>
  </div>

我们可以写一个函数来控制此按钮

  const model = document.querySelector('.model')
  const btn = document.querySelector('button')
  // 第一种方法 引导用户去与页面交互实现播放
  async function play() {
    try {
      await video.play(); 
      //使用await的原因是因为video.play()方法返回的是一个Promise,所以在这里我们可以对他进行一些处理
      model.style.display = 'none';
      btn.removeEventListener('click', play);
      // 如果他自动播放了就隐藏按钮,消除点击事件
    } catch (err) {
      model.style.display = 'block';
      btn.addEventListener('click', play);
      // 如果Promise返回的是error就引导用户点击按钮,在调用play方法
    }
  }
  play();

代码中已经有了非常详细的注释,我也就不做过多的解释,主要思路就是引导用户进行交互,交互了之后在调用方法,肯定是可以实现播放的,通过前面的原理分析可以得知。

2.先静音播放,让用户自己控制声音

这个方法在现在的很多网页中都使用了,比如抖音,B站等。

也是一样写一个函数来控制

  //第二种方法比较主流,类似的有网页版抖音以及B站
  function play() {
    video.muted = true;//设置视频为静音
    video.play();//调用播放方法
    const ctx = new AudioContext();
    const canAutoPlay = ctx.state === 'running'; 
    //通过这个可以判断出视频能不能够自动播放 如果可以它的值就是“running” 否则为"suspended"
    // 如果是不能播放我们就执行下面的逻辑,其实就是类似于第一种方法,让用户与其交互
    ctx.close();
    if (canAutoPlay) {
      video.muted = false;
      model.style.display = 'none';
      btn.removeEventListener('click', play);
    }
    else {
      model.style.display = 'block';
      btn.addEventListener('click', play);
    }
  }
  play()

代码中也已经有了详细的注释,其实现思路也就是和之前进到的原理类似,既然可以静音播放,我们就先静音播放,而后引导用户来做交互

其实可以看到只要明白了原理,解决问题就会很简单

有什么问题可以私信或者留言

详细代码:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <!-- 
    Chrome 浏览器的视频自动播放策略
    1.始终允许静音模式下自动播放
    2.在以下的情况中,带声音播放会被允许:
      ①用户已经与当前的域进行了交互(也就是click,tap事件)。
      ②在桌面设备上,用户的媒体参与度指数阈值已经超过,这意味着用户之前播放过有声视频。
      ③用户已经将网站添加到移动设备上的主屏幕或允在桌面上安装了PWA。
    3.顶部帧可以将自动播放权限委派给其iframe,来允许自动播放声音
    
    媒体参与度(Media Engagement)是指用户与媒体内容进行互动的程度,可以通过多个指标来衡量。这些指标主要包括观看时间、观看率、转化率、交互行为等。
    可以通过:chrome://media-engagement/ 查看
   -->
  <style>
    * {
      margin: 0;
      padding: 0;
    }

    body {
      display: flex;
      justify-content: center;
    }

    video {
      width: 800px;
      height: 600px;
    }

    .box {
      position: relative;
    }

    .box button {
      width: 80px;
      height: 40px;
      position: absolute;
      top: 50%;
      left: 50%;
      border: none;
      background-color: rgb(61, 196, 230);
      transform: translate(-50%);
      color: #fff;
      border-radius: 10px;
    }

    .box button:hover {
      cursor: pointer;
    }
  </style>

</head>

<body>
  <div class="box">
    <video src="./img/_12084f25eab2e6978b505b0520b978b-1-64.MP4" autoplay></video>
    <div class="model">
      <button>开始播放</button>
    </div>
  </div>
</body>
<script>
  const video = document.querySelector('video')
  console.log(video.play());

  const model = document.querySelector('.model')
  const btn = document.querySelector('button')
  // 第一种方法 引导用户去与页面交互实现播放
  async function play() {
    try {
      await video.play();
      //使用await的原因是因为video.play()方法返回的是一个Promise,所以在这里我们可以对他进行一些处理
      model.style.display = 'none';
      btn.removeEventListener('click', play);
      // 如果他自动播放了就隐藏按钮,消除点击事件
    } catch (err) {
      model.style.display = 'block';
      btn.addEventListener('click', play);
      // 如果Promise返回的是error就引导用户点击按钮,在调用play方法
    }
  }
  play();

  //第二种方法比较主流,类似的有网页版抖音以及B站
  function play() {
    video.muted = true;//设置视频为静音
    video.play();//调用播放方法
    const ctx = new AudioContext();
    const canAutoPlay = ctx.state === 'running'; //通过这个可以判断出视频能不能够自动播放 如何可以它的值就是“running” 否则为"suspended"
    // 如果是不能播放我们就执行下面的逻辑,其实就是类似于第一种方法,让用户与其交互
    ctx.close();
    if (canAutoPlay) {
      video.muted = false;
      model.style.display = 'none';
      btn.removeEventListener('click', play);
    }
    else {
      model.style.display = 'block';
      btn.addEventListener('click', play);
    }
  }
  play()
</script>

</html>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1107951.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

chatglm2微调—ptuning

Freeze: 即参数冻结&#xff0c;对原始模型部分参数进行冻结操作&#xff0c;仅训练部分参数&#xff0c;以达到在单卡或不进行TP或PP操作&#xff0c;就可以对大模型进行训练。 P-Tuning: 在输入的embedding层前&#xff0c;将prompt转换为可学习的额外一层embedding层. P-T…

算水质TDS加温度补偿

先上图&#xff0c;就图里这款水质检测&#xff0c;用树莓派3/4的话&#xff0c;要配个温度检测作为温度校正&#xff0c;以及一个adc 元器件。我选ds18b20和ads1115。 再把模拟数据计算过程放一下&#xff1a; 温度检测元器件在农历钟那里提过&#xff0c;就是同款。此处先测个…

网页构造与源代码

下载google浏览器 设置打开特定网址&#xff1a;www.baidu.com 查看网页或元素源代码 网页右键选择“检查”查看源代码 网页源代码 元素源代码

【Git】bad signature 0x00000000 index file corrupt. fatal: index file corrupt

问题描述 电脑写代码时蓝屏。重启后 git commit 出错。 error: bad signature 0x00000000 fatal: index file corrupt原因分析 当电脑发生蓝屏或异常关机时&#xff0c;Git 的索引文件可能损坏。 解决方案 删除损坏的索引文件。 rm -Force .git/index回退到上一个可用的版…

数据结构复盘——第七章:查找和匹配

文章目录 第一部分&#xff1a;折半查找1、查找的主要步骤2、折半查找的判定树 第一部分习题第二部分&#xff1a;分块查找第三部分&#xff1a;散列查找1、散列查找的常用术语2、常用的散列函数&#xff1a;3、处理冲突的方法:3.1 开放定址法3.2 拉链法&#xff08;链接法、链…

【YOLO】语义分割和实例分割(四)

0 YOLO系列笔记 【YOLO】朴实无华的yolov5环境配置&#xff08;一&#xff09; 【YOLO】yolov5训练自己的数据集&#xff08;二&#xff09; 【YOLO】目标识别模型的导出和opencv部署&#xff08;三&#xff09; 1 前言 在之前的实践过程中&#xff0c;总结了如何使用YOLOv…

离线语音与IoT结合:智能家居发展新增长点

离线语音控制和物联网&#xff08;IoT&#xff09;相结合在家居中具有广泛的应用和许多优势。离线语音控制是指在设备在本地进行语音识别和处理&#xff0c;而不需要依赖云服务器进行处理。IoT是指借助网络&#xff0c;通过手机APP、小程序远程控制家居设备。 启英泰伦基于AI语…

一款.NET Core开源的基于Vue+ElementUI开发的博客系统 - StarBlog

前言 今天给大家推荐一款.NET Core开源的基于VueElementUI开发的博客系统 - StarBlog。该项目配套详细的文章教程&#xff0c;可以作为 .Net Core 入门项目学习。 官方项目介绍 StarBlog支持Markdown导入的博客。后端基于最新的.Net6和Asp.Net Core框架&#xff0c;遵循REST…

055:mapboxGL中加载geojson,导出为CSV格式文件

vue+mapbox 第055个 点击查看专栏目录 本示例介绍演示如何在vue+mapbox中加载geojson,导出为CSV格式文件。 通过一个插件,将geojson转化为csv,同时通过file-saver将文件下载下来。 直接复制下面的 vue+mapbox源代码,操作2分钟即可运行实现效果 文章目录 示例效果导出后的…

基于SSM的仓库管理系统设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用JSP技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…

TypeScript深度剖析:TypeScript 中接口的理解?应用场景?

面试官&#xff1a;说说你对 TypeScript 中接口的理解&#xff1f;应用场景&#xff1f; 一、是什么 接口是一系列抽象方法的声明&#xff0c;是一些方法特征的集合&#xff0c;这些方法都应该是抽象的&#xff0c;需要由具体的类去实现&#xff0c;然后第三方就可以通过这组抽…

图像识别-人脸识别与疲劳检测 - python opencv 计算机竞赛

文章目录 0 前言1 课题背景2 Dlib人脸识别2.1 简介2.2 Dlib优点2.3 相关代码2.4 人脸数据库2.5 人脸录入加识别效果 3 疲劳检测算法3.1 眼睛检测算法3.3 点头检测算法 4 PyQt54.1 简介4.2相关界面代码 5 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是…

VRRP基础

1.VRRP概述 VRRP&#xff08; Virtual Router Redundancy Protocol&#xff0c;虚拟路由器冗余协议&#xff09;既能够实现网关的备份&#xff0c;又能解决多个网关之间互相冲突的问题&#xff0c;从而提高网络可靠性。 通过把几台路由设备联合组成一台虚拟的“路由设备”&…

nodejs+vue 学生宿舍管理系统设计与实现

可将教师信息、宿管信息、学生信息、楼栋信息等输入到系统中。只有管理员才能录入相关的资料&#xff0c;按照提示&#xff0c;输入相应的资料&#xff0c;而“导入”则可以通过上传档案&#xff0c;导入成功后&#xff0c;相应的寝室就会相应的减少。在录入大楼的时候&#xf…

Unity之ShaderGraph如何实现积雪效果

前言 我们在一些特殊场景&#xff0c;比如冰雪天&#xff0c;经常会对周围物体添加一些积雪效果&#xff0c;如果我们直接把积雪做到模型上&#xff0c;就无法更加灵活的表现其他天气的环境了&#xff0c;比如春夏秋冬切换。所以一般这种需求我们都是使用Shader来表现。 入下图…

Ubuntu提示 “unable to find the VMX binary ‘D:\VM17\vmware-vmx.exe‘“

参考&#xff1a;完美解决Unable to find the VMX binary ‘C:\Program Files (x86)\VMware\VMware Workstation\vmware-vmx.exe‘. 1.搜索添加或删除程序&#xff0c;找到VM&#xff0c;点击更改 2.点击修复&#xff0c;等待修复完成就可以了

【大数据实训】基于赶集网租房信息的数据分析与可视化(七)

温馨提示&#xff1a;文末有 CSDN 平台官方提供的博主 的联系方式&#xff0c;有偿帮忙部署 基于赶集网租房信息的数据分析与可视化 一、实验环境 &#xff08;1&#xff09;Linux&#xff1a; Ubuntu 16.04 &#xff08;2&#xff09;Python: 3.6 &#xff08;3&#xff09;…

【算法训练-回溯算法 二】【子集组合问题】子集、组合、子集II、组合总和

废话不多说&#xff0c;喊一句号子鼓励自己&#xff1a;程序员永不失业&#xff0c;程序员走向架构&#xff01;本篇Blog的主题是【回溯算法】&#xff0c;使用【数组】这个基本的数据结构来实现&#xff0c;这个高频题的站点是&#xff1a;CodeTop&#xff0c;筛选条件为&…

【APP源码】基于Typecho博客程序开发的博客社区资讯APP源码

全新博客社区资讯APP源码 Typecho后端 一款功能全面&#xff0c;用户交互良好&#xff0c;数据本地缓存&#xff0c;集成邮箱验证&#xff0c;在线投稿&#xff0c;&#xff08;内置Mardown编辑器&#xff09;&#xff0c; 快捷评论的的博客资讯APP。同时兼容H5和微信小程序。 …

基于nodejs+vue学生论坛设计与实现

目 录 摘 要 I ABSTRACT II 目 录 II 第1章 绪论 1 1.1背景及意义 1 1.2 国内外研究概况 1 1.3 研究的内容 1 第2章 相关技术 3 2.1 nodejs简介 4 2.2 express框架介绍 6 2.4 MySQL数据库 4 第3章 系统分析 5 3.1 需求分析 5 3.2 系统可行性分析 5 3.2.1技术可行性&#xff1a;…