1

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?

Pinte Dani
  • 1,989
  • 3
  • 28
  • 35

4 Answers4

6

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

Pinte Dani
  • 1,989
  • 3
  • 28
  • 35
  • 2
    This is the same way as I did it and it worked well. In my project I stuck at point where I needed to save this stream to a file simultaneously with showing it on the screen for more than 2 cameras. I used VLC .NET ActiveX plugin, which worked very unstable and I didn't find any other serious (and free) plugin to do that. In my opinion is much better to use original API rather than buying very expensive Ozeki SDK - but you need to solve the problem with embedding a player into your app. – Paweł Wojtal Sep 30 '15 at 06:36
1

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

Community
  • 1
  • 1
Simon Bagley
  • 318
  • 2
  • 15
0

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;
        }
    }
Naveen Verma
  • 367
  • 1
  • 5
  • 18
0

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");
Ali
  • 1,451
  • 1
  • 15
  • 19