librtmp协议分析---SendConnectPacket函数
Posted alen_xie
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了librtmp协议分析---SendConnectPacket函数相关的知识,希望对你有一定的参考价值。
要想了解这个函数的作用,先了解一下这个图形。它是connect命令。
通过上述的了解,对照一下代码,基本就明白了,上代码:
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
以上是关于librtmp协议分析---SendConnectPacket函数的主要内容,如果未能解决你的问题,请参考以下文章
librtmp协议分析---RTMP_ConnectStream函数
librtmp协议分析---RTMP_ConnectStream函数
librtmp协议分析---RTMP_SendPacket函数