手机淘宝视频h5项目总结

第一次在手机淘宝浏览器内做h5(以下简称手淘),记录一下开发过程中碰到的坎。

项目简介

视频类h5,只有三个按钮,所以几乎不用互动。首尾两页加上中间的视频页,所有流程都是自动跳转。由于内容很简单,所以决定采用zepto做,这样体积可以尽量小。

百度统计

百度统计支持淘宝域名

P.S. 真的是站在风口上猪都能飞,我们的h5上线4天快破千万了

浏览器内核

猜测是同属阿里旗下的UC浏览器内核,所以这次碰到的一些css问题,今后在uc浏览器中可能也会遇到,比如

  • css不支持rem,这个实在让我有点惊讶,但这是我亲自试出来的。当然,以后还有手淘的项目,仍然会先尝试rem

tida

手淘专用的jssdk叫做tida,引入tida时,script标签要写在主业务逻辑的script标签之前,并在主业务逻辑中调用Tida.ready进行声明,样例如下:



  • 作为手机h5重地的微信,weixin.js要放在主业务script标签之后,主业务中先实现WeixinJSBridgeReady的监听事件,这是微信和手淘的区别。
  • appkey有前台key和后台key之分,用的时候记得问清楚部署的同学用的是哪一个

视频播放

这次h5项目最核心的部分就是视频,从最后的实现结果来看,整体的视频效果比微信端要优秀一些,因为仅凭video标签,就能实现ios和android两端相同的,理想的播放效果。

播放时全屏

全屏,无进度条,无广告,并且可以有按钮浮在视频上方,主要代码如下:


  • 这个标签是从淘宝大话西游的项目借鉴过来的
  • 安卓的进度条其实能看见的,在屏幕的最底部,但是不注意看不容易发现,而且手指很难点到
  • raw-controls,x-webkit-airplay,airplay三个属性在做这个项目之前,都没有接触过,之后做淘宝h5时要特别注意,现在想来可能是uc浏览器的内置标签,事后需要再去了解一下
  • 其他的标签属性,例如x5开头的,都是微信端浏览器中惯用的属性,另外,playsinline用来阻止ios自动弹窗全屏播放,都是之前用过的,可能其中仍有些属性是可以删除的,但是这次项目直到最后,都没有明确说过不在微信端投放,所以这些属性一直保留着,没有删除。
  • 这里说一下为什么手淘的视频播放比微信端要好,播放效果上,ios的效果差不多,但是android这边区别就很大:
    1. 视频上不能有按钮,否则就要实现同层播放器,即x5-video-player-type="h5" x5-video-player-fullscreen="true",这样就可以使其他div标签通过z-index浮在视频上方,但这样就会导致一个很严重的问题:浏览器标题消失了! FXXK!!
    2. 如果既要实现视频上按钮,同时还要实现浏览器有标题,也有办法,那就是将video的流媒体转换成ts流媒体播放。但这也有问题,第一,ts文件若要产生和video同样的清晰度,几乎不可能,而且此时码率已经要大一倍,文件会大3倍左右;第二,videots,包括项目中对系统的判断都会产生额外的开发开销;第三,ts视频结束后的跳转,需要修改源码,不太方便。第四,在白鹭引擎下开发时,.ts后缀名的文件会全部默认为typescript文件,ts视频会被误认为是typescript导致编译失败,这时候需要将ts视频改后缀,导致开发不畅。

被省掉的poster属性

