android视频技术

原文章地址
就、像前几年的每个app都会有聊天功能一样,现在的app都会有一个直播功能。对于直播技术,网上并没有什么太多的资料。很大一部分,都是对视频进行播放,也就是我们常说的视频播放器,其中最重要的问题就是视频的编码和解码。现在的直播技术是在原来的基础上多了一个视频录制。

视频编码

android中视频的编码有两种方式,它们有利两个核心类,一个是MediaCodec,另外也给是MediaRecorder。这两个类的功能类似,区别在于前者偏向于原生处理,后者类似于封装之后。
首先会把视频流放入输入流队列,然后从输入流队列中获取数据进行编码,最后在输出流中获取数据源进行处理,然后放入输出流队列。
从这里可以看出,Mediacodec能够接触视频数据源,因此可以进行一些特殊的处理。
MediaEecorder类进行了封装,根据提供的方法可以设置视频的编码格式,视频来源等,但是由于他没有接触视频源,因此不能对原生的数据源进行黑醋栗

视频数据源

视频数据源我们这里指的是进行视频编码的数据源,在手机上,视频的来源一方面是通过摄像头,也就是我们常用的camera类,这个是我们经常使用的。另一个就是,来自手机屏幕,也就是屏幕录制。camera类我们不用多说,这是最基本的一个类,那么屏幕录制呢。google在android5.0的时候,新增了,mediaProjecition和VitualDisplay类

camera类

camera类在美颜相机一类的软件中很重要,在camera类中有一个PreviewCallback接口,其中含有一个onPreviewFrame(byte[] data…),这方法就是摄像头采集的数据,如今的美颜 相机就是通过这得每一帧的数据惊醒处理,然后产生一个美颜过的数据,这个数据就是我们刚才所说的源数据

mediaprojection和vitualdisplay

这俩个类是新加入的方法,不过在使用中需要权限授权的,如果没有,那么会变得很危险,这样软件就可以在后台录制你的操作,就知道你干了什么。

视频预览画面

1.surfaceview类
我们都知道动画的操作继承view类,但是在视频预览方面就需要用到surface类,这么来收surface是图像的绘制数据层,view进行展示。而surfaceview是两者的结合体。它们中间是通过surfaceholder链接。
当我们用surfaceview作为一个预览界面,只是为了获得相对应的suifaceholder或者suface。例如我们可以通过carmera类的setPreviewDisplay方法传入一个surfaceholder设置预览界面。通过VitualDisplay类传入surface类型设置屏幕界面。其中,vitualDisplay是通过MediaProjiction类获得的。
2 textureview类
说到这个类就必须提到surfaceview类,它们的作用类似,不同的是她不像surfaceview那样,在wms单独创建一个窗口,而是作为一个普通的viewgetWindow().setFlags( WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED,WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED); 存在,也就是说它可以向我们寻常的view那样进行移动,放大,缩小。有一点需要注意的是,textureview必须放在硬件加速的窗口中

getWindow().setFlags( WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED,WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED); //窗口级别的硬件加速

3 两者的区别
textur其实跟surface差不多,只是i他的内部不再依赖surface和suifaceholder,而是SurfaceTexture。
surfaceTexture是在android 3.0之后新增的类,他和surfaceview一样,可以从camera preview或者vedio decode里面获得图像流,但是不同的是surface textrue在获得图像流之后不需要显示出来,而camer在获得图像流之后必须显示在surfaceview上。
这样就会有一些问题,如果我们想隐藏摄像头的预览,或者在处理之后再显示图像,当然我们有一些处理的方法。例如用一个布局对surfaceview进行遮盖,问题似乎是解决了,但是图像还是进行了显示,浪费了资源。在android 3.0之前4,这个问题是没法解决的,直到texture的出现

ByteBuffer

