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请求消息