创建完RTMP连接之后就可以创建或者访问RTMP流,对于推流端,客户端要向服务器发送一个releaseStream命令消息,之后是createStream命令消息,对于拉流端,则要发送play消息请求视频资源。我们先来看看推流端的消息流程,当发送完createStream消息之后,解析服务器返回的消息会得到一个stream ID, 这个ID也就是以后和服务器通信的 message stream ID, 一般返回的是1,不固定。
createStream
我们来先看看createStream消息,RTMP客户端发送此消息到服务端,创建一个逻辑通道,用于消息通信。音频、视频、元数据均通过createStream创建的数据通道进行交互,而releaseStream与createStream相对应,为什么有的时候会在createStream之前先来一次releaseStream呢?这就像我们很多的服务实现中,先进行一次stop,然后再进行start一样。因为我们每次开启新的流程,并不能确保之前的流程是否正常走完,是否出现了异常情况,异常的情况是否已经处理等等,所以,做一个类似于恢复初始状态的操作,releaseStream就是这个作用。
我们先来看一下createStream的整体架构:
使用字符串类型标识命令的类型,恒为“createStream”;然后使用number类型标识事务ID;紧接着是command相关的信息,如果存在,用set表示,如果没有,则使用null类型表示。
接下来,我们来看一个具体的抓包文件:
该createStream消息中,事务ID为2,没有command相关的信息,使用Null类型表示。命令的名称(0x02)、事务ID(0x00)、命令的信息(0x03 or 0x05)均按照AMF0的格式进行编码,我们从抓包文件中也可以比较明显的看到。
_result/_error
客户端发送createStream请求之后,服务端会反馈一个结果给客户端,如果成功,则返回_result,如果失败,则返回_error。返回的消息的整体结构如下图:
整体与createStream类似,commandName为固定为"_result"或者"_error",transcationID为createStream中的ID,此例中为2,comamndObject也是与createStream一样的组织方式。不同的是多了一个streamID,成功的时候,返回一个streamID,失败的时候返回失败的原因,类似于错误码。我们还是通过一个具体的抓包文件来看一下:
这样一看就一目了然了。
releaseStream
说完createStream,我们就可以说说releaseStream命令了。关于releaseStream命令,我们还是通过抓包文件来进行分析,首先看一个releaseStream的抓包文件。
release消息的组织结构,comandName transactionID commandObject 流的一些用户名和密码信息等(可能没有),简单示意图如下:
commandName恒为“releaseStream”用以区分类型,transactionID指明要释放的stream,此处id为2,也就是我们前面createStream的id(在客户端请求下一个createStream的时候,就会先释放原有的stream),comandObject携带一些相关的信息(可能没有);userPass部分为针对流的一些用户名和密码的一些信息,本例中没有,所以,字符串中的长度为0。
好了,本篇的介绍就到这里了,下一篇我们继续,欢迎搬好小板凳!