ByteBuffer,从字面是看,这个类是字节缓冲区处理字节的。例如,我们的mediacodec类进行底层的数据流编码的时候我们就会用到这个
1 ByteBuffer的原理
bytebuffer含有两个子类,directbytebuffer,它是不分配在堆上的,因此他不会被gc进行管理回收。但是那是directbuffer的的java对象归gc管理,当该java对象被jc回收的时候,系统释放directbuffer所申请的空间。
另一个子类是heapbyterbuffer,它分配在堆上,因此被gc所管理。
举个例子,我们平常的读写操作,都会在I/Os设备与程序之间建立一内存缓冲区,就相当于directbyte,而heap buffer仅仅相当于byte字节数据的包装形式, 前者的写入速度要比后者快的多。
因此,如果bytebuffer总是被重用,则用dirctbytebuffer,如果 byterbuffer经常被释放和分配地址,则我们选用heapbytebuffer。
从源码上进行分析,dircetbbytebuffer是直接操作系统的内存。而heapbytebuffer是操作堆内存里的byte数组。

视频直播

什么事视频直播,就是把视频推流到服务器,然后再我们的客户端,在进行拉流,进行视频播放。
推拉流端都会支持pc和手机,采用的协议大部分都是rtmp或者hls。而且还有一个推拉流工具包:ffmpeg。
当然我们也可以把推流的数据进行存储,然后我们既可以进行直播的观看,,也可以渐进性视频的播放。

概念的理解

推流为将直播内容推送至服务器的过程;拉流为服务器已有直播内容,用指定地址进行拉取的过程。

rtmp

rtmp是Real Time Messaging Protocol(实时消息传输协议)的首字母缩写。该协议基于TCP,是一个协议族,包括RTMP基本协议及RTMPT/RTMPS/RTMPE等多种变种。RTMP是一种设计用来进行实时数据通信的网络协议,主要用来在Flash/AIR平台和支持RTMP协议的流媒体/交互服务器之间进行音视频和数据通信。

hls

hls (HTTP Live Streaming),Apple的动态码率自适应技术。主要用于PC和Apple终端的音视频服务。包括一个m3u(8)的索引文件,TS媒体分片文件和key加密串文件。
HTTP Live Streaming(HLS)是苹果公司(Apple Inc.)实现的基于HTTP的流媒体传输协议,可实现流媒体的直播和点播,主要应用在iOS系统,为iOS设备(如iPhone、iPad)提供音视频直播和点播方案。HLS点播,基本上就是常见的分段HTTP点播,不同在于,它的分段非常小。要实现HLS点播,重点在于对媒体文件分段,目前有不少开源工具可以使用,这里我就不再讨论,只谈HLS直播技术。

  相对于常见的流媒体直播协议,例如RTMP协议、RTSP协议、MMS协议等,HLS直播最大的不同在于,直播客户端获取到的,并不是一个完整的数据流。HLS协议在服务器端将直播数据流存储为连续的、很短时长的媒体文件(MPEG-TS格式),而客户端则不断的下载并播放这些小文件,因为服务器端总是会将最新的直播数据生成新的小文件,这样客户端只要不停的按顺序播放从服务器获取到的文件,就实现了直播。由此可见,基本上可以认为,HLS是以点播的技术方式来实现直播。由于数据通过HTTP协议传输,所以完全不用考虑防火墙或者代理的问题,而且分段文件的时长很短,客户端可以很快的选择和切换码率,以适应不同带宽条件下的播放。不过HLS的这种技术特点,决定了它的延迟一般总是会高于普通的流媒体直播协议。

  根据以上的了解要实现HTTP Live Streaming直播,需要研究并实现以下技术关键点

采集视频源和音频源的数据
对原始数据进行H264编码和AAC编码
视频和音频数据封装为MPEG-TS包
HLS分段生成策略及m3u8索引文件
HTTP传输协议
rtmp协议是adobe出的一种流媒体格式协议。是目前较为流行的协议的一种。
HLS协议是苹果推出的一种流媒体协议,由于IOS系统不支持RTMP协议,如实现RTMP协议的流媒体需要自己实现RTMP的客户端,这使得移动手机端使用RTMP的流媒体增加了一些开发成本。

你可能感兴趣的:(android视频技术)