视频监控安防平台-onvif协议demo

版权声明:本文为博主原创文章,未经博主允许不得转载。QQ/微信联系:123011785 https://blog.csdn.net/songxiao1988918/article/details/79158928

         视频监控安防平台-onvif协议demo

  最近把onvif设备接入的demo拿出来简单整理了一下,支持的功能有onvif摄像机发现、获取和设置验证状态、获取设备通道数通过通道号获取通道类信息index从0开始、 通过通道号获取设备通道名称、设置和获取设备的uri、PTZ控制、看守卫控制、实时抓拍、订阅报警、获取设备的所能提供的报警类型、时间同步、录像查询、录像点播、获取网络接口配置、设备重启等功能、也简单测试了一下,发现onvif录像查询和录像点播的时候有很大的出入,每个设备貌似格式都不一样,调试时间比较久。下面简单粘贴一下封装的onvif库和onvif的demo代码,欢迎大家一起交流一起探讨

#ifndef __LIBONVIF_H__
#define __LIBONVIF_H__
#include <iostream>
#include <string>
#include <map>
#include <vector>
using namespace std;
#define DEFAULTTIMEOUT	10
namespace sipOnvif{
#define PTZSERVICE			0
#define MEDIASERVICE		1
#define EVENTSSERVICE		2
#define RECORDINGSERVICE	3
#define SEARCHSERVICE		4
#define REPLAYSERVICE		5
#define RECEIVERSERVICE		6
#define MAXSERSIZE			7

typedef enum
{	
	ONVIFEVENT_TYPE_NONE				= -1,
	ONVIFEVENT_TYPE_ALL					= 0,		//所有报警
	ONVIFEVENT_TYPE_VAD_ALARM 			= 1,		//移动侦测
	ONVIFEVENT_TYPE_VIDEO_OCCLUSION,				//视频遮挡
	ONVIFEVENT_TYPE_REGIONAL_INVASION,				//区域入侵报警
	ONVIFEVENT_TYPE_STRANDING,						//徘徊报警
	ONVIFEVENT_TYPE_MIXLINE,						//绊线报警 
	ONVIFEVENT_TYPE_AGAINST_REGULATION,				//违反指定运动规则
	ONVIFEVENT_TYPE_COUNT_LINE,						//过线统计
	ONVIFEVENT_TYPE_QUERY_STREAM_METADA,			//查询流元数据
	ONVIFEVENT_TYPE_RECORDING_STOP,					//录像停止
	ONVIFEVENT_TYPE_RECORDING_DELETE,				//录像删除
	ONVIFEVENT_TYPE_RECORDING_CONFIGURATION_CHANGE,	//录像配置修改

}ONVIF_EVENT_TYPE_CODE;

typedef struct OnvifEventInfo
{
	ONVIF_EVENT_TYPE_CODE type;
	string RecordingToken;
	int channel;
	vector<string> EventContent;
}OnvifEventInfo_t;


typedef enum{
	ONVIFERROR_CODE_UNKNOW = 0,
	ONVIFERROR_VersionMismatch = 1,// SOAP version mismatch
	ONVIFERROR_MustUnderstand,// SOAP header blocks not understood
	ONVIFERROR_DataEncodingUnknown,// Unsupported SOAP data encoding
	
	ONVIFERROR_Sender,
	ONVIFERROR_Receiver,
}Fault_Code_E;	
typedef struct Fault_Code{
	Fault_Code_E faultCode;
	string errorString;

	Fault_Code()
	{
		faultCode = ONVIFERROR_CODE_UNKNOW;
		errorString = "";
	}
	Fault_Code(Fault_Code_E ffaultCode, string ferrorString)
	:faultCode(ffaultCode),errorString(ferrorString)
	{
	}
}Fault_Code_t;
typedef enum{
	ONVIFERROR_PARENT_CODE_UNKNOW = 0,
	//Generic faults
	ONVIFERROR_WellFormed = 1,// Well-formed Error 
	ONVIFERROR_TagMismatch,//There was a tag name ornamespace mismatch.
	ONVIFERROR_Tag,// No Tag XML element tag was missing.
	ONVIFERROR_Namespace,// Namespace Error
	ONVIFERROR_MissingAttr,// Required Attribute not present
	ONVIFERROR_ProhibAttr,// Prohibited Attribute
	ONVIFERROR_InvalidArgs,// Invalid Args
	ONVIFERROR_InvalidArgVal,// Argument Value Invalid
	ONVIFERROR_UnknownAction,// Unknown Action
	ONVIFERROR_OperationProhibited,// Operation not Permitted
	ONVIFERROR_NotAuthorized,// Sender not Authorized
	ONVIFERROR_ActionNotSupported,//Optional Action Not Implemented
	ONVIFERROR_Action,// Action Failed
	ONVIFERROR_OutofMemory,//The device does not have sufficient memory to complete the action.
	ONVIFERROR_CriticalError,//The device has encountered an error condition which it cannot recover by itself and needs reset or power cycle.
}Fault_Code_Parent_Code_E;
typedef struct Fault_Code_Parent_Code{
	Fault_Code_Parent_Code_E ParentCode;
	string errorString;

	Fault_Code_Parent_Code()
	{
		ParentCode = ONVIFERROR_PARENT_CODE_UNKNOW;
		errorString = "";
	}
	Fault_Code_Parent_Code(Fault_Code_Parent_Code_E fParentCode, string ferrorString):ParentCode(fParentCode),errorString(ferrorString)
	{
	}
}Fault_Code_Parent_Code_t;
typedef enum{
	ONVIFERROR_SUBCODE_UNKNOW = 0,//未知错误
	//ONVIFERROR_OK = 0,
	
	// Device service specific fault codes
	ONVIFERROR_EmptyPolicy = 1,//The policy is empty
	ONVIFERROR_EmptyScope,//Scope list is empty.
	ONVIFERROR_FirmwareUpgradeFailed,//The firmware upgrade failed.
	ONVIFERROR_KeyGeneration,//The private/public key generation failed.
	ONVIFERROR_Signature,//Creating a signature failed
	ONVIFERROR_ClientAuth,//Client authentication not supported
	ONVIFERROR_TooManyUsers,//Maximum number of supported users exceeded.
	ONVIFERROR_TooManyScopes,//The scope list exceeds the supported number of scopes.
	ONVIFERROR_NoSuchService,//The service is not supported
	ONVIFERROR_AccesslogUnavailable,//There is no access log information available
	ONVIFERROR_CertificateFormat,//Invalid format
	ONVIFERROR_CertificateID,//Invalid certificate ID 
	ONVIFERROR_CACertificateID,//Invalid CA certificate ID
	ONVIFERROR_InvalidBackupFile,//Invalid file
	ONVIFERROR_InvalidDateTime,//Invalid date and time
	ONVIFERROR_NtpServerUndefined,//NTP server undefined
	ONVIFERROR_InvalidDnsName,//The suggested NTP server name is invalid.
	ONVIFERROR_TimeSyncedToNtp,//Current DateTimeType requires an NTP server.
	ONVIFERROR_InvalidFirmware,//Invalid firmware
	ONVIFERROR_InvalidGatewayAddress,//
	ONVIFERROR_InvalidHostname,//
	ONVIFERROR_InvalidInterfaceSpeed,//
	ONVIFERROR_InvalidInterfaceType,//
	ONVIFERROR_InvalidIPv4Address,//
	ONVIFERROR_NoIPv4Address,//
	ONVIFERROR_InvalidIPv6Address,//
	ONVIFERROR_NoIPv6Address,//
	ONVIFERROR_InvalidMtuValue,//The MTU value is invalid
	ONVIFERROR_InvalidNetworkInterface,//The supplied network interface token does not exists
	ONVIFERROR_InvalidTimeZone,//An invalid time zone was specified.
	ONVIFERROR_IPFilterListIsFull,//
	ONVIFERROR_ModeError,//Monostable delay time not valid.
	ONVIFERROR_PolicyFormat,//The requested policy cannot be set due to unknown policy format.
	ONVIFERROR_RelayToken,//The token reference is unknown.
	ONVIFERROR_ServiceNotSupported,//
	ONVIFERROR_SupportInformationUnavailab,//
	ONVIFERROR_SystemlogUnavailable,//
	ONVIFERROR_UsernameMissing,//
	ONVIFERROR_FixedScope,//
	ONVIFERROR_NoScope,//Trying to Remove scope which does not exist.
	ONVIFERROR_Password,
	ONVIFERROR_PasswordTooLong,
	ONVIFERROR_UsernameTooShort,
	ONVIFERROR_ScopeOverwrite,//
	ONVIFERROR_UsernameClash,
	ONVIFERROR_UsernameTooLong,
	ONVIFERROR_InvalidDot11,
	ONVIFERROR_InvalidSecurityMode,
	ONVIFERROR_InvalidStationMode,
	ONVIFERROR_MissingDot11,
	ONVIFERROR_MissingPSK,
	ONVIFERROR_MissingDot1X,
	ONVIFERROR_IncompatibleDot1X,//
	ONVIFERROR_NotDot11,
	ONVIFERROR_InvalidDot1X,
	ONVIFERROR_NotConnectedDot11,
	ONVIFERROR_NotScanAvailable,
	ONVIFERROR_NotRemoteUser,
	ONVIFERROR_EAPMethodNotSupported,
	ONVIFERROR_MaxDot1X,
	ONVIFERROR_ReferenceToken,
	ONVIFERROR_InvalidCertificate,
	ONVIFERROR_MaxCertificates,//
	ONVIFERROR_PasswordTooWeak,
	ONVIFERROR_AuxiliaryDataNotSupported,
	ONVIFERROR_InvalidTimeOutValue,
	ONVIFERROR_InvalidMode,
	ONVIFERROR_FixedUser,
	ONVIFERROR_AnonymousNotAllowed,
	ONVIFERROR_KeysNotMatching,
	ONVIFERROR_PortAlreadyInUse,
	ONVIFERROR_EnablingTlsFailed,
	ONVIFERROR_InvalidDHCPv6,
	ONVIFERROR_MaximumStorageConfigurations,	
	//device I/O
	ONVIFERROR_NoVideoOutput,
	ONVIFERROR_NoVideoSource,
	ONVIFERROR_NoAudioOutput,
	ONVIFERROR_NoAudioSource,	
	//imag 
	ONVIFERROR_NoImagingForSource,
	ONVIFERROR_SettingsInvalid,
	ONVIFERROR_NoSource,	
	//media
	ONVIFERROR_AudioNotSupported,
	ONVIFERROR_MaxNVTProfiles,
	ONVIFERROR_AudioOutputNotSupported,
	ONVIFERROR_AudioDecodingNotSupported,
	
	//指定媒体文件不包含任何未使用的来源或编码器配置。
	ONVIFERROR_IncompleteConfiguration,	
	
	ONVIFERROR_ProfileExists,
	ONVIFERROR_DeletionOfFixedProfile,
	
	ONVIFERROR_VideoAnalyticsNotSupported,
	//不支持StreamSetup的流类型或传输部分的规范。
	ONVIFERROR_InvalidStreamSetup,
	
	//StreamSetup的流类型或传输部分的规范与其他流冲突
	ONVIFERROR_StreamConflict,
	
	//PTZ
	ONVIFERROR_MovingPTZ,
	ONVIFERROR_TooManyPresets,//达到预设的最大值
	ONVIFERROR_PTZNotSupported, //设备不支持PTZ
	ONVIFERROR_PresetExist,//被要求的名称已存在另一个预设中
	ONVIFERROR_NoStatus,//在媒体文件中没有适合的状态
	ONVIFERROR_ConfigurationConflict,
	ONVIFERROR_CannotOverwriteHome,//归位点是固定的,不能被修改
	ONVIFERROR_NoEntity,
	ONVIFERROR_NoConfig, //被请求的配置不存在
	ONVIFERROR_ConfigModify,
	ONVIFERROR_InvalidPosition,
	ONVIFERROR_InvalidTranslation,
	ONVIFERROR_InvalidSpeed,//要求的速度超出范围
	ONVIFERROR_InvalidVelocity,//请求的速率越界
	ONVIFERROR_InvalidPresetName,//	预设名称过长或包含一个无效的字符
	ONVIFERROR_NoPTZProfile,//	请求的文件标识符不涉及PTZ配置
	ONVIFERROR_NoProfile,//请求的文件标识符ProfileToken不存在
	ONVIFERROR_TimeoutNotSupported,//请求的超时越界
	ONVIFERROR_NoToken,//请求的文件标识符不存在
	ONVIFERROR_NoHomePosition,//请求的文件没有定义中心位置
	ONVIFERROR_SpaceNotSupported,//空间涉及了一个PTZ节点不支持的参数
	ONVIFERROR_Moving,//	预设不能被设定当PTZ装置在移动过程中	
}Fault_Code_Subcode_E;


typedef struct Fault_Code_Subcode{
	Fault_Code_Subcode_E subCode;	
	string errorString;

	Fault_Code_Subcode()
	{
		subCode = ONVIFERROR_SUBCODE_UNKNOW;
		errorString = "";
	}
	Fault_Code_Subcode(Fault_Code_Subcode_E fsubCode, string ferrorString):subCode(fsubCode),errorString(ferrorString)
	{
	}
}Fault_Code_Subcode_t;
class CerrorSet{
public:
	Fault_Code_E faultCode;
	Fault_Code_Parent_Code_E parentCode;
	Fault_Code_Subcode_E subCode;	
	string faultCodeText;
	string subCodeText;
	string errorText;

