A Simple Foscam IP Viewer in C#

Nowadays, you can get IP cameras pretty cheap. If you are not familiar, an IP camera is sort of like a portable/mountable webcam, that has a built-in web server. The purpose being that you can set up this camera, and then view it by going to a certain address in your web browser – if you are connected to the same network.

You can find a bunch, new, which support tilt/pan for around $70-90 on Amazon.

Anyhow, I had something specific in-mind in terms of what I wanted for an user interface, for my cameras. The first step was figuring out how to access the video. I went down that road before and didn’t get very far because the video “stream” it produces was proprietary and not easily consumable. However, I don’t really need a stream – what about just getting snapshots? I just really want a few frames per second and that would be fine.

So, I found this PDF on the Foscam site which describes the web interface to get access to the stream – or in my case, the snapshot. That URL looks something like this:

http://192.168.1.91/snapshot.cgi?user=username&pwd=mypassword

From there, I used a System.Net.WebRequest to go get the snapshot – I take that stream and put it into a System.Drawing.Image object – and then assign that image to a PictureBox object I have on the screen.

Updating the image:
I did some research here and the actual web request takes anywhere from 250ms (1/4 of a second) to 2-3 seconds. I couldn’t find a fix for this. So, as the code stands now, it tries to get a new image a few times per second, but it is not successful and/or it returns from multiple calls at the same time. You still end up with a picture, but there is a just a delay. So, for any given camera, I’ll see an update from twice per second – to an update every 2 seconds.

I also kick off the webrequest and update in another thread by using a Task object. In other words, all 4 cameras as off getting their updated images, while the UI isn’t slowed down or blocked at all during the updates.

Adding timestamp and camera name:
Once you have a .NET System.Drawing.Image object – you can simply create a Graphics object and do a .DrawString on there with the camera name and timestamp of the image:

mx345AD

Dealing with errors:
I chose to still show the timestamp and label – and then just show the exception inside of the image. I will likely change this later. This too, just uses a Graphics object to output text onto the image.

So there it is – a basic viewer for Foscam-style IP cameras. Now that I have basic functionality, I can finish fleshing out my application.

If interested, the code for this project is available here.

