Android视频进阶之旅(一)_概念介绍

一、概述

在项目中多多少少都会涉及到视频播放,相信大多数人都会使用videoview或者mediaplayer+surfaceview,但是这都是基于默认格式的,像avi, rmvb等都是不支持的,那么如果要支持多种视频格式该怎么办呢,那么可以使用一个成熟的第三方框架Vitamio。但是作为想要进阶的程序猿,光会用是不够的,还是对其进行一定的探索,所以我也是在网上浏览了很多相关的文章后,整理了一下相关知识。
我先分享一下视频开发中常见的一些知识点,概念和术语。在之后的章节我会慢慢的介绍除了基本的在线视频播放技术之外,一些更加“高级”的技术 :smirk:,包括安卓平台在4.4之后发布的全新的Codec API, 还有怎么处理自适应视频播放(Adaptive Streaming),版权管理内容(DRM Content),最后几章会使用谷歌开源的ExoPlayer作为例子,从源码的角度分析一个完整的播放器需要哪些构件。

二、Codec(视频编解码器)是做什么的?

视频,音频,大家肯定都听说,至少有所耳闻这两个词 - 编码(encode) 和 解码(decode)。
Codec就是一种程序,这种程序可以对视频文件进行编码和解码。

三、为什么要编码?

视频直接看就可以了啊,为啥要编码呢?
其实编码 就是压缩,解码 就是解压缩。视频文件的本质其实就是图片的集合而已,当一段连续的图片不断的出现在人眼前(一般一个连贯的电影或者动画至少要求一秒24帧,也就是一秒内连续出现24张图片),肉眼就会“欺骗性”的告诉大脑我们在看一个视频,而不是幻灯片。

那我们算一下,假设一张像素为1280X720(清晰度,宽1280个像素点,高720个像素点)的图片,大小为约为1280X720X3 bytes,就是2.7MB。因为一个像素点需要至少三原色(RGB)来显示像素点本身的颜色,所以我们需要3个字节来显示一个像素点,那么一段60秒钟的小电影,就需要60X24(24张图片)X2.7MB ,约为3.9GB了!

那么我们看一部琅琊榜估计得上几十TB的移动硬盘了。

所以Codec这种程序就出现了,它会把这些连续的图片们通过一定的算法压缩成体积更小的文件格式,这就是我们所谓的编码,压缩。但是在播放器的客户端,不管是PC,手机也好,他们要显示在屏幕上的,必须是实实在在的图片,所以这些被压缩过的文件最终又必须被还原成图片格式,这就是解码,解压缩。

视频编码,压缩是一个非常复杂的过程,万幸的是,现在市面上已经有很多工具,还有现有规范来指导开发者进行编码解码了。

四、有哪些地方可以压缩编码?

相信看过《疯狂动物城》的朋友都知道这个家伙吧?
这里写图片描述
除了面部表情缓慢变动外,其他的地方都是不变的,那么对于这种“静态的场景”,视频压缩算法会只取这几十秒的前几帧作为基准帧图片,对其余的帧,采取只保存“不同的部分”的策略,这样就不用保存这些差不多相同的图片,这种做法叫“去冗余”。大大减少了视频的体积。当然这只是视频编码中的冰山一角。

另外需要注意的是,Codec的编码与解码包含对视频数据的编码解码和音频数据的编码解码,因为音频的本质是声波信息,视频是图片处理,他们本质上是不同的,我这里主要是介绍视频数据的处理。

回到我们说的Codec,所以说Codec是一套程序,它遵循不同的规范,根据规范的不同提供不同的压缩解压缩策略。
既然是一套规范,那么就肯定需要实现啊! 在安卓平台里面,谷歌提供了视频编码解码的API,对一些基础的编码解码规范做了API的封装,在接下里的章节我会慢慢介绍,其他移动平台也都差不多,多多少少都会提供API的支持。

五、Container format file(视频容器文件)是什么?

之前说到,咱们在看小电影的时候都会看到很多文件的后缀名,例如mp4,rmvb,avi,喜欢看高清美国大片的同学应该还会经常看到所谓的蓝光mkv格式等等。我们习惯叫他们视频文件,但是这样说显得不够专业。。。

严格的来讲,他们应该被叫做容器文件。。。。因为一个容器里,不仅仅包括了视频(video)数据,还包括了(audio)音频数据,有的容器还内嵌字幕,那么就还有文字(Text)数据。不过容器文件虽然听起来吓人,但是它说到底也就是一个结构化的文件而已。之所以说它结构化,就是它包含的视频,音频,文字数据都必须按照一定的规范,放在文件指定的位置(方便播放器解析)。

容器文件就是上面说到的Codec程序对图片集进行编码之后的产物,被Codec编码之后,除了必要的视频音频信息之外,它还有一些其他的信息。
一个简单的草图
这里写图片描述
里面提到了Track(轨道),这是一个专业术语,用来区分不同的音视频/文字数据
但是MP4文件里面最重要的却是这个MetaData,它包含了很多关于视频的原始数据,比如视频的大小,视频的时长,还有一个索引表,这个索引表包含了不同轨道的起始位置(以字节为单位),又因为每个轨道会被分成若干块sample(采样,每一块采样都是可以单独被播放器播放的一段数据,以微妙为单位),metadata也会维护一个细粒度更小的索引表,记录了每一块sample的大小,起始位置,对应视频的时间是多少(以字节为单位)等等的信息。

举个简单的例子,有些电影包含粤语,国语两个声道。我们想换声道的时候会告诉播放器,我想听粤语,那么播放器会去索引表查找粤语的轨道起始位置,并且源源不断的读取粤语音轨的数据并播放出来。这也解释了为何上图会有两个audio track。

在接下来的章节我会详细介绍播放器是怎么解析容器文件,这里大家只需要知道大概就好。

六、视频处理的流程(一个案例)

这里写图片描述
导演用胶片拍摄了原片(Raw Data),胶片就代表着原始文件,也就是图片集(因为胶片就是一帧一帧的连续图片),使用软件把源文件编码(Encode)成容器文件(Container),之后可能为了不容分辨率的原因,还需要将原始的高清容器,转换成不同的分辨率的容器文件,对应图中的process这一步。最后在放在服务器或者CDN上,又播放器将其下载播放。

盗用网上的一张图
这里写图片描述
好了明天会继续更新

发布了30 篇原创文章 · 获赞 78 · 访问量 15万+

猜你喜欢

转载自blog.csdn.net/u010302765/article/details/73839048