这几天在调研直播的技术。虽然如今有不少“开源”的SDK,或者各个厂家的SDK。可是仍是想本身去调研一下整个的直播流程/技术,而且经过代码去实现一套这样的功能。bash
看网上的文章介绍,基本上的流程是这样的:采集,编码,发送,转发,解码。我此次主要研究一下采集,编码,发送这三个客户端采集的步骤。服务器
采集设备:Android手机摄像头采集视频,麦克风采集音频。 编码格式:音频:aac,视频:h264。 发送协议:rtmp协议。
摄像头采集视频的方法有两种:Camera的onPreviewFrame的回调方法,和MediaRecorder的outPut方法。通过对比,发现各有各的优缺点:网络
Camera的onPreviewFrame方法:socket
优势: 能够获取到视频的原始YUV数据。 使用简单:直接设置一个回调方法就可以获取到预览时的视频数据。 缺点: 须要本身将YUV数据编码为h264格式,对编码须要必定的了解。
MediaRecorder的outPut方法:编码
优势: 能够直接获取到编码后的h264格式的视频帧数据。 缺点: 获取部分的代码比较麻烦:须要在程序内部架设socket服务来获取h264视频数据。
在各有优缺点的状况下,经过对比其余现有的直播SDK的功能,最终采用了Camera的onPreviewFrame的方法。众所周知,美颜功能已是目前直播的主要功能点之一。获取到最原始的YUV数据,对于后期加美颜效果是有极大的帮助的。
麦克风采集音频,也有两种方式:AudioRecorder的read,和MediaRecorder的outPut方法。优缺点基本和视频类似。故仍是选择AudioRecorder来采集音频,这样就能获取到最原始的PCM数据(也就是去掉wav头信息的原始数据)。spa
视频的编码格式采用h264,主要从数据的体积大小上考虑。原始的视频帧YUV数据,是没有通过压缩的,相对来讲体积较大。数据越大,在网络上传输出错的可能性越大,而且对网络的带宽消耗也越大。而h264则对数据进行了压缩和编码,有了关键帧和非关键帧的概念。而非关键帧相对于关键帧,视频数据小了不少。这样带来的好处就是直播须要在网络上传输的数据就变少,对服务器的带宽消耗也相对变小。code
音频的编码格式采用aac,主要仍是因为体积问题。同时,aac在压缩编码以后,声音的变化基本听不出来,声音质量高。视频
目前大多数直播协议都是基于Rtmp协议的。因此我也准备采用这个协议。直播
有了具体的想法以后,就在于代码的实现。而代码实现每每是最难的部分。毕竟空想谁都会,实现起来,就会遇到各类问题。io
看到网上不少是基于ffmpeg去实现直播的采集。可是分析了采集的需求以后,其实发现咱们只须要三个地方作好,基本上采集就OK了。分别是:h264 的编码实现。aac的编码实现。rtmp的编码实现。而通过查阅资料,发现ffmpeg也是集成了这三个功能,从而实现的直播功能。
为了简单,我决定就从这三个方面入手编写代码。编写代码不表明就是要从新造轮子。毕竟一我的彻底从0开始写直播是不太符合目前的情况的:没那个精力。因而,选择库,成了重要的一个步骤。
h264的编码库也很多,最终选择了x264。 aac的编码库,选择了fdkaac。 rtmp的库,选择了rtmpdump。
以上这三种库都是驰骋沙场的老将,应该没有问题。
接下来就是各个击破,一步一步的去完成实现采集所需的功能。