Prerequisites

In order to implement this project you will need some devices and software. Let’s take a look at the prerequisites:

  • Visual Studio installed on your PC: As this project has been written in C#, there is a need for a development interface that supports this programming language. For this purpose Microsoft Visual Studio is recommeneded. (Download the Visual Studio from here.) Please note that .NET Framework 4.0 is also needed, so make sure that it has been also installed with the Visual Studio. (Your ’Target framework’ should be ’.NET Framework 4.0’.)
  • Camera SDK installed on your PC: In this project the prewritten components of Ozeki’s Camera SDK has been used to build the camera discovery feature. It provides instant ONVIF functionality to your IDE to be able to implement webcam / IP camera / ONVIF IP camera solutions easily in C#.NET. (Download the camera SDK from here.) After you have created a new project (a Windows Forms Application) in Visual Studio, you need to add the DLL file provided by the SDK to your references.
  • At least one IP camera: As you could read in the Background section on the HOME tab, camera discovery can only be viable if one or more cameras are connected to the network. So please connect at least one IP camera to your LAN.

(Get more information about the technical background on the HOME tab)

Code explanation in C#

In this documentation three classes will be introduced: Program.cs, From1.cs and Form1.Designer.cs. As a first step, take a look the core of this development. Below you can see the Program.cs class that is the main entry point for the application. The running of the Form will be called here.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;

namespace OnvifIPCameraManager01
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}
}

Code 1: The Program.cs class

Source code analysis

In order to implement the camera discovery functionality there is a need for some statements and methods. Below you can see them:

1. You will see later that a simple ’Discover’ button will be used to start the device discovery. When the user clicks on this button, you need to clear the combobox and the list, then you need to call the DiscoverDevices() method:

_deviceList = new List<DiscoveredDeviceInfo>();
InvokeGuiThread(()=>comboBox_Devices.Items.Clear());
IPCameraFactory.DiscoverDevices();

2. After the previous method has discovered a device, you can handle this event using the DiscoveryCompleted method by adding this device to your list and to your combobox:

_deviceList.Add(e.Device);
InvokeGuiThread(() => comboBox_Devices.Items.Add(e.Device.Name));

3. You need to subscribe to the DiscoveryCompleted event of the IPCamera class by using this command:

IPCameraFactory.DeviceDiscovered += IPCamera_DiscoveryCompleted;

4. And last, but not least, use the following lines to write the address and port number of the selected device to the GUI labels:

var selected = comboBox_Devices.SelectedIndex;
if (selected < 0 || selected > _deviceList.Count-1) return;
label_Host.Text = _deviceList[selected].Host;
label_Port.Text = _deviceList[selected].Port.ToString();

Implementing the ONVIF IP camera discovery feature

After studying the Program.cs and the necessary statements and methods, now take a look at the Form1.cs class (Code 2) that contains all the important functions of the application that are used to implement the device discovery feature:

using System;
using System.Collections.Generic;
using System.Windows.Forms;
using Ozeki.Media.MediaHandlers.IPCamera;
using Ozeki.Media.IPCamera;
using Ozeki.Media.IPCamera.Discovery;
namespace OnvifIPCameraManager01
{
public partial class Form1 : Form
{
private List<DiscoveredDeviceInfo> _deviceList;
public Form1()
{
InitializeComponent();
IPCameraFactory.DeviceDiscovered += IPCamera_DiscoveryCompleted;
}
private void button_Discover_Click(object sender, EventArgs e)
{
_deviceList = new List<DiscoveredDeviceInfo>();
InvokeGuiThread(()=> comboBox_Devices.Items.Clear());
IPCameraFactory.DiscoverDevices();
}
private void IPCamera_DiscoveryCompleted(object sender, DiscoveryEventArgs e)
{
_deviceList.Add(e.Device);
InvokeGuiThread(() => comboBox_Devices.Items.Add(e.Device.Name) );
}
private void comboBox_Devices_SelectedIndexChanged(object sender, EventArgs e)
{
InvokeGuiThread(() =>
{
var selected = comboBox_Devices.SelectedIndex;
if (selected < 0 || selected > _deviceList.Count-1) return;
label_Host.Text = _deviceList[selected].Host;
label_Port.Text = _deviceList[selected].Port.ToString();
});
}
private void InvokeGuiThread(Action action)
{
BeginInvoke(action);
}
}
}

