最近在做直播的App,但是使用的是腾讯云,大部分东西都被封装好了,曾经也想过整理一下关于腾讯云的使用,但是最后想想还是没有必要,官方说的那么好,虽然也会遇到一些坑。所以就找了一些之前留意过的关于直播的东西,整理一下。
视频直播
1:采集:AVCaptureSession,显示:AVCaptureVideoPreviewLayer
2:MP4:MP4 是一种视频容器格式
MP4文件中的所有数据都装在box(QuickTime中为atom)中,也就是说MP4文 件由若干个box组成,每个box有类型和长度,可以将box理解为一个数据对象
MP4 件格式是ISO-14496-12基础 件格式的衍 品,14496-14 中对-12协议进 了扩充与进 步定义。
重要的是该“14496-12 基础 件格式”协议如果认祖归宗,我们发现这种 件 格式最初是由Apple公司的QuickTime媒体格式发展 来的。 即,mov格式发展出了“ISO 14496 – 12协议”,再由该协议衍 出了 mp4,f4v,ismv,3gp等我们常见的媒体封装格式。 因此上述标志位的poster位,在14496-12中并没有见到描述, 在Apple的协 议中却看到了准确定义
H264:H.264 是一种图像编码标准。
H264是一种高压缩率的编码标准,如何压缩嘞?一般的视频采集都是25帧/秒, 也就是每秒截图25次,其实每一张图片的内容都相差不大,压缩的办法就是利用算 法,只将每张图片变动差异化的部分保存下来,这样视频文件就小多了
三种帧
在H264协议里定义了三种帧,完整编码的帧叫I帧,参考之前的I帧生成的只包含差 异部分编码的帧叫P帧,还有一种参考前后的帧编码的帧叫B帧。
H264结构中,一个视频图像编码后的数据叫做一帧,一帧由一个片(slice)或多 个片组成,一个片由一个或多个宏块(MB)组成,一个宏块由16×16的yuv数据 组成。宏块作为H264编码的基本单位。
H264采用的核心算法是帧内压缩和帧间压缩,帧内压缩是生成I帧的算法,帧间压 缩是生成B帧和P帧的算法。
+ I帧:帧内编码帧 ,I帧表示关键帧,你可以理解为这一帧画面的完整保留;解码时只 需要本帧数据就可以完成(因为包含完整画面)
+ P帧:前向预测编码帧。P帧表示的是这一帧跟之前的一个关键帧(或P帧)的差别, 解码时需要用之前缓存的画面叠加上本帧定义的差别,生成最终画面。(也就是差 别帧,P帧没有完整画面数据,只有与前一帧的画面差别的数据)
+ B帧:双向预测内插编码帧。B帧是双向差别帧,也就是B帧记录的是本帧与前后帧的 差别(具体比较复杂,有4种情况,但我这样说简单些),换言之,要解码B帧,不 仅要取得之前的缓存画面,还要解码之后的画面,通过前后画面的与本帧数据的叠 加取得最终的画面。B帧压缩率高,但是解码时CPU会比较累。
一个序列的第一个图像叫做 IDR 图像(立即刷新图像),IDR 图像都是 I 帧图像。 H.264 引入 IDR 图像是为了解码的重同步,当解码器解码到 IDR 图像时,立即将 参考帧队列清空,将已解码的数据全部输出或抛弃,重新查找参数集,开始一个新 的序列。这样,如果前一个序列出现重大错误,在这里可以获得重新同步的机会。 IDR图像之后的图像永远不会使用IDR之前的图像的数据来解码。
一个序列就是一段内容差异不太大的图像编码后生成的一串数据流。当运动变化比 较少时,一个序列可以很长,因为运动变化少就代表图像画面的内容变动很小,所 以就可以编一个I帧,然后一直P帧、B帧了。当运动变化多时,可能一个序列就比 较短了,比如就包含一个I帧和3、4个P帧。
H264编码后的数据分为两层:
1. VCL(video coding layer)视频编码层:它是对核心算法引擎,块,宏块 及片的语法级别的定义,最终输出编码完的数据 SODB。
2. NAL(network abstraction layer)网络提取层:定义片级以上的语法级别 (如序列参数集和图像参数集,针对网络传输),同时支持以下功能:独立 片解码,起始码唯一保证,SEI以及流格式编码数据传送,NAL层将SODB打 包成RBSP然后加上NAL头,组成一个NALU(NAL单元)。
分层的好处显而易见,对于RTMP传输数据,我们只需了解NAL层就足够了。
H264硬编原理
想要采用硬件加速编码视频,苹果提供的只有 AVAssetWriter 类,而它只能写入编码后的文件到指定路径的文件中。我们如果想要实时硬编码,例如将视频流输出到网络,这时就需要从输出文件中不断读取新的编码后视频数据。
实现
AVEncoder 通过使用 GCD Dispatch Source 监听文件的内容改变,通 过此方式高效的读取编码后的数据,然而简单的读取 raw data 并不能满足我们的 需求,因此在代码中根据Mp4的文件结构(要看懂这里就需要前面介绍的知识 了),每次读取一个完整的 NALU 后再将数据通过 block 传递给外部调用者处理。
AVEncoder -> 读入CMBu er -> 调用 AVAssetWriter 编码Bu er -> 设置 header 的 FileHandler -> 获得第一帧(moov[sps, pps]),切换写入文件(寻 找mdat),重设FileHandle -> [输入数据 -> 编码 处理循环 ] -> 发送给调用者 处理。
FLV
FLV里面是由多个Tag构成的:[[tag1][tag2][tag3][tag4]…] 而Tag多种类型,最常见的是 Metainfo Tag , Video Tag , Audio Tag 。
Flv Header 是文件的头部,用 FLV 字符串标明了文件的类型,以及是否有音频、 视频等信息。之后会有几个字节告诉接下来的包字节数。
Metainfo 中用来描述Flv中的各种参数信息,例如视频的编码格式、分辨率、采样 率等等。如果是本地文件(非实时直播流),还会有偏移时间戳之类的信息用于支 持快进等操作。
VideoTag 存放视频数据。对于H.264来说,第一帧发送的NALU应为 SPS和PPS, 这个相当于H.264的文件头部,播放器解码流必须先要找到这个才能进行播放。之 后的数据为I帧或P帧。
AudioTag 存放音频数据。对于AAC来说,我们只需要在每次硬编码完成后给数据 加上adts头部信息即可
VLC:(MobileVLCKit.framework)
VLC Media Player (VideoLAN) 为 Windows、Linux、OS X、Android、iOS、Windows Phone等平台提供 个视频播放 器、解码器。它可以播放来 络、摄像头、磁盘、光驱的 件, 持包括MPEG 1/2/4, H264, VC-1, DivX, WMV, Vorbis, AC3, AAC等格式的解码。在 Windows 和 Linux 上的 VLC 是使 C++/Qt写成,提供了 致的 户体验。同时 VLC 还专门 为 OS X 提供了原 版本,OS X 版的 VLC 的 户界 使 Cocoa框架编写,在 OS X 下拥有卓越的原 体验。
VLC优秀的封装,源码中最核 的部分,被封装成了独 的库,基于FFmpeg,Live555提供完整的媒体播放库,你只 需要定制 的界 , 持CocoaPods导 库,开发 个简单界 的播放器,你只需要 代码, 乎覆盖所有媒体格 式!http://www.videolan.org/vlc/download-ios.html
直播博客推荐
[基于RTMP的视频推流](http://www.jianshu.com/p/8ea016b2720e)
[高仿<喵播APP>](http://www.jianshu.com/p/b8db6c142aad)
[高仿<喵播APP>](http://www.jianshu.com/p/b8db6c142aad)
[吖了个峥](http://www.jianshu.com/users/b09c3959ab3b/latest_articles)
[七牛云技术(三方直播)](http://www.jianshu.com/users/342c4dafa482/latest_articles)
[原文](http://www.cocoachina.com/ios/20161111/18050.html)