随着互联网技术的发展,用户使用QQ浏览器进行上网观看视频越来越多,最近统计目前使用QQ浏览器观看视频已经过亿。不同的用户由于不同的场景下播放不同的网站的视频源,可能会出现播放失败的情况,而这些失败的播放数据会通过数据上报系统上报至运营后台,将后台拉取数据并经过一定的分析,就能得到播放失败的网站、机型、时间、网络状态等信息,下图是最近后台统计的播放失败率最高的几个视频网站,如下图所示:
当然播放失败可能有多种原因而导致的,例如:浏览器对该种类型的网络视频不兼容、网络视频本身出现问题、用户网络环境的原因 等等。所以需要一种快捷准确的方案,能从成千上万用户的播放失败的源中找出是由于播放器或者是代码导致的问题。在这种情况下,引入了视频播放器问题定位方案。
二、实现总体框架
通过获取到一个用户的失败视频源后,验证是否播放器兼容的问题,目前主要有2种方式:
方案一:直接用播放失败的源在浏览器版本进行调试分析,这种方案是最准确,但是耗时比较大,主要因为播放失败并非是播放器的原因,例如:源的问题等。
方案二:先用我们自己产品验证一下,如果确实播放失败,再在第三方产品上也验证一下,如果第三方播放是正常的。很明显的这个应该是自己产品的存在问题。但是这种方案相对来说准确性没有方案一高(不排除第三方产品也有这个问题),相对于来说比较省时,有效。
基于上述2种方案的讨论,视频播放器问题定位方案的实现是基于 方案二 的基础上实现的,整个设计的总体框架如下:
对于整个框架的设计图,这里做一个简单的解释,当测试者启动测试脚本的以后,自动化脚本需要完成以下步骤:
1. 从服务器上拉取用户播放失败的片源。
2. 启动QQ浏览器监控,主要记录视频播放过程中的监控信息,包括日志、CPU、内存、截图等。
3. 在QQ浏览器验证当前片源是否可以播放,然后关闭QQ浏览器监控。如果可以播放,跳过步
4. 如果QQ浏览器播放失败,分别在UC浏览器和Chrome浏览器验证视频播放。
5. 如果QQ浏览器播放正常,同步服务器更新验证QQ浏览器测试结果;如果QQ浏览器播放失败,而第三方APP播放正常,不仅要同步服务器更新验证结果,还要上传QQ浏览器播放过程中监控信息到服务器上。
6. 测试者通过服务器预览真机验证的测试结果和获取监控信息。
三、HTML 5 视频介绍
前面介绍框架中涉及QQ浏览器、UC浏览器、Chrome浏览器视频播放验证的,为了更加清楚了解验证视频可播放性的原理,首先我们来认识一下HTML5视频(简称H5视频)的的HTML的一些特性,我们先看一个简单例子:
<video width=”500″ height=”250″ controls=”controls” src=”movie.ogg” />
从上面例子可以看出,H5视频就是在视频页面中增加一个video 元素和给这个video标签增加一些属性组成。简单介绍基本相关video标签的属性和H5的属性和方法:
属性 | 值 | 描述 |
autoplay | autoplay | 如果出现该属性,则视频在就绪后马上播放。 |
controls | controls | 如果出现该属性,则向用户显示控件,比如播放按钮。 |
height | pixels | 设置视频播放器的高度。 |
src | url | 要播放的视频的 URL。 |
width | pixels | 设置视频播放器的宽度。 |
属性和方法 | 描述 |
currentTime | 设置或返回视频中的当前播放位置(以秒计) |
duration | 返回当前视频的长度(以秒计) |
load() | 重新加载音频/视频元素 |
play() | 开始播放音频/视频 |
pause() | 暂停当前播放的音频/视频 |
从这个例子中,我们可以看出以下几点:
四、实现基本原理
基于前面基本设计框架和H5视频的相关知识,这里分别讨论一下自动化测试脚本对于QQ浏览器、UC浏览器、Chrome浏览器如何实现可播放性的验证?具体如下:
1. QQ浏览器可播放性验证
QQ浏览器是我们自己的产品,获取浏览器内核只用通过浏览器代码一个静态函数就可以搞定,再结合Android 的robertium自动化框架,注入视频相关的javascript脚本(下简称JS脚本),可以实现浏览器的播放视频验证操作,具体流程实现如下:
2. UC浏览器可播放性验证
UC作为我们的商友,但是我们没有UC源码,实现自动化播放视频难度比较高。不过我们通过阅读UC浏览器官网发现,UC为了外部开发者方便用UC浏览器调试网页,官网上提供了一个UC浏览器开发者版本,具体请参考: http://plus.uc.cn/document/webapp/doc5.html 仔细阅读UC文档,PC的Chrome浏览器连接手机的UC浏览器开发版调试发现,他们主要通过javascript的Websocket协议通讯来实现的。为了能在手机端通过脚本控制UC浏览器,这里在脚本中模拟PC端websocket协议完成和UC浏览器的通讯,主要的关键点如下:
1)初始化websocket
前面提到PC端的chrome浏览器和UC浏览器交互通过Websocket协议实现,在它们通讯之前,需要完成Websocket相关初始化,按照下列步骤可以实现java代码模拟webscoket初始化。
步骤1:在PC的Chrome浏览器打开UC动态调试页面,然后在Inspector.js 中websocket初始化增加一个断点,如图所示:
步骤2:刷新一下chrome 页面连接UC浏览器调试页面后,websocket创建断点将被触发,然后观察websocket初始化的参数,如图所示:
步骤3:从步骤2图片中可以看出,在websocket初始化中是“ws://localhost:9998/devtools/page/0″,其中0 代表打开页面的num数。为了方便在脚本中完成websocket协议初始化工作,需要借助于开源库xlightweb(实现websocket协议库)完成websocket初始化,具体代码实现如下:
2)发送websocket消息
在chrome浏览器调试UC浏览器页面时, 涉及到Chrome浏览器操作都是通过websocket协议传递UC浏览器,然后UC浏览器根据相应消息参数来处理相关的操作。通过调试JS代码,再按照下列的步骤可以实现java脚本模拟websoket发送消息,具体步骤如下:
步骤1:首先了解在chrome浏览器页面操作给UC浏览器发送的消息,同理在Chrome浏览器的inspectorBackend.js中发送给手机消息端下一个断点,如图:
步骤2:为了观察消息的发送传递参数,先在Chrome的控制台中向手机UC浏览器发送一个javscript脚本(例如:alert(1)) 断点将被触发,发送给UC的消息参数如下:
图中可以看出发送的消息参数是一个json数据,数据格式如下:
{“method”:”Runtime.evaluate”,”params”:{“expression”:”alert(1)”,”objectGroup”:”console”,”includeCommandLineAPI”:true,”doNotPauseOnExceptions”:false,”frameId”:”0.1″,”returnByValue”:false},”id”:26}
其中expression的值就是我们从chrome的发送的JS脚本。
步骤3:在脚本利用开源xlightweb库模拟websocket发送的消息,代码实现如下:
这里TextMessage是xlightweb库定义Websocket发送消息的一个Message,然后通过writemessage方法把消息发送出去。
3)接受Websocket消息
当UC浏览器处理了chrome浏览器的消息后,对处理的结果需要返回给Chrome浏览器,具体的消息接受也可以通过断点的方式进行调试。但是这个部分对于xlightweb库来说已经帮实现好了,只要重载IwebsoketHandle接口的onMessage方法就可以了,具体的代码实现如下:
代码逻辑很简单,获取消息只要通过创建的websocket 连接的readTextMessage就可以实现,但是注意的读取的Message也是一个json的数据,需要通过解析才能获取获取UC浏览器的处理结果。
4)总结
前面通过chrome浏览器调试和结合开源xlightweb库实现和UC浏览器的websocket的初始化、发送消息、接受消息,然后讲解了脚本中具体的代码实现原理。随后可以利用websocket和UC浏览器连接发送消息方式,注入我们自定义关于视频播放的相关脚本,通过脚本中自定义的HTML5的相关函数就可以控制UC内核播放视频。具体流程图如下:
3. Chrome浏览器可播放性验证
Chrome是一个由Google(谷歌)公司开发的网页浏览器。该浏览器是基于其他开源软件所撰写,包括WebKit,目标是提升稳定性、速度和安全性,并创造出简单且有效率的使用者界面,而且在Chrome浏览器地址栏中输入JS脚本,浏览器内核也可以执行这段脚本,下面是在浏览器地址栏输入一段JS脚本,测试浏览器的执行效果,如图所示:
通过上图可以发现,只要通过Chrome地址栏同样也可以完成JS脚本注入来控制浏览器的内核,为了完成Chrome浏览器可播放性的验证,这里还需要google的开源UIAutomator自动化框架来帮助实现,具体实现步骤如下:
步骤1:利用Andorid 开源UIAutomator获取的Chrome的地址栏的控件,如图:
步骤2:获取到地址栏后,再通过UIAutomator加载自定义关于视频播放的相关JS脚本代码实现如下:
步骤3:成功注入自定义JS代码后,同样在地址栏中调用自定义JS脚本的相关视频函数可以实现视频的播放和获取播放时间,具体chrome浏览器验证视频播放流程如下:
五、测试结果与展望
目前脚本开发完成也有一个多月时间了。自动化脚本上线后,也有一定收益。下面是最近一段时间通过运行这套方案取得的成果:
问题1:播放过程中出现硬解切换软解的问题
根本原因:当前硬解切换软解后,需要reset中清除了updatesurfaceListener而导致的。
解决方案:切换时,不清除updatesurfaceListener。
问题2:文件句柄泄漏的问题
根本原因:下载模块公共问题,当启动下载模块后,downloadmanager启动下载句柄,当下载任务完成后,该句柄不能释放而导致内存泄漏,当达到1024 句柄后,浏览器会Crash.
解决方案:下载任务完成后,downloadmanager释放文件句柄。
问题3:ku6网站少量片源m3u8视频源不规范的问题。
根本原因: 获取的视频裸地址是.m3u8格式的,播放解析的m3u8文件后,里面文件不是ts类型,而是mp4类型。
解决方案:量比较少,而且不符合m3u8规范,目前未解决。
但是目前从每天自动化结果看,能够检测到少量片源仍然在QQ浏览器播放失败,但是在第三方浏览器播放成功的情况。这些都是概率性非常低问题,导致这样问题可能有多方面因素引起的,所以更需要这样的工具来反复验证定位,同时工具记录了播放视频失败源的详细监控信息,结合这些监控的信息再商讨如何解决这类问题。所以后面计划中,需要和开发深度合作,在这三个大方向进行深度优化,以提高工具的实用性:a.)后台上报的失败视频源分类更详细,b.)测试浏览器版本的log上级别更高,c).脚本对于记录失败的场景更加详细和准确,有些了此类强大的工具以及更加丰富、更有价值的信息,相信会有非常不错的收益。