上次说到浏览器对于不同的useragent会返回不同的页面源码,返回源码之后就需要我们
默默无闻的webkit来解析了,这个解析过程相当的复杂,要对页面源码词法解析,语法解析,
然后还要针对不同的tag处理等等生成DOM 树和Render树,不过最主要的两个类就是
HTMLTokenizer.cpp和HTMLParser.cpp.从前者的write中开始往下跟就能看到其解析过程了。
生成DOM树和Render树的过程是同步的,当解析完一个DOM节点(对于不同的tag
会生成不同的HTMLELement,每个Element就是一个节点)的时候会调用attach函数,
在attach函数中会针对不同的元素调用不同的Render Object,生成对应的Render树。后面
的就是Document通过frameView调用layout来布局整个页面了。
这里主要讨论的是HTML5视频播放的内容,就是主要讨论<video>标签,对于这个标签
会生成HTMLVideoElement。具体播放流程请见下图
上图中有背景阴影部分的都是Java类,其余的全部都是C++类。对于Video标签其实生
成的还是HTMLVideoElement,它继承自HTMLMediaElement。因为大部分操作都是在
后者完成,所以就主要分析的后者。通过一个play的调用来从HTMLMediaElement开始
可以一直往下走到底层的视频播放的实现。当解析生成HTMLVideoElement的时候,对于
它的自带的播放控制条中的播放,暂停功能键,会有一个监听函数,当被按下时,会判
断是否播放等等,然后会开始播放视频,HTMLMediaElement中有一个MediaPlayer的
对象指针m_player(此MediaPlayer是webkit中的C++),然后在MediaPlayer中有一个
MediaPlayerPrivateInterface的对象指针m_private,在android中会实例化为
MediaPlayerPrivateAndroid对象,该对象定义了一个JavaGlue结构体,负责调用
HTML5VideoPlayerProxy中的函数,HTML5中有会通过消息处理等机制调用其内部的
VideoPlayer对象中的Play函数,VideoPlayer类中有一VideoViewWebkit对象指针,
实际的play 函数会调用到VideoViewWebkit中的start函数,该类接着会实例化一
MediaPlayer对象,然后调用其start函数,这个是一Java类,通过JNI调用底层库中的
MediaPlayer,该MediaPlayer作为客户端与MediaPlayerService服务端进行交互,
服务端回调用底层的opencore中的PVPlayer完成真正的视频流的播放(
还往下是底层硬件的实现了),至此一个play过程结束。
中间的HTML5VideoPlayerProxy相当于基于浏览器的一个App,脱离了传统的
需要下载安装到系统上的App,这个App直接嵌入到浏览器中,使得App与浏览器的
界限越来越模糊了。在不久的将来,所有的App都可以通过在浏览器中实现。其中
网页游戏的发展应该就是个很好的例子(以前的游戏都是需要下载客户端安装的,
有自己的窗口,独立于浏览器的App)
<上面的只是个人愚见,没有什么理论来源,至于google为什么这么设计,估计
还要考虑到更深的如设计模式等内容,那对于现阶段的我来说还是太高深了>。
PS:将视频页面嵌入到网页中是在HTML5这个类中实现的,
mChildView = proxy.getWebView().addView(mVideoView, poster_x, poster_y, poster_width, poster_height-16);
proxy.getWebView().updateView(mChildView, poster_x, poster_y, poster_width, poster_height-16);