2

This might be a little of a long shot, but here goes: I have a WPF project and need to stream MJPEG video. The library at http://mjpeg.codeplex.com/ seems to be one of the few PnP options. It works great for viewing a single stream. But, when you try to switch from one URI, to a second URI the end result is that you get frames from BOTH streams interlaced into the same image object on my WPF page. Both streams are live, not just a cache of the previous stream.

No matter what I try it seems like the first stream will not go away and the stopstream method in the decoder doesn't do a damn thing other than set a boolean value.

Here's is the pseudo code for how I'm using the library. Am I doing something wrong?

 button_click{
    //Create new decoder instance
    //Remove the previous image object from my WPF page
    //Add a new image object to the WPF page
    //Stop stream
    //Set the event for a new frams
    //Request the new stream with a new URI

    }

I have written to the decoder author with no response. I'm hoping that someone else that has used this library will be able to shed light on this.

Unknown Coder
  • 6,625
  • 20
  • 79
  • 129

2 Answers2

3

Although the MJPEGDecoder library is great, it unfortunately creates a WPF BitmapImage and a System.Drawing.Bitmap at each frame. This is way too much.

What we need is a byte array, which is platform independant. Then it is up to the UI to convert it to an actual Image object.

So I took the AForge.NET MJPEGStream.cs object and tweaked it a bit so it sends a byte array instead of a Bitmap.

MJPEGStream.cs is robust as hell and very fast. I am using it in production to stream up to 30 streams. It automatically stops and restarts the stream as the URI changes, retries by itself if the cam stops responding...

Please take this gist, then use it this way :

var stream = new MJPEGStream("http://webcam.st-malo.com/axis-cgi/mjpg/video.cgi?resolution=352x288");

stream.NewFrame += img => {
    Dispatcher.BeginInvoke(
        System.Windows.Threading.DispatcherPriority.Render,
        new Action(() => {
            var bmp = new BitmapImage();
            bmp.BeginInit();
            bmp.StreamSource = new MemoryStream(img);
            bmp.EndInit();
            bmp.Freeze();
            pic.Source = bmp;
        }));
};

stream.Start();

Of course, have look on the documentation to benefit all its features.

Larry
  • 17,605
  • 9
  • 77
  • 106
3

If you call StopStream(), wait a bit, and then call ParseStream again, it should shut down the first stream, and only display the second one.

The better alternative would be to only use a single instance of MjpegDecoder for each stream you would like to view.

Of course, if you aren't sure how it works, you can just download the code, and see how it works.

davisoa
  • 5,407
  • 1
  • 28
  • 34