




已阅读5页,还剩6页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
成都嗡嗡文化传媒有限公司 HTML5 Video 实现浅析基于android4.1browser1. 基本结构先上一张基本结构图,图中展示了webkit中与HTML5 Video实现相关的一些类。1.1DOM TreeVideo标签在webkit内部对应于HTMLVideoElement类,该类的功能并不多,大多数的功能都在其父类HTMLMediaElement中。1.2Render TreeHTMLVideoElement和HTMLMediaElement分别对应的Render节点是RenderVideo和RenderMedia。它们也一般的Render节点不同,它们只负责layout来确定位置信息,而并不需要绘制(虽然有paint函数,但实际并没有调用到)。1.3BridgeMediaPlayer类指的是WebKit中定义的MediaPlayer类(而不是系统定义的),它只是一个桥接类,相关功能交由MediaPlayerPrivateInterface类实现,并将某些反馈信息回调给HTMLMediaElement。1.4Player按照webkit的一贯风格,MediaPlayerPrivateInterface只是一个基类,具体需要不同的平台来提供具体实现。Android平台下为MediaPlayerPrivate类,它也是一个基类,分别由MediaPlayerVideoPrivate和MediaPlayerAudioPrivate来实现。很显然,它们分别对应Video和Audio的实现。 上述是webkit内的类,下面再看看webkitporting之后外部的类结构:可以看到,这些类大多数都是轻量级类,它们主要负责功能转发。最终实现类是android中的MediaPlayer类(请与前述MediaPlayer区别开来)。至于该MediaPlayer再怎么实现,已不在本文的讨论范围内。值得注意的是,HTML5VideoViewProxy类继承自Handler,它转发到VideoPlayer的消息使用了android的异步调用机制。2. 操作控制同过上述基本结构的介绍,我们可以想象一个播放器操作,如play,seek等,它们从HTMLMediaElement发出,最终一步一步到达android的Mediaplayer。下面是一个seek过程的调用堆栈:#0 WebKit:HTML5VideoViewProxy:seek#1WebCore:MediaPlayerPrivate:seek#2WebCore:MediaPlayer:seek#3 WebCore:HTMLMediaElement:seek#4WebCore:MediaControlTimelineElement:defaultEventHandler当然基本流程是这样,有时候也不是一成不变的,比如play就有多种方式,多种流程来实现。具体问题具体分析,打一个断点一切流程都一目了然。上图展示的是一个播放器状态转移情况,只有这么几种状态,还是很好理解的,这里就不赘述了。3. 渲染流程上述业务操作逻辑比较简单,我们更感兴趣的是video的显示过程,也就是渲染流程。前面说过,RenderVideo虽然有paint函数,但并没有派上用场。那是怎样完成渲染的呢?还需要从webkit的渲染结构说起。这张图片所展示的内容大家应该都很熟悉,是webkit中的基础结构。但这还没有完,在硬件加速渲染下,还需要更多的结构来支持:如果大家对这些结构不熟悉,可以参考:/milado_nju/article/details/7292131和/milado_nju/article/details/8900792两篇文档。GraphicsLayer也是一个基类,在android下的实现为GraphicsLayerAndroid,该类包含一个LayerAndroid类,才是硬件加速用到的Layer。当然LayerAndroid也是一个基类,Video对应的是VideoLayerAndroid类。可以简单这样理解,一个Video标签在硬件加速部分对应于一个VideoLayerAndroid类,用于显示Video内容。那么我们看看VideoLayerAndroid是怎么创建的,如下堆栈:#0VideoLayerAndroid#1MediaPlayerPrivate#2MediaPlayerVideoPrivate#3WebCore:MediaPlayerPrivate:create#4WebCore:MediaPlayerPrivate:create#5 WebCore:MediaPlayer:loadWithNextMediaEngine#6WebCore:MediaPlayer:load#7WebCore:HTMLMediaElement:loadResource 可以看到,load操作引起了一系列初始化,其中VideoLayerAndroid由MediaPlayerPrivate来初始化。这个过程与GraphicsLayerAndroid没有关系,也就是说VideoLayerAndroid并没有与webkit的主体结构联系起来。事实上另有玄机:#3WebCore:GraphicsLayerAndroid:setContentsToMedia#4 WebCore:RenderLayerBacking:updateGraphicsLayerConfiguration#5WebCore:RenderLayerCompositor:updateLayerCompositingState#6 WebCore:RenderLayer:contentChanged (#7 WebCore:RenderVideo:updatePlayer#8WebCore:HTMLMediaElement:mediaPlayerSizeChanged#9 WebCore:MediaPlayer:loadWithNextMediaEngine上述流程最终调用到GraphicsLayerAndroid:setContentsToMedia,会将VideoLayerAndroid设入GraphicsLayerAndroid,这样创建的VideoLayerAndroid就与webkit的主体结构联系在一起,成为硬件加速LayerAndroid树的一部分。VideoLayerAndroid中有一个drawGL函数,就是该Layer的绘制函数。其中有一个非常重要的成员m_surfaceTexture, 它是一个SurfaceTexture类型。正是通过调用SurfaceTexture:updateTexImage来绘制的GL纹理。那么m_surfaceTexture成员是怎么得到的呢?看下面堆栈:#0WebCore:VideoLayerAndroid:setSurfaceTexture#1android:SendSurfaceTexture#2WebKit:HTML5VideoViewProxyDelegate:nativeSendSurfaceTexture#3 WebKit:VideoPlayer:setBaseLayer可见SurfaceTexture是在外部创建(事实上有HTML5VideoInline类创建),并传递给VideoLayerAndroid。另外setSurfaceTexture函数还会将VideoLayerAndroid的信息设置给VideoLayerManager类。现在从webkit硬件加速的角度看,绘制需要的对象已经准备就绪。主要是video所对应的硬件加速层VideoLayerAndroid,以及绘制GL纹理所需要的类SurfaceTexture(通过updateTexImage函数来绘制)。SurfaceTexture既然在webkit外部创建,那它在外部是怎样被使用的呢?可以看HTML5VideoInline:decideDisplayMode函数。先用SurfaceTexture构造一个Surface,然后将该Surface设置给MediaPlayer。MediaPlayer做的事情就是,从站点上下载video数据,并进行解码,解码后的结果输出给Surface,再经过SurfaceTexture: updateTexImage来最终成为GL纹理。看下图:该图大体上描述了整个HTML5 Video的控制,渲染的主要类的关系。该图中大部分内容前文已经介绍过了,那么我们关注一点,解码的结果怎样从surface传送到surfacetexture,因为只有内容在surfacetexture才能被绘制成GL纹理。其实这个过程曾经深入研究过android surface系统的同学应该很熟悉。我在这里简单介绍一下。Surfacetexture创建的时候也会创建一个BufferQueue,这才是一个重要的类,它维护了一个共享内存的队列。Surface通过binder机制与BufferQueue通信。Surface每次向BufferQueue申请一块空的内存,解码结果就保存在这块内存中。之后将装满的内存还给BufferQueue。SurfaceTexture: updateTexImage的时候,会向BufferQueue请求一块满的内存,并将其内容渲染成GL纹理,随后将空内存还给BufferQueue。可以说Surface与SurfaceTexture形成了一个经典的生产者消费者模式。这样HTML5 Video的大体渲染框架就搭建完成了。4. 控制条播放时,与Video相配套的还有一个控制条,它是完全由webkit来实现的。控制条所涉及的元素都定义在MediaControlElement.h文件中。包括开始按钮,时间条,全屏按钮等元素。这些元素同时也负责接收并处理触摸事件。例如MediaControlTimelineElement对应于时间条,它的defaultEventHandler函数处理时间条相关的事件,比如时间改变,会导致调用seek函数。这个过程在前面已经介绍过了。上述的所有元素都被添加到MediaControlRootElement上,而MediaControlRootElement又被添加到ShadowRoot上。熟悉前端技术的同学可能对ShadowRoot比较熟悉了,没错,控制条是在一棵Shadow DOM子树中,游离于主DOM树之外的。控制条并不是一个HTML DOM节点,当然也就没有对应的Render节点。它的绘制在RenderSkinMediaButton类的draw函数中完成。从该函数中看,控制条中相关元素(如play按钮)对应的是一个RenderBox类,然后根据其RenderStyle中的ControlPart熟悉来确定究竟是什么按钮,应该进行怎样绘制。5. 全屏模式控制条全屏按钮可以使视频进入全屏模式,全屏模式的绘制方式与普通模式不太相同,全屏模式专门有一个类HTML5VideoFullScreen来支持,它是HTML5VideoView的子类。按全屏按钮后流程如下:#0 WebKit:HTML5VideoViewProxy:enterFullscreenForVideoLayer#1 WebKit:HTML5VideoViewProxyDelegate:enterFullscreenForVideoLayer#2 WebCore:MediaPlayerVideoPrivate:enterFullscreenMode#3 WebCore:MediaPlayerVideoPrivate:enterFullscreenMode#4 android:ChromeClientAndroid:enterFullscreenForNode#5 android:ChromeClientAndroid:enterFullscreenForNode#6 WebCore:HTMLMediaElement:enterFullscreen#7 WebCore:HTMLMediaElement:enterFullscreen#8 WebCore:MediaControlFullscreenButtonElement:defaultEventHandler#0 VideoSurfaceView#1 HTML5VideoFullScreen#2 WebKit:VideoPlayer:enterFullScreenVideo#3 WebKit:HTML5VideoViewProxy:handleMessage#4 gaia:Handler:dispatchMessage中间经过了WebCore线程到UI线程的转换,可见在HTML5VideoFullScreen 中创建了一个VideoSurfaceView对象。VideoSurfaceView是一个SurfaceView,在SurfaceView创建时会触发如下事件:#0 WebKit:HTML5VideoFullScreen:attachMediaController#1 WebKit:HTML5VideoFullScreen:setMediaController#2 WebKit:HTML5VideoFullScreen:prepareForFullScreen#3 WebKit:HTML5VideoFullScreen:VideoSurfaceHolderCallback:surfaceCreated在attachMediaController 函数中将VideoSurfaceView设置给MediaController,这样MediaController解析的视频直接输出给VideoSurfaceView来显示(在HTML5VideoFullScreen 是用MediaController来播放视频,MediaController相当于一个带操作条的MediaPlayer),这样就没有了上述普通模式那样复杂的显示过程。全屏模式的显示过程与webkit是没有一毛钱关系的,完全由android ui控件来显示。那么VideoSurfaceView怎样与浏览器的UI联系起来呢? 通过onShowCustomView回调。将控件回调给浏览器UI,与UI联系起来。直到现在,仍然不存在一项旨在网页上显示视频的标准。目前,大多数视频是通过插件(比如 Flash)来显示的。然而,并非所有浏览器都拥有同样的插件。HTML5 规定了一种通过 video 元素来包含视频的标准方法。当前HTML
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 安徽公务员的考试题目及答案
- 医疗质量安全核心制度考试试题附答案(B卷)
- 2025年成人教育领域线上学习模式下的在线教育市场细分与定位研究
- 2025年老年健康管理长期照护服务模式与护理团队协作研究报告001
- 2025年电商平台售后服务与品牌形象塑造研究报告
- 河北张家口2025年公开招聘农村党务(村务)工作者笔试题带答案分析及完整答案详解1套
- 国企企业面试题库及完整答案详解【易错题】
- 考点解析-河南省登封市中考数学真题分类(实数)汇编单元测试试题(详解版)
- 2025年度票据保险与损失补偿服务合同
- 2025版汽车销售与保险组合合同范本
- 健康养生+情绪价值+中华文化茶饮品牌走出消费“双循环”之路
- 2025年民族宗教政策法规学习月知识竞赛试题库(含答案)
- T/ZHCA 007-2019染发化妆品眼刺激性试验体外测试方法牛角膜浑浊和渗透性试验
- 电梯砝码租凭合同协议书
- 基于人工智能的性传播疾病预防个性化方案研究-洞察阐释
- (高清版)DG∕TJ 08-2093-2019 电动汽车充电基础设施建设技术标准 含2021年局部修订
- 私人诊所免责协议书
- 三年级数学下册计算题专项练习大全(每日一练共22份)
- 蒸汽锅炉试题及答案
- 2025-2030羽毛球产业规划专项研究报告
- 儿童合唱教学课件
评论
0/150
提交评论