浅谈基于HTML5的在线视频播放方案


Posted in HTML / CSS onFebruary 18, 2016

如今在这个特殊的时代下:flash将死未死,微软和IE的历史问题,html5标准未定,苹果和谷歌的闭源和开源之争,移动互联网的大势所趋,浏览器各自为战…这些都导致web开发者在设计视频解决方案的时候相当困惑。本文围绕这个主题,来探讨一下相关的技术,原理和工具。

编码与格式的误区
很多人将编码和格式误认为是同一个东西,往往以视频文件的后缀来唯一确定视频文件的支持程度。而事实上,用一句话来概括就是:视频的文件后缀(假设没有恶意修改后缀)实际上代表一种封装格式,而视频或者音频的编码算法与封装格式本身无直接的关系:同样的封装格式(即同样的后缀)可以封装不同编码算法的视频和音频。而视频播放设备或软件是否支持视频的播放,不仅仅要看封装格式,还要看编码算法。认清这一点是理解和排查问题的基础。

封装格式规定了视频的所有内容,包括图像,声音,字幕,系统控制等,其中以图像和声音最为关键。

从MPEG说起
MPEG是一个定义视频规格的国际组织,他们曾经推出的MPEG-1和MPEG-2实际上分别就是大家熟知的VCD和DVD,不过这都是远古的东西了。我们来看看跟本文主题有关的MPEG-4规范。

MPEG-4规范规定了文件后缀名为.mp4,目前包括三种图像编码和压缩算法:Xvid\DivX\AVC(H.264),其中Xvid和DivX也可以统称为MPEG-4 Part 2或者MPEG-4 Visual,而更为知名的H.264和AVC是相同的概念。音频方面则是AAC。以下关于兼容的内容,来源于维基百科和格式工厂以及笔者的测试:

Android浏览器:支持DivX和AVC,Xvid应该不支持
iPhone和iPad(iOS):支持DivX和AVC,Xvid不支持
Chrome:支持AVC,不支持DivX和Xvid。谷歌曾在2011年初宣布由于许可问题,将移除Chrome浏览器对AVC(H.264)的支持。但是直到目前的版本,AVC还在被支持。另外,实际测试下来,如果是DivX和AAC封装在mp4中的话,chrome可以播放,但是只有声音(AAC)。
Firefox和Opera:还是由于许可的问题,Firefox和Opera逐渐动摇了对AVC的支持,笔者在最新的Firefox中测试AVC仍然可以播放(维基百科的解释是可能与系统本身具有解码器有关);至于DivX和Xvid,笔者在Firefox下的测试结果是不支持。从维基百科的兼容列表看,Opera对AVC支持的不好。
IE:笔者的IE11能够支持AVC,不支持DivX和Xvid
WebM的倡导
由于AVC(H.264)的授权问题,以Chrome、Firefox、Opera为首的开源阵营开始动摇对AVC的支持,尽管目前这些浏览器仍然能够支持AVC,但是它们也倾向于一个叫做WebM的开源多媒体项目,该项目包括一个叫VP8的新的开源视频编解码方案。目前VP8已经发展到了VP9。作为封装格式的WebM具有.webm的后缀和video/webm的MIME类型。在音频方面,可以使用Vorbis/Opus。从兼容性看,Chrome、Firefox、Opera对VP8的兼容性相当理想,但是Safari和IE几乎无法支持。

开源的Ogg
Ogg几乎与WebM相同,开源,被广泛的在开源平台支持。其视频编码方案称为Theora(有VP3发展而来,由Xiph.org基金会开发,可被用于任何封装格式),音频为Vorbis。后缀通常为.ogv或.ogg,MIME类型为video/ogg。在兼容性上,Chrome、Firefox、Opera能够支持(但是Opera在移动平台上无法支持),但是Safari和IE几乎无法支持。

