创造我自己的MJPEG流(creating my own MJPEG stream)

2019-08-22 03:15发布

我试图创建一个MJPEG流,我有一系列的我想拼凑成一个流,使得用户可以只投中一URL,并得到一个MJPEG流JPEG文件。 我一直试图在过去的几天得到这个工作,它可能只是是不可能的。 我已经长大空灵并听取轴相机即将在网络上某处的数据包,并试图mimmick它。 我最初尝试使用WCF,并返回一个“流”,但后来发现,我需要设置内容类型在那个流,所以后来我尝试了WCF REST API,但是从同一个问题的困扰。 所以我现在只使用一个光秃秃的骨头HTTPListener,以及处理该事件。 我非常喜欢使用WCF,但我不知道它会允许我用正确的内容类型返回流。 所以这里就是我对httpListener。

在监听通话的处理程序后,我把下面。

        HttpListenerResponse response = context.Response;
        response.ProtocolVersion = new System.Version(1, 0);
        response.StatusCode = 200;
        response.StatusDescription = "OK";
        response.ContentType = "multipart/x-mixed-replace;boundary=" + BOUNDARY + "\r\n";
        System.IO.Stream output = response.OutputStream;
        Render(output);

在Render方法看起来是这样的

        var writer = new StreamWriter(st);
        writer.Write("--" + BOUNDARY + "\r\n");
        while (true)
        {
            for (int i = 0; i < imageset.Length; i++)
            {
                var resource = Properties.Resources.ResourceManager.GetObject(imageset[i]) as Bitmap;
                var memStream = new MemoryStream();
                resource.Save(memStream,ImageFormat.Jpeg);
                byte[] imgBinaryData = memStream.ToArray();
                string s = Convert.ToBase64String(imgBinaryData);
                writer.Write("Content-type: image/jpeg\r\n");
                foreach (var s1 in imgBinaryData)
                {
                    writer.Write((char)s1);
                }
                writer.Write("\n--" + BOUNDARY + "\n");
                writer.Flush();
                Thread.Sleep(500);
            }
        }

在这一点上,我只是添加了一些JPEG图像上的dll属性,我遍历他们,最终这将是动态图像,但现在我只是想获得的东西的工作。

从我的理解对MJPEG(SPEC)是内容必须设置为multipart / X - 混合替换和边界集。 然后你只是deliminate由边界流内的JPEG文件。

这似乎是那么我做它应该是简单的,但我不知道我要去哪里错了。 如果我加载IE或Firefox这个URL时,它只是挂起。 如果我尝试做一个短线的HTML页面img标签,它的来源是URL,然后我得到一个破碎的形象。

任何想法,谢谢

玩笑

Answer 1:

好了,据我所知,这是你的问题:

  1. StreamWriter是不是一个正确的选择。 使用常规流写入功能是好的。 意思是,你应该写在字节数组,而不是字符串数据。

  2. 您图像的二进制数据转换为String64,浏览器不知道,还在想着它是32位的数据。

  3. 您的JPEG帧格式不正确。 您还应该添加Content-Length帧头,使得接收流的应用程序知道何时停止阅读,而不是来检查下一个边界字符串每次读取。 这将导致约4-5倍的数据读取速度。 而且也有不一致的新行字符,有些是“\ r \ n”,而另一些“\ n”。

  4. While循环是一个无限循环。

所以,这里是解决方案。

注:可能有一些语法错误,但你可能得到的总体思路。

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);
    }
}


Answer 2:

此外,还有一个实施@ https://net7mma.codeplex.com/SourceControl/latest图书馆里可以转码的HTTP来RTP在飞行兼容!



文章来源: creating my own MJPEG stream