Code 2: The Form1.cs class

Implementing the GUI for the camera discovery application

After you have finished the implementation of the core functionality, let’s continue the development by creating a Graphical User Interface for your application. Below the Form1.Designer.cs can be seen (Code 3), that presents all you need for creating the GUI. If you use this code, the GUI of your application will contain all the important elements such as the ’Discover’ button, the dropdown menu for device listing, etc. 

namespace OnvifIPCameraManager01
{
partial class Form1
{
private System.ComponentModel.IContainer components = null;
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
private void InitializeComponent()
{
this.button_Discover = new System.Windows.Forms.Button();
this.groupBox1 = new System.Windows.Forms.GroupBox();
this.label_Port = new System.Windows.Forms.Label();
this.label_Host = new System.Windows.Forms.Label();
this.label2 = new System.Windows.Forms.Label();
this.label1 = new System.Windows.Forms.Label();
this.comboBox_Devices = new System.Windows.Forms.ComboBox();
this.groupBox1.SuspendLayout();
this.SuspendLayout();
//
// button_Discover
//
this.button_Discover.Location = new System.Drawing.Point(10, 10);
this.button_Discover.Name = "button_Discover";
this.button_Discover.Size = new System.Drawing.Size(75, 25);
this.button_Discover.TabIndex = 4;
this.button_Discover.Text = "Discover";
this.button_Discover.UseVisualStyleBackColor = true;
this.button_Discover.Click += new System.EventHandler(this.button_Discover_Click);
//
// groupBox1
//
this.groupBox1.Controls.Add(this.label_Port);
this.groupBox1.Controls.Add(this.label_Host);
this.groupBox1.Controls.Add(this.label2);
this.groupBox1.Controls.Add(this.label1);
this.groupBox1.Controls.Add(this.comboBox_Devices);
this.groupBox1.Location = new System.Drawing.Point(10, 40);
this.groupBox1.Name = "groupBox1";
this.groupBox1.Size = new System.Drawing.Size(300, 100);
this.groupBox1.TabIndex = 5;
this.groupBox1.TabStop = false;
this.groupBox1.Text = "Device list";
//
// label_Port
//
this.label_Port.AutoSize = true;
this.label_Port.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.label_Port.Location = new System.Drawing.Point(205, 40);
this.label_Port.Name = "label_Port";
this.label_Port.Size = new System.Drawing.Size(2, 15);
this.label_Port.TabIndex = 4;
//
// label_Host
//
this.label_Host.AutoSize = true;
this.label_Host.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.label_Host.Location = new System.Drawing.Point(205, 20);
this.label_Host.Name = "label_Host";
this.label_Host.Size = new System.Drawing.Size(2, 15);
this.label_Host.TabIndex = 3;
//
// label2
//
this.label2.AutoSize = true;
this.label2.Location = new System.Drawing.Point(160, 40);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(29, 13);
this.label2.TabIndex = 2;
this.label2.Text = "Port:";
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(160, 20);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(48, 13);
this.label1.TabIndex = 1;
this.label1.Text = "Address:";
//
// comboBox_Devices
//
this.comboBox_Devices.FormattingEnabled = true;
this.comboBox_Devices.Location = new System.Drawing.Point(20, 20);
this.comboBox_Devices.Name = "comboBox_Devices";
this.comboBox_Devices.Size = new System.Drawing.Size(120, 21);
this.comboBox_Devices.TabIndex = 0;
this.comboBox_Devices.SelectedIndexChanged += new System.EventHandler(this.comboBox_Devices_SelectedIndexChanged);
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(324, 154);
this.Controls.Add(this.groupBox1);
this.Controls.Add(this.button_Discover);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
this.MaximizeBox = false;
this.Name = "Form1";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "Discover Onvif IP cameras";
this.groupBox1.ResumeLayout(false);
this.groupBox1.PerformLayout();
this.ResumeLayout(false);
}
private System.Windows.Forms.Button button_Discover;
private System.Windows.Forms.GroupBox groupBox1;
private System.Windows.Forms.ComboBox comboBox_Devices;
private System.Windows.Forms.Label label_Port;
private System.Windows.Forms.Label label_Host;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.Label label1;
}
}