Tagged with: , ,
Posted in Computers and Internet, Infrastructure, Parallelism, Sensors, Sensors and Controllers, Uncategorized
17 comments on “A Simple Foscam IP Viewer in C#
  1. Leonardo Martínez says:

    Hi, how are you? Great job! It works really well. I would like to see the video instead of the snapshot? What have you advanced in this term? I need for a mobile robot… I have guessed that i could see it in the browser tool but it’s like IE, it can’t open cgi files…

    Like

  2. Rob Seder says:

    Unfortunately, I haven’t made a lot of progress. I have found that I can get maybe 3 frames-per-second using this technique and it works pretty well. However, if there are network problems – I have had many, many problems with the Graphics object. Something in it blows up, in another thread, which I can’t catch. So, this ends up making the application very flaky.

    As for capturing the actual video stream, I looked into this a few times. Apperently, it’s a partially proprietary mp4-type of stream, and the only way to decode it was with unmanaged DirectX and some custom C++ header files that people on the internet created. So, I never did find a way to do that. You would think that IP cameras, by nature, would be easier to work with – but I haven’t found a reasonable way to capture or show the video stream. If you ever do – please post back and let me know!! Good luck with your robot!

    Like

  3. Leonardo Martínez says:

    Hi Rob,
    It would be great if i could find something like a google chrome browser where i could play the url: 192.168.5.20/videostream.cgi

    Now, i am viewing with VLC player the videostream.asf and its fps are really low. Just like yours… I guess it won’t work well with my robot…

    It’s for my grade project in electronic engineer so i am a “beginner” in c# by the way…

    Thanks!

    Like

  4. Rob Seder says:

    Ah-HA!! I just found this:

    http://channel9.msdn.com/coding4fun/articles/MJPEG-Decoder

    This works great and is free to download. In case the link breaks in the future, here are the file names that this project created:
    1.MjpegProcessorSL.dll – Silverlight (Out of Browser Only!)
    2.MjpegProcessorWP7.dll – Windows Phone 7 (XNA or Silverlight, performance maxes out around 320×240 @ 15fps, so set your camera settings accordingly)
    3.MjpegProcessorXna4.dll – XNA 4.0 (Windows)
    4.MjpegProcessor.dll – WinForms and WPF

    Like

    • Leonardo Martínez says:

      Hi Rob,

      That seems interesting…
      I am seeing this site: http://www.codeproject.com/Articles/15537/Camera-Vision-video-surveillance-on-C in this moment.
      I have just tested the sample .exe and it works great with my camera. Almost no problems with the video stream…

      I am trying to understand the code and how to translate it to my code…

      I will write when i see any progress in my app… This is the best way I’ve found. I’ve also seen that i could play the url in a vlc player but it doesn’t get such high fps as the site i wrote…

      I am almost dying trying to understand the code… jaja…

      Thanks for writting!

      Kind regards!

      Like

  5. Leonardo Martínez says:

    Hi Rob,

    How are you?
    I am writting because i could get the video stream taking the code, from the site I mentioned, as reference…

    Just including the dlls for mjpeg and doing is:

    mjpeg.MJPEGSource video = new mjpeg.MJPEGSource();
    video.Password = “”;
    video.Login = “admin”;
    video.VideoSource = “http://192.168.5.20/videostream.cgi”;
    video.Start();

    video.NewFrame += new CameraEventHandler(video_NewFrame);

    In video_NewFrame, I update the image in a Picture Box…

    I works great…

    Now, I am trying to use your code to send request in order to move the camera (decoder_control.cgi)…
    I am getting the following error

    System.Net.WebException: Error en el servidor remoto: (401) No autorizado.

    I guess It’s because the camera doesn`t understand what i am sending to it ( private String coreUrl = “http://{0}/decoder_control.cgi?command=0”;)

    Did you do something related with moving the camera?

    Is it with the get method?

    Kind regards!
    Leonardo.

    Like

  6. Rob Seder says:

    Leonardo,

    As far as that, include the credentials:
    http://0/decoder_control.cgi?command=0&user=username&pwd=mypassword
    if that still doesn’t work, set the .Credentials properties on the WebRequest that you are using. Something like:
    request.Credentials = new NetworkCredentials(username, password);
    That should do it.
    I too – am up and running. I will refine my app in the coming days/weeks and will post the code. This streaming video is MUCH better than the snapshots I was taking – and it’s much more stable too!
    -Rob

    Like

    • Leonardo Martínez says:

      Rob,

      Thanks! It worked adding this:

      request.Credentials = new NetworkCredential(“admin”, “”);

      I thought thats this cgi didn’t need credentials…

      How did you finally manage to get the streaming?
      With MjpegProcessor.dll?

      It’s huge the difference between snapshots and video…
      But, obviously, it depends for each situation…

      Like

  7. Rob Seder says:

    I used the MjpegProcess.dll – well, I started with that, but it didn’t have much error handling. So, I started from that codebase and I’m cleaning it up significantly to make it my own and to make it more stable. Glad you got this working too!

    Like

    • Leonardo Martinez says:

      Oh, it’s pretty the same that we are using… As I wanted a quick solution i decided to use that Dll, maybe if i have any problem i will change… It’s not the main part of our project.

      Thanks for your kind replies. I will see your code when you post it…

      By the way, we are gonna mention you in our documentation, I hope it’s ok…

      Kind regards.

      Like

  8. Rob Seder says:

    Haha sure – this is a public forum! Good luck with your project

    Like

  9. Seems the link to OneDrive is now broken (the file is missing), but you can find another article with downloadable code about controlling a FOSCAM IP camera at http://blogs.infosupport.com/writing-an-ip-camera-viewer-in-c-5-0/

    Like

  10. btw, I’ve just cleaned up / refactored that code sample and uploaded to https://foscamcontroller.codeplex.com

    Like

  11. …note that you have to edit the constants at the MainWindow.xaml.cs file in the current version

    #region — Constants —

    private const string CAMERA_URL = “http://yoururl”;
    private const string USERNAME = “yourusername”;
    private const string PASSWORD = “yourpassword”;

    #endregion

    Like

  12. note that this is for older MJPEG Foscam cameras, not for their newer HD ones. For those better use ONVIF (see port settings in the camera browser-based configuration pages). Can use OZEKI ONVIF IP Camera SDK for C# (commercial) or opensource code from ONVIF Device Manager (odm) that exists on SourceForge, or can develop your own code using Web Services (WSDL/SOAP) using the WSDL definitions available at onvif.org (note that not all cameras support the latest onvif definitions)

    for RTSP video can use FFMPEG (like odm does), also see another sample using FFMPEG at http://www.codeproject.com/Articles/885869/Stream-Player-control or use VLC ActiveX control (see http://miteshsureja.blogspot.gr/2011/11/creating-simple-video-player-using-vlc.html) or use WPF MediaKit (which uses DirectShow layer)

    Like

    • Robert Seder says:

      This is great, thanks George!!

      For me, I ended up going in the other direction with my old IP cameras. The HTML5 element <video> doesn’t support MJPEG, but the “poster”, or what the video still image looks like while the video is not playing… DOES support it. So, nowadays, I use a webpage which shows each camera like this:

      <video poster="http://192.168.1.91/videostream.cgi?user=jdoe&pwd=thepassword&resolution=8&rate=6&quot; width="100%" autoplay></video>

      Then, using bootstrap (www.getbootstrap.com), I have some buttons for the presents, to turn the light on and off, and to reboot. Those look like this:

      Light: <a href="javascript:lightOff(‘192.168.1.91’);" class="btn btn-primary btn-xs" rel="nofollow">Off</a> <a href="javascript:lightOn(‘192.168.1.91’);" class="btn btn-primary btn-xs" rel="nofollow">On</a>

      where those functions look like this:

      function lightOn(ipAddress){
      $.get( “http://” + ipAddress + “/decoder_control.cgi?user=jdoe&pwd=password&command=95”, function( data ) {});
      }
      function lightOff(ipAddress){
      $.get( “http://” + ipAddress + “/decoder_control.cgi?user=jdoe&pwd=password&command=94”, function( data ) {});
      }

      So now, instead of having more code for these cameras, I can easily access and control them from any any browser by just opening this .html file! FYI

      Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Archives
Categories

Enter your email address to follow this blog and receive notifications of new posts by email.

Join 2 other followers

%d bloggers like this: