Introduction: DIY Camera Streaming Tutorial for the Easter Holiday: How to Stream the Image of Your Surveillance Camera to Remote Places (C# Source Code)

This article is intended to open your eyes to the significance of surveillance systems – especially in the times of national holidays – and it presents how to view the image of your security cameras on remote computers and mobile devices by using your C# WPF application.

The idea of writing this tutorial came into my mind apropos of my previous article (’How to stream the solar eclipse to a website with a USB webcam (C# source code) - 20th March, 2015’) in which I discovered the world of camera programming. It opens the door to so much security developments…

Before the Easter Holiday season, it occured to me that: ’How to monitor what happens in the office during these days?’ In addition to the Easter Holiday there are many cases when remote access to your cameras is needed: for instance if you are out of the office, you are on Holiday or it is weekend. On this basis, in my article I inteded to show and explain a code example that can be used to implement RTSP camera streaming to be able view the image of your surveillance cameras if you are out of the office.

Introduction to Easter

Easter is a Christian festival and holiday celebrating the resurrection of Jesus Christ. The date of Easter is not fixed in relation to the civil calendar. It adjusts to the first Sunday after the full moon following the March equinox. Therefore the date of Easter varies from 22 March to 25 April. (Eastern Christianity bases its calculations on the Julian calendar, whose 21 March corresponds, during the 21st century, to 3 April in the Gregorian calendar, and in which therefore the celebration of Easter varies between 4 April and 8 May.) In 2015 the spring full moon will be on 4 April, therefore the astronomical Easter (that is the first Sunday after the astronomical full moon) will be on 5 April. (Accordingly: Gregorian Easter will be on 5 April; Julian Easter will be on 12 April; Jewish Passover will be on 4 April.)

In countries where Christianity is a state religion, or where the country has large Christian population, Easter is often a public holiday. As Easter is always a Sunday, many countries in the world also have Easter Monday as a public holiday. Good Friday, which occurs two days before Easter Sunday, is also a public holiday in many countries. Even in states where Good Friday is not a holiday, many financial institutions, stock markets, and public schools are closed. Few banks that are normally open on regular Sundays are closed on Easter. Some retail stores, shopping malls, and restaurants are closed on Easter. These days are a holiday for most workers except some shopping malls which usually keep open for a half-day. Many businesses give their employees almost a week off, called Easter break.

Easter eggs are a popular cultural symbol of Easter. These are specially decorated eggs given out to celebrate the Easter holiday. The oldest tradition is to use dyed and painted chicken eggs, but a modern custom is to substitute eggs made from chocolate, or plastic eggs filled with candy such as jellybeans.

Security measures during the Easter Holiday

Apart from the fact that the celebration of Easter varies country by country, it is commonly true that increased security measures are required during the bigger national holidays (not just in the time of Easter, but during other festivals as well). During this period there is often an increase in petty crime. Pickpocketing, purse snatching, and thefts of cell phones and cameras occurrence commonly and difficult to detect in crowds. In addition, home or office break-ins are also common because empty homes or even offices seem easy targets. For all people and companies who plan to travel over the Easter weekend it is advised to take the necessary precautions to reduce the risks of burglary.

Naturally, the necessity of precautions also varies country by country (and there can be differences on this point within a country or even a city). The intension of precaution depends of many things (including financial circumstances, the value of the defended area, localization, etc.). Anyway, surveillance cameras are a great way to provide security for your home or workplace. As well as providing you with video footage of any events which may happen, they also act as a visible deterrent to criminals.

On this basis, I would like to help those who have at least one security camera to bring more out of their surveillance system. The following explanation can be also useful for anybody interested in surveillance systems because this solution can be tried out by using simple USB webcams and IP cameras as well.

The rest of the article contains a detailed C# code explanation on how to create a WPF application. This software will be a simple camera viewer that allows you to monitor the area that is under video surveillance even remotely due to the RTSP streaming functionality.

References, useful links and prerequisites

Step 1: Implementation of Remote Camera Streaming in C# - MainWindow.xaml (GUI)

Do not waste our time, let’s have a go! After you have successfully installed MS Visual Studio, MS .NET Framework and the C# Onvif library, let's create a new WPF project in Visual Studio. Thereafter, add the necessary ONVIF components to your references.

Let’s start by building the GUI. The attached figure illustrates how this application will look like… and the corresponding C# code can be also seen (MainWindow.xaml). For better understanding, let’s take a closer look at its content:

  • To be able to handle the application there is a need for 2 groupboxes (one for connecting to an USB camera and an other one to connect to an IP camera).
  • Since the USB webcams are usually a simple ’plug-and-play’ devices, the groupbox of the USB camera contains only two buttons (one for connecting to the camera, and an other one for disconnecting).
  • In contrast, an IP camera should be connected to your IT network, so in its groupbox some additional network configurations are needed. Therefore, in addition to the connect and disconnect buttons, in this section there is a need for 3 textboxes (Host, Username, Password) for network authentication purposes.
  • To be able to display the image of the preferred camera, you also need to create a camera viewer panel within the CameraBox.
  • And finally, one more groupbox is needed for starting and finishing the RTSP streaming. This groupbox contains 2 texboxes (Address, Port) to be able to specify the listening address, and it also contains 2 buttons to start and stop the camera streaming.

Step 2: Implementation of Remote Camera Streaming in C# - MainWindow.xaml.cs (1)

Having done the GUI elements, let’s move on to the MainWindow.xaml.cs file. After inserting the necessary using lines, there is a need for some variables to be able to handle the application. In the constructor you need to initialize the MediaConnector and the BitmapSourceProvider. Thereafter you need to create and set the camera viewer control and add it to the grid called Camerabox. You also need to set the BitmapSourceProvider instance to the video viewer control.

After this, two regions come in the code: the content of the first one is used to connect and disconnect an USB camera, and the other one is used to implement the IP camera connection and disconnection.

All the necessary methods and the corresponding event handlers can be seen below in the code snippet. The rest of the code snippet (after the connection/disconnection methods) will be demonstrated in Step 4. (The attached example project contains the full source code including the GUI elements as well. Feel free to use and modify the attached sample program.)

<p>using System;<br>using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Ozeki.Media.IPCamera;
using Ozeki.Media.MediaHandlers;
using Ozeki.Media.MediaHandlers.Video;
using Ozeki.Media.MJPEGStreaming;
using Ozeki.Media.Video.Controls;</p><p>namespace Basic_CameraViewer
{
    /// 
</p>
    /// Interaction logic for MainWindow.xaml
    /// <p>    public partial class MainWindow : Window
    {
        private VideoViewerWPF _videoViewerWpf;</p><p>        private BitmapSourceProvider _provider;</p><p>        private IIPCamera _ipCamera;</p><p>        private WebCamera _webCamera;</p><p>        private MediaConnector _connector;</p><p>        private MyServer _server;</p><p>        private IVideoSender _videoSender;</p><p>        public MainWindow()
        {
            InitializeComponent();</p><p>            _connector = new MediaConnector();</p><p>            _provider = new BitmapSourceProvider();</p><p>            _server = new MyServer();</p><p>            SetVideoViewer();
        }</p><p>        private void SetVideoViewer()
        {
            _videoViewerWpf = new VideoViewerWPF
            {
                HorizontalAlignment = HorizontalAlignment.Stretch,
                VerticalAlignment = VerticalAlignment.Stretch,
                Background = Brushes.Black
            };
            CameraBox.Children.Add(_videoViewerWpf);</p><p>            _videoViewerWpf.SetImageProvider(_provider);
        }</p><p>        #region USB Camera Connect/Disconnect</p><p>        private void ConnectUSBCamera_Click(object sender, RoutedEventArgs e)
        {
            _webCamera = WebCamera.GetDefaultDevice();
            if (_webCamera == null) return;
            _connector.Connect(_webCamera, _provider);
            _videoSender = _webCamera;</p><p>            _webCamera.Start();
            _videoViewerWpf.Start();
        }</p><p>        private void DisconnectUSBCamera_Click(object sender, RoutedEventArgs e)
        {
            if (_webCamera == null) return;
            _videoViewerWpf.Stop();</p><p>            _webCamera.Stop();
            _webCamera.Dispose();</p><p>            _connector.Disconnect(_webCamera, _provider);
        }
        #endregion</p><p>        #region IP Camera Connect/Disconnect</p><p>        private void ConnectIPCamera_Click(object sender, RoutedEventArgs e)
        {
            var host = HostTextBox.Text;
            var user = UserTextBox.Text;
            var pass = Password.Password;</p><p>            _ipCamera = IPCameraFactory.GetCamera(host, user, pass);
            if (_ipCamera == null) return;
            _connector.Connect(_ipCamera.VideoChannel, _provider);
            _videoSender = _ipCamera.VideoChannel;</p><p>            _ipCamera.Start();
            _videoViewerWpf.Start();
        }</p><p>        private void DisconnectIPCamera_Click(object sender, RoutedEventArgs e)
        {
            if (_ipCamera == null) return;
            _videoViewerWpf.Stop();</p><p>            _ipCamera.Disconnect();
            _ipCamera.Dispose();</p><p>            _connector.Disconnect(_ipCamera.VideoChannel, _provider);
        }</p><p>        #endregion</p><p>        private void GuiThread(Action action)
        {
            Dispatcher.BeginInvoke(action);
        }</p><p>        private void StartServer_Click(object sender, RoutedEventArgs e)
        {
            var ipadress = IpAddressText.Text;
            var port = int.Parse(PortText.Text);
            _server.VideoSender = _videoSender;</p><p>            _server.OnClientCountChanged += server_OnClientCountChanged;</p><p>            _server.Start();
            _server.SetListenAddress(ipadress, port);
        }</p><p>        void server_OnClientCountChanged(object sender, EventArgs e)
        {
            GuiThread(() =>
            {
                ConnectedClientList.Items.Clear();</p><p>                foreach (var client in _server.ConnectedClients)
                    ConnectedClientList.Items.Add("End point: " +
                        client.TransportInfo.RemoteEndPoint);
            });
        }</p><p>        private void StopServer_Click(object sender, RoutedEventArgs e)
        {
            _server.OnClientCountChanged -= server_OnClientCountChanged;
            _server.Stop();
        }
    }
}</p>

Step 3: Implementation of Remote Camera Streaming in C# - MyServer.cs

The MyServer.cs class is responsible for the streaming. Let's analyse this class!

After inserting the necessary using lines, there is a need for some objects (MediaConnector, IPCameraClient, VideoSender) and an event handler method. After initializing the MediaConnector in the constructor, you need to code the ClientsChanged method that indicates when a new client connects to or disconnects from the server. As it can be seen below, the OnClientConnected and the OnClientDisconnected methods has been overwrited. (The first one is used to connect the client to the image of the camera and to call the ClientsChanged method. The OnClientDisconnected method is responsible for disconnecting the client from the image of the camera.)

After this, you need a VideoSender object that will contain the image of the camera.You also need an instance from the MyServer class, then initialize it in the constructor. The VideoSender instance needs to be equal to the image of the webcamera and to the VideoChannel of the IP camera.

<p>using System;<br>using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Ozeki.Media.IPCamera;
using Ozeki.Media.IPCamera.Server;
using Ozeki.Media.MediaHandlers;</p><p>namespace Basic_CameraViewer
{
    public class MyServer : IPCameraServer
    {
        private MediaConnector _connector;</p><p>        private IIPCameraClient _client;</p><p>        public IVideoSender VideoSender { get; set; }</p><p>        public event EventHandler OnClientCountChanged;</p><p>        public MyServer()
        {
            _connector = new MediaConnector();
        }</p><p>        protected override void OnClientConnected(IIPCameraClient client)
        {
            _client = client;
            _connector.Connect(VideoSender, _client.VideoChannel);</p><p>            var handler = OnClientCountChanged;
            if (handler != null)
                handler(null, new EventArgs());</p><p>            base.OnClientConnected(_client);
        }</p><p>        protected override void OnClientDisconnected(IIPCameraClient client)
        {
            _client = client;</p><p>            _connector.Disconnect(VideoSender, _client.VideoChannel);
            _connector.Dispose();</p><p>            var handler = OnClientCountChanged;
            if (handler != null)
                handler(null, new EventArgs());</p><p>            base.OnClientDisconnected(_client);
        }
    }
}</p>

Step 4: Implementation of Remote Camera Streaming in C# - MainWindow.xaml.cs (2)

Now let's return to the MainWindow.xaml.cs and take a look at the end of the class (after the connection/disconnection regions). Here you need to create access to the GuiThread.

After this you need to start the server in the StartServer_Click event. Provide the value of the VideoSender to the VideoSender of the MyServer instance, then subscribe to the event defined in the MyServer class.

Finally, you need to set the listening address and finally to implement the methods that are used to stop the server.

Step 5: Test the Camera Streamer

After you have implemented the program successfully, let's run the application. Check how the software works by specifying the listening address: enter your IP address and the listening port number. Finally, click on the Start button to start RTSP streaming.

Now open a video player supporting RTSP streaming (e.g. VLC media player) on an other device. It can be a remote PC or even a mobile device. Open the following network MRL:

rtsp://192.168.112.122:554

  • 192.168.112.122 = your IP address specified above
  • 554 = the listening port number specified above

You will see that the image of the camera will appear on the remote device!

This amazing red egg is my 'Easter Egg' for you in 2015! :) Happy Easter!

Conclusion

I hope you gained all the necessary knowledge that is needed to take the proper precautions during the Easter Holiday in 2015! Feel free to use this example project to stream the image of your security cameras to remote computers and smartphones any time.

References, useful links and prerequisites

Thank you for your attention!