	CerrorSet()
	{
		faultCode = ONVIFERROR_CODE_UNKNOW;
		parentCode = ONVIFERROR_PARENT_CODE_UNKNOW;
		subCode = ONVIFERROR_SUBCODE_UNKNOW;
		faultCodeText="";
		subCodeText="";
		errorText = "";
	}
	~CerrorSet(){};
};
typedef struct FloatRange
{
	float Min;
	float Max;
}FloatRange_t;

typedef struct PanTiltSpaces
{
	string URIRange;
	string URISpeed;
	FloatRange_t XRange;
	FloatRange_t YRange;
	FloatRange_t Speed;
	PanTiltSpaces()
	{
		URIRange = "";
		URISpeed = "";
		XRange.Min = -1.0;
		XRange.Max = 1.0;
		YRange.Min = -1.0;
		YRange.Max = 1.0;
		Speed.Min = 0.0;
		Speed.Max = 1.0;
	}
}PanTiltSpaces_t;
typedef struct ZoomSpaces
{
	string URIRange;
	string URISpeed;
	FloatRange_t Range;
	FloatRange_t Speed;
	ZoomSpaces()
	{
		URIRange = "";
		URISpeed = "";
		Range.Min = -1.0;
		Range.Max = 1.0;
		Speed.Min = 0.0;
		Speed.Max = 1.0;
	}
}ZoomSpaces_t;


/////////////////////////////////////////////
typedef struct VideoResolution
{
	int Width;	/* required element of type xsd:int */
	int Height;	/* required element of type xsd:int */
	VideoResolution(int fWidth=0, int fHeight=0)
	:Width(fWidth),Height(fHeight)
	{}
}VideoResolution_t;
enum VideoEncoding {VideoEncoding__JPEG = 0, VideoEncoding__MPEG4 = 1, VideoEncoding__H264 = 2, VideoEncoding__UnKnow = 3};
enum Mpeg4Profile {Mpeg4Profile__SP = 0, Mpeg4Profile__ASP = 1,Mpeg4Profile__UnKnow=2};
typedef struct Mpeg4Configuration
{
	int GovLength;
	enum Mpeg4Profile mpeg4Profile;
	Mpeg4Configuration(int fGovLength = 0,
					enum Mpeg4Profile fMpeg4Profile = Mpeg4Profile__UnKnow)
	:GovLength(fGovLength),mpeg4Profile(fMpeg4Profile)
	{}
}Mpeg4Configuration_t;
enum H264Profile {H264Profile__Baseline = 0, H264Profile__Main = 1, H264Profile__Extended = 2, H264Profile__High = 3,H264Profile__UnKnow=4};
typedef struct H264Configuration
{
	int GovLength;
	enum H264Profile H264profile;
	H264Configuration(int fGovLength = 0,
					enum H264Profile fH264Profile=H264Profile__UnKnow)
	:GovLength(fGovLength),H264profile(fH264Profile)
	{}
}H264Configuration_t;
enum IPType {IPType__IPv4 = 0, IPType__IPv6 = 1, IPType__UnKnow = 2};
typedef struct IPAddress
{
	enum IPType Type;
	string IPv4Address;
	string IPv6Address;
	IPAddress(enum IPType fType=IPType__UnKnow,
			string fIPv4Address="",
			string fIPv6Address="")
	:Type(fType),IPv4Address(fIPv4Address),IPv6Address(fIPv6Address)
	{}
}IPAddress_t;
typedef struct MulticastConfiguration
{
	IPAddress_t *Address;
	int Port;
	int TTL;
	bool AutoStart;
	MulticastConfiguration(IPAddress_t *fAddress=NULL,
							int fPort = 0,
							int fTTL = 0,
							bool fAutoStart = false)
	:Address(fAddress),Port(fPort),TTL(fTTL),AutoStart(fAutoStart)
	{	
	}
	MulticastConfiguration()
	{
		if(Address)
		{
			delete Address;
			Address = NULL;
		}
	}
}MulticastConfiguration_t;
typedef struct VideoEncoderConfig
{
	string Name;
	int UseCount;
	string token;
	enum VideoEncoding Encoding;
	VideoResolution_t *Resolution;
	float Quality;
	//struct VideoRateControl *RateControl;
	Mpeg4Configuration_t *MPEG4;
	H264Configuration_t *H264;
	MulticastConfiguration_t *Multicast;
	
	VideoEncoderConfig(string fName = "",
					int fUseCount = 0,
					string ftoken ="",
					enum VideoEncoding fEncoding = VideoEncoding__UnKnow,
					VideoResolution_t *fResolution = NULL,
					float fQuality=0.0,
					Mpeg4Configuration_t *fMPEG4 = NULL,
					H264Configuration_t *fH264 = NULL,
					MulticastConfiguration_t *fMulticast = NULL)
	:Name(fName),UseCount(fUseCount),token(ftoken),Encoding(fEncoding),
	Resolution(fResolution),Quality(fQuality),MPEG4(fMPEG4),H264(fH264),
	Multicast(fMulticast)
	{		
	}
	~VideoEncoderConfig()
	{
		if(Resolution)
		{
			delete Resolution;
			Resolution = NULL;
		}
		if(MPEG4)
		{
			delete MPEG4;
			MPEG4 = NULL;
		}
		if(H264)
		{
			delete H264;
			H264 = NULL;
		}
		if(Multicast)
		{
			delete Multicast;
			Multicast = NULL;
		}
	}
}VideoEncoderConfig_t;

enum AudioEncoding {AudioEncoding__G711 = 0, AudioEncoding__G726 = 1, AudioEncoding__AAC = 2, AudioEncoding__UnKnow = 3};
typedef struct AudioEncoderConfig
{
	string Name;
	int UseCount;
	string token;
	enum AudioEncoding Encoding;
	int Bitrate;
	int SampleRate;
	MulticastConfiguration_t *Multicast;
	
	AudioEncoderConfig(string fName = "",
					int fUseCount = 0,
					string ftoken = "",
					enum AudioEncoding fEncoding = AudioEncoding__UnKnow,
					int fBitrate = 0,
					int fSampleRate = 0,
					MulticastConfiguration_t *fMulticast = NULL)
	:Name(fName),UseCount(fUseCount),token(ftoken),Encoding(fEncoding),
	Bitrate(fBitrate),SampleRate(fSampleRate),Multicast(fMulticast)
	{
	}
	~AudioEncoderConfig()
	{
		if(Multicast)
		{
			delete Multicast;
			Multicast = NULL;
		}
	}
}AudioEncoderConfig_t;
typedef struct SourceConfig
{
	string Name;
	string token;
	string SourceToken;
	SourceConfig():Name(""),token(""),SourceToken("")
	{}
}SourceConfig_t;
class CPTZConfig{
public:
	CPTZConfig()
	{
		PanTiltSpaces = new PanTiltSpaces_t;
		ZoomSpaces = new ZoomSpaces_t;
	}
	~CPTZConfig()
	{
		if(PanTiltSpaces) 
		{
			delete PanTiltSpaces;
			PanTiltSpaces = NULL;
		}
		if(ZoomSpaces){
			delete ZoomSpaces;
			ZoomSpaces = NULL;
		}
	}

	PanTiltSpaces_t *PanTiltSpaces;
	ZoomSpaces_t 	*ZoomSpaces;
};
class CPTZProfileConfig{
public:
	CPTZProfileConfig()
	:Name(""),token(""),NodeToken("")
	{
	}
	~CPTZProfileConfig()
	{

	}
	string Name;
	string token;
	string NodeToken;
};
class CProfile{
public:	
	string Name;
	string token;
	SourceConfig_t		*VSouConfig;
	SourceConfig_t		*ASouConfig;
	VideoEncoderConfig_t *VEncConfig;
	AudioEncoderConfig_t *AEncConfig;
	CPTZProfileConfig	*ptzProfileConfig;
	string rtspUri;
	CProfile()
	:Name(""),token(""),VSouConfig(NULL),ASouConfig(NULL),VEncConfig(NULL),AEncConfig(NULL),ptzProfileConfig(NULL)
	{
		
	}
	~CProfile()
	{
		if(VSouConfig)
		{
			delete VSouConfig;
			VSouConfig = NULL;
		}
		if(ASouConfig)
		{
			delete ASouConfig;
			ASouConfig = NULL;
		}
		if(VEncConfig)
		{
			delete VEncConfig;
			VEncConfig = NULL;
		}
		if(AEncConfig)
		{
			delete AEncConfig;
			AEncConfig = NULL;
		}
		if(ptzProfileConfig)
		{
			delete ptzProfileConfig;
			ptzProfileConfig = NULL;
		}
	}
	enum VideoEncoding getVideEncode(void){
		if(VEncConfig)
		{
			return VEncConfig->Encoding;
		}
		return VideoEncoding__UnKnow;
	};
	int getResolution(int &Width, int &Height)
	{
		if(VEncConfig && VEncConfig->Resolution)
		{
			Width = VEncConfig->Resolution->Width;
			Height = VEncConfig->Resolution->Height;
			return 0;
		}
		return -1;
	}
	string GetrtspUri(){return rtspUri;};
	
