Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

38. 视频优化(2) 与 ios 滑动bug研究 #38

Open
funfish opened this issue Mar 30, 2019 · 1 comment
Open

38. 视频优化(2) 与 ios 滑动bug研究 #38

funfish opened this issue Mar 30, 2019 · 1 comment
Assignees

Comments

@funfish
Copy link
Owner

funfish commented Mar 30, 2019

去年项目上遇到视频加载问题的时候,想到了 preload 的方式来加载视频 虽然效果不佳。只是视频的问题还有很多没有解决,这次项目里面又再次遇到视频问题,

ie 9 视频显示问题:

目前已经抛弃了低版本的 IE,至少 IE 8 是不支持得了,但是 IE 9 还是要支持的。想到我厂在全国销量,人群分布情况,win 7 + IE 9 还是有很多的,具体的浏览器分布数据一直没有拿到。在 全球范围内,IE 份额已经只有 5.34% 了,但是在国内,ie 9 的份额居然还有 9.72%,ie 11 有 7.26%,ie 8 有 5.86%,咦,原来 ie 的份额都这么多多。。。如果没有天猫以及甚至淘宝的强势推广,可能这个份额会更高。目前看来,ie 9 这两年国内的市场份额没有降低的趋势,兼容 ie 9 也是必要的了。

这里 ie 9 的 video 显示问题,指的是有些 mp4 文件可以在 ie 9 播放,有的就不能。之前处理方式都是对不能在 ie 9 播放的视频,专门替换成图片,规避问题,但是 video 标签明明是支持 ie 9 的,为何有些可以,有些不能呢?在 win 7 系统上面可以清晰的看到,支持 ie 9 播放的视频,可以看到帧宽,帧高,而不能播放的视频,则看不到,很明显 win 7 不支持这些视,所以应该是视频源的问题。

一开始以为是视频丢失帧高帧宽,通过 ffmpeg 的 scale 方式给视频一个指定高度和宽度,发现当高度高度 1088 的时候视频无法播放,而低于 1088 的时候则正常显示,这又是什么问题?由于 scale 后清晰的显示模糊,采用软件格式工厂得出的视频,指定帧宽高后,视频质量堪忧,模糊是模糊了点,但起码能用,在 video 里面采用两个标签的形式,还是可以播放的。只是具体为何 ie 9 不能播放,还是没有找到原因。

直到某天不小心发现 这篇文字,可以看到 H.264 Video Decoder,哦,原来是 win 7 平台 H.264 解码器不支持超过 1920 × 1080

[!Note] In Windows 7, the maximum supported resolution is 1920 × 1088 pixels for both software and DXVA decoding.

只要将视频的高度压缩到 1920 × 1088 就可以了。原先不能在 ie 9 播放的视频,帧高都超过了 1088。这个时候也遇到了另外一个神器 HandBrake,压缩视频非常好用,张大神的 文章有介绍到。通过反复尝试,高于超过 1920 × 1088,无法在 ie 9 播放。这是 win 7 系统的问题。甚至 ie 11 也会有这样的问题

于是合理的处理方式是有两个视频源,一个是正常的,一个是为 win 7 上面的 ie 浏览器准备的低尺寸视频。当然这会增加设计师的工作。。。。

mp4 加载的3次请求

在之前的视频优化里面,就发现视频会有三次请求,如下:

只是视频一多,发现个别视频又不会有三次网络请求。尤其是 banner 位的视频,是要秒开的(well,虽然没有人要求),三次来回的请求占据了太多时间。后来反复查找资料,发现张大神的文章 从天猫某活动视频不必要的3次请求说起。简而言之就是 mp4 文件是由一个个 box 组成的,一级嵌套一级来存放媒体信息。其中视频文件的宽高、时长、码率、编码格式等存放在 moov box 里面,如下图

mp4 box 的信息,win 10 可以通过软件 mp4info 来查看,地址: https://pan.baidu.com/s/1PcAMVaX2cc8UV3vFxpBSFQ,提取码:3ua3;
这个工具可以查看其 box 信息,如下所示:

moov 后置,如上图,则浏览器会发送三次请求,具体请求内容看张大神的解释。而 moov 前置,若没有moov.udta.meta,也可能会有三次请求(不同浏览器策略不一)。可见这个 moov 的前后置以及 moov.udta.meta 情况影响加载是否有三次请求。

至于 moov 修改,或者添加,则可以通过 ffmpeg 修改,或者简单的通过上面提到的 HandBrake,里面有 Web Optimized 可以导出优化后的视频。

