视频监控安防平台-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;
}