	friend bool operator==(CProfile& c1, CProfile& c2){
		if(c1.Name == c2.Name && c1.token == c2.token)
			return true;
		return false;
	};
	friend bool operator!=(CProfile& c1, CProfile& c2)
	{
		if(c1 == c2)
			return false;
		return true;
	};
};
class CMediaConfig{
public:		
	CMediaConfig()
	:RTPMulticast(false),RTP_TCP(false),RTP_RTSP_TCP(false)
	{
	}
	~CMediaConfig()
	{
	}
	bool RTPMulticast;
	bool RTP_TCP;
	bool RTP_RTSP_TCP;
};
class CTimePair{
public:		
	CTimePair(time_t fstart, time_t fend)
	:start(fstart), end(fend)
	{
	}
	~CTimePair()
	{
	}
	void setTimePair(time_t fstart, time_t fend){
		start = fstart , end = fend;
	};
	void getTimePair(time_t &fstart, time_t &fend){
		fstart = start , fend = end;
	};
	//Transformation time from utc to cst
	void toCSTtime_str(string &fstart, string &fend);
private:
	time_t start;
	time_t end;
};
typedef enum{
	RecordingEventType_start,
	RecordingEventType_end,
}ERecordingEventType;

class CRecordingEvent{
public:		
	CRecordingEvent(ERecordingEventType ftype, time_t feventTime)
	:type(ftype), eventTime(feventTime){};
	~CRecordingEvent(){};
	
