浏览器自动播放音视频-前端实现方案
目录
前言
浏览器自动播放策略
策略详情:
实现方案
方案1: 互动后播放
方案2: 互动后出声
总结
前言
在开发中可能有遇到这样的需求,当用户打开页面后,需要自动播放视频或音频,按理说那就打开页面时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
<!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="./test.mp4"></video></div><script>const vdo = document.querySelector('video');vdo.play();</script></body>
</html>
这个错误的意思是浏览器已经尝试在没有用户交互的情况下播放媒体文件,但是因为这是不允许的,所以浏览器拒绝了该操作。如果没有这个保护机制,那么网站可以在用户不知情的情况下播放音频和视频,这是不安全和不负责任的行为。
方案1: 互动后播放
先尝试自动播放,若发生异常,则引导用户进行互动操作,然后再进行播放
<!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="./test.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');async function play() {try {await vdo.play();modal.style.display = 'none';btn.removeEventListener('click', play);} catch (err) {modal.style.display = 'flex';btn.addEventListener('click', play);}}play();</script></body>
</html>
进入页面后发现不能自动播放,这时显示开始播放按钮,用户点击后开始播放。
方案2: 互动后出声
先静音播放,然后根据是否能自动播放决定是否取消静音,如果:
- 能自动播放,取消静音
- 不能自动播放,引导用户进行互动操作后取消静音
<!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="./test.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>
进入页面后静音播放视频,然后判断是否允许自动播放,如果允许,则取消静音,但我们这里不允许,所以显示打开声音按钮。
引用的index.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;
}
总结
如果文中出现有瑕疵的地方各位通过评论或者私信联系我,我们一起进步,有兴趣的伙伴可以关注订阅一下:点击查看更多实用技巧及技术
相关文章:

浏览器自动播放音视频-前端实现方案
目录 前言 浏览器自动播放策略 策略详情: 实现方案 方案1: 互动后播放 方案2: 互动后出声 总结 前言 在开发中可能有遇到这样的需求,当用户打开页面后,需要自动播放视频或音频,按理说那就打开页面…...
HttpUtils工具类
作为Java开发程序员,需要我们经常写一些工具类来简化开发过程,我们自己肯定写过或者用过HttpUtils用来发送http请求,但是每次手写太繁琐了,于是就按照标准写了一个Http工具类,现在分享出来。 1.HTTP请求简介 HTTP(Hy…...

AI:59-基于深度学习的行人重识别
🚀 本文选自专栏:AI领域专栏 从基础到实践,深入了解算法、案例和最新趋势。无论你是初学者还是经验丰富的数据科学家,通过案例和项目实践,掌握核心概念和实用技能。每篇案例都包含代码实例,详细讲解供大家学习。 📌📌📌在这个漫长的过程,中途遇到了不少问题,但是…...

TCP编程及基础知识
一、端口号 为了区分一台主机接收到的数据包应该转交给哪个进程来进行处理,使用端口号来区分TCP端口号与UDP端口号独立端口用两个字节来表示 2byte(65535个) 众所周知端口:1~1023(1~255之间为众所周知端口ÿ…...

二百零一、Flink——Flink配置状态后端运行后报错:Can not create a Path from an empty string
一、目的 在尚硅谷学习用Flink配置状态后端的项目中,运行报错Exception in thread "main" java.lang.IllegalArgumentException: Can not create a Path from an empty string 二、Flink的状态后端(state backend)类型 (一)Memo…...

Python 爬虫基础
Python 爬虫基础 1.1 理论 在浏览器通过网页拼接【/robots.txt】来了解可爬取的网页路径范围 例如访问: https://www.csdn.net/robots.txt User-agent: * Disallow: /scripts Disallow: /public Disallow: /css/ Disallow: /images/ Disallow: /content/ Disallo…...

亚马逊云科技大语言模型的创新科技
陈老老老板🤴 🧙♂️本文专栏:生活(主要讲一下自己生活相关的内容)生活就像海洋,只有意志坚强的人,才能到达彼岸。 🧙♂️本文简述:亚马逊云科技大语言模型的创新科技 🧙♂️上…...

Qt 各种数据类型
目录 1. 基础类型 2. log 输出 3. 字符串类型 3.2 QByteArray 构造函数 数据操作 子字符串查找和判断 遍历 查看字节数 类型转换 3.3 QString 4. QVariant 4.1 标准类型 4.2 自定义类型 5. 位置和尺寸 5.1 QPoint 5.2 QLine 5.3 QSize 5.4 QRect 6. 日期和…...

电动车展示预约小程序的作用如何
电动车可以说是现在出行常见的方法,覆盖年龄广几乎是每家必备,也有不小大小品牌和经销商,市场需求较高,但在实际经营中,对经销商来时也面临着一些痛点: 1、品牌传播产品展示难 不同品牌竞争很大ÿ…...

「随笔」浅谈2023年云计算的发展趋势
在2023年,云计算的发展趋势将受到政治、经济、社会和科技四个维度的影响。以下是对这些维度的具体分析: 1.1 政治维度: 全球政策推动: 随着全球各国政策对云计算的重视程度不断提高,云计算服务将获得更广泛的市场准入…...

高性能三防工业平板电脑 防摔防爆电容屏工控平板
HT1000是一款高性能工业三防平板,10.1英寸超清大屏,厚度仅14.9mm,超薄机身,可轻松插入袋中,方便携带,搭载8核2.0GHz高性能CPU,行业领先的Android 11.0,设备性能大幅提升,…...
mac flutter pb解析报错:protoc-gen-dart: program not found or is not executable
在mac对pb文件转dart文件的时候报错:protoc-gen-dart: program not found or is not executable 原因是没有安装protoc-gen-dart或者protoc-gen-dart没有设置到环境变量中 解决办法: 1、安装protoc-gen-dart flutter pub global activate protoc_plu…...

PostgreSQL 连接是否要通过SSL,为什么使用SSL 连接后,业务部门会投诉我?
开头还是介绍一下群,如果感兴趣PolarDB ,MongoDB ,MySQL ,PostgreSQL ,Redis, Oceanbase, Sql Server等有问题,有需求都可以加群群内有各大数据库行业大咖,CTO,可以解决你的问题。加群请联系 liuaustin3 ,(…...

Linux驱动开发——USB设备驱动
目录 一、 USB 协议简介 二、 Linux USB 驱动 三、 USB 设备驱动实例 一、 USB 协议简介 USB(Universal Serial Bus,通用串行总线)正如它的名字一样,是用来连接PC外设的一种通用串行总线,即插即用和易扩展是它最大的特点。所谓即插即用&am…...

微服务使用指南
微服务使用指南 1.初识微服务 微服务可以认为是一种分布式架构的解决方案,提供服务的独立性和完整性,做到服务的高内聚、低耦合。 目前服务架构主要包含:单体架构和分布式架构。 1.1 单体架构 单体架构:把所有业务功能模块都…...

MYSQL运维篇(已完结)
一、日志 1. 错误日志 2. 二进制日志 😎 介绍 😎 日志格式 😎 日志查看 😎 日志删除 3. 查询日志 4. 慢查询日志 二、主从复制 1. 概述 2. 原理 3. 搭建 4. 总结 三、分库分表 1. 介绍 🍤 问题分析 🍤…...

MapReduce性能优化之小文件问题和数据倾斜问题解决方案
文章目录 MapReduce性能优化小文件问题生成SequenceFileMapFile案例 :使用SequenceFile实现小文件的存储和计算 数据倾斜问题实际案例 MapReduce性能优化 针对MapReduce的案例我们并没有讲太多,主要是因为在实际工作中真正需要我们去写MapReduce代码的场…...

面向萌新的数学建模入门指南
时间飞逝,我的大一建模生涯也告一段落。感谢建模路上帮助过我的学长和学姐们,滴水之恩当涌泉相报,写下这篇感想,希望可以给学弟学妹们一丝启发,也就完成我的想法了。拙劣的文笔,也不知道写些啥,…...

基于 golang 从零到一实现时间轮算法 (二)
Go实现单机版时间轮 上一章介绍了时间轮的相关概念,接下来我们会使用 golang 标准库的定时器工具 time ticker 结合环状数组的设计思路,实现一个单机版的单级时间轮。 首先我们先运行一下下面的源码,看一下如何使用。 https://github.com/x…...
【系统架构设计】架构核心知识: 5 系统安全性与保密性设计
目录 一 信息安全基础 1 信息安全的基本要素 2 信息安全的范围 3 网络安全...

网络六边形受到攻击
大家读完觉得有帮助记得关注和点赞!!! 抽象 现代智能交通系统 (ITS) 的一个关键要求是能够以安全、可靠和匿名的方式从互联车辆和移动设备收集地理参考数据。Nexagon 协议建立在 IETF 定位器/ID 分离协议 (…...
多场景 OkHttpClient 管理器 - Android 网络通信解决方案
下面是一个完整的 Android 实现,展示如何创建和管理多个 OkHttpClient 实例,分别用于长连接、普通 HTTP 请求和文件下载场景。 <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas…...
【Go】3、Go语言进阶与依赖管理
前言 本系列文章参考自稀土掘金上的 【字节内部课】公开课,做自我学习总结整理。 Go语言并发编程 Go语言原生支持并发编程,它的核心机制是 Goroutine 协程、Channel 通道,并基于CSP(Communicating Sequential Processes࿰…...
【学习笔记】深入理解Java虚拟机学习笔记——第4章 虚拟机性能监控,故障处理工具
第2章 虚拟机性能监控,故障处理工具 4.1 概述 略 4.2 基础故障处理工具 4.2.1 jps:虚拟机进程状况工具 命令:jps [options] [hostid] 功能:本地虚拟机进程显示进程ID(与ps相同),可同时显示主类&#x…...

OPenCV CUDA模块图像处理-----对图像执行 均值漂移滤波(Mean Shift Filtering)函数meanShiftFiltering()
操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 在 GPU 上对图像执行 均值漂移滤波(Mean Shift Filtering),用于图像分割或平滑处理。 该函数将输入图像中的…...
DeepSeek 技术赋能无人农场协同作业:用 AI 重构农田管理 “神经网”
目录 一、引言二、DeepSeek 技术大揭秘2.1 核心架构解析2.2 关键技术剖析 三、智能农业无人农场协同作业现状3.1 发展现状概述3.2 协同作业模式介绍 四、DeepSeek 的 “农场奇妙游”4.1 数据处理与分析4.2 作物生长监测与预测4.3 病虫害防治4.4 农机协同作业调度 五、实际案例大…...
大语言模型(LLM)中的KV缓存压缩与动态稀疏注意力机制设计
随着大语言模型(LLM)参数规模的增长,推理阶段的内存占用和计算复杂度成为核心挑战。传统注意力机制的计算复杂度随序列长度呈二次方增长,而KV缓存的内存消耗可能高达数十GB(例如Llama2-7B处理100K token时需50GB内存&a…...
rnn判断string中第一次出现a的下标
# coding:utf8 import torch import torch.nn as nn import numpy as np import random import json""" 基于pytorch的网络编写 实现一个RNN网络完成多分类任务 判断字符 a 第一次出现在字符串中的位置 """class TorchModel(nn.Module):def __in…...
C++.OpenGL (14/64)多光源(Multiple Lights)
多光源(Multiple Lights) 多光源渲染技术概览 #mermaid-svg-3L5e5gGn76TNh7Lq {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-3L5e5gGn76TNh7Lq .error-icon{fill:#552222;}#mermaid-svg-3L5e5gGn76TNh7Lq .erro…...
iOS性能调优实战:借助克魔(KeyMob)与常用工具深度洞察App瓶颈
在日常iOS开发过程中,性能问题往往是最令人头疼的一类Bug。尤其是在App上线前的压测阶段或是处理用户反馈的高发期,开发者往往需要面对卡顿、崩溃、能耗异常、日志混乱等一系列问题。这些问题表面上看似偶发,但背后往往隐藏着系统资源调度不当…...