怎么在c#中使用MJPEG实现一个客户端功能

  介绍

怎么在c#中使用MJPEG实现一个客户端功能?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。

环境:

服务端

MJPEG服务器使用的是手机的DroidCam,很方便的一个MJPEG服务器、端口4747,打开软件就能使用,并且还附带了web端展示。

客户端

MJPEG客户端使用c# Http请求,并获取到响应MJPEG视频流,截取到图片数据部分,用图片框展示图片内容。

整体流程:

1。c#向MJPEG发送请求URL,请求URL是MJPEG服务器定的,例如DroidCam,可以通过访问:{手机所在IP}: 4747

怎么在c#中使用MJPEG实现一个客户端功能

图片中红框内容就是视频流的地址,使用得到请求后,服务端就会一直往这个请求的响应内容中写照片信息,直到这个得到请求断开为止(客户端,服务端其中一个主动退出)

ps:如果使用DroidCam当服务器,建议使用手机热点,或者手机通过数据线共享链接方式链接,因为MJPEG实际是把视频的每一帧截成一张图片发送过来的,非常的占带宽,并且网速不好还有图片数据不完整情况,需要手动处理跳过。手机开WiFi热点电脑链接,手机端IP: 192.168.43.1:4747,手机数据线连接usb网络共享,手机端IP: 192.168.43.129:4747;

2。c#读响应头,找出视频流中每张图片的分隔符,读取每张图片前内容长度长度,读图片;

3。每读到一张图片,刷新一次图片框控件;

具体实现

//创建一个HTTP请求,只要请求不结束,MJPEG服务端会一直给请求的响应体中发送实时图片内容   HttpWebRequest  hwRequest =, (System.Net.HttpWebRequest) WebRequest.Create(“请求URL地址“);   时间=hwRequest.Method “GET";   HttpWebResponse  hwResponse =, (HttpWebResponse) hwRequest.GetResponse ();//读边界指定的每张图片分隔符,DroidCam为:——dcmjpeg   string  contentType =, hwResponse.Headers (“Content-Type");   string  boundryKey =,“边界=?   string  boundary =, contentType.Substring (contentType.IndexOf (boundryKey), +, boundryKey.Length);   ,//拿到响应体流   Stream  Stream =, hwResponse.GetResponseStream ();   内容长度string  headerName =,“:“;//临时存储字符串数据   StringBuilder  sb =, new  StringBuilder ();   int  len =, 1024;   while (真正的)   {   ,,,//读取一行数据   ,,,while (真实),{   ,,,,,,,char  c =, (char) stream.ReadByte ();   ,,,,,,,//Console.Write (c);   ,,,,,,,if  (c ==, & # 39; \ n # 39;), {   ,,,,,,,,,,,休息;   ,,,,,,,}   ,,,,,,,sb.Append (c);   ,,,}   ,,,string  line =, sb.ToString ();   ,,,sb.Remove (0,, sb.Length);   ,,,//当前行中是否包含内容长度:   ,,,int 小姐:=,line.IndexOf (headerName);   ,,,if (小姐:!=,1),{   ,,,,,,,//每张图片前有一段图片简单介绍(图片类型,长度),这里只关心长度(内容长度:)后边的值,用于后续读取图片   ,,,,,,,int  imageFileLength =, Convert.ToInt32 (line.Substring(小姐:+,headerName.Length) .Trim ());   ,,,,,,,//内容长度:xxx 完后会有一个/r/n的换行符,换行符后才是真正的图片数据(不知道是DroidCam自己这样还是都这样…)   ,,,,,,,//这里跳过/r/n   ,,,,,,,stream.Read (new 字节[2],,0,,2);   ,,,,,,,//开始读取图片数据,imageFileLength就是读到的内容长度:后的长度   ,,,,,,,byte [], imageFileBytes =, new 字节(imageFileLength);   ,,,,,,,stream.Read (imageFileBytes, 0, imageFileBytes.Length);   ,,,,,,,//JPEG的文件头是:,FF  D8  FF 文件尾是:,FF  D9,非常重要,调试时最好打印一下,便于区分读入的数据是否正好时图片的所有内容   ,,,,,,,//Console.WriteLine(“文件头:“,+,imageFileBytes [0] .ToString (“X"), +,,,,, +, imageFileBytes [1] .ToString (“X"), +,,,,, +, imageFileBytes [2] .ToString (“X"), +,,,,, +, imageFileBytes [3] .ToString (“X"), +,,,,, +, imageFileBytes [4] .ToString (“X"));   ,,,,,,,//Console.WriteLine(“文件尾:“,+,imageFileBytes (imageFileLength 作用;2).ToString (“X"), +,,,,, +, imageFileBytes [imageFileLength 安康;1].ToString (“X"));   ,,,,,,,//此处做了一个如果读入文件不全时处理,图片越大,程序循环读取速度越快,越有可能导致读取文件不全情况…,如果有好的办法解决希望前辈们指教,非常感谢!   ,,,,,,,//文件尾是否是FF  D9   ,,,,,,,if  (imageFileBytes (imageFileLength 作用;2).ToString (“X"), !=,“FF",,,, imageFileBytes [imageFileLength 安康;1].ToString (“X"), !=,“D9")   ,,,,,,,{   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null

怎么在c#中使用MJPEG实现一个客户端功能