介绍服务端
客户端
整体流程:
怎么在c#中使用MJPEG实现一个客户端功能?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。
环境:
服务端
MJPEG服务器使用的是手机的DroidCam,很方便的一个MJPEG服务器、端口4747,打开软件就能使用,并且还附带了web端展示。
客户端
MJPEG客户端使用c# Http请求,并获取到响应MJPEG视频流,截取到图片数据部分,用图片框展示图片内容。
整体流程:
1。c#向MJPEG发送请求URL,请求URL是MJPEG服务器定的,例如DroidCam,可以通过访问:{手机所在IP}: 4747
图片中红框内容就是视频流的地址,使用得到请求后,服务端就会一直往这个请求的响应内容中写照片信息,直到这个得到请求断开为止(客户端,服务端其中一个主动退出)
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实现一个客户端功能