作者:赵六四

一、方案背景介绍

随着互联网技术的发展,用户使用 QQ 浏览器进行上网观看视频越来越多,最近统计目前使用 QQ 浏览器观看视频已经过亿。不同的用户由于不同的场景下播放不同的网站的视频源,可能会出现播放失败的情况,而这些失败的播放数据会通过数据上报系统上报至运营后台,将后台拉取数据并经过一定的分析,就能得到播放失败的网站、机型、时间、网络状态等信息,下图是最近后台统计的播放失败率最高的几个视频网站,如下图所示:

当然播放失败可能有多种原因而导致的,例如:浏览器对该种类型的网络视频不兼容、网络视频本身出现问题、用户网络环境的原因 等等。所以需要一种快捷准确的方案,能从成千上万用户的播放失败的源中找出是由于播放器或者是代码导致的问题。在这种情况下,引入了视频播放器问题定位方案。

二、实现总体框架

通过获取到一个用户的失败视频源后,验证是否播放器兼容的问题,目前主要有 2 种方式:

方案一:直接用播放失败的源在浏览器版本进行调试分析,这种方案是最准确,但是耗时比较大,主要因为播放失败并非是播放器的原因,例如:源的问题等。

方案二:先用我们自己产品验证一下,如果确实播放失败,再在第三方产品上也验证一下,如果第三方播放是正常的。很明显的这个应该是自己产品的存在问题。但是这种方案相对来说准确性没有方案一高(不排除第三方产品也有这个问题),相对于来说比较省时,有效。

基于上述 2 种方案的讨论,视频播放器问题定位方案的实现是基于方案二的基础上实现的,整个设计的总体框架如下:

对于整个框架的设计图,这里做一个简单的解释,当测试者启动测试脚本的以后,自动化脚本需要完成以下步骤:

从上面例子可以看出,H5 视频就是在视频页面中增加一个 video 元素和给这个 video 标签增加一些属性组成。简单介绍基本相关 video 标签的属性和 H5 的属性和方法:

部分属性:

部分属性和方法:

从这个例子中,我们可以看出以下几点:

步骤 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 浏览器播放失败,但是在第三方浏览器播放成功的情况。这些都是概率性非常低问题,导致这样问题可能有多方面因素引起的,所以更需要这样的工具来反复验证定位,同时工具记录了播放视频失败源的详细监控信息,结合这些监控的信息再商讨如何解决这类问题。所以后面计划中,需要和开发深度合作,在这三个大方向进行深度优化,以提高工具的实用性:

有些了此类强大的工具以及更加丰富、更有价值的信息,相信会有非常不错的收益。

本章完~~

本文连接:http://tmq.qq.com/2016/07/it-is-necessary-to-know-the-background-performance-test/


TMQ(腾讯移动品质中心)是腾讯最早专注在移动 APP 测试的团队
我们专注于移动测试技术精华,饱含腾讯多款亿级 APP 的品质秘密,文章皆独家原创,我们不谈虚的,只谈干货!

扫码关注我们

扫一扫 关注 TMQ
精彩分享不断


↙↙↙阅读原文可查看相关链接,并与作者交流