前端音视频技术实施、性能、及兼容性调研
最近公司上个项目,希望里面有视频功能,之前知道 H5 支持 video 标签,拿过来一用,结果在移动端出现了各种兼容问题。于此展开调研。 来吧,让我们看一下开发之最有趣又有意义的历史故事👇
历史:
基础篇: 适用一些短视频的默认兼容问题。
很多开发在做视频的时候,PC端已相对成熟,在移动端就会碰见各种兼容问题。例如想进入页面自动播放视频之类的。全屏播放,禁止自动全屏,ios,android,微信端口之类的常见问题解决、video常用属性、ios、android自动播放。
2G 时代已经相隔甚远。 可以想象一下为什么不允许自动播放? 播放即代表着下载,那个时候用户还是比较在乎流量的。
so ~ 只在产生用户交互时才可以播放
而技术相对成熟的今天流量大都消费的起了,一些浏览器在4G等网络下也会提示:要播放视频耗费流量了,是否继续?
so ~ 在IOS10 ,安卓的 chrome 53之后又开放了此功能。
无音频源的 video 元素 允许自动播放
- elements will be allowed to
autoplay
without a user gesture if their source media contains no audio tracks.禁音的 video 元素允许自动播放
- elements will also be allowed to autoplay without a user gesture.
如果 video 元素在没有用户手势下有了音频源或者变成非禁音,会暂停播放
- If a
<video>
element gains an audio track or becomes un-muted without a user gesture, playback will pause.video 元素屏幕可见才开始播放
- elements will only begin playing when visible on-screen such as when they are scrolled into the viewport, made visible through CSS, and inserted into the DOM.
video元素不可见后停止播放
- elements will pause if they become non-visible, such as by being scrolled out of the viewport.
亲测后发现:
同时设置autoplay muted 后 ios、android 默认浏览器都实现了,微信要载入微信的SDK的方法,ios有效,安卓无效。
进阶篇: 适用一些长视频的性能问题,如加载视频,无缝切分辨率等。
我们知道一段动画是由一帧帧静态的图片组成的。图片帧数的密集度决定了动画是否流畅,顺滑,图像的质量,清晰度,决定了动画的清晰度。视频或者直播我们可想而知:经过摄像头的采集,经过视频编辑加字幕、修图等等最终导成计算机可识别的编码。集成在一个文件内,这个文件可能是mp4? 可能是webm、hls、flv、ts等。 这些格式各有所长,如早期Flash主要是flv与苹果推出的hls视频协议后缀为ts主要偏直播使用,mp4,webm为电影视频等使用。
2000年左右,网络上的视频播放主要依靠Flash插件。这是因为当时没有其他方法可以在浏览器上流式传输视频。
苹果公司在其产品上禁用 Flash 后,加速促成了现在的 HTML5 的标准之 “将 video 标签带到当前 Web”
使用video播放视频非常的简单,文档较全,也兼容了大多数浏览器。但是出于当今拼用户体验的时代,精益求精成为难题。我们经常看电视剧电影的都知道,当在流畅模式切换到高清模式都要等待一会“切换中...”。 那么其中的原理为何这样,又如何向YouTube一样实现无缝切播视频?
现大多数网站都会将视频切割,如一小时的一个视频文件,切成20s的N个视频文件。当我们播放视频时可以看到浏览器会不断的请求视频资源。那么这样做的好处就是加载完第一个20s的视频文件即可开播,无需等待视频全部下载完毕,用户感觉爽歪歪啊!
同步的加载这些视频,加载好的丢进一个源队列,按序播放,这也解释了为什么我们看视频时可以看到缓冲条一点一点的往前加而不是一大块或全部视频加载完毕。这也解释了为什么流畅模式缓存的内容,切换到高清模式都没了要重新缓存。对这种下载也可以加以控制,队列内最大允许存在10个?时时下载避免资源浪费。后续中讲说到的SourceBuffer也会有一定关系。
那这种做法的弊端相对于切成更长,例如20min的视频也体现了,在网络不好的情况下,会经常断断续续卡顿。。。这也解释了为什么当我们看春晚或某些现场直播时,主持人这边说完,另一边要迟缓几秒作答。。视频的切割多少,及网速的响应能否持续下载。应取一个相对稳定的值保证播放的顺畅。 说到这里我们又要拓展一个概念流式传输,以上所述的切割视频分段播放需要流式传输的支持,比如webm就是流式传输的,mp4就不是,所以不能切割播放。
我们知道了一种视频的不同清晰度并非是一个视频文件,各是各的。 那么在切换的时候就需要另一个视频文件缓存区已下载好可以开播,我们还要记录并控制切换时的播放时间,还要替换video的src? 这种操作一定不是无缝的,视频的src都更换了,中间要闪一下撒~~。 那么有的开发想到同时播俩video呢,用z-index控制层级呢?这种做法不光白白下载了很多资源及下载卡顿,在网速及设备的性能处理,JS处理浏览器的处理下,同时播的俩视频也并非会在同一时间完全吻合上。所以还是不行!
此时就要更强大的Web API登场 Media Source Extensions(MSE) 、 SourceBuffers
MediaSource
对象(一个包含即将播放的媒体文件的准备状态等信息的容器)
SourceBuffer
对象(代表多个组成整个串流的不同媒体块)的元素
粗糙的理解,可以一个一小时的视频文件可以拆成3个20min的SourceBuffer,然后依次处理SourceBuffer传递到MediaSource,MediaSource经过处理展现在浏览器的荧屏上。
官方文档上也声明了这是个新东西,许多浏览器还在开发阶段,兼容性有限。
如果没有精确的控制时间、媒体质量和内存释放等需求,使用 <video>
和 <source>
是一个更加简单但够用的方案。
底层原理篇: 未完待续....
相关第三方插件:
相关播放器:
DASH、HLS、Smooth Streaming