偶然在多个页面使用了阿里云提供的播放器的系统里发现个 BUG
在 PC/MAC 端的 Chrome 浏览器中
1. 一部分页面加载播放器时报错且没有任何提示
2. 而另一部分页面加载播放器时,Chrome 会弹出“是否允许该页面使用 Flash Player”的提示,点击”允许“,则视频正常播放
3. 在可正常播放视频的页面中,点击了“允许”后,再回到有问题的页面,刷新,发现此时这类页面的播放器也可以正常工作了
简单对两类页面进行人肉 diff 操作发现
1. 表现不正常的页面引用的 js 路径为 http://g.alicdn.com/de/prismplayer/1.5.2/prism-min.js
2. 而可以正常工作的页面引用 js 路径为 http://g.alicdn.com/de/prismplayer/1.4.7/prism-min.js
因官方宣称这个播放器会自适应 H5 和 Flash 两种模式,从出错的表象来看,猜测是 1.5.2 版本的自适应逻辑有一些问题。一开始想简单解决,猜测最新版本的播放器应该已经解决了这个 BUG,于是直接换用最新版本(1.5.7),测试后发现问题依旧,只是最新版本在播放器中多了一行文字提示,大意是播放类型不支持
为了定位问题,下载了两个链接对应的源 prism.js
(去除后缀 -min,一般带 -min 的 js 都是经过压缩、混淆,用于正式环境加载使用)文件
分析对比两个版本,发现与此问题相关的核心代码如下
v1.4.7
return tag['player'] ||
(UA.IS_MOBILE ? new Player(tag, option) : new FlashPlayer(tag, option));
v1.5.7
return tag['player'] ||
(UA.IS_H5 ? new Player(tag, option) : new FlashPlayer(tag, option));
可以从代码中看出该播放器自适应的逻辑,在 v1.4.7 中依据 UA.IS_MOBILE
来判断是否是移动端,是则创建 H5 播放器对象,否则 创建 Flash 播放器对象;而在 v1.5.7 中,依据UA.IS_H5
来判断,如果该变量为逻辑真,则使用 H5 播放器,否则为 Flash 播放器
所以在 PC/MAC 平台,且使用了 v1.4.7 版本的页面上,IS_MOBILE
值一定为逻辑假,所以无论如何,都会直接创建 Flash 播放器对象,从而触发向 Chrome 申请 Flash Player 使用权限的逻辑,看上去没有什么问题
而在使用了 v1.5.7 版本的页面上,IS_H5
值为逻辑真,于是创建 H5 播放器对象。那么问题来了,为什么这种情况下会出错。在重新仔细阅读了一遍官方文档后,看到文档中有这样一段内容
Flash 模式:
* 视频格式: mp4、flv、m3u8、rtmp、mp3
* 视频编码: H.264
* 音频编码: AAC、MP3HTML5 模式:
* 视频格式: mp4、m3u8
* 视频编码: H.264
* 音频编码: AAC
m3u8格式播放依赖调用端浏览器支持情况:iOS全系列支持,Android 4.0及以上版本支持。
根据播放类型不支持的错误提示,对照这段内容,想到业务所需播放的视频类型为 m3u8 格式,正好对上了上述内容最后一句话
m3u8格式播放依赖调用端浏览器支持情况:iOS全系列支持,Android 4.0及以上版本支持。
看来问题是出在 PC/MAC 端的 Chrome 目前并不支持 HTML5 播放器播放 m3u8 格式的视频流
到这里,问题已经原因基本已经明确了,但是还有个小问题,即前文提到的
在可正常播放视频的页面中,点击了“允许”后,再回到有问题的页面,刷新,发现此时这类页面的播放器也可以正常工作了
为什么会有这种情况,难道在使用 v1.4.7 播放器的页面点击了“允许该域名使用 Flash Player”后,使用 v1.5.* 播放器的页面中 UA.IS_H5
的值发生了变化,从而变成了 Flash 模式?
为了验证这个疑问,修改 v1.5.7 版本 prism.js 的内容,加一行 console.log(UA.IS_H5)
接下来进行验证
1. 清空 Chrome 中的 Flash Player 使用权限白名单,保证该域名如需使用 Flash Player,需先向用户请求权限
2. 在使用 v1.5.7 版本播放器的页面中,在控制台看到 UA.IS_H5
值为 True
3. 在使用 v1.4.7 版本播放器的页面中,点击播放器视频,在浏览器弹出提示框点击“允许”。此时该域名将被添加到 Chrome 白名单,永久拥有了使用 Flash Player 的权限
4. 重新回到使用 v1.5.7 版本播放器的页面,刷新并发现此时 UA.IS_H5
值为 False
可以看出页面是否拥有 Flash Player 使用权限,确实影响到了 UA.IS_H5
的值,从而影响了页面自适应播放器模式
因 UA
对象是 prism.js 通过 require() 方式从其他 js 中得到,而阿里云限制了对该 js 的访问,所以 UA.IS_H5
究竟是如何获得值,也就不得而知了
到此,导致该问题的全部原因都清楚了
从文档来看,阿里云的开发人员很清楚这个问题,但给出的兼容方案并不好,可以考虑优化,比如以下方案
- 最简单版本:播放器提示语除了表明“播放类型不支持”,最好再明确一下为什么不支持,即便在原提示语上加个可以点击跳转到官方文档的链接都好
- 自适应逻辑中,多加一层判断,当前浏览器内核是否支持 HTML5 模式下 m3u8 格式视频流的播放。如果不能且非移动端浏览器,转而执行 Flash 模式流程,而不是强行走 HTML5 流程,给用户一个莫名其妙的错误