Closed AndreWicked closed 5 years ago
The ONVIF Core Specification states that the "Device Management" service is the entry point for all other services (refer Core Spec. 5.1.1). Consequently a ONVIF compliant devices returns the URL to its device management endpoint if you run the WS discovery (The URL for the device management service should be fixed to: http://
So the first thing to do after the WS discovery would be to create a new OnvifDeviceClient
instance and provide it with the URL pointing to the device management service (here). The next thing to do would be to set the credentials for authorization (here). From there on you should request all the other service endpoints your ONVIF device supports by calling GetServices()
(here). For every endpoint you may want to instantiate a new client class that matches the service name (like OnvifAnalyticsClient, OnvifRecordingClient, OnvifMediaClient
, ...) and call the ctor with the matching endpoint URL (here). For every service exists a class following the naming scheme Onvif*Client
(* matches service name).
Thank you very much! Your example really helped! I was able to authorize, get streams, but I ran into a problem. How can I transfer the protocol when I receive the uri? My code is:
`auto builder = SoapCtx::Builder();
auto ctx = builder
.SetConnectTimeout(3000)
.Build();
OnvifDeviceClient *device = new OnvifDeviceClient(dev_endpoint, ctx, this);
device->SetAuth(new_user, new_pswd, AUTO);
Request<_tds__GetServices> request;
request.IncludeCapability = false;
auto servicesResponse = device->GetServices(request);
if(servicesResponse) {
for(auto service : servicesResponse.GetResultObject()->Service) {
qDebug() << service->Namespace;
if(service->Namespace == OnvifMediaClient::GetServiceNamespace()) {
OnvifMediaClient *dev_media = new OnvifMediaClient(QUrl(qPrintable(service->XAddr)), ctx, this);
dev_media->SetAuth(new_user, new_pswd, AUTO);
Request<_trt__GetProfiles> request;
auto mediaResponse = dev_media->GetProfiles(request);
if(mediaResponse) {
for(auto profile : mediaResponse.GetResultObject()->Profiles) {
Request<_trt__GetStreamUri> stream_uri_request;
stream_uri_request.ProfileToken = profile->token;
stream_uri_request.StreamSetup->Stream = tt__StreamType(0);
stream_uri_request.StreamSetup->Transport->Protocol = tt__TransportProtocol(0);
auto streamUriResponse = dev_media->GetStreamUri(stream_uri_request);
if (streamUriResponse) {
json json_profile = json::object({{"dev_type", "onvif"}, {"profile_name", profile->Name.toUtf8()}, {"profile_uri", streamUriResponse.GetResultObject()->MediaUri->Uri.toUtf8()}});
json_profilesArray.push_back(json_profile);
qDebug() << streamUriResponse.GetResultObject()->MediaUri->Uri;
}
else {
qDebug() << "stream not given";
}
}
json json_response = {
{"type", "settings"},
{"status", "device_ok"},
{"data", json_profilesArray}
};
std::string response = json_response.dump();
int size = response.size();
_busy = true;
socket->write((const char*) &size, sizeof(int));
socket->write(response.c_str());
socket->waitForBytesWritten();
}
else {
qDebug() << "Couldn't get media properties" << mediaResponse.GetSoapFault();
json json_response = {
{"type", "settings"},
{"status", "device_fail"}
};
std::string response = json_response.dump();
int size = response.size();
_busy = true;
socket->write((const char*) &size, sizeof(int));
socket->write(response.c_str());
socket->waitForBytesWritten();
}
}
}
}`
When you try to transfer the protocol, the program fails. Thank you in advance!
I don't understand. What do you mean by "How can I transfer the protocol" and where exactly does the crash happen?
`Request<_trt__GetStreamUri> stream_uri_request;
stream_uri_request.ProfileToken = profile->token;
stream_uri_request.StreamSetup->Stream = tt__StreamType(0); //This
stream_uri_request.StreamSetup->Transport->Protocol = tt__TransportProtocol(0); // And this
auto streamUriResponse = dev_media->GetStreamUri(stream_uri_request);
if (streamUriResponse) {
json json_profile = json::object({{"dev_type", "onvif"}, {"profile_name", profile->Name.toUtf8()}, {"profile_uri", streamUriResponse.GetResultObject()->MediaUri->Uri.toUtf8()}});
json_profilesArray.push_back(json_profile);
qDebug() << streamUriResponse.GetResultObject()->MediaUri->Uri;
}
else {
qDebug() << "stream not given";
}`
In lines 3 and 4, I want to specify the settings for the stream, obviously I am doing this incorrectly and a failure occurs on these lines.
You have to instantiate the StreamSetup object first:
stream_uri_request.StreamSetup = new tt__StreamSetup();
stream_uri_request.StreamSetup->Stream = tt__StreamType::RTP_Unicast;
stream_uri_request.StreamSetup->Transport = new tt__Transport();
stream_uri_request.StreamSetup->Transport->Protocol = tt__TransportProtocol::UDP;
auto streamUriResponse = dev_media->GetStreamUri(streamUriRequest);
Hello! Thanks for the library!
I managed to use the discovery method, I received a list of uri, but I just can not figure out how to perform the authorization! I am new to onvif, I will be grateful for a small example!