程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> C# 實現IP視頻監控(攝像頭)畫面推送(簡單的不能再簡單的DEMO),

C# 實現IP視頻監控(攝像頭)畫面推送(簡單的不能再簡單的DEMO),

編輯:C#入門知識

C# 實現IP視頻監控(攝像頭)畫面推送(簡單的不能再簡單的DEMO),


 

  最近繼續在家休息,在完成上一個Python抓取某音樂網站爬蟲後,琢磨著實現一個基於HTTP推送的 IP視頻監控,比如外出的時候,在家裡

開啟一個監控端(攝像頭+服務端),可以看到實時畫面,如果再加上自動告警,就更好了。公網訪問需要在 路由器上設置 花生殼+端口轉發。

計劃在退休的安卓手機上實現這IP視頻監控軟件,雖然應用市場一大堆別人寫好的軟件,不過我覺得吧,既然是程序員,自己敲代碼實現的軟件會

更有成就感。考慮到需要先驗證下方案的可行性,我用比較熟悉的C# 控制台實現了一個DEMO。

 

設想的方案:

  1.實現一個簡單HTTP服務器,用來接受請求並啟動一個線程處理圖片流的推送功能

  2.開發一個實時抓取圖片的線程,並將圖片交給HTTP推送線程

  3.HTTP的請求URL參數中 附帶推送頻率、圖片高度和寬度

  4.使用一個IP攝像頭監控端(或者Firefox浏覽器),實時查看視頻畫面

  5.循環錄制視頻(未實現)

  6.對畫面進行監控告警(未實現)

 

核心技術點:

  1.HttpListener (HTTP.SYS)

  2.HTTP :multipart/x-mixed-replace;

  3.線程同步、委托、事件

  4.攝像頭驅動、圖片抓取(Andrew Kirillov 寫的)

  5.圖片流解析,顯示(Andrew Kirillov 寫的,也可以直接在Firefox浏覽器打開直接顯示)

 

運行截圖:

  1.視頻監控端 (Andrew Kirillov 寫的 視頻源支持N種,當前配置推送頻率50毫秒 w=240&h=120)

  

 

  2.視頻服務端(我寫的 簡陋的DEMO 不過實現了功能 嘎嘎)

 

 

下面開始貼核心源碼(最近右胳膊有石膏,左手寫代碼  湊合看吧!):

 

1.建立HTTP服務:

