RTSP:Read network & Netscape共同提出的如何有效的在IP网路上传输流媒体数据的应用协议。
RTSP建立并控制一个或几个时间同步的连续流媒体,如音频和视频。
按需传送,提供了选择发送通道(UDP,组播UDP与TCP),并提供基于RTP的发送机制方法。RTSP控制的流可能用到RTP.
RTSP中客户端和服务器口可以发送请求。
RTSP是一种文本协议,采用UTF-8编码中的ISO 10646字符集。
RTSP的消息有两大类:请求消息,回应消息:
请求消息:
简单的rtsp交互过程:
C表示rtsp客户端;S表示rtsp服务器端:
1、C->S:OPTION request;//询问s有哪些方法可用
BOOL RtspRequest::RequestOptions()
{ if (m_State < stateConnected) return FALSE;SendRequest("OPTIONS");
printf("\n");
if ( !GetResponses() )
return FALSE;return TRUE;
}1、S->C:OPTION response;//S回应信息中包括提供的所有可用方法
void RtspResponse::ResponseOptions()
{ AddField("Public: OPTIONS, DESCRIBE, SETUP, TEARDOWN, PLAY, PAUSE"); SendResponse("");printf("\n");
}
2、C->S:DESCRIBE request//要求得到S提供的媒体初始化描叙信息
BOOL RtspRequest::GetDescribe(string* pDescribe)
{ BYTE* pDescribeBuffer = NULL; int describeSize; string describe; string searchField;if ( !SearchResponses(&searchField, "Content-Length") )
return FALSE;describeSize = atoi( searchField.c_str() );
pDescribeBuffer = new BYTE[describeSize + 1]; if (!pDescribeBuffer) return FALSE; memset(pDescribeBuffer, 0, describeSize);describeSize = Tcp::Read(pDescribeBuffer, describeSize);
if (describeSize != describeSize) { delete []pDescribeBuffer; return FALSE; } pDescribeBuffer[describeSize] = '\0';*pDescribe = (char*)pDescribeBuffer;
delete []pDescribeBuffer;
printf("%s\n\n", pDescribe->c_str());
return TRUE;
}2、S->C:DESCRIBE response//S回应媒体初始化描叙信息,主要是sdp
void RtspResponse::ResponseDescribe(PCSTR sdp, UINT sdpLength)
{ string contentBase; string contentType; string contentLength; string server;char temp[20];
string requestMrl;server = "Server: RTSP Service";
contentType = "Content-Type: application/sdp";_snprintf(temp, 20, "%lu", sdpLength);
contentLength = "Content-Length: "; contentLength += temp;GetRequestMrl(&requestMrl);
contentBase = "Content-Base: "; contentBase += requestMrl;AddField(server);
AddField(contentBase); AddField(contentType); AddField(contentLength); SendResponse("");printf("\n");
Tcp::Write((PBYTE)sdp, sdpLength);
printf("Content:\n");
printf(sdp); printf("\n\n");}3、C->S:SETUP request//设置会话的属性,以及传输模式,提醒S建立会话
BOOL RtspRequest::RequestSetup(PCSTR setupName, INT transportMode, INT clientPort, INT clientRtcpPort, INT64* pSession)
{ if (m_State < stateConnected) return FALSE;string transportField;
if (setupName == NULL)
m_SetupName = ""; else m_SetupName = setupName;if ( !GenerateTransportField(&transportField, transportMode, clientPort, clientRtcpPort) )
return FALSE;AddField(transportField);
SendRequest("SETUP");printf("\n");
if ( !GetResponses() )
return FALSE;m_State = stateReady;
if (pSession)
*pSession = m_Session;return TRUE;
}3、S->C:SETUP response//S建立会话,返回会话标识符,以及会话相关信息
void RtspResponse::ResponseSetup( PCSTR serverIp, INT serverRtpPort,
PCSTR targetIp, INT targetRtpPort, INT32 ssrc){ string transport; string client_port; string server_port; string ssrc_; char temp[100];if (!m_Session)
m_Session = GenerateOneNumber();_snprintf(temp, 100, "server_port=%u-%u", serverRtpPort, serverRtpPort+1);
server_port = temp;_snprintf(temp, 100, "client_port=%u-%u", targetRtpPort, targetRtpPort+1);
client_port = temp;_snprintf(temp, 100, "ssrc=%u", ssrc);
ssrc_ = temp;transport += "Transport: RTP/AVP;unicast;";
transport += "source="; transport += serverIp; transport += ';'; transport += server_port; transport += ';'; transport += client_port; transport += ';'; transport += ssrc_; AddField(transport); SendResponse("");printf("\n");
}4、C->S:PLAY request//C请求播放
BOOL RtspRequest::RequestPlay()
{ if (m_State < stateReady) return FALSE;SendRequest("PLAY");
printf("\n");
if ( !GetResponses() )
return FALSE; m_State = statePlaying;return TRUE;
}4、S->C:PLAY request//S回应请求信息
void RtspResponse::ResponsePlay(PCSTR setupUrl)
{ string rtpinfo = "RTP-Info: "; rtpinfo += setupUrl;//string range = "Range: npt=now-";
//AddField(range); AddField(rtpinfo); SendResponse("");printf("\n");
}
S->C:发送流媒体数据
5、C->S:TEARDOWN request//C 请求关闭会话
BOOL RtspRequest::RequestTeardown()
{ if (m_State < stateConnected) return FALSE;SendRequest("TEARDOWN");
printf("\n");
if ( !GetResponses() )
return FALSE;m_State = stateInit;
return TRUE;
}5、S->C:TEARDOWN response//S回应请求
void RtspResponse::ResponseTeardown()
{ AddField("Connection: Close"); SendResponse("");printf("\n");
}上面的过程是标准的,友好的rtsp流程。其中3、4步时必须的;
1、OPTION
目的是得到服务器提供的可用方法:
OPTION rtsp://192.168.20.136:5000/xxx666 RTSP/1.0
CSeq:1 //每个消息都有序号来标记,第一个包通常是option请求消息