视频编解码对于大多数前端工程师来说是一个比较少涉足的领域,业内主流的处理是通过 FFmpeg 做简单的转码和简单的优化,其中涉及到流媒体技术中的文本、图形、图像、音频和视频多种理论知识。
视频编码
我们常说的视频编码是指通过特定的压缩技术,将某个视频格式的文件转换成另一种视频格式文件的方式。常见的视频编码 H.265、H.264 等。
H.264
H.264,同时也是 MPEG-4 第十部分,是由视频编解码技术的组织国际电联(ITU-T)视频编码专家组(VCEG)和 ISO/IEC 动态图像专家组(MPEG)联合组成的联合视频组(JVT)提出的高度压缩数字视频编解码器标准。这个标准通常被称之为 H.264/AVC–用来明确的说明它两方面的开发者。因此,不论是 MPEG-4 AVC、MPEG-4 Part 10,还是 ISO/IEC 14496-10,都是指 H.264。
H.265
H.265(HEVC,High Efficiency Video Coding,高效率视频编码),是新一代视频编码技术。它围绕现有视频编码标准 H.264,保留原来的某些技术,使用新技术对某些方面进行改进优化,如码流、编码质量、延时等,提高压缩效率、增强鲁棒性和错误恢复能力、减少实时的时延、降低复杂度等。
H.265 与 H.264
H.265 与 H.264 的区别,就在于 H.265 压缩效率更高,传输码率更低,视频画质更优,实现监控视频传输带宽减半、存储减半、成本减半,带给人们更优质的体验。
但是因为 H.265 专利及硬解支持情况不完善的原因,主流现代浏览器均不兼容 H.265 编码的视频播放。想要在浏览器端播放 H.265 原生的视频标签是没有办法支持的。浏览器兼容性:
解码支持
硬解码
Apple 公司的最新的操作系统版本(Mac Hight Sierra 和 iOS 11)迎来了 HEVC (高效视频编码,也称 H.265) 这一新的行业标准,也是上面的 safari 13 以上版本支持的原因。
Web 软解码
主要用到了 WebAssembly 及 WebWorker 的支持,通过解码器编译为 wasm 库,wasm 文件是以二进制形式存在的,这也是很多移动平台采用的方案。该技术方案已经能在大部分机器的主流浏览器上流畅的播放 720P 的高清直播流,但是在性能稍差的机器上还是存在高清视频解码性能不能满足流畅播放的风险,针对 WebAssembly 达到 native 速度的目标还有一定距离,尤其是汇编并行计算的支持。
遇到的问题
有了上面的理论基础我们来看看问题:
测试在上传视频时有的视频无法获得宽高默认是 0
上传组件是用的 @du/upload ,通过代码研究发现 @du/upload 获取宽高是基于 loadedmetadata
1 | video.addEventListener( |
通过分析异常视频:
出现错误的视频编码是 HEVC 也就是 H.265,因为当前浏览器不支持解析视频所以拿不到视频资源的数据。至于为什么通过飞书、微信之类的聊天工具传输过就可以是因为在传输过程中通讯工具已经默认转码成 AVC(H.264) 格式。最快解决方案目前做的是提醒用户转换视频。
1 | var supportHEVC = function(video) { |
- web 播放 H.265 视频
libde265.js 是一个通过 JS 来解码 H.265 视频的库,它通过将 视频的 frame data 转化为 rgba 像素,然后绘制到 Canvas 上。
未来展望
在有限带宽下 H.265 能传输更高质量的网络视频,更低的带宽可以更好的降低存储及传输成本,H.265 将为未来基于短视频及直播领域更多更复杂好玩的互动玩法做铺垫。以后借助 WebAssembly 的跨平台优势,web 端可以将传统的其他语言的开源框架如图形相关开源库 OpenGL、SDL 等的能力移植到浏览器上来。借助性能上的优势也可以将传统的图像、3D 等运算能力要求较高的应用扩展到浏览器端,前端将会后更多的玩法,尤其是直播的兴起,所以在 WebAssembly 技术上需要提前做好积累。
参考链接
1.花椒前端基于 WebAssembly 的 H.265 播放器研发
2.ffmpeg
3.webassembly