creating my own MJPEG stream

夙愿已清 提交于 2019-11-28 11:19:15

Well, as far as I can tell, here are your issues:

  1. The StreamWriter is not a correct choice. Use a regular stream write function is fine. Meaning, you should write data in Byte array instead of string.

  2. You convert the Binary data of the image to String64, the browser does not known that, still thinking it is 32bit data.

  3. Your jpeg frame format is not correct. You should also add Content-Length to the frame header so that the application that receive the stream know when to stop reading rather than having to check for the next boundary string every read. This will result in about 4-5 times faster in reading data. And there are also inconsistency in your new line character, some are "\r\n" while some others are "\n".

  4. While loop is a infinite loop.

So, here is the solution.

Note: There might be some syntax errors but you probably get the general idea.

private byte[] CreateHeader(int length)
{
    string header = 
        "--" + BOUDARY + "\r\n" +
        "Content-Type:image/jpeg\r\n" +
        "Content-Length:" + length + "\r\n" +
        + "\r\n"; // there are always 2 new line character before the actual data

    // using ascii encoder is fine since there is no international character used in this string.
    return ASCIIEncoding.ASCII.GetBytes(header); 
}

public byte[] CreateFooter()
{
    return ASCIIEncoding.ASCII.GetBytes("\r\n");
}

private void WriteFrame(Stream st, Bitmap image)
{
    // prepare image data
    byte[] imageData = null;

    // this is to make sure memory stream is disposed after using
    using (MemoryStream ms = new MemoryStream())
    {
        image.Save(ms, ImageFormat.Jpeg);

        imageData = ms.ToArray();
    }

    // prepare header
    byte[] header = CreateHeader(imageData.Length);
    // prepare footer
    byte[] footer = CreateFooter();

    // Start writing data
    st.Write(header, 0, header.Length);
    st.Write(imageData, 0, imageData.Length);
    st.Write(footer, 0, footer.Length);
}

private void Render(Stream st)
{
    for (int i = 0; i < imageset.Length; i++)
    {
        var resource = Properties.Resources.ResourceManager.GetObject(imageset[i]) as Bitmap;
        WriteFrame(st, resource);
        Thread.Sleep(500);
    }
}

There is also an implementation @ https://net7mma.codeplex.com/SourceControl/latest the library there can transcode the Http to Rtp compatible on the fly!

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!