视频使用心得

桌面视频播放在突破了 ie 之后,基本没有什么问题,唯一要注意的是添加 poster 来过渡好视频首帧播放。

安卓播放的问题是最多的。由于视频多为手机录像,需要有手机框配套,并且有圆角,有浮层。为了避免各式各样的问题,采用的是做个折中的弹出层播放。也采用过手机框和录像一起作为整个视频播放,但是在安卓浏览器上,原本的视频的内部圆角出现了折痕,虽然不是很明显,但是也是够奇葩的了。

HandBrake 默认的配置里面,一般没有对应的视频源尺寸,多为 1080/720/480 等尺寸,可以自己创建新的 Preset,比如采用视频源方式。

HandBrake 尺寸设置里面,要注意裁边模式,默认是自动的,但可能会出现自动模式下,裁边错误的情况,这个时候就需要手动调整了。

HandBrake 可以通过 video 选项里面 Eencoder Preset 来设置编码的速率,越慢压缩效果越好,处理后视频体积越小,但是时间开销越多。

IOS scroll 引起的bug

ios 的 safari 从 ios 5 就带有弹性滚动,而如果你要有需要在 div 里面做滚动,若只是单纯的设置 overflow-y: scroll;,页面会滚动,但是也会变得非常僵硬,卡顿。为了达到原生的效果,需要有如下设置 -webkit-overflow-scrolling: touch; 。如此可以达到原生滑动的效果。然而这个设置会带来诸多意想不到的 bug。

首先是为了配合 scroll,自然要设定一个固定高度。遇到的问题简化为如下情况:

<div class="wrapper">
  <ul class="inner">
    <li class="inner-item">
      <div class="img-wrapper">
        <img src="" alt="" /> 
      </div>
      <div class="img-wrapper">
        <img src="" alt="" /> 
      </div>      
    </li>
  </ul>
</div>

.wrapper {
  position: absolute; 
  left: 0; 
  top: 0; 
  height: 100%; 
  width: 100%; 
  overflow: auto;
}
.inner {
  overflow: scroll;
  -webkit-overflow-scrolling: touch;
}
.inner-item {}
.img-wrapper {
  position: relative;
  overflow: hidden;
  width: 100px;
  height: 100px;
}
.img {
  position: absolute;
  height: 200px;
  bottom: 0;
  left: 0;
}

-webkit-overflow-scrolling: touch; 放在 inner 类里面,是由于放在 wrapper 类里面,会经常性导致页面滑不动,触发 ios 的橡皮筋效应,而不是页面的滚动。

遇到的神奇的 bug 是:页面初始化正常,并且能够正常滚动。但是里面的 image 却会在快速滚动中出现溢出情况,而且是第二张溢出,第一张不溢出,慢慢滚动还不会出现,防不胜防。

先回顾一下溢出问题,这里的 image 由于设置了绝对定位,顾其尺寸大小,受其最近的包含块影响。image 上级元素,position: relative;,所以包含块为 img-wrapper,其是不会产生溢出效果的。那怎么这样的问题呢?难道是 -webkit-overflow-scrolling: touch; 的锅?

于是查看 apple 的官方 文档,写道:

touch Native-style scrolling. Specifying this style has the effect of creating a stacking context (like opacity, masks, and transforms).

通过设置 -webkit-overflow-scrolling: touch; 会让元素的叠层水平和 opacity, masks, and transforms 之类的一样。而值得一提的是 transforms 也可以生成包含块。难道滚动的时候,img-wrapper 这个包含块不起作用了,倒是 inner 这个包含块其作用?这么说好,好像行得通,第一张图片没有溢出,是被 inner 给设定死了溢出空间了?为了提升包含块,于是分别在 img-wrapper 与 inner-item 设定 transform: translateZ(0)。结果 设置在 inner-item 的起作用了。看来 img-wrapper 的包含块无效化了,但是这个叠层关系实在有点远,看不出所以然。只能当作是个诡异事件。

后来觉得 transform 的设置还有个妙处,针对 ios 可以起到硬件加速渲染,避免图片出不了。

@funfish funfish pinned this issue Mar 30, 2019
@funfish funfish unpinned this issue Mar 30, 2019
@funfish funfish self-assigned this Mar 30, 2019
@funfish
Copy link
Owner Author

funfish commented Mar 30, 2019

#35

@funfish funfish closed this as completed Mar 30, 2019
@funfish funfish reopened this Mar 30, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant