前篇

这篇博客内容特别长,但总结得非常系统,可以学到很多东西,让大家少走很多弯路

刚学音视频的,千万不要排斥逐个字节去分析文件结构,这个是音视频的基础

没有这些基本功,最多只能在网上抄抄Demo,任何小细节自己都处理不了

RTMP和FLV的关系

FLV是一种文件格式,RTMP是一种流媒体格式

FLV出现在先,RTMP完全照搬了FLV对音视频文件的封装方式,但是对Header部分做了自己的修改

所以如果想做RTMP和FLV之间的互转,最重要的知识就是按字节读出头中的每个参数,再写成另一个头格式

FLV是由一个FLV Header + 若干FLV Tag构成的,而RTMP则是由若干RTMP Packet构成的

FLV Tag和RTMP Packet,除了Header部分,Body部分格式是完全一样的

android yuv视频流处理 android flv_Packet


android yuv视频流处理 android flv_FLV_02


FLV文件结构本篇博客中图片较多,如果嫌图片太小,可右键拖拽到新窗口单独查看

android yuv视频流处理 android flv_android yuv视频流处理_03


FLV中的首个TAG,必然是脚本数据,Script Tag一般用于指明媒体文件的参数信息

RTMP流结构

android yuv视频流处理 android flv_RTMP_04


FLV TAG块结构

android yuv视频流处理 android flv_RTMP_05


RTMP Packet包结构

android yuv视频流处理 android flv_android yuv视频流处理_06


RTMP Header有多种格式

Header Type为0时,Header具有完整的12个字节,为1时,共8个字节,首个音频帧或视频帧,都要采用这种格式

Header Type为1时,Header只有8个字节,没有Stream ID,使用和前个包一样的Stream ID

Header Type为2时,Header只有4个字节,没有Body Size和Packet Type,对于某些音频格式来说,每个包的格式和大小都是一样的,可以使用和前个包一样的值

Header Type为3时,Header只有1个字节,没有Timestamp,当一个Packet放不下数据,分割为多个Packet时,就会使用这种格式

Script Body结构

android yuv视频流处理 android flv_Packet_07

android yuv视频流处理 android flv_Tag_08


AMF全称Action Message Format,是FLV TAG中用来存储消息内容的一种格式单元

AMF Array中的Attribute又称为Metadata,每个属性代表了一个媒体参数,从格式可以看出,Attribute实际上就是一个子的AMF

媒体文件的duration,width,height,framerate,bitrate等参数,就存储在Attribute里面

AMF2的类型,既可以是AMFArray,也可以AMFObject,Array用的更多,有些解析工具不支持AMFObject

Audio Body结构

android yuv视频流处理 android flv_android yuv视频流处理_09

Video Body结构

android yuv视频流处理 android flv_Packet_10


通过librtmp将RTMP流转换为FLV文件,H264文件,AAC文件

以上只是理论部分,通过这个实际案例,我们可以对RTMP和FLV格式有一个完整的了解

只有百分百掌握了文件格式,才可能准确无误地实现格式转换


网上有很多一上来就直接解析文件的教程,但是在对整体结构不是很清楚的情况下,是很难阅读的

如果完整看完这篇博客,再对照代码去逐行对比阅读,就会发现太简单了,实践和理论一模一样