Html5方案
以上的讨论实际上的大前提是:视频基于Html5的<video>方案。现在我们来总结一下兼容性:
浅谈基于HTML5的在线视频播放方案

*IE9 “只有当用户安装了VP8的编解码器时”才能支持VP8。

‡Google Chrome 2011年宣布 放弃H.264, 但是“还没兑现”。 可以看出现在主流的仍然是MP4(AVC),但是为了解决“开源阵营”对AVC的摇摆不定,可以选择利用video的多源方案,在AVC的基础上额外提供对webm或ogg的支持:

XML/HTML Code复制内容到剪贴板
  1. <video poster="movie.jpg" controls>  
  2.   <source src="movie.webm" type='video/webm; codecs="vp8.0, vorbis"'>  
  3.   <source src="movie.ogg" type='video/ogg; codecs="theora, vorbis"'>  
  4.   <source src="movie.mp4" type='video/mp4; codecs="avc1.4D401E, mp4a.40.2"'>  
  5.   <p>This is fallback content</p>  
  6. </video>  

浏览器会根据自己的偏好来选择具体加载那种格式的流媒体文件,当然服务端必须对同一个视频提供多种格式的支持,具体可以这么做:

提供一个WebM的视频版本(VP8+Vorbis)
提供一个MP4的视频版本(H.264+AAC(low complexity))
提供Ogg版本(Theora+Vorbis)
服务端推荐使用nginx,尽量注意MIME类型的配置正确

旧版本的IE和flash
在html5流行之前,通用的视频播放解决方案是flash和flv(flash从9开始支持h.264的mp4)。但是随着ios设备的流行,flash已经不是万能药了,越来越多的视频网站提供多元的解决方案,而且偏向于html5:也就是说,通过检测agent是否支持html5来决定使用video还是flash。在面对IE8以下的浏览器时,flash几乎是唯一的选择(silverlight的接受度普遍不高)。

当然针对flash和flv的方案,也有多种实现方法,笔者能够想到的有如下两种:

服务端根据agent的类型,输出不同的html,如果支持html5就输出video+mp4(avc)和webm(或者ogg),否则输出flash相关的标签或脚本
使用html5shiv和html5-video是IE也能够支持video标签,并且使用Flash播放器来代替原生的video播放。
将object内嵌在video中:

XML/HTML Code复制内容到剪贴板
  1. <video id="movie" width="320" height="240" preload controls>  
  2.   <source src="pr6.webm" type="video/webm; codecs=vp8,vorbis" />  
  3.   <source src="pr6.ogv" type="video/ogg; codecs=theora,vorbis" />  
  4.   <source src="pr6.mp4" />  
  5.   <object width="320" height="240" type="application/x-shockwave-flash"  
  6.     data="flowplayer-3.2.1.swf">  
  7.     <param name="movie" value="flowplayer-3.2.1.swf" />  
  8.     <param name="allowfullscreen" value="true" />  
  9.     <param name="flashvars" value="config={'clip': {'url': 'http://wearehugh.com/dih5/pr6.mp4', 'autoPlay':false, 'autoBuffering':true}}" />  
  10.     <p>Download video as <a href="pr6.mp4">MP4</a><a href="pr6.webm">WebM</a>, or <a href="pr6.ogv">Ogg</a>.</p>  
  11.   </object>  
  12. </video>  
