Search code examples
asp.net-web-apimjpeg

Using WebAPI to stream MJPEG always buffers


I'm using HttpSelfHostConfiguration to create a WebAPI (service). My goal is to have one route stream the mjpeg video from a security feed and have other routes available for configuration and the web interface.

The issue I'm having is that every example I've come across expects a known quantity of images in order to set the content-length for the main response. I don't have this, and flushing the stream doesn't do anything.

Here's the current code for the response. If I use this same code with raw sockets instead of through an ApiController, I can stream it just fine, but creating a webserver from scratch for everything else I'm needing doesn't seem like a lot of fun.

[HttpGet]
public HttpResponseMessage Stream(int channel)
{
    var response = Request.CreateResponse();
    response.Content = new PushStreamContent((outputStream, content, context) =>
    {
        StreamWriter writer = new StreamWriter(outputStream);
        while (true)
        {
            using (MemoryStream ms = new MemoryStream())
            {
                ReadMemoryMappedFile(channel);

                ms.SetLength(0);
                this.Image.Bitmap.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
                byte[] buffer = ms.GetBuffer();


                writer.WriteLine("--boundary");
                writer.WriteLine("Content-Type: image/jpeg");
                writer.WriteLine(string.Format("Content-length: {0}", buffer.Length));
                writer.WriteLine();
                writer.Write(buffer);

                writer.Flush();
            }
        }
    });
    response.Content.Headers.ContentType = System.Net.Http.Headers.MediaTypeHeaderValue.Parse("multipart/x-mixed-replace; boundary=--boundary");
    return response;
}

Solution

  • I hope my late answer will help, since I ran into the same issue recently and it took me some time to figure it out...

    My solution was to specify the boudary int the ContentType without the "--" (but you need to keep them while writing in the stream).

    Try to configure the Headers like that :

    response.Content.Headers.ContentType = System.Net.Http.Headers.MediaTypeHeaderValue.Parse("multipart/x-mixed-replace; boundary=boundary");
    

    And write boundaries in the stream like that :

    writer.WriteLine("--boundary");
    

    Like this it works for me.