	ERecordingEventType type;
	time_t eventTime;
	
};
class CRecording{
public:		
	CRecording();
	~CRecording();
	
	void cleanRecordingEvent(void);
	void deleteRecordingEvent(void);
	void printfRecordingEvent(void);
	int createTimeList(time_t seconds, vector<CTimePair *> *timeList);
	
	string token;
	string rtspURI;
	
	vector<CRecordingEvent *> *recordEventList;
	
	int source_i;
	string ProfileSources;
	time_t EarliestRecording;
	time_t LatestRecording;
	
	string TrackToken_video;
	time_t DataFrom_video;
	time_t DataTo_video;
};
class CVideoSources{
public:
	CVideoSources():token(""),Framerate(0.0),ptzConfig(NULL),mediaConfig(NULL)
	{	
		profiles = new vector<CProfile *>;
	}
	~CVideoSources()
	{
		if(profiles)
		{
			deleteProfiles();
			delete profiles;
		}
		if(ptzConfig)
		{
			delete ptzConfig;
			ptzConfig = NULL;
		}
	}
	friend bool operator==(CVideoSources& c1, CVideoSources& c2);
	friend bool operator!=(CVideoSources& c1, CVideoSources& c2)
	{
		if(c1 == c2)
			return false;
		return true;
	};
	void deleteProfiles(void);
	int instertProfile(CProfile* profile);
	vector<string> * split(const string &str, const string &sep);
	CProfile* findProfile(string name = "", string flag = "");
	
	string token;
	float Framerate;
	VideoResolution_t Resolution;

	vector<CProfile *> *profiles;
	
	CPTZConfig *ptzConfig;
	CMediaConfig *mediaConfig;
};
/////////////////////////


class Services{
public:
	Services(string fXAddr = "")
	:XAddr(fXAddr)
	{}
	
	~Services()
	{
	}
	string addrMap(string addr);
	string XAddr;
};
#define MediaType_RTPMULTICAST		1
#define MediaType_RTP_TCP			2
#define MediaType_RTP_RTSP_TCP		4

typedef struct DeviceInformation
{
	string Manufacturer;	//厂家
	string Model;	//模型
	string FirmwareVersion;	//固件版本
	string SerialNumber;	//串号
	string HardwareId;	//硬件id
}DeviceInformation_t;
typedef struct Authentication
{
	string userName;
	string passwd;
}Authentication_t;
typedef struct PTZPreset
{
	string Name;
	string token;
}PTZPreset_t;
typedef enum{
	PTZ__MoveStatus__IDLE = 0, 
	PTZ__MoveStatus__MOVING = 1, 
	PTZ__MoveStatus__UNKNOWN = 2
}PTZ__MoveStatus_E;
typedef struct PTZStatus
{
	PTZ__MoveStatus_E PanTilt;
	PTZ__MoveStatus_E Zoom;
}PTZStatus_t;
typedef struct PTZPresets
{
	int size;
	PTZPreset_t *Presets;
	
	PTZPresets()
	{
		size = 0;
		Presets = NULL;
	}
	~PTZPresets()
	{
		size = 0;
		if(Presets)
		{
			delete [] Presets;
			Presets = NULL;
		}
	}
}PTZPresets_t;
class ConvifDev{
public:
	/*fXAddrs: for example http://192.168.12.174:81/onvif/device_service
	or http://192.168.12.122/onvif/device_service
	if not appoint port,default is 80. 
	path is not always "/onvif/device_service"
	*/
	ConvifDev(string fip, string fXAddrs,string fuuid="", string user="", string passwd="")
	:isOnline(true),AuthStatus(false),XAddrs(fXAddrs),uuid(fuuid),auth(NULL),ip(fip),devInfo(NULL),sizeVideoSources(0),videoSources(NULL),sizeRecord(0),records(NULL),MetadataSearch(false)
	,GeneralStartEvents(false){
		if(user != "" || passwd != "")
		{
			auth = new Authentication_t;
			if(auth != NULL){
				auth->userName = user;
				auth->passwd = passwd;
			}
		}
	};
	~ConvifDev()
	{
		clearDevInfo();
	};
	friend ostream& operator<<(ostream& out, const ConvifDev& s);
	friend bool operator==(ConvifDev& c1, ConvifDev& c2);
	//friend bool operator===(ConvifDev& c1, ConvifDev& c2);
	friend bool operator!=(ConvifDev& c1, ConvifDev& c2)
	{
		if(c1 == c2)
			return false;
		return true;
	};
	void deleteVideoSources(void);
	void deleteRecord(void);
	void clearDevInfo(void);
	void setOnlineStatus(bool flag){isOnline = flag;};
	bool GetOnlineStatus(){return isOnline;};
	//获取和设置验证状态
	void setAuthStatus(bool flag){AuthStatus = flag;};
	bool GetAuthStatus(){return AuthStatus;};
	
	//为实现其它功能获取设备的一些相关信息
	int Prepare(CerrorSet &error);
	
	//about username and passwd for authentication
	int setAuthentication(string user, string passwd);
	int getAuthentication(string &user, string &passwd) const;
	
	CVideoSources * findVideoSource(string videoSourceName = "");
	int httpGet(const char *uri);
	string Ip()const{return ip;};
	//获取设备通道数
	int ChannelSize(){return sizeVideoSources;};
	//通过通道号获取通道类信息index从0开始
	CVideoSources *Channels(int index){return videoSources + index;};
	//通过通道号获取设备通道名称。
	string getVideoname(int index, CerrorSet & error);
	//设置和获取设备的uri
	void SetXAddrs(string strXAddrs){XAddrs = strXAddrs;};
	string GetXAddrs(){return XAddrs;};
	
	string Getuuid(){return uuid;};
	//获取设备所有通道的rtsp地址
	int GetStreamUri_all(CerrorSet &error);
	
	//设备信息
	int GetDeviceInformation(DeviceInformation_t &fdevInfo, CerrorSet &error);
	
	//about continueMove operation
	int ContinuousMoveLeft(FloatRange_t range, float speed, CerrorSet &error, string videoname = "");
	int ContinuousMoveLeftUp(FloatRange_t range, float speed, CerrorSet &error, string videoname = "");
	int ContinuousMoveLeftDown(FloatRange_t range, float speed, CerrorSet &error, string videoname = "");
	int ContinuousMoveRight(FloatRange_t range, float speed, CerrorSet &error,  string videoname = "");
	int ContinuousMoveRightUp(FloatRange_t range, float speed, CerrorSet &error, string videoname = "");
	int ContinuousMoveRightDown(FloatRange_t range, float speed, CerrorSet &error,string videoname = "");
	int ContinuousMoveUp(FloatRange_t range, float speed, CerrorSet &error,string videoname = "");
	int ContinuousMoveDown(FloatRange_t range, float speed, CerrorSet &error,string videoname = "");
	int ContinuousMoveStop(CerrorSet &error, string videoname = "");
	int ContinuousMoveZoomNear(FloatRange_t range, float speed, CerrorSet &error, string videoname = "");
	int ContinuousMoveZoomFar(FloatRange_t range, float speed, CerrorSet &error, string videoname = "");
	int ContinuousMoveZoomStop(CerrorSet &error, string videoname = "");
	
	//To stop all kinds of PanTilt move
	int PTZPanTiltStop(CerrorSet &error, string videoname = "");
	//To stop all kinds of Zoom move
	int PTZZoomStop(CerrorSet &error, string videoname = "");
	//To stop all kinds of move, include PanTilt and Zoom
	int PTZAllStop(CerrorSet &error, string videoname = "");
	//获取ptz状态
	int PTZGetStatus(PTZStatus_t & status, CerrorSet &error, string videoname = "");
	//预置位操作
	int SetPreset(PTZPresets_t &presets, int index, CerrorSet &error,string videoname = "");
	int GetPresets(PTZPresets_t &presets, CerrorSet &error, string videoname = "");
	int GotoPreset(PTZPresets_t &presets, int index, CerrorSet &error,string videoname = "");
	int RemovePreset(PTZPresets_t &presets, int index, CerrorSet &error, string videoname = "");
	//看首位操作
	int SetHomePosition(CerrorSet &error,string videoname = "");
	int GotoHomePosition(CerrorSet &error,string videoname = "");
	
	//获取预览的rtsp地址
	int GetStreamUri(string &rtspUri, CerrorSet &error, string profilename = "", string videoname = "");
	//获取抓拍的uri。
	int GetSnapshotUri(string &Uri, CerrorSet &error, string videoname = "");
	//查询设备的功能
	int GetCapabilities(CerrorSet &error);
	//用于保活
	int GetCapabilities();
	int GetServiceCapabilities_ptz(CerrorSet &error);
	int GetServiceCapabilities_recording(CerrorSet &error);
	int GetServiceCapabilities_replay(CerrorSet &error);
	int GetServiceCapabilities_Receiver(CerrorSet &error);
	int GetServiceCapabilities_Event(CerrorSet &error);
	int GetServiceCapabilities_Search(CerrorSet &error);
	int GetServiceCapabilities_media(CerrorSet &error);
	
	int GetVideoSources(CerrorSet &error);
	
	int PTZPrepare(CerrorSet &error);
	int PTZPrepare(FloatRange_t range, float speed, CerrorSet &error);

	//报警相关函数
	//获取设备的所能提供的报警类型
	int GetEventProperties(CerrorSet &error);
	//订阅报警
	int Subscribe(CerrorSet &error, string InitialTerminationTime, char * MyLocalIp, int ListenPort);
	//设置同步点
	int SetSynchronizationPoint(CerrorSet &error);
	//订阅报警(轮询方式)
	int CreatePullPointSubscription(CerrorSet &error, string TerminationTime);
	//接收报警信息(轮询方式)
	int PullMessages(CerrorSet &error, unsigned long long TimeOut, vector<string> &messages);
	//延长订阅时间
	int Renew(CerrorSet &error, unsigned long seconds);
	//取消订阅
	int Unsubscribe(CerrorSet &error);
	//得到设备的系统时间
	int GetSystemDateAndTime(CerrorSet &error);
	//将服务器的时间与设备的时间进行同步
	int SetSystemDateAndTime(CerrorSet &error);
	//得到报警源的通道号
	void GetEventSourceChannel(vector<OnvifEventInfo_t> &EventInfo);
	
	//查询录像在一个时间范围内的时间对列表,seconds表示容错时间 
	/*return
	0 success
	-1 error
	-2 设备不支持按时间查询
	*/
	int QueryRecordTimePair(CerrorSet &error, 
					string starttime, string endtime,
					vector<class CTimePair*> *timeList,
					time_t seconds = 0,//Record allowable interval time
					string videoSourceName = "");
	//获取录像回放的rtsp地址
	int GetReplayUri(CerrorSet &error, string &rtspuri, string videoSourceName = "");
private:
	int findRecordFormVideoSource(CerrorSet &error,string videoSourceName, int &recordIndex, int &videoIndex);
	int FindEvents(CerrorSet &error, int index, time_t start, time_t end);
	int GetEventSearchResults(CerrorSet &error, char *SearchToken, int index, int timeout);
	int GetRecordings(CerrorSet &error);
	int findRecordSource(string ProfileSources);
	int GetReplayUri(CerrorSet &error, char *RecordingToken, string &rtspuri);
	int GetRecordingOptions(CerrorSet &error, char *RecordingToken, string &sourceProfile);
	int GetRecordingInformation(CerrorSet &error, int index);
	int Prepare_Recordings(CerrorSet &error);
	int Prepare_media(CerrorSet &error);
	
	int GetServices(CerrorSet &error);
	int ContinuousMovePanTilt(float panTiltX, float panTilty, CerrorSet &error, CVideoSources * videoSource);
	//int PTZPrepare(FloatRange_t range, float speed, CerrorSet &error);
	int PTZStop(string what, CerrorSet &error, string videoname = "");
	int ContinuousMoveZoom(float ZoomX, CerrorSet &error, CVideoSources * videoSource);
	
	int GetStreamUriPrepare(CerrorSet &error, string videoname = "");

	int GetConfigurations_PTZ(CerrorSet &error);
	int GetConfigurationOptions_PTZ(CerrorSet &error, string token, CVideoSources *videoSources);
	//获取媒体文件
	int GetProfiles(CerrorSet &error);	
	
	//获取网络接口配置
	int GetNetworkInterfaces();
	//获取网络协议
	int GetNetworkProtocols();
	//获取默认的网关
	int GetNetworkDefaultGateway();
	//获取0配置
	int GetZeroConfiguration();
	//获取IP地址过滤
	int GetIPAddressFilter();
	//获取用户
	int GetUsers(CerrorSet &error);
	
	//获取WSDL的URL
	int GetWsdlUrl(CerrorSet &error);
	//系统重启
	int SystemReboot(CerrorSet &error);	
	
private:
	bool isOnline;
	bool AuthStatus;
	string XAddrs;
	string uuid;
	string ManagerAddress;
	
	Authentication_t *auth;
	
	string ip;
	DeviceInformation_t* devInfo;

	int sizeVideoSources;
	CVideoSources *videoSources;
	Services services[MAXSERSIZE];
	
	int sizeRecord;
	CRecording *records;
	bool MetadataSearch;
	bool GeneralStartEvents;

};

class ConvifCtl{
public:
	ConvifCtl();
	~ConvifCtl();
	
	//录像回放功能查询回来的时间对列表处理函数
	void cleanTimeList(vector<class CTimePair*> *timeList);
	void deleteTimeList(vector<class CTimePair*> **timeList);
	void printfTimeList(vector<CTimePair *> *timeList);
	
	//自动发现
	int Discovery(map<string, class ConvifDev*> *devList, CerrorSet &error, int timeout);
	//为实现其它功能,自动向设备获取相关信息,输入参数是一个设备列表
	int Prepare_ALL(vector<class ConvifDev*> *devList);
	//先检查是否列表中已经有此设备,没有再添加。
	void mix(vector<class ConvifDev*> *desList, map<string, class ConvifDev*> *srcList);
	void insertDevList(string ip, class ConvifDev* dev, 
							map<string, class ConvifDev*> *devList);
	void deleteDevList(map<string, class ConvifDev*> *devList);
	void deleteDevList_1(vector<class ConvifDev*> *devList);
	ConvifDev* findDevList(vector<class ConvifDev*> *devList, string ip, vector<class ConvifDev*>::iterator &it);
	void printDevList(map<string, class ConvifDev*> *devList);

	//报警相关
	//初始化接收报警信息的端口(起监听)
	int InitNotifyNetInterface(void **msoap, char *MyIP, int ListenPort);
	//销毁接收报警消息的端口(停监听)
	void DestoryNotifyNetInterface(void *msoap);
	//接收报警消息
	int GetNotify(CerrorSet &error, void *msoap, string &DevIpaddr, vector<OnvifEventInfo_t> &EventInfo);
private:
	int Discovery_1(map<string, class ConvifDev*> *devList,
					CerrorSet &error,
				   int timeout);

};

}
#endif
onvif测试demo代码:

#include <iostream>
#include <string>
#include <map>
#include <libOnvif.h>

using namespace std;
using namespace sipOnvif;
typedef struct 
{
	string ip;
	string user;
	string passwd;
}User_t;
User_t users[] = {
	{"192.168.1.65", "admin", "hik123456"},
	{"192.168.1.63", "admin", "admin123"},
};
int main(int argc, char *argv[])
{
	int ret = 0;
	CerrorSet error;
	ConvifCtl onvifCtl;
	map<string, class ConvifDev*> *devList = NULL;
	devList = new map<string, class ConvifDev*>;
	onvifCtl.Discovery(devList, error, 1);	
	onvifCtl.printDevList(devList);
	
	map<string, class ConvifDev*>::iterator it;
	class ConvifDev* dev = NULL;
	int i = 0; 
	for(i = 0; i < (int)sizeof(users) / (int)sizeof(User_t); i++)
	{
		it = devList->find(users[i].ip);
		if(it!=devList->end())
		{
			dev = it->second;
			dev->setAuthentication(users[i].user ,users[i].passwd);
			it->second = dev;
		}
	}
	DeviceInformation_t fdevInfo;
	string rtspUri;
	
	FloatRange_t range = {0.0, 255.0};
	PTZPresets_t presets;
	
	vector<class CTimePair*> *timeList = new vector<class CTimePair*>;
	it = devList->find("192.168.1.65");
	if(it!=devList->end())
	{
		dev = it->second;
		// ret = dev->GetSnapshotUri(rtspUri,error);
		// if(!ret)
			// cout << rtspUri << endl;
		// dev->httpGet(rtspUri.c_str());
		
		dev->QueryRecordTimePair(error, "2018-01-25T00:00:00", "2017-01-25T10:00:04", timeList, 5, dev->getVideoname(1, error));
		ret = dev->GetReplayUri(error, rtspUri, dev->getVideoname(1, error));
		if(!ret)
			cout << rtspUri << endl;
		dev->GetStreamUri_all(error);
		ret = dev->GetStreamUri(rtspUri,error);
		if(!ret)
			cout << rtspUri << endl;
		
		dev->GetPresets(presets,error);
		for(i = 0; i < presets.size; i++)
		{
			cout << presets.Presets[i].Name << endl;
			cout << presets.Presets[i].token << endl;
		}
		// cout << "Left" << endl;
		dev->ContinuousMoveLeft(range, 80,error);
		// sleep(2);
		dev->PTZAllStop(error);
		// sleep(1);
		
		// cout << "LeftUp" << endl;
		dev->ContinuousMoveLeftUp(range, 80,error);
		// sleep(2);
		dev->PTZAllStop(error);
		// sleep(1);
		presets.size = 0;
		if(presets.Presets){
			delete [] presets.Presets;
			presets.Presets = NULL;
		}
		dev->SetPreset(presets, 0, error);
		
		
		dev->GetPresets(presets,error);
		for(i = 0; i < presets.size; i++)
		{
			cout << presets.Presets[i].Name << endl;
			cout << presets.Presets[i].token << endl;
			
			//dev->RemovePreset(presets, i);
		}

		// dev->GetPresets(presets);
		// for(i = 0; i < presets.size; i++)
		// {
			// cout << presets.Presets[i].Name << endl;
			// cout << presets.Presets[i].token << endl;			
		// }
		
		
		// cout << "LeftDown" << endl;
		dev->ContinuousMoveLeftDown(range, 80,error);
		// sleep(2);
		dev->PTZAllStop(error);
		// sleep(1);
		
		
		// cout << "Right" << endl;
		dev->ContinuousMoveRight(range, 80,error);
		// sleep(2);
		dev->PTZAllStop(error);
		// sleep(1);
		
		presets.Presets[0].Name = "test";
		dev->SetPreset(presets, 0,error);
		
		// cout << "RightUp" << endl;
		dev->ContinuousMoveRightUp(range, 80,error);
		// sleep(2);
		dev->PTZAllStop(error);
		// sleep(1);
		
		dev->GotoPreset(presets, 0,error);
		
		// cout << "RightDown" << endl;
		dev->ContinuousMoveRightDown(range, 80,error);
		// sleep(2);
		dev->PTZAllStop(error);
		// sleep(1);
		
		// cout << "Up" << endl;
		dev->ContinuousMoveUp(range, 80,error);
		// sleep(2);
		dev->PTZAllStop(error);
		// sleep(1);
		
		// cout << "Down" << endl;
		dev->ContinuousMoveDown(range, 80,error);
		// sleep(2);
		dev->PTZAllStop(error);
		// sleep(1);
		
		// cout << "ZoomNear" << endl;
		dev->ContinuousMoveZoomNear(range, 80,error);
		// sleep(2);
		dev->ContinuousMoveZoomStop(error);
		// sleep(1);
		
		// cout << "ZoomFar" << endl;
		dev->ContinuousMoveZoomFar(range, 80,error);
		// sleep(2);
		dev->ContinuousMoveZoomStop(error);
		// sleep(1);

		it->second = dev;
	}
	return 0;
}





猜你喜欢

转载自blog.csdn.net/songxiao1988918/article/details/79158928