librtmp协议分析---SendConnectPacket函数

要想了解这个函数的作用,先了解一下这个图形。它是connect命令。

librtmp协议分析---SendConnectPacket函数_第1张图片

librtmp协议分析---SendConnectPacket函数_第2张图片

通过上述的了解,对照一下代码,基本就明白了,上代码:

static int SendConnectPacket(RTMP *r, RTMPPacket *cp)
{
	RTMPPacket packet;
	char pbuf[4096], *pend = pbuf + sizeof(pbuf);
	char *enc;

	if (cp)
		return RTMP_SendPacket(r, cp, TRUE);

	packet.m_nChannel = 0x03; /* control channel (invoke),, 块流ID*/
	packet.m_headerType = RTMP_PACKET_SIZE_LARGE;// 块消息头类型,长度为11字节
	packet.m_packetType = 0x14; /* INVOKE */// 消息类型ID为20,表示该消息用AMF0编码
	packet.m_nTimeStamp = 0;// 时间戳
	packet.m_nInfoField2 = 0;// 消息流id
	packet.m_hasAbsTimestamp = 0;// 相对时间
	packet.m_body = pbuf + RTMP_MAX_HEADER_SIZE;

	enc = packet.m_body;
	enc = AMF_EncodeString(enc, pend, &av_connect);// 将"connnect"字符串采用AMF0编码
	enc = AMF_EncodeNumber(enc, pend, ++r->m_numInvokes);// 编码命令消息的数目,也就是传输ID
	*enc++ = AMF_OBJECT;// 接下来是AMF对象,内含多个属性编码

	enc = AMF_EncodeNamedString(enc, pend, &av_app, &r->Link.app);// 编码客户端要连接到的服务应用名
	if (!enc)
		return FALSE;
	if (r->Link.protocol & RTMP_FEATURE_WRITE)
	{
		enc = AMF_EncodeNamedString(enc, pend, &av_type, &av_nonprivate);
		if (!enc)
			return FALSE;
	}
	if (r->Link.flashVer.av_len)
	{// 编码flash播放器版本
		enc = AMF_EncodeNamedString(enc, pend, &av_flashVer, &r->Link.flashVer);
		if (!enc)
			return FALSE;
	}
	if (r->Link.swfUrl.av_len)
	{// 编码发起连接的swf文件的url
		enc = AMF_EncodeNamedString(enc, pend, &av_swfUrl, &r->Link.swfUrl);
		if (!enc)
			return FALSE;
	}
	if (r->Link.tcUrl.av_len)
	{// 编码服务url,有下列的格式  protocol://servername:port/appName/appInstance
		enc = AMF_EncodeNamedString(enc, pend, &av_tcUrl, &r->Link.tcUrl);
		if (!enc)
			return FALSE;
	}
	if (!(r->Link.protocol & RTMP_FEATURE_WRITE))//以下的设置可以参考:协议标准7.2.1.1. connect 命令.参考图片.
	{
		enc = AMF_EncodeNamedBoolean(enc, pend, &av_fpad, FALSE); 编码是否使用代理true:使用  false:没有使用
		if (!enc)
			return FALSE;
		enc = AMF_EncodeNamedNumber(enc, pend, &av_capabilities, 15.0);
		if (!enc)
			return FALSE;
		enc = AMF_EncodeNamedNumber(enc, pend, &av_audioCodecs, r->m_fAudioCodecs);// 编码客户端支持的音频编解码器
		if (!enc)
			return FALSE;
		enc = AMF_EncodeNamedNumber(enc, pend, &av_videoCodecs, r->m_fVideoCodecs);// 编码支持的视频编解码器
		if (!enc)
			return FALSE;
		enc = AMF_EncodeNamedNumber(enc, pend, &av_videoFunction, 1.0);//表明所支持的特殊视频方法
		if (!enc)
			return FALSE;
		if (r->Link.pageUrl.av_len)
		{
			enc = AMF_EncodeNamedString(enc, pend, &av_pageUrl, &r->Link.pageUrl);// 编码SWF文件被加载的页面的Url
			if (!enc)
				return FALSE;
		}
	}
	if (r->m_fEncoding != 0.0 || r->m_bSendEncoding)
	{ /* AMF0, AMF3 not fully supported yet *//* AMF0, AMF3 not fully supported yet, AMF编码方法 */
		enc = AMF_EncodeNamedNumber(enc, pend, &av_objectEncoding, r->m_fEncoding);
		if (!enc)
			return FALSE;
	}
	if (enc + 3 >= pend)
		return FALSE;
	// AMF对象结束标志
	*enc++ = 0;
	*enc++ = 0; /* end of object - 0x00 0x00 0x09 */
	*enc++ = AMF_OBJECT_END;

	/* add auth string */
	if (r->Link.auth.av_len)
	{
		enc = AMF_EncodeBoolean(enc, pend, r->Link.lFlags & RTMP_LF_AUTH);
		if (!enc)
			return FALSE;
		enc = AMF_EncodeString(enc, pend, &r->Link.auth);
		if (!enc)
			return FALSE;
	}
	if (r->Link.extras.o_num)
	{
		int i;
		for (i = 0; i < r->Link.extras.o_num; i++)
		{
			enc = AMFProp_Encode(&r->Link.extras.o_props[i], enc, pend);
			if (!enc)
				return FALSE;
		}
	}
	packet.m_nBodySize = enc - packet.m_body;

	return RTMP_SendPacket(r, &packet, TRUE);
}


发送connect命令. 这是每次程序运行的时候发送的第一个命令消息.
命令消息由命令名,传输ID,和命令对象组成.
命令对象由一系列的相关参数组成.
可参考rtmp协议:rtmp命令消息--7.2.1.1



你可能感兴趣的:(流媒体传输协议分析)