微信内置浏览器 MP4 无法自动播放
#前言
在不久之前,在我爆改博客时,我将我的博客首页background换成了.mp4,甚至我的启动当时也是.mp4,方便是方便,但是也出现了一系列问题。
出现问题
- 部分国内基于X5内核的浏览器无法正常地识别background,导致访问的时候直接将background视频全屏展开播放器。
- 微信的手机端浏览器内核不支持自动播放视频,查到资料说把声轨去掉就可以了,但是我实践过,其实还是不行。
围绕着这两个问题,我兜兜转转了几天。
问题与答案
以下是我遇到的一些问题和解决方案
启动页无法播送
因为对于MP4的无法自动播送,也就是说我的启动页面无法正常地播放,这对于我来说是个大挑战。少完成一次接触反馈才可以播放视频。
一、核心原理说明
- iOS Safari/微信:默认播放视频会弹出系统全屏播放器,用
playsinline系列属性强制页面内同层播放,不脱离页面; - 安卓微信X5内核:不写专属X5属性会直接接管视频,弹出独立播放器,遮挡页面内容;
- 默认controls控件自带全屏、播放、进度按钮,通过CSS伪元素全部隐藏;
- JS拦截用户点击、触摸触发的自动全屏API,彻底杜绝弹窗播放器。
- 有声MP4:微信不能自动播放;
- 无声MP4:删音频轨道 + 全套video属性 + 用户触摸唤醒,才能自动播放;
- 安卓X5内核限制远严于iOS,必须监听touchstart手势。
在思索片刻后,我将启动页的音轨舍弃,转而走向无音轨的.webp格式,这时有可能有人会疑惑,为什么我不选带有音轨的.webm呢?实则我测试过,这种格式在大陆内并不普及,国内的浏览器都不兼容它基本上一到网页就全屏加弹出播放器。
定制对应的音效,让音频播放轨迹跟动图的播放轨迹一致几乎不可能,需要额外的插件去增加整个网站的加载时间,而且引入的越多,bug越多,所以放弃应该是最合理。
至此,完美解决了这个播放页的播放问题。
面对background的难题
启动页的问题是解决了,但是我的background还是处于视频格式如果将它也压缩成动图,它的体积将会增长十几倍,这是因为.webp和.mp4的压缩方式不同,后者再多帧压缩的能力更高,况且前者也没有多余的音轨,所以再三考虑,还是保留.mp4格式比较好。
其实面对原生浏览器的播放不成问题,但是国内的浏览器大部分对视频元素极为敏感。他们的嗅探一旦感知到了有<video>,就会像狗一样,立马抓出资源,这样子对我们是不利的。
兼容Video标签(微信/手机/PC都可用)
视频防全屏核心属性逐行说明
playsinline/webkit-playsinlineiOS 标准 + Safari私有属性,禁播放时弹出播放器,视频固定在页面内渲染。x5-playsinline安卓微信 X5 内核专属属性,关闭X5独立全屏播放器,实现页面内同层播放。x5-video-player-type="h5-page"X5内核开启同层H5播放器,视频DOM层级融入页面,不会浮于顶层遮挡页面元素。x5-video-player-fullscreen="false"强制关闭安卓微信X5的自动全屏逻辑,加载/播放时不会自动切全屏。controlslist="nofullscreen nodownload"原生标准属性,移除播放器控件内的全屏按钮、下载按钮。disablepictureinpicture禁止浏览器弹出画中画悬浮播放窗口。x-webkit-airplay="deny"屏蔽苹果AirPlay投屏功能,避免触发外部播放器弹窗。
HTML 示例
<video> class="bg-video" src="bg-silent.mp4" muted autoplay loop preload="auto" controlslist="nofullscreen nodownload noremoteplayback" playsinline="true" webkit-playsinline="true" x5-playsinline="true" x5-video-player-type="h5-page" x5-video-player-fullscreen="false" x-webkit-airplay="deny" disablepictureinpicture</video>CSS 隐藏浏览器原生播放器所有控件
/* 背景视频容器一定要铺满页面 */.bg-video-wrap { position: fixed; top: 0; left: 0; width: 100vw; height: 100vh; overflow: hidden; z-index: -1;}.bg-video { width: 100%; height: 100%; object-fit: cover; pointer-events: none; /* 关键:禁止用户点击视频区域,彻底杜绝触发全屏 */}
/* 隐藏WebKit内核全部的掉价原生控件 */.bg-video::-webkit-media-controls-enclosure { display: none !important;}.bg-video::-webkit-media-controls-fullscreen-button { display: none !important;}.bg-video::-webkit-media-controls-play-button { display: none !important;}.bg-video::-webkit-media-controls-timeline { display: none !important;}.bg-video::-webkit-media-controls-mute-button { display: none !important;}
/* 特殊屏蔽火绒控件 */.bg-video::-moz-media-controls { display: none !important;}JS 去拦截和禁止那些代码或者是手势触发视频全屏
const video = document.querySelector('.bg-video');
// 重写全屏请求方法,拦截任何强制进入全屏操作video.requestFullscreen = () => Promise.reject('禁止全屏');video.webkitRequestFullscreen = () => Promise.reject('禁止全屏');video.mozRequestFullScreen = () => Promise.reject('禁止全屏');
// 监听全屏切换事件,一旦意外进入立刻强制退出,断尾求生document.addEventListener('fullscreenchange', () => { if (document.fullscreenElement) document.exitFullscreen();});document.addEventListener('webkitfullscreenchange', () => { if (document.webkitFullscreenElement) document.webkitExitFullscreen();});
// 专门的微信JS桥就绪后自动唤醒播放document.addEventListener('WeixinJSBridgeReady', () => { video.play().catch(e => console.log('播放拦截:', e));});
// 页面触摸唤醒播放,安卓X5兼容最沙币,这样基本不会弹出播放器document.addEventListener('touchstart', function oncePlay() { video.play(); document.removeEventListener('touchstart', oncePlay);});然后经过前端三兄弟的加持下,应该理论是基本不会出现弹出播放器或者全屏跳的情况。但国内部分浏览器像百度浏览器、UC浏览器、X5内核浏览器(微信/QQ内置)、夸克浏览器、QQ浏览器、小米原生浏览器,他们是比较顽固的,需要单独调,而且我测过百度浏览器是最难搞的,他把我的页面全排乱了,跟IE浏览器坐一桌。
总结
目前我的博客还在不断的完善,现在应该还有很多bug等待修复,也欢迎各位大佬前来体验,如果发现bug,可以在下方评论区留言,或者直接call我邮箱,阿里嘎多阔赛伊马斯~~~~~
部分内容可能已过时

