1 综述
在客户端发起createStream命令之后,客户端收到服务端反馈的_result消息,接下来客户端就可以向服务端发起请求播放的指令,这个指令就是play。首先我们看一下官方给出的关于play的消息流示意图。
首先我们来简单介绍一下关于play的流程,客户端向服务端发送play指令之后,服务端收到之后向客户端发送SetChunkSize消息,实际场景中大都在服务器回复客户端connect消息的时候一起发送setChunkSize消息;
服务端向客户端发送StreamIsRecorded消息(实际场景中比较少见);服务端向客户端发送StreamBegin消息,向客户端指示流传输的开始;StreamIsRecoreded消息和StreamBegin消息组织结构比较简单,RTMP Body部分使用2个字节表示事件类型,StreamBegin的类型为0x00,4个字节表示StreamID。
说明:streamBegin wireshark过滤条件
rtmpt.ucm.eventtype == 0x00
客户端成功发送play请求后,服务端向客户端发送onStatus命令消息NetStream.Play.Start 和 NetStream.Play.Reset消息。其中NetStream.Play.Reset消息只有在客户端发送play消息的时候设置了reset标志的时候才会发。如果客户端请求播放的流不存在,服务端会返回onStatus命令消息NetStream.Play.StreamNotFound。
这些交互结束之后,服务端就会向客户端发送音频和视频数据,客户端就可以进行解码,然后渲染播放了。接下来我们来看一下这几条消息(streamBegin前面已介绍):
2 play
首先来看一下play消息的整体组织结构。
commandName:命令的名称,为“connect”;
transaction ID:事务ID,用number类型表示;
command Object:如果有,用object类型表示,如果没有,则使用null类型指明;
stream Name:请求的流的名称,一般在url中application后面的字段,如rtmp://192.17.1.202:1935/rtmp_live/test,rtmp_live为application,test为流的名称;
start:可选字段,使用number类型表示,指示开始时间,默认值为-2,表示客户端首先尝试命名为streamName的实时流(官方文档中说以秒单位,实际抓包文件中看到的单位应该是毫秒,要注意);
duration:可选字段,用number类型表示,指定播放时间,默认值为-1,表示播放到流结束;
reset:可选字段,用boolean类型表示,用来指示是否刷新之前的播放列表;
好了,看一个具体的抓包文件。
该抓包文件中的play命令,transactionID为4,commandObject中没有内容,streamName为“test”,没有duration和reset字段,有start字段,默认值为-2000,2000毫秒,即2s。
3 setChunkSize
setChunkSize消息结构也比较简单,RTMP Header中的typeID,用来表示消息类型,setChunkSize的类型为0x01。RTMP Body部分直接用4个字节表示chunk size,此例中chunkSize设为4000。
说明:setChunkSize消息wireshark中的过滤条件为:
rtmpt.header.typeid == 0x01
4 onStatus-play start
如果没有任何异常情况,服务器会向客户端发送一个onStatus的状态,如果没有异常,该状态的描述为play start。
onStatus消息的组织结构如下:
onStatus消息由三部分组成:
command Name:表示消息类型,恒为“onStatus”;
transaction ID:设为0;
command Object:用null表示;
info Object:使用object类型表示多个字段,一般有warn,status,code,description等状态。
我们来看一下抓包文件:
command Name, command Object,transaction ID我们已经很熟悉了。我们来看看info Object中的内容,按照AMF0的格式编码,开头表示类型0x03,之后有3个字段描述object;最后有一个End of Obejct Maker用来标记。对于play命令的请求,回应的level为status,code为NetStream.Play.Start,desription为Start live。这些表示play请求命令成功,接下来可以进行音视频的播放了。下一讲我们开始讲讲音频数据的交互流程。
往期推荐
扫描二维码更精彩