ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

协议圣经 四 rtspclient

2021-08-02 21:31:21  阅读:266  来源: 互联网

标签:协议 圣经 rtspclient void rtsp unsigned char callback int


live555 rtsp client

为了让读者快速掌握或者说快速做出一个rtspclient ,我们使用live555 来做一个客户端,live555是一个比较出名的rtsp协议实现库,虽然说他代码c++中继承较多,但不失为一个比较认真和全面的库。

rtsp client 注意点

1 、要做一个rtsp客户端,必须实现rtp协议,rtcp协议和rtsp协议
2、 rtcp可以用来保活和统计
3、可以使用 rtp over tcp 和 rtp over udp
4、在局域网里面,可以使用udp 甚至 multicast 组播,外网,请使用tcp

show me the code

这里提供一个rtsp client ,非常简便,一个头文件搞定。


/* ---------------------------------------------------------------------------
**
2021-02-13
email 418511899@qq.com
** 
** -------------------------------------------------------------------------*/

#pragma once

#include "BasicUsageEnvironment.hh"
#include "liveMedia.hh"
#include <string>
#include <iostream>
#ifdef WIN32
#pragma warning (disable: 4512) 
#pragma warning (disable: 4100) 
#pragma warning (disable: 4091) 
#include <stdint.h>
typedef int ssize_t;
#endif



#define RTSP_CALLBACK(uri, resultCode, resultString) \
static void continueAfter ## uri(RTSPClient* rtspClient, int resultCode, char* resultString) { static_cast<c_rtsp::RTSPClientConnection*>(rtspClient)->continueAfter ## uri(resultCode, resultString); } \
void continueAfter ## uri (int resultCode, char* resultString); \
/**/

#define TASK_CALLBACK(class,task) \
TaskToken m_ ## task ## Task; \
static void Task ## task(void* rtspClient) { static_cast<class*>(rtspClient)->Task ## task(); } \
void Task ## task (); \
/**/


#if LIVEMEDIA_LIBRARY_VERSION_INT > 1371168000 
	#define RTSPClientConstrutor(env, url, verbosity, appname, httpTunnelPort) RTSPClient(env, url, verbosity, appname, httpTunnelPort ,-1)
#else					
	#define RTSPClientConstrutor(env, url, verbosity, appname, httpTunnelPort) RTSPClient(env, url, verbosity, appname, httpTunnelPort)
#endif



class Environment : public BasicUsageEnvironment
{
public:
	Environment(char * stop) : BasicUsageEnvironment(*BasicTaskScheduler::createNew()), m_stop(stop)
	{
		m_stop = stop;
	}

	~Environment()
	{
		TaskScheduler* scheduler = &this->taskScheduler();
		delete scheduler;
	}

	void mainloop()
	{
		this->taskScheduler().doEventLoop(m_stop);
	}

	void stop()
	{
		*m_stop = 1;
	}


protected:
	char* m_stop;
};


typedef void (*callback_onData)(void * puser, uint8_t*, ssize_t len);


class c_rtsp
{
	public:
		class Callback
		{
			public:
				virtual bool    onNewSession(const char* id, const char* media, 
					const char* codec, const char* sdp) { return true; }
				virtual bool    onData(const char* id, unsigned char* buffer,
					ssize_t size, struct timeval presentationTime)
				{
					if (v_callback != NULL) {
						//回调函数,传回名称和数据,数据大小+头部的大小
						v_callback(v_user, buffer, size);
						return true;
					}
					return false;
				}
				virtual ssize_t onNewBuffer(unsigned char* buffer, ssize_t size) 
				{
					return 0; 
				}
				virtual void    one rror(c_rtsp&, const char*message)  {
					std::cout << v_name << ":Error:" << message << std::endl;
				}
				virtual void    onConnectionTimeout(c_rtsp& connection)
				{
					std::cout << v_name << ":Connection timeout -> retry" << std::endl;
					connection.start();
				}
				virtual void    onDataTimeout(c_rtsp& connection)
				{
					std::cout << v_name << ":Data timeout -> retry" << std::endl;
					connection.start();
				}
				//增加的头部长度
				int v_header = 0;
				std::string v_name= "empty" ;
				void RegisterCallBack(void * puser, int headlen, callback_onData cb) {
					v_user = puser;
					v_header = headlen;
					v_callback = cb;
				}
				callback_onData v_callback = NULL;
				void * v_user = NULL;
		};

	protected:

		class SessionSink: public MediaSink 
		{
			public:
				static SessionSink* createNew(UsageEnvironment& env, Callback* callback) { return new SessionSink(env, callback); }

			private:
				SessionSink(UsageEnvironment& env, Callback* callback);
				virtual ~SessionSink();

				void allocate(ssize_t bufferSize);

				static void afterGettingFrame(void* clientData, unsigned frameSize,
							unsigned numTruncatedBytes,
							struct timeval presentationTime,
							unsigned durationInMicroseconds)
				{
					static_cast<SessionSink*>(clientData)->afterGettingFrame(frameSize, numTruncatedBytes, presentationTime, durationInMicroseconds);
				}
				
				void afterGettingFrame(unsigned frameSize, unsigned numTruncatedBytes, struct timeval presentationTime, unsigned durationInMicroseconds);

				virtual Boolean continuePlaying();

			private:
				u_int8_t*              m_buffer;
				ssize_t                 m_bufferSize;
				Callback*              m_callback; 	
		};
	
	
		class RTSPClientConnection : public RTSPClient
		{
			public:
				RTSPClientConnection(c_rtsp& connection, Environment& env, Callback* callback, const char* rtspURL, int timeout, bool rtpovertcp, int verbosityLevel);
				virtual ~RTSPClientConnection(); 
			
			protected:
				void sendNextCommand(); 
						
				RTSP_CALLBACK(DESCRIBE,resultCode,resultString);
				RTSP_CALLBACK(SETUP,resultCode,resultString);
				RTSP_CALLBACK(PLAY,resultCode,resultString);
			
				TASK_CALLBACK(c_rtsp::RTSPClientConnection,ConnectionTimeout);
				TASK_CALLBACK(c_rtsp::RTSPClientConnection,DataArrivalTimeout);
				
			protected:
				c_rtsp&          m_connection;
				int                      m_timeout;
				bool                     m_rtpovertcp;
				MediaSession*            m_session;                   
				MediaSubsession*         m_subSession;             
				MediaSubsessionIterator* m_subSessionIter;
				Callback               * m_callback; 	
				unsigned int             m_nbPacket;
		};
		
	public:
		c_rtsp(const char* rtspURL,
			int header = 4,
			int timeout = 5, 
			bool rtpovertcp = false, 
			int verbosityLevel = 0);
		virtual ~c_rtsp();

		void Register_Callcack(void * puser,const char * name, int headlen, callback_onData cb)
		{
			if (name != NULL)
				m_callback.v_name = name;
			else
				m_callback.v_name = "empty";
			m_callback.RegisterCallBack(puser, headlen, cb);
		}
		void start(unsigned int delay = 0);
		void stop();

	protected:
		TASK_CALLBACK(c_rtsp,startCallback);
	
	protected:
		Environment              m_env;
		Callback                 m_callback; 	
		std::string              m_url;
		int                      m_timeout = 2;
		bool                     m_rtpovertcp = false;
		int                      m_verbosity = 0;
	
		RTSPClientConnection*    m_rtspClient;
};

调用

请听下回分解

标签:协议,圣经,rtspclient,void,rtsp,unsigned,char,callback,int
来源: https://blog.csdn.net/qianbo042311/article/details/119334116

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有