这次很常用的poster属性最终被舍弃了,以下说明原因:

  • 在项目的一开始,加入poster后,ios上视频不能全屏播放,四周都有黑边,视频长宽比是正确的,但是面积小了许多,删除poster之后立即恢复正常。但问题不是一直出现的,当video采用了大话西游的标签之后,即使加了poster,也不会改变视频面积了。怀疑和其他标签也有关系(raw-controls,x-webkit-airplay,airplay
  • android设备在视频播放时,即使poster存在,仍然会有一瞬间,poster消失但是视频黑屏的现象,这样poster的意义就没有了,但同样的黑屏现象,ios上没有。
  • android设备在视频播放时,如果在4g环境下,可以看到在poster消失后,视频出现了一次明显的形变。形变大致是视频面积很小,以宽屏的形式在屏幕居中,能看到进度条,然后突然放大撑满屏幕。但是这个形变的现象在wifi环境下就没有。

视频自动播放

淘宝环境下,视频是可以实现自动播放的,实现方式如下:

Tida.network.getType(function(data) {
                        if(data.errorCode) {
                            return;
                        }
                        
                        appView.playMainVideo();
                    });

来自阿里巴巴技术人员的原话:成功回调是客户端的能力,操作权限会高一些。

隐藏h5标题栏

tida自带hideTitle方法来隐藏标题栏,但在iphoneX下,设备隐藏标题栏后的窗口宽高并不是全屏,隐藏后窗口宽度相同,但是高度会比屏幕短一截。这是手淘的bug。可以通过再来一遍showTitle,hideTitle来解决。所以总体解决流程为:hideTitle,showTitle,hideTitle,最后手工render渲染。

Tida.hideTitle();
                
setTimeout(function() {
    Tida.showTitle();
}, 130);

setTimeout(function() {
    Tida.hideTitle();
}, 260);

setTimeout(function() {
    loadCss(); // 加载css
    loadJs(); // 加载js
    loadHtml(); // 加载html
}, 390);

隐藏h5标题栏是客户在半途中提出来的,这带来了一个挺严重的问题,高度太高,设计稿分辨率不足。自从有了全面屏,设计稿的尺寸就一变再变,如今我们的统一设计稿都用640 * 1236的分辨率,但都是有标题栏的,而且在微信中,除了在播放视频时,其他时候并不会有这样的问题出现。现在标题隐藏后,实际分辨率达到了640 * 1386。最终采用的方案是画面整体宽高同时拉伸,使高度撑满屏幕,这样会导致宽度左右两边都超出屏幕一点,幸好机智的设计师们在一开始就考虑了安全区的问题,配上大行其道的flex布局,最后的效果还是比较满意的。

链接跳转≠网页关闭

当调用window.location.href时,手淘的做法和微信不同,微信会直接修改当前链接地址,这就相当于当前网页关闭了,而手淘更像是打开了一个新标签页,并将这个新标签页置顶。手淘的这个做法会带来一个新的问题,就是原标签页并没有关闭,而是继续运行,只不过是被新的页面盖住了,这样就会造成比如动画,视频,背景音乐始终在播放,必须手动将这些停止。幸好tida预料到了这种情况,给出了页面激活状态api来解决问题

var watchId = Tida.pageVisibility.watch(function(result){
     ///~ visible 1为激活 0为隐藏
     ///~ 移动端按Home键回到桌面js会挂起不执行,所有再次回到页面该方法会先后一起调用,注意区别该值
     if(result.visible ==1 ){
         // 页面显示了
     }else{
         // 页面隐藏了
     }
});

但是这个api并不是完美的,官方自己也说了ios下回碰到问题

~ 移动端按Home键回到桌面js会挂起不执行,所有再次回到页面该方法会先后一起调用,注意区别该值

这句话很拗口,而且还有两层意思

  • 第一层意思:当整个手淘被最小化退回系统桌面时,会触发一个result.visible = 0pageVisibility事件,但这个事件需要当你重新打开手淘后,才能收到。而当你打开页面的时候,如果当前标签页在最前方,还会在收到一个result.visible = 1pageVisibility事件
  • 第二层意思:ios端当按home键也好,手机屏幕底部上滑也好,总之当整个手淘被最小化,退回系统桌面后,再次点击打开手淘时,一定会触发一次pageVisibility事件,且result.visible = 1,无论此时你的页面是不是被隐藏在后面。android和ios的区别就在这里了,android在整个退出回来的过程中,一定能收到一条visible = 0,但是能不能收到第二条visible = 1,这要取决于退出的时候,当前标签页是不是在最前方;而ios在整个退出回来的过程中,一定能收到两条消息,也就是visible = 0visible = 1都会收到,晕!

嗯,是阿里的大牛们展示真正的技术了,面对这个尴尬的问题,人家轻描淡写的一句话就给我指明了方向:你可以加一个 requestAnimationFrame 来避免这个问题。牛逼,requestAnimationFrame只在页面真正渲染时才调用,也就是说,当收到visible = 1后,不要马上执行,而是将执行的内容延迟到requestAnimationFrame里,如果这个延迟的时间间隔太长,就说明页面并没有被真正激活,问题解决,代码如下:

var watchId = Tida.pageVisibility.watch(function(result) {
            ///~ visible 1为激活 0为隐藏
            ///~ 移动端按Home键回到桌面js会挂起不执行,所有再次回到页面该方法会先后一起调用,注意区别该值
            if(result.visible == 1) {
                var evtTime = Date.now();
                requestAnimationFrame(function(){
                    var reqTime = Date.now();
                    if(reqTime - evtTime > 1000){
                        return;
                    }
                    // do something
                });
                
            } else {
                // 页面隐藏了
                // do something
            }
        });

部署

不同于一般的部署方法(直接访问linux服务器部署相关文件),手淘使用了聚石塔作为工具,这是为了统一大家的部署方式,同时也解决了n台服务器n个系统如何同时部署的困难(我们这次一共是20台服务器上跑60个容器)。习惯了聚石塔的操作步骤后,使用起来还是比较方便的。但在实际过程中,仍然有很多槽点,我们的使用环境是tomcat,碰到的问题如下:

  • 聚石塔页面逻辑非常奇怪,页面内的功能几下跳转后居然就跳出聚石塔管理端意外了,而且跳出来就回不去了
  • 发布过程中,下方控制台输出的反馈不及时,有时明明正在部署中,但是控制台内容是空的,可以通过F5刷新一遍可以解决,但刷新也往往以为着需要重新部署一遍。
  • 重新部署一遍war包的开销相当大,遇上控制台反馈不及时的时候,体验近乎崩溃,半个小时都部署不了一个war
  • 后期经常采用单个文件部署的形式,但每次只能提交5个文件,导致这对序列帧这样的图片很不友好。一秒24张图片部署就要10分钟左右。
  • 两个人同时登陆聚石塔进行部署,聚石塔可能会在一端直接卡死,想来逻辑确实不太好做,今后要注意避免这种情况
  • 有时聚石塔莫名就慢下来了,这个时候可以通过更换浏览器,重新登录的方式解决

weex

weex是阿里系的移动框架。在这次的项目中,我们的h5算是内嵌在阿里自己的weex之中的,相比于h5,我觉得weex的体验会更好:基本没有loading的过程,无缝适配iphoneX的无标题窗口,也没有h5碰到的这种需要反复hide,show才能解决的问题。当然,这其中也有一部分原因是因为写weex就是阿里的大神们。。。

这次去云栖大会上,听了天施大牛的演讲,我们这套h5聚石塔的做法,在阿里的眼里其实已经落伍了,属于1.0时期的老技术。目前阿里前段已经进入了3.0时期,旨在阿里系的APP中全面使用weex的做法,并且主打小程序应用。那为什么这次手淘还会采用两端weex中间夹h5呢?是给广大小公司的福利吗?还是因为weex支持视频仍然不到位?还是本身这个项目需要跨淘宝,跨微信呢?可能还是最后一个理由比较说的通吧。。。

你可能感兴趣的:(手机淘宝视频h5项目总结)