Pinte Dani
Pinte Dani

Reputation: 2049

ONVIF api capture image in C#

I have an ONVIF ip camera.

I want to to capture an image from the camera so that I can process that image and save it to the file system.

I found out that there is an onvif api which provides a method GetSnapshotUri which should provide me with an image snapshot:

http://www.onvif.org/onvif/ver10/media/wsdl/media.wsdl

I managed to import this api in visual studio by adding a service reference to it:

enter image description here

How do I construct a client to call GetSnapshotUri from this service?

Upvotes: 1

Views: 21547

Answers (4)

Ali
Ali

Reputation: 1551

For me basic authentication didn't work. The following code works for me and downloads the image:

string username = "username";
string password = "password";
string cameraIP = "";
var messageElement = new TextMessageEncodingBindingElement()
{
    MessageVersion = MessageVersion.CreateVersion(
      EnvelopeVersion.Soap12, AddressingVersion.None)
};
HttpTransportBindingElement httpBinding = new HttpTransportBindingElement()
{
    AuthenticationScheme = AuthenticationSchemes.Digest
};
CustomBinding bind = new CustomBinding(messageElement, httpBinding);
MediaClient mediaClient = new MediaClient(bind, new EndpointAddress($"http://{cameraIP}/onvif/device_service"));
mediaClient.ClientCredentials.HttpDigest.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation;
mediaClient.ClientCredentials.HttpDigest.ClientCredential.UserName = username;
mediaClient.ClientCredentials.HttpDigest.ClientCredential.Password = password;
Profile[] profiles = mediaClient.GetProfiles();
string profileToken = profiles[0].token;
MediaUri mediaUri = mediaClient.GetSnapshotUri(profileToken);
WebClient webCl = new WebClient()
{
    Credentials = new NetworkCredential(username, password)
};
webCl.DownloadFile(mediaUri.Uri, @"D:\test.jpg");

Upvotes: 1

Naveen Verma
Naveen Verma

Reputation: 387

I am using onvif device manager dll here. To implement this method camera's IP, username and password must be known.

// Onvif ODM
using onvif.services;
using odm.core;
using onvif.utils;
using utils;
public string GetSnapshotUrl()
{
  try
        {
            string camera_ip = "http://" + camIp + "/onvif/device_service";
            Uri Camuri = new Uri(camera_ip);
            NvtSessionFactory sessionFactory = new NvtSessionFactory(account);
            INvtSession session = sessionFactory.CreateSession(Camuri);
            Profile[] Profiles = session.GetProfiles().RunSynchronously();
            var snapshotlink = session.GetSnapshotUri(Profiles[0].token).RunSynchronously(); // taking snapshot on the first profile of the camera
            return snapshotlink.uri;
        }
        catch (Exception ex)
        {
            return null;
        }
    }

Upvotes: 1

Pinte Dani
Pinte Dani

Reputation: 2049

So, after lots of searching I managed to capture an image from the camera.

The first Problem was that I have used "Add Service Reference->Advanced->Add Web reference" instead of typing the service address directly in the "Add Service Reference" box.

Here, I added the address: http://www.onvif.org/onvif/ver10/media/wsdl/media.wsdl

Then I could use the MediaClient class, correctly pointed out by pepOS in a comment, and the final code looks like:

var messageElement = new TextMessageEncodingBindingElement();
messageElement.MessageVersion = MessageVersion.CreateVersion(EnvelopeVersion.Soap12, AddressingVersion.None);
HttpTransportBindingElement httpBinding = new HttpTransportBindingElement();
httpBinding.AuthenticationScheme = AuthenticationSchemes.Basic;
CustomBinding bind = new CustomBinding(messageElement, httpBinding);
EndpointAddress mediaAddress = new EndpointAddress("http://192.168.1.168:10001/onvif/Media");
MediaClient mediaClient = new MediaClient(bind, mediaAddress);
mediaClient.ClientCredentials.UserName.UserName = "admin";
mediaClient.ClientCredentials.UserName.Password = "admin";
Profile[] profiles = mediaClient.GetProfiles();
string profileToken = profiles[1].token;
MediaUri mediaUri = mediaClient.GetSnapshotUri(profileToken);

The uri of the image could then be fount at the MediaUri.Uriaddress

Upvotes: 7

Simon Bagley
Simon Bagley

Reputation: 320

The GetSnapshotUri returns a uri for downloading an image using HTTP get. So in theory you just need to call this function, and use the returned uri in the function shown in this Stackoverflow article: https://stackoverflow.com/a/3615831/4815603

Upvotes: 1

Related Questions