随着互联网的发展,在网页上观看视频变得越来越流行,尤其是泛娱乐(手机直播)大行其道的今天。在HTML5之前,在网页上播放视频需要插件支持,例如Flash插件。有了HTML5之后,标签<video>使得浏览器有了播放视频的功能。与插件相比,浏览器的视频播放功能不仅在产品上体验更好,在技术上也更加稳定。本文接下来就简要介绍Chromium是如何实现<video>标签的视频播放功能的,以及制定学习计划。

老罗的新浪微博:http://weibo.com/shengyangluo,欢迎关注!

《Android系统源代码情景分析》一书正在进击的程序员网(http://0xcc0xcd.com)中连载,点击进入!

本文以及接下来的文章,我们主要关注Chromium在Android平台上是如何实现<video>标签的视频播放功能的。我们知道,Android平台提供播放视频的API接口,也就是MediaPlayer接口。这个接口不仅可以用来播放本地媒体文件,也就用来播放网络上的流媒体文件。这可以大大简化Chromium在Android平台上支持<video>标签的工作,因为前者可以直接利用后者提供的MediaPlayer接口实现视频播放功能,如图1所示:

图1 <video>标签的实现

从前面Chromium多进程架构简要介绍和学习计划这个系列的文章可以知道,Chromium是一个多进程架构。其中,Render进程负责加载、解析和渲染网页,Browser进程负责将Render进程渲染出来的网页内容合成到屏幕上显示。Render进程又是通过WebKit来加载和解析网页内容的。

WebKit在解析网页内容时,每当遇到<video>标签,就会在DOM Tree中创建一个类型为HTMLMediaElement的节点。这个HTMLMediaElement节点又会在内部创建一个WebMediaPlayerClientImpl对象。这个WebMediaPlayerClientImpl对象在WebKit内部就描述为一个播放器,用来为<video>标签提供视频播放功能。

WebMediaPlayerClientImpl类是由WebKit提供的,它本身不实现视频播放功能,因为视频播放是一个平台相关的功能。我们知道,WebKit是平台无关的,所有平台相关的功能都需要由它的使用者实现。在Chromium中,WebKit的使用者即为运行在Render进程中的Content模块。Content模块提供了一个WebMediaPlayerAndroid类,用来向WebKit提供视频播放功能。

WebKit层的每一个WebMediaPlayerClientImpl对象在Content层都有一个对应的WebMediaPlayerAndroid对象。这些WebMediaPlayerAndroid对象就相当于是在Render进程内部实现的播放器。每一个播放器都关联有一个ID,它们被另外一个称为RendererMediaPlayerManager的对象管理。通过这种方式,就可以在一个网页上同时支持多个<video>标签,也就是可以同时播放多个视频。

我们知道,Render进程运行在一个沙箱中,也就是它是一个受限进程。播放网络上的视频需要访问网络,以及使用系统的解码器等资源。因此,Render进程也没有实现视频播放功能,而是通过Browser进程进行播放。因此,对于Render进程中的每一个WebMediaPlayerAndroid对象,在Browser进程中都会有一个对应的WebMediaPlayerBridge对象。这些WebMediaPlayerBridge对象就相当于在Browser进程内部实现的播放器。这些播放器被另外一个称为BrowserMediaPlayerManager的对象管理,使得Browser进程可以同时创建多个播放器,以支持在一个网页上同时播放多个视频。

WebMediaPlayerBridge类本身也不实现播放器功能。在Android平台上,WebMediaPlayerBridge类将通过SDK提供的MediaPlayer接口来实现视频播放功能。SDK是在Java层提供MediaPlayer接口的,而WebMediaPlayerBridge类是实现在C++层的,因此后者在使用前者时,需要通过JNI使用。

总结来说,在Android平台上,Chromium会通过SDK接口MediaPlayer为网页中的每一个<video>标签创建一个播放器。播放器负责从网络上下载视频内容,并且进行解码。解码后得到的视频画面需要作为网页的一部分进行显示。从前面Chromium网页渲染机制简要介绍和学习计划这个系列的文章可以知道,在Chromium中,网页是Render进程进行渲染的,并且当前需要渲染的内容来自于网页的CC Active Layer Tree。这意味着要将播放器解码出来的视频画面交给网页的CC Active Layer Tree处理。

播放器解码出来的视频画面是通过SurfaceTexture接口交给网页的CC Active Layer Tree处理的,如图2所示:

图2 <video>标签的视频画面渲染方式

在Android平台上,SurfaceTexture是一个完美的接口。一方面它支持跨进程传输数据,另一方面传输的数据可以作为纹理使用。在我们这个情景中,MediaPlayer运行在Browser进程中,CC Active Layer Tree运行在Render进程中,并且是通过OpenGL进行渲染的。因此,SurfaceTexture非常适合将前者的输出作为后者的输入,并且通过OpenGL以纹理的方式渲染出来。

具体来说,就是CC Active Layer Tree会为每一个<video>标签创建一个类型为VideoLayerImpl的节点。这个节点的内容就来自于播放器解码出来的视频画面。这些视频画面最终又是通过纹理来描述的。从前面Chromium网页渲染机制简要介绍和学习计划这个系列的文章可以知道,CC Active Layer Tree其它节点的内容,最终也是描述为纹理进行渲染的。因此,Chromium可以轻松地将播放器解码出来的视频画面作为网页的一部分进行显示。

在Android平台上,Chromium还为<video>标签提供了全屏播放功能。全屏播放与非全屏播放可以进行无缝切换,它是怎么实现的呢?我们通过图3来说明,如下所示:

图3 <video>标签的全屏播放功能实现

在<video>标签全屏播放的情况下,我们是看不到网页的其它内容的。这使得Chromium可以使用一种简单的方式实现<video>标签的全屏播放功能。当<video>标签全屏播放的时候,Browser进程会在浏览器窗口上创建一个全屏的SurfaceView,然后将这个SurfaceView底层的Surface取出来,设置为MediaPlayer的解码输出。这样就可以将MediaPlayer的解码输出全屏显示在屏幕上了。这时候由于网页是不可见的,Render进程不需要对它进行渲染。

接下来,我们结合源码,按照三个情景深入分析Chromium对<video>标签的支持:

1. 为<video>标签创建播放器的过程。

2. 渲染<video>标签视频画面的过程。

3. 全屏播放<video>标签视频的过程。

学习了这三个情景之后 ,我们就会对HTML5中的<video>标签有更深刻的了解,敬请关注!更多的信息也可以关注老罗的新浪微博:http://weibo.com/shengyangluo。

Chromium视频标签video简要介绍和学习计划相关推荐

  1. Android进程间通信(IPC)机制Binder简要介绍和学习计划

    在Android系统中,每一个应用程序都是由一些Activity和Service组成的,这些Activity和Service有可能运行在同一个进程中,也有可能运行在不同的进程中.那么,不在同一个进程的 ...

  2. Android WebView简要介绍和学习计划

    我们通常会在App的UI中嵌入WebView,用来实现某些功能的动态更新.在4.4版本之前,Android WebView基于WebKit实现.不过,在4.4版本之后,Android WebView就 ...

  3. Android系统匿名共享内存Ashmem(Anonymous Shared Memory)简要介绍和学习计划

    在Android系统中,提供了独特的匿名共享内存子系统Ashmem(Anonymous Shared Memory),它以驱动程序的形式实现在内核空间中.它有两个特点,一是能够辅助内存管理系统来有效地 ...

  4. Android应用程序组件Content Provider简要介绍和学习计划

    在Android系统中,Content Provider作为应用程序四大组件之一,它起到在应用程序之间共享数据的作用,同时,它还是标准的数据访问接口.前面的一系列文章已经分析过Android应用程序的 ...

  5. 老郭的《Dalvik虚拟机垃圾收集机制简要介绍和学习计划》

    伴随着"Dalvik is dead,long live Dalvik"这行AOSP代码提交日志,在Android5.0中,ART运行时取代了Dalvik虚拟机.虽然Dalvik虚 ...

  6. Android窗口管理服务WindowManagerService的简要介绍和学习计划

    在前一个系列文章中,我们从个体的角度来分析了Android应用程序窗口的实现框架.事实上,如果我们从整体的角度来看,Android应用程序窗口的实现要更复杂,因为它们的类型和作用不同,且会相互影响.在 ...

  7. Android系统Surface机制的SurfaceFlinger服务简要介绍和学习计划

    前面我们从Android应用程序与SurfaceFlinger服务的关系出发,从侧面简单学习了SurfaceFlinger服务.有了这些预备知识之后,我们就可以从正面来分析SurfaceFlinger ...

  8. Chromium插件(Plugin)机制简要介绍和学习计划

    在Chromium中,除了可以使用Extension增强浏览器功能,还可以使用Plugin.两者最大区别是前者用JS开发,后者用C/C++开发.这意味着Plugin以Native Code运行,在性能 ...

  9. Chromium多进程架构简要介绍和学习计划

    Chromium以多进程架构著称,它主要包含四类进程,分别是Browser进程.Render进程.GPU进程和Plugin进程.之所以要将Render进程.GPU进程和Plugin进程独立出来,是为了 ...

最新文章

  1. ADO.NET并发性
  2. 叙述式教学方案计算机技术,计算机病毒及防治叙述式教学设计方案.doc
  3. C Primer Plus_第8章_字符输入输出和输入确认_编程练习
  4. Linux网络编程---详解TCP
  5. php网站服务器500,php服务器错误500
  6. mysql truncate 授权_Oracle给用户授权truncatetable的实现方案
  7. 在网页在播放flv格式的视频
  8. 多路复用实现单服百万级别RPS吞吐
  9. java中堆和栈的区别_java中堆和栈的区别
  10. SteamVR 错误代码 108 / 203 / 208 / 301 / 306 / 308 / 400 / 405 排解方法
  11. 关于扩散模型(Diffusion Models)中的P2-weighting使用防坑
  12. 愤怒的小鸟AR 版终于正式上架!场景超逼真
  13. 小程序下拉刷新没有响应
  14. 微信小程序入门与实战笔记
  15. 面试官:说一下Redis和MongoDB的区别?
  16. 自己做量化交易软件(44)小白量化实战17--利用小白量化金融模块在迅投QMT极速策略交易系统上仿大智慧指标回测及实战交易设计
  17. 32位/64位系统,jdk32位,64位,32/64位jdk编译出来的class和eclipse 32位和64位
  18. OpenWrt一些小问题的解决方法
  19. 《中国美食》习字优秀作品展示
  20. 基于JAVA汽车租赁平台的设计与实现计算机毕业设计源码+系统+mysql数据库+lw文档+部署

热门文章

  1. Jquery Autocomplete 实例教程
  2. 3dTile技术研究-概述
  3. 3d数字孪生仿真城市三维模型展示平台
  4. 数字孪生智慧城市运用于三维可视化管理系统
  5. 查论文、期刊的排名等的方法
  6. 2019浙大计算机初试经验帖
  7. 浏览器的重排与重绘是什么意思?
  8. 华清远见星创客:未来智造者
  9. 调查:IT网民中近八成24小时开机
  10. 宇信科技收购鸿蒙,宇信科技(300674)12月26日14:30大单揭秘