LibRTMP源代码分析1

1. 背景知识

   RTMP(Real Time Messaging Protocol)实时消息传送协议是Adobe Systems公司为Flash播放器和服务器之间音频、视频和数据传输开发的开放协议。RTMP协议广泛用于直播、点播、聊天等应用,以及pc、移动、嵌入式等平台,是做流媒体开发经常会接触到的协议。想要了解RTMP,需要首先了解Flash流媒体系统。最简单的Flash流媒体系统由两部分组成:

    客  端:Flash Player(一般只有这一种)
    服务器端:有很多知名的rtmp server,其中既有商业程序也有开源程序,简单列举如下:
        开源项目
      LibRTMP源代码分析1:概述 - nkwavelet - 小波的世界
  商业程序   
           LibRTMP源代码分析1:概述 - nkwavelet - 小波的世界
当然,还有一些其他的开源、商业rtmp服务器(如ffserver),我就不一一列举了。一般来说,商业rtmp程序要比开源程序支持更多的协议以及更多的平台,至于哪个更好,这就不好说了。RTMP服务器的功能比较复杂,要完整实现比较困难,如果你需要的是一个完整功能的rtmp server,那就可以从它们之中选择一个,如果你的需求只是一个简单的、输出H.264AAC直播流的rtmp server,那就需要自己来设计和实现。
 

2. libRTMP源代码分析

   学习libRTMP源代码之前需要有一定的Socket编程的基础。首先需要学习《RTMP协议规范》,

中文版下载地址:http://download.csdn.net/detail/leixiaohua1020/6563059

英文版下载地址:http://www.adobe.com/cn/devnet/rtmp.html

2.1 RTMP流媒体播放过程       

    我们必须了解rtmp服务器和flash播放器客户端之间是怎样的一个交互流程。通过阅读RTMP协议就可以了解,这里把它归纳总结如下:

LibRTMP源代码分析1:概述 - nkwavelet - 小波的世界
播放一个RTMP协议的流媒体需要经过以下几个步骤:握手,建立连接,建立流,播放。RTMP连接都是以握手作为开始的。建立连接阶段用于建立客户端与服务器之间的“网络连接”;建立流阶段用于建立客户端与服务器之间的“网络流”;播放阶段用于传输视音频数据。

 2.1.1 握手(HandShake)
       一个RTMP连接以握手开始,双方分别发送大小固定的三个数据块
     a)  握手开始于客户端发送C0、C1块。服务器收到C0或C1后发送S0和S1。
     b)  当客户端收齐S0和S1后,开始发送C2。当服务器收齐C0和C1后,开始发送S2。
     c)  当客户端和服务器分别收到S2和C2后,握手完成。
       握手阶段所发送的三个固定大小数据块可用下图简单表示:
LibRTMP源代码分析1:概述 - nkwavelet - 小波的世界
 
客户端握手代码可参见rtmp.c文件中函数 : static int  HandShake(RTMP *r, int FP9HandShake)
服务端握手代码可参见rtmp.c文件中函数 : static int SHandShake(RTMP *r, int FP9HandShake)

2.1.2 建立网络连接(NetConnection)
a)  客户端发送命令消息中的“连接”(connect)到服务器,请求与一个服务应用实例建立连接。 
     代码可参见rtmp.c文件中函数 : static int SendConnectPacket(RTMP *r, RTMPPacket *cp)
b)  服务器接收到连接命令消息后,发送确认窗口大小(Window Acknowledgement Size)协议消息到客户端,同时连接到连接命令中提到的应用程序。 
     代码可参见rtmp.c文件中函数 : int RTMP_SendServerBW(RTMP *r)
c)  服务器发送设置带宽()协议消息到客户端。 
d)  客户端处理设置带宽协议消息后,发送确认窗口大小(Window Acknowledgement Size)协议消息到服务器端。 
     代码可参见rtmp.c文件中函数 : int RTMP_SendClientBW(RTMP *r)
