亲测有效,先上效果图
安卓机效果:
苹果手机效果:
前言: 早期由于带宽和流量的因素,移动端浏览器禁止视频自动播放,需要用户进行交互才可以触发播放,再加上安卓各个厂家对
<video>
标签的劫持,导致H5上自动播放视频这个功能实现出现种种困难
通过各种途径寻找实现方法及采坑,我这里整理出了一套兼容 Android/IOS 微信浏览器上自动播放的代码
实现功能:
- 兼容Android/IOS
- 进入即可自动播放
- 取消强制全屏
- 不会出现进度条等控制模块
在开始撸码前, 我们需要说一下我们需要用到的库:
JSMpeg是用JavaScript编写的视频播放器。它由MPEG-TS多路分配器,MPEG1视频和MP2音频解码器,WebGL和Canvas2D渲染器以及WebAudio声音输出组成。JSMpeg可以通过Ajax加载静态视频,并允许通过WebSockets进行低延迟的流传输(〜50ms)。
JSMpeg可以在iPhone 5S上以30fps的速度解码720p视频,可以在任何现代浏览器(Chrome,Firefox,Safari,Edge)中使用,并且压缩后的速度仅为20kb。
简单的说就是这个库使用js进行视频解码,再用 canvas 逐帧画出图像,那么只要WebView支持 canvas,就能用 JSMPeg 播放。
下载地址:https://ffmpeg.zeranoe.com/builds/
下载完成后, 解压到任意目录FFmpeg 是一个文件转换的工具,用这个库把 mp4 转成 ts 文件才能被 JSMPeg 所解析。
ffmpeg -i test.mp4 -f mpegts -vcodec mpeg1video -s 360*640 -b:v 600k -r 24 -bf 0 -codec:a mp2 -ar 44100 -ac 1 -b:a 128k test.ts
命令执行完后,会在当前目录创建转换后的 .ts 视频文件。通用参数解释 :
test.mp4 是视频文件
360*640 是视频的宽高
-r 是视频的帧率
-b:v 视频比特率,值越大视频越清晰 .ts 文件体积也越大
test.ts 是转换后的文件名(建议跟视频文字的名字一样)
完整参数可以参考官网文档:http://ffmpeg.org/ffmpeg.html这里参数的调整建议参考视频本身的参数
注意命令行的代码,一个错误都可能导致 .ts 视频文件解析不了
接下来进入JSMpeg库拿到 jsmpeg.min.js
文件
这个时候我们就可以开始撸码了
目录结构如下:主要页面代码
<!-- index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Android/IOS微信浏览器中自动播放视频</title>
<link rel="stylesheet" href="css/index.css">
</head>
<body>
<div class="wrap">
<div class="video_box"></div>
</div>
</body>
</html>
<script src="js/vendor/jquery-3.2.1.min.js"></script>
<script src="js/vendor/jsmpeg.min.js"></script>
<script src="js/vendor/f-video.js"></script>
<script>
let params = {
objectFit: 'cover', // 视频的object-fit样式, 默认 cover
loop: false, // 是否循环, 默认false
autoplay: true, // 自动播放, 默认false
onPlay: play, // 触发播放事件
onPause: pause, // 触发暂停事件
onEnded: ended, // 触发播放结束事件
}
let player = F_Video('media/test.mp4', params)
$('.video_box').append(player.domElement);
function play() {
console.log('视频播放')
}
function pause() {
console.log('视频暂停')
}
function ended() {
console.log('视频结束')
}
// console.log(player.currentTime) // 获取视频当前时间
// player.currentTime = 1 // 调整当前视频时间
// console.log(player.volume) // 获取视频当前音量
// player.volume = 0; // 调整视频声音 0-1
</script>
/* f-video.js */
let F_Video;
(function () {
F_Video = function (url, option) {
const u = window.navigator.userAgent.toLowerCase();
const isAndroid = u.indexOf('android') > -1;
let player = new Object;
if (isAndroid) {
let newCanvas = document.createElement('canvas');
let params = {
canvas: newCanvas,
loop: option.loop || false,
autoplay: option.autoplay || false,
onEnded: () => {
option.onEnded && option.onEnded();
player.currentTime = 0;
},
}
newCanvas.style.width = '100%';
newCanvas.style.height = '100%';
newCanvas.style.objectFit = option.objectFit || 'cover';
player = new JSMpeg.Player(url.replace('.mp4', '.ts'), { ...option, ...params });
player.domElement = newCanvas;
} else {
let newVideo = document.createElement('video');
newVideo.setAttribute('x5-video-player-type', 'h5');
newVideo.setAttribute('x-webkit-airplay', 'true');
newVideo.setAttribute('airplay', 'allow');
newVideo.setAttribute('playsinline', '');
newVideo.setAttribute('webkit-playsinline', '');
newVideo.setAttribute('src', url);
option.loop && newVideo.setAttribute('loop', 'loop');
!option.autoplay && newVideo.setAttribute('preload', 'auto')
option.autoplay && window.WeixinJSBridge.invoke('getNetworkType', {}, (e) => { player.play(); })
newVideo.style.width = '100%';
newVideo.style.height = '100%';
newVideo.style.objectFit = option.objectFit || 'cover';
player = newVideo;
player.domElement = newVideo;
option.onPlay && player.addEventListener('play', option.onPlay);
option.onPause && player.addEventListener('pause', option.onPause);
option.onEnded && player.addEventListener('ended', option.onEnded);
}
return player
}
})();
关于
f-video.js
,这是我自己封装自用的一个 js 文件,里面兼容了视频播放,暂停,结束的监听,以及对视频是否静音, 进度条调整进行了整合, 目前对于自己来说这些功能已经够用于实现业务了, 如果对这方面感兴趣或者目前功能仍不满足于业务的实现, 可以参考 JSMpeg 库提供的API进行调整添加
采坑记录
- 刚开始的时候,由于没有注意CMD命令行,打错了命令导致转码出来的视频播放不了,后面在JSMpeg库的Issues才找到了问题的所在(Issues真是个好东西)
- 之前接到过一个业务,一个完全由多个视频组成的 H5 ,当时信心满满,结果做出来各种神奇的bug,播放一半卡住,切换到这个视频不会播放,白屏等。后面排查发现问题是 JSMpeg 在解码视频的时候, 会大量占用内存,而当时的视频是有7,8个,再加上微信浏览器不能手动释放内存,导致这些问题出现。所以这里建议用这种方法来实习业务的时候,最好不要处理太多视频,否则就会出现上述问题。