using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Net; using System.IO; using System.Drawing; using System.Threading; using log4net; namespace ArdupilotMega.Utilities { public class CaptureMJPEG { private static readonly ILog log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); static Thread asyncthread; static bool running = false; public static string URL = @"http://127.0.0.1:56781/map.jpg"; public static event EventHandler OnNewImage; static DateTime lastimage = DateTime.Now; static int fps = 0; public static void runAsync() { while (asyncthread != null && asyncthread.IsAlive) { running = false; } asyncthread = new Thread(new ThreadStart(getUrl)) { IsBackground = true, Priority = ThreadPriority.BelowNormal, Name = "mjpg stream reader" }; asyncthread.Start(); } public static void Stop() { running = false; } public static string ReadLine(BinaryReader br) { StringBuilder sb = new StringBuilder(); while (true) { byte by = br.ReadByte(); sb.Append((char)by); if (by == '\n') break; } sb = sb.Replace("\r\n", ""); return sb.ToString(); } static void getUrl() { running = true; Bitmap frame = new Bitmap(640, 480); try { // Create a request using a URL that can receive a post. WebRequest request = HttpWebRequest.Create(URL); // Set the Method property of the request to POST. request.Method = "GET"; ((HttpWebRequest)request).AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate; request.Headers.Add("Accept-Encoding", "gzip,deflate"); // Get the response. WebResponse response = request.GetResponse(); // Display the status. log.Debug(((HttpWebResponse)response).StatusDescription); // Get the stream containing content returned by the server. Stream dataStream = response.GetResponseStream(); BinaryReader br = new BinaryReader(dataStream); // get boundary header string mpheader = response.Headers["Content-Type"]; if (mpheader.IndexOf("boundary=") == -1) { ReadLine(br); // this is a blank line string line = "proxyline"; do { line = ReadLine(br); if (line.StartsWith("--")) { mpheader = line; break; } } while (line.Length > 2); } else { int startboundary = mpheader.IndexOf("boundary=") + 9; int endboundary = mpheader.Length; mpheader = mpheader.Substring(startboundary, endboundary - startboundary); } dataStream.ReadTimeout = 30000; // 30 seconds br.BaseStream.ReadTimeout = 30000; while (running) { try { // get the multipart start header int length = int.Parse(getHeader(br)["Content-Length"]); // read boundary header if (length > 0) { byte[] buf1 = new byte[length]; dataStream.ReadTimeout = 3000; int offset = 0; int len = 0; while ((len = br.Read(buf1, offset, length)) > 0) { offset += len; length -= len; } /* BinaryWriter sw = new BinaryWriter(File.OpenWrite("test.jpg")); sw.Write(buf1,0,buf1.Length); sw.Close(); */ try { frame = new Bitmap(new MemoryStream(buf1)); } catch { } fps++; if (lastimage.Second != DateTime.Now.Second) { Console.WriteLine("MJPEG " + fps); fps = 0; lastimage = DateTime.Now; } if (OnNewImage != null) OnNewImage(frame, new EventArgs()); } // blank line at end of data ReadLine(br); } catch (Exception ex) { log.Info(ex); break; } } // clear last image if (OnNewImage != null) OnNewImage(null, new EventArgs()); dataStream.Close(); response.Close(); } catch (Exception ex) { log.Error(ex); } running = false; } static void getUrlRTSP() { } static Dictionary getHeader(BinaryReader stream) { Dictionary answer = new Dictionary(); string line; do { line = ReadLine(stream); string[] items = line.Split(new char[] { ':' }, StringSplitOptions.RemoveEmptyEntries); if (items.Length == 2) answer.Add(items[0].Trim(), items[1].Trim()); } while (line != ""); return answer; } } }