最近在整一个直播串流小项目,刚把推流和CDN给测试好,开始开发前端。
前端主要是播放器功能,为了良好的兼容性,我选择使用hls.js进行播放,HTML5播放器。
开发过程中,我测试了DPlayer,PC端和IOS端表现良好,但是在安卓Chrome上表现有问题,画面会卡住不动,音频正常,于是放弃。后来还测试了直接用<video>标签,以及字节的西瓜播放器,都表现不错,但全都有同一个问题:
在我安卓手机的微信内置浏览器(Chrome 86)上打开播放视频,在视频播放过程中,点击右上角使用浏览器打开,我测试了各个浏览器(Chrome 124,系统Webview),均发现其他浏览器上播放视频会隔几秒就被自动暂停,完全不是网络卡顿,点一下播放又会立刻继续播放,过几秒又会被暂停。此时微信是在后台运行,切回去微信内置浏览器后,是可以正常播放的,而一清理掉微信后台之后,其他浏览器都能正常播放了。我又尝试了多个不同的播放器和播放地址,都是相同情况。而且当我关闭微信的情况下,只使用Chrome 124内核的浏览器,多个标签页多个APP同时播放视频时,又没有问题,我估计问题就是在微信内置浏览器了。
我检查了下微信浏览器的User Agent,好啊😓,Chrome/86 XWEB/4443,又在网上查了资料,发现微信内置浏览器用的引擎不统一,把兼容性问题留给了开发者自己处理。
八成是微信内置浏览器Chrome/86版本太低的问题了,只要在微信浏览器里播放了HLS视频,放在后台(没有播放),其他地方再用新版本的Chrome/124播放另一个HLS视频,新播放的这个视频就会被自动暂停。实际使用过程中肯定会有人点在浏览器打开的,又要因为微信内置浏览器写多一个处理了。。。
这应该与微信版本无关,我在Google Play上已经更新到了最新版。
UPDATE: 又发现奇怪的地方了,开微信浏览器的情况下,再用一个低版本的Chrome/89打开视频,不会出现问题。。
解决方法:
经过几天观察,发现问题应该是与同时有多个HLS拉取视频的网络请求有关,那么只需要限制网络请求即可,不需要对播放器进行销毁等操作,hls.js有提供网络请求相关API: hls.stopLoad()
,可以停止请求,也有hls.startLoad
()可以恢复请求,那么思路就来了,只要在微信内置浏览器不在前台,那么就停止请求,测试后发现有效,可以解决问题,大概的代码如下:
if (isAndroidWX()) {
document.addEventListener("visibilitychange", function () {
if (document.visibilityState === "visible") {
// 页面可见
player.plugins.hlsjsplugin.hls.startLoad();
} else {
// 页面不可见
player.plugins.hlsjsplugin.hls.stopLoad();
}
});
}
isAndroidWX()为判断是否为安卓微信,可以根据UserAgent进行判断,大家各有各的写法,我就不放上来了。