HTML / CSS 相关文章推荐
css3让div随鼠标移动而抖动起来
Feb 10 HTML / CSS
一款纯css3制作的2015年元旦雪人动画特效教程
Dec 29 HTML / CSS
CSS3实现线性渐变用法示例代码详解
Aug 07 HTML / CSS
Html5实现单张、多张图片上传功能
Apr 28 HTML / CSS
html5 Canvas画图教程(9)—canvas中画出矩形和圆形
Jan 09 HTML / CSS
HTML5样式控制示例代码
Nov 27 HTML / CSS
HTML5 video标签(播放器)学习笔记(二):播放控制
Apr 24 HTML / CSS
使用phonegap克隆和删除联系人的实现方法
Mar 31 HTML / CSS
html5中audio支持音频格式的解决方法
Aug 24 HTML / CSS
canvas中普通动效与粒子动效的实现代码示例
Jan 03 HTML / CSS
CSS3鼠标悬浮过渡缩放效果
Apr 17 HTML / CSS
CSS实现九宫格布局(自适应)的示例代码
Feb 12 HTML / CSS
全面解析HTML5中的标准属性与自定义属性
Feb 18 #HTML / CSS
简单整理HTML5的基本特性和语法
Feb 18 #HTML / CSS
HTML5实现预览本地图片
Feb 17 #HTML / CSS
HTML5新特性之用SVG绘制微信logo
Feb 03 #HTML / CSS
HTML5未来发展趋势
Feb 01 #HTML / CSS
详解HTML5中的Communication API基本使用方法
Jan 29 #HTML / CSS
HTML5中的音频和视频媒体播放元素小结
Jan 29 #HTML / CSS
You might like
PHP 图片上传实现代码 带详细注释
2010/04/29 PHP
PHPCMS的使用小结
2010/09/20 PHP
解析php中memcache的应用
2013/06/18 PHP
关于php微信订阅号开发之token验证后自动发送消息给订阅号但是没有消息返回的问题
2015/12/21 PHP
PHP获取网站中各文章的第一张图片的代码示例
2016/05/20 PHP
php页面跳转session cookie丢失导致不能登录等问题的解决方法
2016/12/12 PHP
判断浏览器的javascript版本的代码
2010/09/03 Javascript
jQuery1.4.2与老版本json格式兼容的解决方法
2011/02/12 Javascript
JavaScript判断一个URL链接是否有效的实现方法
2011/10/08 Javascript
15条JavaScript最佳实践小结
2013/08/09 Javascript
document.documentElement和document.body区别介绍
2013/09/16 Javascript
js 判断文件类型并控制表单提交示例代码
2013/11/14 Javascript
jQuery中验证表单提交方式及序列化表单内容的实现
2014/01/06 Javascript
js调试系列 断点与动态调试[基础篇]
2014/06/18 Javascript
javascript中String对象的slice()方法分析
2014/12/20 Javascript
用JavaScript实现PHP的urlencode与urldecode函数
2015/08/13 Javascript
js获取当前日期时间及其它日期操作汇总
2016/03/08 Javascript
JavaScript中匿名函数的用法及优缺点详解
2016/06/01 Javascript
详解vue axios中文文档
2017/09/12 Javascript
使用vue-cli3 创建vue项目并配置VS Code 自动代码格式化 vue语法高亮问题
2019/05/14 Javascript
vue中的面包屑导航组件实例代码
2019/07/01 Javascript
使用Vue.js中的过滤器实现幂方求值的方法
2019/08/27 Javascript
Python多线程学习资料
2012/12/19 Python
遗传算法之Python实现代码
2017/10/10 Python
python使用 HTMLTestRunner.py生成测试报告
2017/10/20 Python
浅谈python3发送post请求参数为空的情况
2018/12/28 Python
如何定义TensorFlow输入节点
2020/01/23 Python
python之生成多层json结构的实现
2020/02/27 Python
VSCode中autopep8无法运行问题解决方案(提示Error: Command failed,usage)
2021/03/02 Python
HelloFresh澳大利亚:订购你的美味食品盒、健康餐食
2018/03/28 全球购物
爱尔兰领先的在线体育用品零售商:theGAAstore
2018/04/16 全球购物
应聘教师推荐信
2013/10/31 职场文书
2015年社区流动人口工作总结
2015/05/12 职场文书
邹越演讲观后感
2015/06/15 职场文书
招商银行收入证明
2015/06/17 职场文书
标准演讲稿格式结尾应该怎么书写?
2019/07/17 职场文书