Code 3: The Form1.Designer.cs class

After you have implemented successfully the Form1.Desginer.cs class, let’s run the application and try out the device discovery functionality. The following figure illustrates the GUI that can be achieved by using the previous code snippet:

The GUI of the C#-based ONVIF IP camera discovery application

Figure 3: The GUI of the C#-based ONVIF IP camera discovery application

Now check out, how it works. You can start to find IP cameras on your local network by clicking on the ’Discover’ button. After pressing it, the program starts to list the available cameras. If you open the drop-down menu in the ’Device list’ section you can see the cameras that has been found by the application (Figure 4):

The camera discovery application lists the available devices

Figure 4: The camera discovery application lists the available devices

Select one of the detected cameras (in this case only one device has been found) by clicking on its IP address. After this, as you can see below, the application displays the preferred camera’s IP address and port number.

The application displays the address and port number of the selected camera

Figure 5: The application displays the address and port number of the selected camera

Now, after finding out the selected camera’s address and port number, you can use them for different kind of network settings. For example, it facilitates to connect to an IP camera with a camera viewer application.

Example for field of use

Need more control over your surveillance system? With this camera SDK (www.camera-sdk.com) it is quite easy to implement further camera solutions such as video viewer (in a desktop application or a webbrowser), PTZ (Pan-Tilt-Zoom) motion control, video recording, video analytics, camera-to-SIP video phone call gateway, etc.

The best way to achieve full control over your security system, if you integrate all the required functionalities into only one application that can be used as a central camera manager software. The Onvif IP Camera Manager offered by Ozeki can be a good example for this (Figure 6).

As you can see on the following figure, for displaying a network camera’s image, first you need to connect a camera to the camera manager application. Concerning that this Onvif IP Camera Manager has built-in device discovery functionality, you can easily add new devices by clicking on the ’Discover’ button (Figure 6). It makes the whole camera connection process faster and easier.

Onvif IP Camera Manager with built-in device discovery functionality

Figure 6: Onvif IP Camera Manager with built-in device discovery functionality

Note: This Onvif IP Camera Manager is a free demo program offered by Ozeki. You can use the application or download and modify its source code freely. The Camera Manager is available on the official website of the developer.

Summary

To sum it up, in this project I have presented how to implement a C# application that can be used to find/discover ONVIF IP cameras on your local network (LAN). If you want to build additional camera solutions to improve your surveillance/security system, you can easily create further more professional features by using Ozeki Camera SDK. The best way to achieve full control over your security system, if you integrate all the required functionalities into only one application that can be used as a central camera manager software.

I hope you found my solution interesting! Good work!

Useful links for more information on this topic

Camera SDK: www.camera-sdk.com
IP Camera Manager: http://www.camera-sdk.com/p_105-exe-demo-for-onvif-ip-camera-manager-onvif.html
ONVIF Specification: http://www.onvif.org/specs/core/ONVIF-Core-Spec-v210.pdf

Reviewed literature

  1. http://www.axis.com/solutions/system/connect_lan.htm
  2. http://www.onvif.org/ 
  3. http://en.wikipedia.org/wiki/Open_Network_Video_Interface_Forum
  4. http://www.onvif.org/specs/core/ONVIF-Core-Spec-v210.pdf
  5. http://en.wikipedia.org/wiki/WS-Discovery
  6. http://www.camera-sdk.com/p_105-exe-demo-for-onvif-ip-camera-manager-onvif.html

Last edited Oct 10, 2014 at 9:00 AM by simonrobert, version 28