<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12
      【Talk is cheap. Show me the code.】 公眾號如有回復不及時的,麻煩點擊聯系關于我-聯系博主,微信我。謝謝!
      老帥哥

      Stephen-kzx的博客

      【Talk is cheap. Show me the code.】【公眾號如有回復不及時的,麻煩點擊聯系關于我-聯系博主,微信我。謝謝!】

      C# 視頻監控系統(提供源碼分享)

        去過工廠或者倉庫的都知道,在工廠或倉庫里面,會有很多不同的流水線,大部分的工廠或倉庫,都會在不同流水線的不同工位旁邊安裝一臺電腦,一方面便于工位上的師傅把產品的重要信息錄入系統,便于公司系統數據采集分析。另一方面嚴謹的工廠或倉庫也會在每個工位上安裝攝像頭,用于采集或監控流水線上工人的操(是)作(否)習(偷)慣(懶)。

        好了,閑話少說,咱們直入主題吧!

        本系統監控系統,主要核心是使用AForge.NET提供的接口和插件(dll),感興趣的朋友也可以去他們官網查看文檔http://www.aforgenet.com/framework/documentation.html

        Talk is cheap,show me the code!

        系統初始化時,首先檢查工位的機臺是否開啟了攝像頭,具體檢測代碼如下:

       /// <summary>
      /// 監控bind
      /// </summary>
      private void bind()
      {
          try
          {
              FilterInfoCollection videoDevices = new FilterInfoCollection(FilterCategory.VideoInputDevice);
              if (videoDevices.Count <= 0)
              {
                  MessageBox.Show("請連接攝像頭");
                  return;
              }
              else
              {
                  CloseCaptureDevice();
                  if (!Directory.Exists(path)) Directory.CreateDirectory(path);
        
                  videoSource = new VideoCaptureDevice(videoDevices[0].MonikerString);
                  videoSource.VideoResolution = videoSource.VideoCapabilities[0];
                  sourcePlayer.VideoSource = videoSource;
                  sourcePlayer.Start();
              }
          }
          catch (Exception ex)
          {
              MessageBox.Show(ex.Message);
          }
      }

        好了,攝像頭沒問題,咱在檢查網絡是否正常(這事兒可以交給運維,當然也可以通過程序控制,具體校驗網絡代碼比比皆是,此處忽略,如有興趣的朋友可以在公眾號Call我一起探討),至于為什么要校驗網絡,一部分是用于機臺系統的數據采集,另一部分就是錄制的視頻文件不可能存儲在工位機臺上,不然流水線和工位足夠多,豈不是一個工位一個幾天的查看視頻監控嘛!咱這都是智能化時代,錄制的視頻可以保存在本地,不過為了方便起見,需要定時清理,定時上傳到服務器便于領導審查。視頻上傳到服務器一般用到最多的莫非兩種情況,1.網絡足夠穩定,足夠快的可以直接和服務器開個磁盤映射(共享目錄),視頻錄制完后系統直接剪切到服務器保存即可。2.把不同時段錄制的視頻先存儲到本地,然后單獨開發個定時任務FTP定時上傳即可。今天先跟大家分享下第一種方法,第二種方法也比較簡單,有興趣的朋友可以公眾號call我一起探討。

        不知不覺又扯了一堆廢話,都是實在人,直接上源碼吧:

      /// <summary>
      /// 開啟或者關閉程序后將多余文件copy到相應目錄,并開啟磁盤映射上傳到共享目錄
      /// </summary>
      private void CopyFilesToServer()
      {
          try
          {
              //遍歷 當前PC文件夾外是否存在視頻文件,如存在,移動到目標目錄 
              string newPath = path + MacAddressPath + @"-Video\";
              if (!Directory.Exists(newPath)) Directory.CreateDirectory(newPath);
              //將上一次最后一個視頻文件轉入目錄
              var files = Directory.GetFiles(path, "*.wmv");
              foreach (var file in files)
              {
                  FileInfo fi = new FileInfo(file);
                  string filesName = file.Split(new string[] { "\\" }, StringSplitOptions.RemoveEmptyEntries).LastOrDefault();
                  fi.MoveTo(newPath + filesName);
              } 
          }
          catch (Exception ex)
          {
              //TODO:異常拋出
          }
          finally
          {
              uint state = 0;
              if (!Directory.Exists("Z:"))
              {
                  //計算機名
                  string computerName = System.Net.Dns.GetHostName();
                  //為網絡共享目錄添加磁盤映射 
                  state = WNetHelper.WNetAddConnection(computerName + @"\" + netWorkUser, netWorkPwd, netWorkPath, "Z:");
              }
              if (state.Equals(0))
              {
                  //本地磁盤視頻文件copy到網絡共享目錄
                  CopyFolder(path + MacAddressPath + @"-Video\", zPath); 
              }
              else
              {
                  WNetHelper.WinExec("NET USE * /DELETE /Y", 0);
                  throw new Exception("添加網絡驅動器錯誤,錯誤號:" + state.ToString());
              }
          }
      }

        其中CopyFolder方法代碼如下:

      #region 通過共享網絡磁盤映射的方式,講文件copy到指定網盤
        /// <summary>
        /// 通過共享網絡磁盤映射的方式,講文件copy到指定網盤
        /// </summary>
        /// <param name="strFromPath"></param>
        /// <param name="strToPath"></param>
        public static void CopyFolder(string strFromPath, string strToPath)
        {
            //如果源文件夾不存在,則創建
            if (!Directory.Exists(strFromPath))
            {
                Directory.CreateDirectory(strFromPath);
            } 
            if (!Directory.Exists(strToPath))
            {
                Directory.CreateDirectory(strToPath);
            } 
            //直接剪切moveto,本地不留副本
            string[] strFiles = Directory.GetFiles(strFromPath);
            //循環剪切文件,此處循環是考慮每日工作站最后一個文件無法存儲到根目錄,導致出現兩個視頻文件的問題
            for (int i = 0; i < strFiles.Length; i++)
            {
                //取得文件名,只取文件名,地址截掉。
                string strFileName = strFiles[i].Substring(strFiles[i].LastIndexOf("\\") + 1, strFiles[i].Length - strFiles[i].LastIndexOf("\\") - 1);
                File.Move(strFiles[i], strToPath + "DT-" + strFileName);
            }  
        }
        #endregion

         做完機臺檢查工作,也做好了視頻傳輸的工作,接下來就是視頻錄制的主角戲了,完整錄制視頻源碼如下(有疑問的朋友可以公眾號-聯系我一起探討):

      /// <summary>
              /// videosouceplayer 錄像
              /// </summary>
              /// <param name="sender"></param>
              /// <param name="image"></param>
              private void sourcePlayer_NewFrame(object sender, ref Bitmap image)
              {
                  try
                  { 
                      //寫到屏幕上的時間
                      g = Graphics.FromImage(image);
                      SolidBrush drawBrush = new SolidBrush(Color.Yellow);
      
                      Font drawFont = new Font("Arial", 6, System.Drawing.FontStyle.Bold, GraphicsUnit.Millimeter);
                      int xPos = image.Width - (image.Width - 15);
                      int yPos = 10;
      
                      string drawDate = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
                      g.DrawString(drawDate, drawFont, drawBrush, xPos, yPos);
      
                      //save content
                      string videoFileName = dt.ToString("yyyy-MM-dd HHmm") + ".wmv";
      
                      if (TestDriveInfo(videoFileName)) //檢測硬盤空間足夠
                      {
                          if (!stopREC)
                          {
                              stopREC = true;
                              createNewFile = true; //這里要設置為true表示要創建新文件
                              if (videoWriter != null) videoWriter.Close();
                          }
                          else
                          {
                              //開始錄像
                              if (createNewFile)
                              {
                                  //第二次錄像不一定是第二次開啟軟件時間(比如:連續多小時錄制),所以應該重新給新錄制視頻文件重新賦值命名
                                  dt = DateTime.Now;
                                  videoFileFullPath = path + dt.ToString("yyyy-MM-dd HHmm") + ".wmv";//videoFileName;
      
                                  createNewFile = false;
                                  if (videoWriter != null)
                                  {
                                      videoWriter.Close();
                                      videoWriter.Dispose();
                                  }
      
                                  videoWriter = new VideoFileWriter();
                                  //這里必須是全路徑,否則會默認保存到程序運行根據錄下了
                                  videoWriter.Open(videoFileFullPath, image.Width, image.Height, 30, VideoCodec.WMV1);
                                  videoWriter.WriteVideoFrame(image);
                              }
                              else
                              {
                                  if (videoWriter.IsOpen)
                                  {
                                      videoWriter.WriteVideoFrame(image);
                                  }
                                  if (dt.AddMinutes(1) <= DateTime.Now)
                                  { 
                                      createNewFile = true;
                                      //modify by stephen,每次寫入視頻文件后,即刻更新結束時間戳,并存入指定文件夾(目的:如果只有關閉的時候處理此操作,就會出現大于1小時的視頻文件無法更新結束時間戳,且無法轉入指定文件夾)
                                      if (videoWriter != null)
                                      {
                                          videoWriter.Close();
                                          videoWriter.Dispose();
                                      }
                                      string newPath = path + MacAddressPath + @"-Video\";
                                      if (!Directory.Exists(newPath)) Directory.CreateDirectory(newPath);
                                      string newStr = newPath + dt.ToString("yyyyMMddHHmm") + "-" + DateTime.Now.ToString("yyyyMMddHHmm") + ".wmv";
                                      FileInfo fi = new FileInfo(videoFileFullPath);
                                      fi.MoveTo(newStr); 
                                      ////轉移到網路目錄
                                      //CopyFilesToServer();
                                  }
                              }
                          }
                      }
      
                  }
                  catch (Exception ex)
                  {
                      videoWriter.Close();
                      videoWriter.Dispose();
                  }
                  finally
                  {
      
                      if (this.g != null) this.g.Dispose();
                  }
      
              }

            其中TestDriveInfo方法是用來獲取保存視頻的磁盤信息的,具體代碼如下:

      #region 獲取保存視頻的磁盤信息
        /// <summary>
        /// 獲取保存視頻的磁盤信息
        /// </summary>
        bool TestDriveInfo(string n)
        {
            try
            {
                DriveInfo D = DriveInfo.GetDrives().Where(a => a.Name == path.Substring(0, 3).ToUpper()).FirstOrDefault();
                Int64 i = D.TotalFreeSpace, ti = unchecked(50 * 1024 * 1024 * 1024);
                if (i < ti)
                {
                    DirectoryInfo folder = new DirectoryInfo(path + MacAddressPath + @"-Video\");
                    //modify by stephen,驗證當前指定文件夾是否存在元素
                    if (folder.Exists)
                    { 
                        var fisList = folder.GetFiles("*.wmv").OrderBy(a => a.CreationTime); 
                        if (fisList.Any())
                        {
                            List<FileInfo> fis = fisList.ToList();
                            if (fis.Count > 0 && fis[0].Name != n)
                            {
                                File.Delete(fis[0].FullName);
                            }
                        }
                    } 
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "處理硬盤信息出錯");
                return false;
            }
            return true;
        }
        #endregion

          當然,如果工位師傅錄入產品信息有疑問的話,也可以利用系統截圖來保留證據,這個是我自己畫蛇添足的功能,反正是為了方便嘛,別耽誤了工位師傅的辦事效率,利用攝像頭截圖代碼如下:

      try
      { 
          string pathp = $@"{Environment.GetFolderPath(Environment.SpecialFolder.MyPictures)}\";
          if (!Directory.Exists(pathp)) Directory.CreateDirectory(pathp);
          if (sourcePlayer.IsRunning)
          {
              BitmapSource bitmapSource = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
            sourcePlayer.GetCurrentVideoFrame().GetHbitmap(),
            IntPtr.Zero,
            Int32Rect.Empty,
            BitmapSizeOptions.FromEmptyOptions());
              PngBitmapEncoder pE = new PngBitmapEncoder();
              pE.Frames.Add(BitmapFrame.Create(bitmapSource));
              string picName = $"{pathp}{DateTime.Now.ToString("yyyyMMddHHmmssffffff")}.jpg";
              if (File.Exists(picName))
              {
                  File.Delete(picName);
              }
              using (Stream stream = File.Create(picName))
              {
                  pE.Save(stream);
              }
          }
      }
      catch (Exception ex)
      {
          MessageBox.Show(ex.Message);
      }

          代碼比較簡單,就不寫備注了。當然部署系統的時候也不是一帆風順,有的工廠或者倉庫會購買第三方的攝像頭,礙于工位環境,攝像頭有可能與機臺角度偏差較大,所以我又畫蛇添足的了校驗攝像頭的小功能,可以左右90°上下180°畫面翻轉,具體代碼如下:

      #region  設置攝像頭旋轉調整
        if (image != null)
        {
            RotateFlipType pType = RotateFlipType.RotateNoneFlipNone;
            if (dAngle == 0)
            {
                pType = RotateFlipType.RotateNoneFlipNone;
            }
            else if (dAngle == 90)
            {
                pType = RotateFlipType.Rotate90FlipNone;
            }
            else if (dAngle == 180)
            {
                pType = RotateFlipType.Rotate180FlipNone;
            }
            else if (dAngle == 270)
            {
                pType = RotateFlipType.Rotate270FlipNone;
            } 
            // 實時按角度繪制
            image.RotateFlip(pType);
        }
        #endregion 

        當然,站在公司角度,為了防止工位師傅手誤(誠心)關掉視頻監控程序,我們也可以從程序的角度來防患于未然,比如禁用程序的關閉按鈕,禁用工具欄右鍵程序圖標關閉程序的操作。

         我們可以重寫窗口句柄來防止,具體代碼如下:

      #region 窗口句柄重寫,禁用窗體的關閉按鈕      
      private const int CP_NOCLOSE_BUTTON = 0x200;
      protected override CreateParams CreateParams
      {
          get
          {
              CreateParams myCp = base.CreateParams;
              myCp.ClassStyle = myCp.ClassStyle | CP_NOCLOSE_BUTTON;
              return myCp;
          }
      }

        至此,系統代碼告一段路,一起來看看軟件效果吧!(請自動忽略視頻內容,以及筆記本攝像頭帶來的渣渣像素

         最后,由于系統引用文件較多,壓縮后源碼文件仍然很大,如果有需要源碼的朋友,可以微信公眾號聯系博主,源碼可以免費贈予~!有疑問的也可以CALL我一起探討,最最后,如果覺得本篇博文對您或者身邊朋友有幫助的,麻煩點個關注!贈人玫瑰,手留余香,您的支持就是我寫作最大的動力,感謝您的關注,期待和您一起探討!再會!(公眾號回復:視頻或者監控獲取源碼)

      posted @ 2020-03-09 11:18  何以解憂唯有*碼  閱讀(5283)  評論(11)    收藏  舉報
      主站蜘蛛池模板: 99国产精品白浆无码流出| 国産精品久久久久久久| 99re6这里有精品热视频| 国产永久免费高清在线观看 | 动漫AV纯肉无码AV电影网| 成人午夜污一区二区三区| 偷柏自拍亚洲综合在线| 久久精品蜜芽亚洲国产av| 日本久久一区二区免高清| 天堂а√在线中文在线| 亚洲欧洲日产国产av无码| 亚洲黄色一级片在线观看| 蜜桃av亚洲精品一区二区| 亚洲日韩成人无码不卡网站| 日韩熟妇中文色在线视频| 亚洲AV日韩精品久久久久| 永久无码天堂网小说区| 精品日本乱一区二区三区| 亚洲国产另类久久久精品小说| 日韩av在线一区二区三区| 久久精品国产亚洲av天海翼| 国产午夜福利短视频| 中文字幕第一页亚洲精品| 韩国精品久久久久久无码| 亚洲av鲁丝一区二区三区黄| 尤物国精品午夜福利视频| 色视频在线观看免费视频| 日韩丝袜欧美人妻制服| 一区二区三区四区精品黄| 国产一区二区三四区| 欧美videos粗暴| 甘谷县| 福利一区二区在线播放| 无码一区中文字幕| 性虎精品无码AV导航| 日韩V欧美V中文在线| 国产精品一区二区三区91| 色综合AV综合无码综合网站| 国产精品户外野外| 亚洲精品一区二区三天美| 欧美巨大巨粗黑人性aaaaaa|