1 using (HttpListener listerner = new HttpListener()) 2 { 3 listerner.AuthenticationSchemes = AuthenticationSchemes.Anonymous;//指定身份驗證 Anonymous匿名訪問 4 listerner.Prefixes.Add("http://+:6666/"); 5 6 //listerner.Prefixes.Add("http://+/"); 7 //listerner.Prefixes.Add("http://+:8080/"); 8 //listerner.Prefixes.Add("http://+:6666/"); 9 //listerner.Prefixes.Add("http://+/video.cgi/"); 10 //listerner.Prefixes.Add("http://+:8080/video.cgi/"); 11 12 listerner.Start(); 13 Console.WriteLine("WebServer Start Successed......."); 14 while (true) 15 { 16 try 17 { 18 //等待請求連接 19 //沒有請求則GetContext處於阻塞狀態 20 HttpListenerContext ctx = listerner.GetContext(); 21 22 SendImgService oService = new SendImgService(); 23 oService.Ctx = ctx; 24 localsev.NewFrame += new CameraEventHandler(oService.camera_NewFrame); 25 ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadProc), oService); 26 27 //Thread osThread = new Thread(new ThreadStart(oService.ServiceRun)); 28 //osThread.Start(); 29 } 30 catch (Exception ex) 31 { 32 Console.WriteLine(ex); 33 } 34 } 35 listerner.Stop(); 36 listerner.Close(); 37 } View Code

2.啟動本地視頻頭,並抓取圖片

1 public void ServiceRun() 2 { 3 4 FilterCollection filters = new FilterCollection(FilterCategory.VideoInputDevice); 5 6 if (filters.Count == 0) 7 throw new ApplicationException(); 8 9 // add all devices to combo 10 foreach (Filter filter in filters) 11 { 12 Console.WriteLine(filter.Name + ":" + filter.MonikerString); 13 } 14 CaptureDevice localSource = new CaptureDevice(); 15 localSource.VideoSource = filters[0].MonikerString; 16 17 // create camera 18 camera = new Camera(localSource); 19 // start camera 20 camera.Start(); 21 22 23 // set event handlers 24 camera.NewFrame += new CameraEventHandler(camera_NewFrame); 25 26 } 27 28 // On new frame ready 29 private void camera_NewFrame(object sender, CameraEventArgs e) 30 { 31 if (seq == 999) 32 { 33 seq = 0; 34 } 35 // Console.WriteLine("LocalCamService get camera_NewFrame ==> {0}", ++seq); 36 37 // lock 38 Monitor.Enter(this); 39 40 if (camera != null) 41 { 42 camera.Lock(); 43 44 // dispose old frame 45 if (lastFrame != null) 46 { 47 lastFrame.Dispose(); 48 } 49 // draw frame 50 if (camera.LastFrame != null) 51 { 52 lastFrame = (Bitmap)camera.LastFrame.Clone(); 53 // notify client 54 if (NewFrame != null) 55 NewFrame(this, new CameraEventArgs(lastFrame)); 56 } 57 58 59 camera.Unlock(); 60 } 61 62 // unlock 63 Monitor.Exit(this); 64 } 65 } View Code

3.圖片推送

1 public void ServiceRun() 2 { 3 remoteInfo = ctx.Request.RemoteEndPoint.ToString(); 4 string intervalstr = ctx.Request.QueryString["i"]; 5 string widthstr = ctx.Request.QueryString["w"]; 6 string heightstr = ctx.Request.QueryString["h"]; 7 8 if (!string.IsNullOrWhiteSpace(intervalstr)) 9 { 10 interval = int.Parse(intervalstr); 11 } 12 if (!string.IsNullOrWhiteSpace(widthstr)) 13 { 14 width = int.Parse(widthstr); 15 } 16 if (!string.IsNullOrWhiteSpace(heightstr)) 17 { 18 height = int.Parse(heightstr); 19 } 20 Console.WriteLine("Accept one new request:{0},interval:[{1}]", remoteInfo, interval); 21 22 23 ctx.Response.StatusCode = 200;//設置返回給客服端http狀態代碼 24 ctx.Response.ContentType = "multipart/x-mixed-replace; boundary=--BoundaryString"; 25 26 string rspheard = "--BoundaryString\r\nContent-type: image/jpg\r\nContent-Length: {0}\r\n\r\n"; 27 string strrn = "\r\n"; 28 29 using (Stream stream = ctx.Response.OutputStream) 30 { 31 while (true) 32 { 33 Thread.Sleep(interval); 34 35 try 36 { 37 // lock 38 Monitor.Enter(this); 39 40 if (newFrame == null) 41 { 42 continue; 43 } 44 //得到一個ms對象 45 byte[] imageBuffer; 46 using (MemoryStream ms = new MemoryStream()) 47 { 48 49 //newFrame = (Bitmap)GetThumbnail(newFrame, width, height); 50 //將圖片保存至內存流 51 newFrame.Save(ms, ImageFormat.Jpeg); 52 53 rspheard = string.Format(rspheard, ms.Length); 54 55 byte[] heardbuff = Encoding.ASCII.GetBytes(rspheard); 56 stream.Write(heardbuff, 0, heardbuff.Length); 57 58 imageBuffer = new byte[512]; 59 int c; 60 ms.Position = 0; 61 //通過內存流讀取到imageBytes 62 while ((c = ms.Read(imageBuffer, 0, 512)) > 0) 63 { 64 stream.Write(imageBuffer, 0, c); 65 } 66 byte[] rnbuff = Encoding.ASCII.GetBytes(strrn); 67 stream.Write(rnbuff, 0, rnbuff.Length); 68 69 Console.WriteLine("[{0}] : SendImgService send NewFrame", remoteInfo); 70 71 } 72 73 // stream.Flush(); 74 } 75 catch (Exception ex) 76 { 77 Console.WriteLine(ex); 78 79 break; 80 } 81 finally 82 { 83 // unlock 84 Monitor.Exit(this); 85 } 86 } 87 } 88 Console.WriteLine("[{0}] : 線程結束...", remoteInfo); 89 } View Code

 

附件:(剛會傳文件,還不知道怎麼插入鏈接,誰教我下?)

可運行程序:

http://files.cnblogs.com/files/ryhan/%E7%9B%91%E6%8E%A7%E5%8F%8A%E6%9C%8D%E5%8A%A1%E7%AB%AF%E5%8F%AF%E8%BF%90%E8%A1%8C%E7%A8%8B%E5%BA%8F.zip

 

監控端源碼:

http://files.cnblogs.com/files/ryhan/%E7%9B%91%E6%8E%A7%E7%AB%AF%E6%BA%90%E7%A0%81.zip

 

服務端源碼:

http://files.cnblogs.com/files/ryhan/%E6%9C%8D%E5%8A%A1%E7%AB%AF%E6%BA%90%E7%A0%81%28%E5%8D%9A%E5%AE%A2%E4%B8%AD%E5%AE%9E%E7%8E%B0%29.zip

 

PS:

  1.建議用VS2010打開

  2.監控端cv_src目錄下cv3.sln為監控客戶端程序,用來看畫面,cameras.config配置視頻源

  3.HttpImageStream是本次實現的圖片推送Demo 效率上估計有點問題。

  4.運行HttpImageStream時,建議電腦上有攝像頭,不然估計會無法啟動。

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved