Chromium是Google浏览器Chrome的开源版本,但是这两个浏览器在feature上有一些细微的差别,比如在HTML5媒体格式的支持种类上Chromium要少于Chrome。说到HTML5,与HTML4相比最有意义的改进之一就是新增了video tag,可以在网页上直接播放视频而不需要安装插件,至于HTML5 video tag支持哪些种类的视频格式取决于浏览器,目前各家浏览器支持的HTML5视频格式主要有3种:
1) H.264,容器格式一般采用MP4,音频格式通常为AAC,被微软IE 9以上支持;
2) Theora,容器格式采用OGG,音频格式为Vorbis,被Chrome和Chromium支持;
3) VP8,容器格式采用WebM,音频格式为Vorbis,被Chrome和Chromium支持。VP8/WebM是Google推的一种免费开放的视频格式,VP8与Theora是同一个系列的视频编码技术,后者是从VP3衍生出来的。
其中H.264是一种专利视频格式,使用H.264需要向MPEG-LA公司交纳专利费并获取许可证,虽然目前暂未收费,但不保证将来永远免费。也正是基于这个原因,Google才重金收购了开发VP8技术的On2公司并在此基础上推出了免费开放的VP8/WebM格式。按照Google官方说法,Chrome/Chromium今后不再支持H.264这样的专利格式,只支持VP8/WebM这样的开放视频格式。
目前Chromium已经不支持H.264,而Chrome暂时仍然支持H.264,这就是本文开头提到的Chromium与Chrome在对HTML5视频格式的支持种类上的差别。除了H.264,Chrome还比Chromium多支持两种音频格式:AAC和MP3。
各种主流浏览器对HTML5媒体格式的支持对比可以看这篇文章:http://en.wikipedia.org/wiki/HTML5_video。Chromium与Chrome在feature上的差别可以看这篇文章:http://code.google.com/p/chromium/wiki/ChromiumBrowserVsGoogleChrome。
虽然Google抵制H.264,但事实是H.264已经成为目前网络上用得最多的视频格式之一,而VP8/WebM尚未普及,暂时也还未得到芯片厂家的支持。因此,如果我们基于开源的Chromium做二次开发,就可能会面临一个需要解决的问题:不支持H.264视频。
在ubuntu上,要想给Chromium增加支持H.264并不难,可以看这篇文章:Get Chromium on Ubuntu To Play mp4, H.264, MP3 & view PDF files natively - OMG! Ubuntu!。
在Windows上,要给Chromium增加支持H.264,一种办法是安装微软给Chrome提供的WMP扩展(extension),在这里下载:http://www.interoperabilitybridges.com/wmp-extension-for-chrome,当然不是开源的。给Chromium安装这个extension后,如果遇到H.264格式的MP4视频,就会调用Windows Media Player来播放。除此之外,还有没有其他办法?这正是本文要讨论的主题。
Chrome和Chromium的音视频解码是由FFmpeg提供支持的,提到FFmpeg凡是搞多媒体软件的应该都知道。在Chromium源码树third_party文件夹下可以看到有ffmpeg,但是奇怪的是在编译Chromium源码时,ffmpeg的代码并没有参加编译,而是由third_party\ffmpeg\chromium\binaries\Chromium\win\ia32\下面的3个预编译好的动态链接库来提供给Chromium用的:
avcodec-54.dll
avformat-54.dll
avutil-51.dll
至于linux下的Chromium是如何使用FFmpeg的就不清楚了,因为源码中并未包含linux下面的预编译好的FFmpeg共享库(.so)。
Chromium启动时会加载这3个.dll,具体代码是在media\base\media_win.cc中的函数InitializeMediaLibrary。
在Chromium中播放HTML5视频时就会调用FFmpeg的这3个.dll,具体代码在media\filters\ffmpeg_video_decoder.cc。
这3个.dll跟源码里的third_party\ffmpeg\是什么关系?不得而知,反正Google没有在Chromium中提供编译这3个.dll的Visual Studio工程文件。既然Chromium是开源的,FFmpeg也是个开源项目,那就不应该也没有必要以预编译二进制库的形式提供。事实上FFmpeg采用GPL或LGPL license,Google的这种做法是否违反了GPL/LGPL的原则?很值得怀疑。Chromium源码里的third_party\ffmpeg\或许只是个幌子,我怀疑Chromium使用FFmpeg实际上是闭源的。
至于Chrome,按照网上的说法“由于FFmpeg采用LGPL 2.1许可证,而Chrome是闭源的,所以Google指出Chrome并不会使用FFmpeg库,而是使用本地的视频音频库(Windows上可能是Windows Media Player)”,实际情况是这样吗?我在Chrome的安装路径下看到同样也有前述的那3个FFmpeg的动态库,试一下,如果把这3个.dll删掉,就会发现Chrome无法播放HTML5视频了,可见Chrome仍然是使用FFmpeg来播放视频的,至少我使用的Chrome 20.0.1096.1是这样的。
既然Chrome也使用FFmpeg,就想到一个问题,如果把Chrome中那3个.dll跟Chromium中的对调会怎么样?试了一下,结果如下:
用Chrome的3个.dll代替Chromium的,结果Chromium仍然无法播放H.264,但可以播放ogg和webm,情形与未替换库相同;再用Chromium的3个.dll代替Chrome的,结果Chrome也只能播放ogg和webm,不能播放H.264了。
由此可见Chromium的这3个.dll不支持H.264解码,从库文件大小也可以看出来Chromium的这3个.dll比相近版本的Chrome的要小很多,显然是裁剪掉了对H.264解码的支持。事实上,在Chromium源码third_party\ffmpeg\chromium\config\下有Chrome、Chromium等不同系统的FFmpeg配置文件,可以看到针对H.264解码器的宏CONFIG_H264_DECODER在Chromium和ChromiumOS中是定义成0,而在Chrome和ChromeOS中是定义成1。
需要说明的是只有版本相近的Chrome和Chromium才可以直接相互替换这3个.dll,比如我用的Chrome版本是20.0.1096.1,Chromium版本是20.0.1090.0,如果版本相差太大替换库后可能无法正常播放视频。
看来要想让Chromium支持H.264视频,第一步就是让FFmpeg库支持H.264解码,在没有Visual Studio工程文件无法重新编译FFmpeg库的情况下,可以采用直接拿相近版本的Chrome中的FFmpeg库替换。
下一步就是让Chromium在解析HTML5网页时支持H.264视频,确切地说是让它能识别网页中MIME类型为"video/mp4"的视频源,就象下面这个网页在Chromium中原本是不被支持的MIME类型:
<video width="320" height="240" controls="controls">
<source src="Big_Buck_Bunny_Trailer.m4v" type="video/mp4">
Your browser does not support the video tag.
</video>
分析Chromium源码后找到在net\base\mime_util.cc中定义了支持哪些MIME类型,实际上只要增加定义宏USE_PROPRIETARY_CODECS就可以支持H.264视频以及AAC和MP3音频。此外还有另一个宏GOOGLE_CHROME_BUILD也可以达到这个目的,这个宏显然是Google在编译Chrome时使用的。
除掉测试用的代码,一共有两个工程chrome\browser和net\base中的代码使用了宏USE_PROPRIETARY_CODECS,为此在Visual Studio 2010中给这两个工程增添了预定义的宏USE_PROPRIETARY_CODECS,重新编译出chrome.exe,试验结果OK!现在Chromium可以象Chrome一样支持H.264视频了。
虽然Chromium可以播放H.264视频了,但上述解决办法有点取巧,如果今后Chrome象Google说的那样不再使用FFmpeg,这个办法就行不通了。因此要想真正实现Chromium播放H.264,还有两个遗留问题要解决:
1. 如何修改Chromium使用的FFmpeg库以便进一步定制和优化?Google没有提供编译FFmpeg的工程文件,只能自己摸索了;
(补充:关于Chromium中的FFmpeg,目前Windows上的Chromium中的FFmpeg需要手工单独编译,有关信息详见third_party\ffmpeg\chromium\README.chromium和third_party\ffmpeg\chromium\patches\README.chromium,看起来还是比较麻烦的,如果不是特别需要就不自己编译了。)
2. 除了使用微软给Chrome提供的WMP扩展,如何不使用FFmpeg,改为调用系统提供的音视频解码库比如Windows Media Player或者其他音视频解码库来支持HTML5媒体播放?