e)  服务器发送用户控制消息中的“流开始”(Stream Begin)消息到客户端。
f)   服务器发送命令消息中的“结果”(_result),通知客户端连接的状态
    代码可参见rtmp.c文件中函数 : static int SendCheckBWResult(RTMP *r, double txn)

 2.1.3 建立网络流(NetStream)
a)  客户端发送命令消息中的“创建流”(createStream)命令到服务器端。 
      代码可参见rtmp.c文件中函数 : int RTMP_SendCreateStream(RTMP *r)
b)  服务器端接收到“创建流”命令后,发送命令消息中的“结果”(_result),通知客户端流的状态。
     创建一个流的代码可参见rtmp.c文件中函数 : int RTMP_ConnectStream(RTMP *r, int seekTime)

2.1.4 播放(Play)
a)  客户端发送命令消息中的“播放”(play)命令到服务器。
     发送play命令的代码可参见rtmp.c文件中函数 : static int SendPlay(RTMP *r)
b)  接收到播放命令后,服务器发送设置块大小(ChunkSize)协议消息。 
     代码可参见函数 :  static void HandleChangeChunkSize(RTMP *r, const RTMPPacket *packet)
c)  服务器发送用户控制消息中的“streambegin”,告知客户端流ID。 
d)  播放命令成功的话,服务器发送命令消息中的“响应状态” NetStream.Play.Start & NetStream.Play.reset,告知客户端“播放”命令执行成功。 
e)  在此之后服务器发送客户端要播放的音频和视频数据。

 2.2 RTMP协议简单分析

       RTMP协议是一个互联网TCP/IP五层体系结构中应用层的协议。RTMP协议中基本的数据单元称为消息(Message)。当RTMP协议在互联网中传输数据的时候,消息会被拆分成更小的单元,称为消息块(Chunk)。

 2.2.1  消息

       消息是RTMP协议中基本的数据单元。不同种类的消息包含不同的Message Type ID,代表不同的功能。RTMP协议中一共规定了十多种消息类型,分别发挥着不同的作用。例如,Message Type ID1-7的消息用于协议控制,这些消息一般是RTMP协议自身管理要使用的消息,用户一般情况下无需操作其中的数据。Message Type ID89的消息分别用于传输音频和视频数据。Message Type ID15-20的消息用于发送AMF编码的命令,负责用户与服务器之间的交互,比如播放,暂停等等。消息首部(Message Header)有四部分组成:标志消息类型的Message Type ID,标志消息长度的Payload Length,标识时间戳的Timestamp,标识消息所属媒体流的Stream ID。消息的报文结构如下图所示:
LibRTMP源代码分析1:概述 - nkwavelet - 小波的世界
 
2.2.2  消息块
       在网络上传输数据时,消息需要被拆分成较小的数据块,才适合在相应的网络环境上传输。RTMP协议中规定,消息在网络上传输时被拆分成消息块(Chunk)。消息块首部(Chunk Header)有三部分组成:用于标识本块的Chunk Basic Header,用于标识本块负载所属消息的Chunk Message Header,以及当时间戳溢出时才出现的Extended Timestamp。消息块的报文结构如下图所示:
LibRTMP源代码分析1:概述 - nkwavelet - 小波的世界
 

2.2.3  消息分块

       在消息被分割成几个消息块的过程中,消息负载部分(Message Body)被分割成大小固定的数据块(默认是128字节,最后一个数据块可以小于该固定长度),并在其首部加上消息块首部(Chunk Header),就组成了相应的消息块。消息分块过程如图5所示,一个大小为307字节的消息被分割成128字节的消息块(除了最后一个)
LibRTMP源代码分析1:概述 - nkwavelet - 小波的世界

RTMP传输媒体数据的过程中,发送端首先把媒体数据封装成消息,然后把消息分割成消息块,最后将分割后的消息块通过TCP协议发送出去。接收端在通过TCP协议收到数据后,首先把消息块重新组合成消息,然后通过对消息进行解封装处理就可以恢复出媒体数据。

2.2.4  消息格式简单图解

       总结以上三个图,消息格式大致可以用以下图描述:

LibRTMP源代码分析1:概述 - nkwavelet - 小波的世界
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值