2016年是移动直播爆发年,不到半年的时间内无数移动直播App掀起了全民直播的热潮。然而我的以为直播的门槛相对较高,从推流端到服务端器到播放端,无不须要专业的技术来支撑,仅仅推流端就有很多须要学习的知识.目前大部分直播采用的都是RTMP协议,我这里写一个简单的Demo,帮助你们更好的理解直播推流的过程,主要包括:音视频采集, 音视频编码, 数据打包, RTMP协议等相关的知识等.项目结构分的很清楚,各个模块也用协议进行了分离,方便你们学习不一样的模块.git
创建tcp链接github
创建rtmp链接,以及发送各类控制指令算法
获取原始视频数据和音频数据服务器
对原始视频数据和音频数据进行压缩编码网络
对编码后的视频数据和音频数据进行打包app
发送打包后的音频和视频数据框架
`SGSimpleSession` 是Api接口层,负责对外提供可直接调用的接口,同时也是一个数据分发中心,获取到的原始音视频数据和编码后的数据都在这里被分发到不一样的类进行处理.tcp
视频相关的类ide
1.SGVideoSource 原始视频数据获取类,底层用的是AVFoundation框架来实现.对外提供原始未经编码的的视频数据,同时提供图像预览功能.若是须要添加美颜,摄像头切换,翻转,闪光灯等操做,也是在这里处理的.性能
原始视频帧: 原始视频数据其实就是一帧一帧的数据,它们没有通过压缩编码,每一帧包含了图像信息和时间信息,咱们经过代码提取出图片.
fps :1s中包含的帧数就是帧速(fps),通常fps的范围是15~30帧,帧速越高画面越流畅,带宽消耗量越大.实际直播中,大部分采用15到20就能够了.
分辨率 : 一帧的图像的大小,iOS原生的有352*288,640*480,1280*720等,通常直播采用640 *480,而后裁剪为640 *360.
码率 : 也叫比特率,数据传输时单位时间传送的数据位数. 能够理解为码率决定一帧图像的显示精细程度.在必定范围内,码率越大,图像越清晰,消耗带宽或者文件体积就越大.超过必定范围后,清晰度不变.通常640 * 480分辨率的,码率512kbps就可以保证清晰度.
2.SGVideoConfig这个视频配置的类,主要包括压缩等级,分辨率,码率等的配置
3.SGH264Encoder这个类是编码器,主要功能是对原始的视频帧进行编码压缩处理,这里采用的是`硬编码`,编码输出格式为H264格式.
编码 : 编码是指将原始的帧数据编码压缩,编码后数据更小,方便在网络上传输.原始数据体积较大,网络传输十分不方便,所以须要将数据压缩,视频压缩算法当前比较主流的是H264,这里咱们压缩格式是H264格式.H264有不一样的压缩等级,压缩等级不一样,压缩比也不一样.常见的压缩等级有:`baseline ` , `main` , `high`.
硬编码 : 硬编码是相对软编码而言的,通常软编码是经过cpu来运算,比较消耗cpu性能,耗时大,可是兼容性好,软编码通常采用ffmpeg或者x264.相对而言,硬编码使用gpu来编码,速度效率很高.这里采用的是iOS自带的硬解码,只支持iOS8之后的系统.
压缩后的视频帧 : 压缩后的视频有三种帧类型:I ,B ,P帧,I帧也叫关键帧.通过解码后可以独立展现出一幅图像,P帧是前向预测帧,参考前一帧才能解码显示出一幅完整的图像.B 为双向预测帧,必须参考前一帧和后一帧才能解码出图像.所以,I帧的压缩比最低,大约为0.7,它只能采用帧内压缩,P帧压缩比次之,大概能达到0.5,B帧压缩比则更高,达到了0.3~0.5,B帧和P帧采用的是帧内压缩和帧间压缩技术(也就是运动估计,原理是相邻帧的图像有一部分是同样的,专业术语叫空间冗余).实际上,视频压缩等级不一样,帧种类也不一样,好比`baseline等级`压缩后的视频只有I帧 和 P帧.`main等级` 和 `high等级` 则三种帧都包含,它们的总体压缩比要比`baseline`要高.可是由于B帧须要参考前一帧和后一帧才能显示,很容易形成卡顿状况,由于万一后面的帧没有获取到,致使前一帧已也不能显示,因此在实际应用中(直播app),通常压缩等级采用`baseline`.
gop : 这个我试着描述一下:由于除了I帧,其它帧都不能独立渲染显示,理论上只须要一个I帧其它所有是非I帧,这样压缩比最高,可是由于`(B帧和P帧)参考其余帧`的缘由会有必定的偏差,当一段时间后,累计偏差会原来越大,致使图像失真.解决办法就是以一小段为一个单元,每一个单元第一帧都是I帧;这样,即便前面某一小段出了问题也不会影响后面的一小段,每个小段咱们称做一个关gop.每一个gop的第一帧必定是关键帧,由于你的没得参考;一般咱们设置gop的大小为1s到3s,所以关键帧与关键帧之间的间隔就是1s的帧数(对应gop为1s)到3s的帧数(对应gop为3s),根据上面的定义,1s的帧数为fps,所以关键帧间隔为1*fps 到 3*fps.秒开的优化点之一就是减少gop大小,由于gop第一帧是关键帧,能独立渲染出来,用户进入直播间的时间是随机的,为确保用户尽快拿到关键帧,尽快渲染出图像;同时gop越小,关键帧数量就越多,带宽消耗量就越大.
4.SGH264Packager 这个类负责对已经编码好的H264帧数据进行打包处理,打包成符合RTMP协议格式的数据,而后才能发送.
SGAudioSource 这个类主要负责录制音频数据,输出原始音频帧,音频的格式为PCM格式.
SGAudioConfig 这个类是音频配置相关的类,主要包括声道数,码率,采样率的配置.
SGAACEncoder 这个类做用是将原始PCM音频数据进行编码压缩,编码结果为AAC格式的音频数据,这里采用的是硬编码.软编码的库有faac.
SGAACPackager 这个了类做用是将编码后的AAC格式数据大波按成符合RTMP协议的数据.
`SGStreamSession`这个类主要是用来创建tcp链接,底层数据的读取和发送,以及链接状态的回调,整个链接状态贯穿整个项目,十分重要.
`SGRtmpSession`这个类主要与RTMP相关,主要负责与服务器交互,包括RTMP握手,指令的发送,对数据的进一步封装,封装成消息,而后再发送.指令有不少,说点重要的,好比握手完成之后,要从新协商消息大小(默认128字节),可是128字节过小,影响效率,通常都稍微改大点,好比这里设置为16kb,若是太大也很差,会致使带宽浪费.这个类涉及到rtmp相关的比较多,比较难以理解,网上有开源的实现librtmp这个库,能够用这个来替代.
以上就是整个项目的基本结构,整个过程相似工厂流水线,能够自行对各个模块进行替换和研究.demo中注释也很多,方便理解.是否是感受信息量有点大?可能有些地方说的不严谨,还望你们多多指正哈.
这个项目在去年7月份左右就写完了,后来加了一些乌七八糟的东西,后来项目挂了,转战新项目(仍是直播).中间写过几篇入门文章,原本打算写成一个系列文章,无奈太忙了,写的不完整.新年伊始,趁着项目不太忙,赶忙整理了一下,纯码字,若是有任何问题能够直接留言.
附上学习博客:
雷晓华博士的博客:这个是很是好的视音频开发技术文章,喜欢视音频的能够看看 http://blog.csdn.net/leixiaohua1020
硬编码的详细说明: http://www.jianshu.com/p/a6530fa46a88