Http 创建我自己的MJPEG流
我正在尝试创建一个MJPEG流,我有一系列JPEG,我想把它们放在一个流中,这样用户就可以点击一个URL,得到一个MJPEG流。 在过去的几天里,我一直在努力让它发挥作用,但这可能是不可能的。我提到了ethereal,听了网络上某个地方的axis摄像机传来的信息包,并试图模仿它。我最初尝试使用WCF并返回一个“流”,但后来发现我需要在该流上设置内容类型,因此我尝试了WCF REST api,但遇到了相同的问题。所以我现在只使用一个简单的HTTPListener,并处理该事件。我非常希望使用WCF,但我不确定它是否允许我返回具有正确内容类型的流。 下面是我对httpListener的介绍 在侦听器回调的处理程序中,我放置了以下内容Http 创建我自己的MJPEG流,http,video,streaming,jpeg,mjpeg,Http,Video,Streaming,Jpeg,Mjpeg,我正在尝试创建一个MJPEG流,我有一系列JPEG,我想把它们放在一个流中,这样用户就可以点击一个URL,得到一个MJPEG流。 在过去的几天里,我一直在努力让它发挥作用,但这可能是不可能的。我提到了ethereal,听了网络上某个地方的axis摄像机传来的信息包,并试图模仿它。我最初尝试使用WCF并返回一个“流”,但后来发现我需要在该流上设置内容类型,因此我尝试了WCF REST api,但遇到了相同的问题。所以我现在只使用一个简单的HTTPListener,并处理该事件。我非常希望使用WCF
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);
渲染方法如下所示
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);
}
}
var writer=newstreamwriter(st);
writer.Write(“--”+BOUNDARY+”\r\n”);
while(true)
{
对于(int i=0;i
在这一点上,我刚刚在dll上添加了一些jpeg图像作为属性,并对它们进行迭代,最终这些将是动态图像,但现在我只想让它工作起来
根据我对MJPEG(规范)的理解,内容必须设置为multipart/x-mixed-replace和边界集。然后你只需通过边界消除流中的JPEG图像
这看起来应该比我做的更简单,但我想知道我哪里做错了。如果我在IE或Firefox中加载此URL,它就会挂起。如果我试图创建一个带有img标记的存根html页面,其源是URL,那么我会得到一个损坏的图像
有什么想法吗,谢谢
Josh据我所知,以下是你的问题:
StreamWriter
不是正确的选择。使用常规流写入函数是可以的。也就是说,您应该以字节数组而不是字符串形式写入数据Content Length
,以便接收流的应用程序知道何时停止读取,而不必每次读取都检查下一个边界字符串。这将使读取数据的速度提高约4-5倍。并且新行字符中也存在不一致性,有些是“\r\n”,有些是“\n”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);
}
}
private byte[]CreateHeader(int-length)
{
字符串头=
“-”+BOUDARY+“\r\n”+
“内容类型:图像/jpeg\r\n”+
内容长度:“+Length+”\r\n+
+“\r\n”;//在实际数据之前始终有两个新行字符
//使用ascii编码器很好,因为此字符串中没有使用国际字符。
返回ascienceoding.ASCII.GetBytes(头);
}
公共字节[]CreateFooter()
{
返回ascienceoding.ASCII.GetBytes(“\r\n”);
}
私有void WriteFrame(流st、位图图像)
{
//准备图像数据
字节[]imageData=null;
//这是为了确保在使用后释放内存流
使用(MemoryStream ms=new MemoryStream())
{
保存(ms,ImageFormat.Jpeg);
imageData=ms.ToArray();
}
//准备收割台
byte[]header=CreateHeader(imageData.Length);
//准备页脚
字节[]页脚=CreateFooter();
//开始写入数据
st.Write(头,0,头.长度);
st.Write(imageData,0,imageData.Length);
st.Write(页脚,0,页脚长度);
}
私有void渲染(Stream st)
{
对于(int i=0;i
还有一个实现@library可以动态地将Http转换为Rtp兼容 我知道这已经一年多了。。。但仍然如此。规范规定,在“标题名称”后面的冒号和标题值之间应该有一个空格(“”,ASCII 32)。