1、问题的提出

某一天接了个需求,需要在手机的H5页面内加入视频,我开开心心做完,准备交付的时候,问题来了,PM想要用户一进入页面,视频就开始播放,不需要用户手动点击。

2、尝试解决

加autoplay

“视频自动播放”这个需求是ok的,那我就在video标签上加个autoplay属性嘛,在PC端浏览器里面试了一下,运行流畅,没有遇到什么问题,但是放在手机浏览器里面打开,就跟没设置autoplay是一样的。

监听canplay

那不行的话,我在页面加载完成的时候,监听video的canplay,然后执行play(),应该可以运行了吧?然而放到手机里一看,还是不行。

<video id="video" src="video.mp4" controls></video>
var video = document.querySelector('#video');
video.addEventListener('canplay', function () {
video.play();
})

3、思考

问题来了,加autoplay不行,可以理解,可能手机浏览器不支持这个属性吧,但是我监听视频加载完成,手动去play(),这是程序常规方法,为什么也不行?
我尝试在监听回调里面加了个alert,发现没有弹出框。
所以我很长一段时间认为,手机浏览器无法自动播放视频,是因为内存大小的限制,导致无法监听video的加载完成。

4、解决方案

方案1 使用弹框

昨天在segment上游荡,发现了原来现在的手机浏览器是不允许网页中视频自动播放的,只有与用户进行了一次交互动作,才可以播放视频。(音频同理,这里就不重复提)
我尝试了一下,在页面上加一个弹框,用户点击了弹框之后(相当于一次交互完成),开始播放视频,发现是可以播放的,部分代码如下。

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no, width=device-width">
<title>视频自动播放</title>
<style>
html, body {
width: 100%;
height: 100%;
}
.video-container {
width: 300px;
height: 600px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
overflow: hidden;
margin: 0 auto;
}
#video {
display: block;
width: 100%;
}
#mask {
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.83);
position: absolute;
top: 0;
left: 0;
z-index: 2;
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
}
.pop-container {
width: 250px;
height: 200px;
background: white;
border-radius: 5px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
button {
width: 50px;
height: 30px;
border-radius: 4px;
}
</style>
</head>
<body> <div class="video-container">
<video id="video" src="video.mp4"></video>
</div>
<div id="mask">
<div class="pop-container">
<p>页面内有自动播放视频 请注意流量</p>
<button onclick="playVideo()">我知道了</button>
</div>
</div>
<script>
function playVideo() {
document.getElementById('mask').style.display = 'none';
var video = document.querySelector('#video');
video.play();
}
</script>
</body>
</html>

所以解决视频自动播放的一般做法是,在页面加载的时候弹框与用户产生交互,然后才能开始自动播放(如此看来,手机浏览器是真的很重视用户的流量了。)

存在的问题

按照上面的方法,只要想要在手机端页面中实现 进入页面,视频立即自动播放,就必须要借助一个额外的动作去引导与用户发生一次交互,那岂不是很丑,有没有办法是可以不借助弹框呢?答案是 有的。

方案2 使用jsmpeg.js

jsmpeg是一款视频解码器,具体怎么用,可以百度相关文档,实话说我对此也不熟悉,第一次听见的时候是听说jsmpeg可以实现网页端的视频直播功能,这一次用来解决视频自动播放的需求也是借鉴别人的想法。
关键代码如下:(前提:项目中已经引入了jsmpeg.min.js)

<canvas id="canvas" height="750" width="750"></canvas>

页面加载完成的时候执行下面的js代码:
var canvas = document.querySelector('#canvas');
// 注意这里需要将video.mp4转换成ts格式的文件 才能生效
var player = new JSMpeg.Player('video.ts', { canvas: canvas, loop: false, autoplay: false, audio: true });
player.audioOut.unlock(this.onUnlocked);
player.play(); // onUnlocked方法
function onUnlocked() {
player.volume = 1;
}

这样即使不跟用户产生交互 视频也能自动播放了,
注意点
1.demo必须放在服务器上面跑才能正常加载ts文件,如果是在本地的话,不能直接拖进浏览器运行,需要起个本地服务器
2.ts文件编码方式必须为MPEG编码,考虑到现在先进的ts编码方式是H.264了,之前用H.264编码的ts发现播放不了
存在的问题
1.这样播出的视频是没有声音的
附参考链接:微信Android自动播放视频(可交互,设置层级,无控制条,非X5)ffmpeg,jsmpeg.js,.ts视频

5、补充

1.虽然最后不管通过什么方法,算是实现了视频自动播放的需求,但是在真正播放的示例中,你会发现,使用video标签的时候,虽然设置了视频的宽高,但是不起作用,所以需要在video中使用下面的属性
<video id="video" src="" controls webkit-playsinline="webkit-playsinline" playsinline></video>
这样就可以在固定区域播放视频了。
2.借助方案1的思路,其实可以实现用户上传视频时的预览

<input type="file" id="filepicker" accept="video/mp4" onchange="chooseVideoInput()">
<div class="video-container">
<video id="video" src="" controls webkit-playsinline="webkit-playsinline" playsinline></video>
</div>
<script>
function chooseVideoInput() {
var files = document.getElementById('filepicker').files[0];
var video = document.getElementById('video');
// 注意下面3行代码
var url = URL.createObjectURL(files);
video.src = url;
video.play();
}
</script>

3.将mp4转换成jsmpeg可播放的ts文件的方法
mac os下安装homebrew,之后使用brew install jsmpeg,运行下面命令:ffmpeg -i in.mp4 -f mpegts -codec:v mpeg1video -codec:a mp2 -b 0 out.ts (其中in.mp4和out.ts填写原视频的路径以及转出ts的路径),亲测有效

6、总结

其实关于浏览器video的问题困扰了我很久,昨日在segment上浏览到“chrome66 禁止自动播放后,有什么比较好的方法实现audio的自动播放吗”这样一个提问的时候,进去看到回答,突然想起video是不是也是一样的情况,今天看了下,果然是类似的,解了很久的疑问,所以勉励自己一定要善于发现并举一反三。
上面提到的不论是解决方案或者说补充的,大概能解决一大半手机浏览器视频相关的问题,剩下的问题有机会再补充。

参考链接:
chrome66 禁止自动播放后,有什么比较好的方法实现audio的自动播放吗
微信Android自动播放视频(可交互,设置层级,无控制条,非X5)ffmpeg,jsmpeg.js,.ts视频
mac osx 下 homebrew安装
mac 系统安装使用 ffmpeg
HTML5音视频播放(Video,Audio)和常见的坑处理
video在微信和QQ浏览器中不全屏播放解决

手机浏览器自动播放视频video(设置autoplay无效)的解决方案的更多相关文章

  1. 群晖synology的Video Station无法通过浏览器在线播放视频

    群晖synology的Video Station无法通过浏览器在线播放视频 http://www.hangge.com/blog/cache/detail_419.html

  2. h5页面自动播放视频、音频_关于媒体文件自动全屏播放的实现方式

    在移动端(ios和android)播放视频的时候,我们即使定义了autoplay属性,仍然不能自动播放.这是由于手机浏览器为了防止浪费用户的网络流量,在默认情况下是不允许媒体文件自动播放的,除非用户自 ...

  3. 树莓派USB存储设备自动挂载并通过脚本实现自动拷贝,自动播放视频,脚本自动升级等功能

    需求:首先需要树莓派自动挂载USB设备,然后扫描USB指定目录下文件,将相关文件拷贝至树莓派指定目录,然后通过omxplayer循环播放新拷贝文件视频 1. 树莓派实现USB存储设备自动挂载 树莓派U ...

  4. vue中解决chrome浏览器自动播放音频 和MP3语音打包到线上

    一.vue中解决chrome浏览器自动播放音频 需求 有新订单的时候,页面自动语音提示和弹出提示框: 问题 chrome浏览器在18年4月起,就在桌面浏览器全面禁止了音视频的自动播放功能.严格地来说, ...

  5. 使用 JS 嵌入的方式来加载 Flash 插件,在各浏览器中播放视频

    嵌入插件 使用 object 和 embed 标签 这种方法用到的是 Object 和 Embed 标签,可以看到 object 的很多参数和 embed 里面的很多属性是重复的.浏览器兼容性,有的浏 ...

  6. [转][CEF]自动播放视频

    1.CEF 默认不支持 mp4,可以在网上下载热心网友提供的修改版. 查看支持的特性的方法:在 CEF 中访问网页 :http://html5test.com/ 2. 打开网页后视频自动播放: mut ...

  7. 微信Android自动播放视频(可交互,设置层级,无控制条,非X5)ffmpeg,jsmpeg.js,.ts视频

    原料: ffmpeg : http://ffmpeg.zeranoe.com/builds/  win64 https://evermeet.cx/ffmpeg/   mac OS X 64 jsmp ...

  8. 需求:在浏览器加载完毕后,自动播放视频:出现play() failed because the user didn't interact with the document first.错误

    解决方法:给video标签加入<video muted></video> 静音即可. Chrome 66为了避免标签产生随机噪音. 参考链接:https://juejin.im ...

  9. 实现微信浏览器自动播放MP3音乐

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...

随机推荐

  1. 随机函数rand()的使用方法——C语言

    原理: 引用自百度百科: 所需包含的头文件: #include <stdlib.h> rand()函数是按指定的顺序来产生整数,因此每次执行上面的语句都打印相同的两个值,所以说C语言的随机 ...

  2. 数学中的距离distance(未完成)

    manhattan distance(曼哈顿距离) euclidean distance(欧几里得距离) cosine distance(cosine距离) 闵式距离 切比雪夫距离

  3. PAT甲级——1027 Colors in Mars

    1027 Colors in Mars People in Mars represent the colors in their computers in a similar way as the E ...

  4. Docker系列六: 使用Docker官方公共仓库和私有仓库

    使用公共仓库 登陆官方网站:https://hub.docker.com/   注册账号和密码 在Docker hub中创建一个资源,  create  respositories,   创建后会提示 ...

  5. 解决一个通过 WebReference 调用 WCF 时自定义 DataContract 类参数提交的问题

    先看一下VS2013自动创建默认的IService1.vb,注意自定义的数据契约 CompositeType ' 注意: 使用上下文菜单上的“重命名”命令可以同时更改代码和配置文件中的接口名“ISer ...

  6. appium自动化的工作原理(1)

    用appium开发移动端自动化测试脚本这么长时间,还没有认证的了解下它的原理是什么,到底是如何实现的呢? 1.先看一个Appium加载的过程图解(来自:了解appium自动化的工作原理--https: ...

  7. 忘记mysql root用户密码的解决办法(skip-grant-tables)

    skip-grant-tables顾名思义,数据库启动的时候 跳跃权限表的限制,不用验证密码,直接登录. 注意: 这种情况只有在忘记root密码 不得已重启数据库的情况下使用的.现网环境慎用,需要重启 ...

  8. 高级I/O

    1.阻塞问题的几种解决模型 1.1 非阻塞模型:类似于死循环,需要适当加休眠,防止cpu占用太高:效率较低 1.2 线程异步:效率最高的一种解决方案 1.3 I/O多路转接与复用  select(低) ...

  9. dubbo服务调用

    1.Dubbo的缺省(默认)协议:采用单一长连接和NIO异步通讯. 2.  3.调用关系说明 0. 服务容器负责启动,加载,运行服务提供者. 1. 服务提供者在启动时,向注册中心注册自己提供的服务. ...

  10. JS UTC 昨天

    var birthday = new Date("Jan 01, 1983 01:15:00") var formatDate = function (date) {       ...