博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
2012.02.13(rtsp)
阅读量:7127 次
发布时间:2019-06-28

本文共 4520 字,大约阅读时间需要 15 分钟。

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/archive/2012/02/13/2348653.html

你可能感兴趣的文章
Linux内核跟踪之trace框架分析【转】
查看>>
XCode v9.6.2017.0830
查看>>
ES不设置副本是非常脆弱的,整个文章告诉了你为什么
查看>>
设置nmon 每天自动收集性能信息
查看>>
python写一段脚本代码自动完成输入(目录下的所有)文件的数据替换(修改数据和替换数据都是输入的)【转】...
查看>>
JVM的内存分配与垃圾回收策略
查看>>
分布式设计与开发(二)------几种必须了解的分布式算法
查看>>
IT高管和易筋经的故事
查看>>
ASP.NET 2.0新控件、管理外观、布局及其它用户体验
查看>>
Javascript分号,加还是不加?
查看>>
[Ubuntu Setup] Ubuntu 14.10 LTS 中文输入法的安装
查看>>
Selenium获取当前窗口句柄与切换回原窗口句柄
查看>>
迁移 SQL Server 到 Azure SQL 实战
查看>>
Linux 内核中断内幕【转】
查看>>
Learning Perl 第3章习题答案
查看>>
ReportView 添加自动增长序号
查看>>
关于在IBatis中返回DataSet
查看>>
Android -- TypedArray
查看>>
android开发系列文章集合
查看>>
rsync+inotify实时同步环境部署记录
查看>>