2012.02.13(rtsp)

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

原文地址:https://www.cnblogs.com/itxiaocaiyidie/p/2348653.html